ESP 协处理器 WiFi 安全测试工具
作者:钟智强 · 哪吒网络安全
WifiSec 是 Go 编写的无线安全测试工具,采用 Hexagonal Architecture:应用编排不感知底层注入方式,平台能力收敛在 adapter 层。
核心特性:
| 特性 | 描述 |
|---|---|
| 协处理器注入 | 帧注入跑在 ESP8266/ESP32 板载射频上,宿主机零依赖,macOS/Linux/Windows/Termux 免 root |
| 能力位图协商 | 握手时固件上报协议版本与能力位(bit0 = 5GHz),主机按能力分发,不猜板型 |
| 全链路日志 | 复位握手 → 扫描 → 命中 → 注入 → Ctrl-C 统计,每阶段可观测,串口占用进程点名 |
| 802.11 帧构造 | deauth 帧在 internal/ieee80211 纯字节编解码层构造,与传输介质解耦,可独立单测 |
| 跨平台原生路径 | Linux iw+AF_PACKET、Windows Npcap+WlanHelper、macOS CoreWLAN 扫描,按构建标签分发 |
| SSID/BSSID 双选 | 目标可传 SSID(同名多 AP 全部命中、轮流切信道)或 BSSID(精确锁定) |
| 串口诊断 | VID:PID 芯片识别、复位时序、74880 噪声重同步、占用进程(lsof)点名 |
| 表驱动测试 | 协议编解码、AP 解析去重、MAC 归一化、CLI 校验等关键逻辑集中在 tests/ 独立 package |
中华人民共和国境内法律红线:《中华人民共和国网络安全法》第二十七条明确禁止任何个人和组织从事非法侵入他人网络、干扰他人网络正常功能、窃取网络数据等危害网络安全的活动;对他人无线网络实施 deauth 干扰,可能同时触犯《中华人民共和国刑法》第二百八十五条第三款(提供侵入、非法控制计算机信息系统程序、工具罪)与第二百八十六条(破坏计算机信息系统罪)。本工具仅限自有网络或已获书面授权的测试环境使用,使用者须自行确认符合所在地法律法规。
左:串口设备枚举代码与 `wifisec serial` 输出 · 右:CoreWLAN 扫描封装与 `wifisec list` 输出
wifisec brute 在线爆破:逐次尝试带耗时,命中即停并输出 SSID/BSSID/密码凭证块(macOS 本机网卡路径)
两条注入路径按构建与平台自动分发:
| 路径 | 原理 | 平台 | 权限 |
|---|---|---|---|
| ESP 协处理器(默认) | 帧注入在板载 ESP8266/ESP32 射频上完成,宿主机经 USB 串口下发协议帧 | macOS / Linux / Windows / Termux | 无需 root |
| Linux 原生 | iw 创建 monitor 接口 + AF_PACKET 原始套接字 |
Linux / Termux(Android) | root 或 CAP_NET_RAW |
| Windows 原生 | Npcap 驱动注入 + WlanHelper 切 monitor | Windows | 管理员 + Npcap |
| macOS 原生 | 不可用——Apple 未开放任何公开的 802.11 帧注入 API,返回精确技术说明 | macOS | - |
macOS 用户走协处理器路径即可:插一块 ESP8266 开发板(约十元),烧录固件后全部功能免 root 可用,同时绕过系统对 BSSID 的定位脱敏。
权限不足时(非 root / 非管理员),命令启动前自动弹出 GUI 提示窗说明所需权限:Linux 走 zenity/kdialog(桌面环境缺失时静默回退终端文本),Windows 走 MessageBoxW;macOS 首次定位授权先弹品牌预提示窗(WiFi Logo + 授权说明),系统弹窗期间显示等待窗。
应用层只依赖端口(frameWriter / channelSetter / wirelessScanner 等),五个平台 adapter 提供实现;串口帧协议见下文。
flowchart TB
CLI["cmd/wifisec/main.go<br/>命令路由: list / serial / deauth / jam / brute / clone / devices / scan_ports / sniff / bind / shell / get_packet / pmkid / extract / ids / help"] --> APP["internal/functions<br/>应用编排: deauther · jammer · brute · clone · devices · portscan · lateral · sniff · pmkid · extract · ids · lists · serial"]
APP -->|"端口: frameWriter<br/>channelSetter"| ESP["internal/platform/esp<br/>串口帧协议 · 复位时序 · 噪声重同步"]
APP -->|"端口: 无线扫描"| DAR["darwin · CoreWLAN"]
APP --> LIN["linux · iw + AF_PACKET<br/>termux · Android API"]
APP --> WIN["windows · Npcap + netsh"]
APP --> LAN["lan · 邻居表/网关<br/>capture · AF_PACKET/BPF/Npcap"]
APP -->|"端口: writer<br/>fwd"| RAW["原始帧发送 · IP 转发开关<br/>mitm · ARP 毒化状态机"]
ESP -->|"115200 8N1"| HW["ESP8266 / ESP32<br/>core/esp/esp.ino"]
IEEE["internal/ieee80211<br/>deauth / disassoc 帧纯字节编解码"] -.-> APP
PCAP["internal/pcapfile + ethernet<br/>pcap 写入器 · 帧摘要"] -.-> LAN
WIDS["internal/wids<br/>无线 IDS 纯检测引擎<br/>快照差分 + 帧滑窗计数"] -.-> APP
PMK["internal/rsnie · eapol · pmkid<br/>RSN IE 状态机 · EAPOL M1-M4 配对<br/>PMKID 主动获取 · hashcat 22000/16800"] -.-> APP
ESP --> HW2["射频注入<br/>wifi_send_pkt_freedom / esp_wifi_80211_tx"]
📁 图表源码:flow.puml(deauth 执行流程)| sequence.puml(串口协议时序)
wifisec list # 列出无线接口与周边网络
wifisec serial # 列出 USB 串口设备(协处理器入口排查)
wifisec deauth <ssid|bssid> [串口] # 对目标持续发送 deauth 帧,Ctrl-C 停止
wifisec jam <ssid|all|bssid> [串口] # deauth+disassoc 双帧全频段干扰,jam all 打所有可见 AP;未插板回落本机网卡
wifisec brute <ssid|bssid> with-pass: <字典> [串口] # 在线密码字典爆破,命中即停
wifisec clone <ssid>:<密码> up [nokick] [串口] # 克隆同名热点(Evil Twin),Ctrl-C 结束
wifisec clone down [串口] # 停止固件上的克隆热点
wifisec devices [网卡名] # 列出当前局域网在线设备(IP/MAC/主机名/网关),免 root
wifisec sniff [--recon] [--spoof] [--targets ip1,ip2] [--iface 网卡] # bettercap 风格事件流(需 root/管理员);--recon ARP 扫描预填充主机表,--spoof ARP 欺骗 MITM,退出自动还原
wifisec scan_ports <目标> [端口] # nmap 风格 TCP 扫描:open/closed/filtered + banner
wifisec bind [--port N] [--token 令牌] # 被控端:bind shell 监听,等待控制端接入
wifisec <ip> bash [--token 令牌] # 控制端:交互 shell(IP 开头自动路由)
wifisec <ip> whoami [--token 令牌] # 控制端:单命令一步执行,退出码映射本地
wifisec get_packet [网卡] [秒] [文件] # 抓包导出 pcap(Wireshark 直读),Ctrl-C 结束
wifisec get_packet --eapol [网卡] [秒] [文件] # 同上,实时分析 EAPOL 握手并按 --bssid/--ssid 过滤
wifisec pmkid <ssid|bssid> [网卡] [-o out.22000] # 主动获取 PMKID(免客户端、免踢人),产出 hashcat 22000 行
wifisec extract capture.pcap [--hashcat out.22000] [--pmkid out.16800] # 离线分析 pcap:握手数/PMKID/帧合法性,择优导出
wifisec ids [SSID] [网卡] [秒数] # 无线入侵检测:伪造AP/KARMA/降级/泛洪/deauth 风暴,可锁定单个 SSID
wifisec heatmap [SSID] [平面图.txt] # TUI 信号热力图:走位采样 + IDW 插值 + AP 方位估计,免 root
wifisec help # 用法总览
wifisec man <主题> # 阅读内置手册页(无参列出全部主题)| 命令 | 功能 | 详细文档 |
|---|---|---|
list |
无线接口枚举与周边网络扫描 | wifi_list.md |
serial |
串口设备发现与 VID:PID 判读 | wifi_serial.md |
deauth |
802.11 deauthentication 帧注入 | wifi_deauth.md |
jam |
deauth + disassoc 双帧全频段干扰,jam all 扫描全部可见 AP 逐个打击;未插板自动回落本机网卡 |
wifi_jam.md |
brute |
在线密码字典爆破,命中即停并输出 SSID/BSSID/密码凭证块(ESP 协处理器;无设备时回落本机网卡) | wifi_brute_force.md |
clone |
热点克隆(Evil Twin):同名同密码 SoftAP + 可选 kick 驱赶真实 AP 客户端(ESP 协处理器;无设备时回落 Linux hostapd) | wifi_clone.md |
devices |
局域网设备发现:TCP 探针刷 ARP + 系统邻居表交叉,输出 IP/MAC/主机名/角色,四平台免 root | lan_analysis.md |
sniff |
bettercap 风格事件流(需 root/管理员):DNS/HTTP/SNI/ARP/凭据/主机上线实时标注;--recon ARP 扫描预填充主机表;--spoof 双向 ARP 毒化 + IP 转发 + redirect 压制的透明 MITM,退出自动还原(Windows 欺骗不支持,被动可用) |
wifi_sniff.md |
scan_ports |
nmap 风格 TCP connect 扫描(200 并发、1.5s 超时),open/closed/filtered 三态 + 被动 banner 抓取,四平台免 root | lan_analysis.md |
bind / shell |
横向移动:被控端 bind shell 监听 TCP(HMAC 挑战应答认证,令牌不落网),控制端 wifisec <ip> bash 交互 shell 或单命令一步执行,stdout/stderr 实时回传,超时击杀回退出码 124 |
lateral_movement.md |
get_packet |
连接态网卡抓包:Linux AF_PACKET / macOS BPF / Windows Npcap,实时摘要限速打印,全帧写 pcap 供 Wireshark 分析;--eapol 实时分析握手,--pmkid 主动会话与抓包共存 |
lan_analysis.md · wifi_pmkid.md |
pmkid |
PMKID 主动获取:假客户端发 Auth+Assoc 抓 RSN IE 中的 PMKID,免客户端、免踢人、不怕 802.11w,产出 hashcat 22000 行 | wifi_pmkid.md |
extract |
pcap 离线提取:握手数 / PMKID 有无 / 各帧合法性,同一 AP 双证据时优先 PMKID,--hashcat/--pmkid/--json 导出 |
wifi_pmkid.md |
ids |
无线入侵检测:扫描差分(伪造AP/KARMA/加密降级/弱加密盘点,免 root)+ 帧级监测(deauth 风暴/信标泛洪,需特权),防御视角 | wireless_ids.md |
heatmap |
TUI 信号热力图:走位勘测(空格钉采样、IDW 插值成面、AP 方位估计、风险徽章),退出自动落盘 JSON,免 root | wifi_heatmap.md |
| 文档站 | HTML/JS/CSS 静态文档 | docs/index.html(Arco Design 风格) |
主机 ↔ 固件帧格式(小端,双向各一个魔数防方向错乱):
| 方向 | 帧头 | 帧格式 |
|---|---|---|
| 主机 → ESP | 0xA5 |
[A5][cmd][len_lo][len_hi][payload] |
| ESP → 主机 | 0x5A |
[5A][cmd][len_lo][len_hi][payload] |
| cmd | 方向 | 含义 | payload |
|---|---|---|---|
0x00 |
主机→ESP | PING | 无 |
0x00 |
ESP→主机 | PONG | 协议版本(1) + 能力位图(1),bit0 = 5GHz |
0x01 |
主机→ESP | 扫描 | 无 |
0x01 |
ESP→主机 | 扫描条目 | bssid(6) + channel(1) + rssi(1) + ssidLen(1) + ssid |
0x02 |
ESP→主机 | 扫描结束 | 无 |
0x02 |
主机→ESP | 注入 | 信道(1) + 802.11 帧(已剥 radiotap) |
0x03 |
主机→ESP | 关联尝试 | ssidLen(1) + ssid + passLen(1) + password |
0x03 |
ESP→主机 | 关联结果 | result(1):0 = 密码错误/超时,1 = 关联成功 |
0x04 |
ESP→主机 | 错误 | 出错命令(1) + 错误码(1) |
0x05 |
主机→ESP | 克隆开关 | op(1) + channel(1) + ssidLen(1) + ssid + passLen(1) + password |
0x05 |
ESP→主机 | 克隆结果 | result(1) + apMAC(6);down 回复 MAC 全零 |
0x06 |
主机→ESP | 克隆状态 | 无 |
0x06 |
ESP→主机 | 在线设备 | count(1) + count×MAC(6) |
两个关键设计:
- 复位时序——打开串口先 DTR 拉低 → RTS 复位 100ms → 释放。NodeMCU 自动复位电路把 DTR 接到 GPIO0,驱动默认电平会把芯片锁进 ROM 下载模式(115200 完全静默)。
- 噪声重同步——ESP 上电以 74880 输出启动日志,在 115200 下是随机字节;解析器逐字节丢弃直至帧头
0x5A,残缺帧保留待下一段拼齐。
wifisec/
├── cmd/wifisec/main.go # 入口:命令注册与路由(list/serial/deauth/jam/brute/clone/devices/scan_ports/sniff/bind/shell/get_packet/pmkid/extract/ids/help)
├── core/esp/esp.ino # 协处理器固件(ESP8266/ESP32 全系,编译期条件分支)
├── internal/
│ ├── constants/ # 开发者元数据等常量
│ ├── functions/ # 应用编排:deauther · jammer · connect(brute) · clone · devices · portscan · lateral · sniff · pmkid · extract · ids · lists · serial · help
│ ├── ethernet/ # 帧摘要(ARP/IPv4/IPv6/TCP/UDP/ICMP/EAPOL)+ ARP 帧构造 + DNS/HTTP/SNI 应用层解析
│ ├── ieee80211/frame.go # deauth / disassoc 帧纯字节编解码(与介质解耦,可独立单测)
│ ├── rsnie/parse.go # RSN IE(0x30) 状态机解析:密码套件/AKM/RSN 能力/PMKID 列表,malformed 即弃
│ ├── eapol/ # EAPOL-Key 帧解析与 M1-M4 配对,归一 Candidate → hashcat 22000/16800
│ ├── pmkid/client.go # PMKID 主动获取状态机(随机 STA MAC · 重试退避 · 失败分类)
│ ├── lateral/ # 横向移动通道:HMAC 挑战应答认证 + 长度前缀帧(bind 服务执行 / client 交互)
│ ├── mitm/spoof.go # ARP 欺骗状态机:1s 双向毒化 · who-has 即时应答 · 5 轮真实 MAC 恢复
│ ├── model/ # wifi / command / author 领域模型
│ ├── pcapfile/pcap.go # 纯 Go pcap v2.4 写入器(Wireshark/tcpdump 直读)
│ ├── heatmap/survey.go # 走位勘测纯数据层(网格采样 · IDW 插值 · JSON 落盘)
│ ├── wids/wids.go # 无线 IDS 纯检测引擎(快照差分 + 帧滑窗计数,可注入测试)
│ ├── platform/
│ │ ├── darwin/ # CoreWLAN 扫描 + reexec(TCC 定位授权 bundle)
│ │ ├── esp/esp.go # 串口帧协议 · 复位时序 · 噪声重同步 · 能力位图
│ │ ├── lan/ # 邻居表与默认网关读取(/proc/net/arp · arp -an · arp -a)
│ │ ├── capture/ # 抓包源:Linux/Android AF_PACKET · macOS BPF · 无平台错误桩
│ │ ├── writer/ # 原始帧发送:与 capture 同构的三平台端口(写侧独立句柄)
│ │ ├── fwd/ # IP 转发 + ICMP redirect 开关(备份旧值 → 开 → 退出还原)
│ │ ├── linux/ # iw 解析 · monitor · AF_PACKET 注入 · Android
│ │ ├── termux/ # Android Termux API 适配
│ │ └── windows/ # netsh 解析 · Npcap/WlanHelper 注入与抓包
│ ├── radio/regulatory.go # 信道合规边界
│ ├── security/permission.go # 按 operation 判断权限,不无条件要求 root
│ └── utilities/ # argv · logger · platform
├── tests/ # 全部 *_test.go(独立 package,表驱动测试)
├── docs/
│ ├── index.html # 文档站入口(Arco Design 风格静态站)
│ ├── logo.svg # 项目 Logo
│ ├── src/style/ · src/scripts/ # 文档站样式(SCSS 源 + 编译产物)与交互脚本
│ ├── diagram/ # PlantUML:执行流程 + 串口协议时序
│ └── feature/ # wifi_list / wifi_serial / wifi_deauth / wifi_jam / wifi_brute_force / wifi_clone / lan_analysis / wifi_sniff / lateral_movement / wireless_ids / wifi_heatmap / wifi_pmkid 详细文档
├── Makefile # build / list / test / 等构建编排
└── .githooks/ # Conventional Commits 提交信息校验钩子
打 tag(v*)会触发 CI 自动发布到 GitHub Releases,含三平台产物:
| 平台 | 文件 | 说明 |
|---|---|---|
| macOS | wifisec-macos-app.zip |
解压后得 wifisec.app,定位授权依赖 bundle |
| Linux (amd64) | wifisec-linux-amd64 |
单文件二进制,chmod +x 后运行 |
| Linux (arm64) | wifisec-linux-arm64 |
树莓派 / ARM 服务器 |
| Android (Termux) | wifisec-android-arm64 |
下载后 chmod +x 直接运行,无需 Go 环境 |
| Windows | wifisec-windows-amd64.exe |
单文件可执行 |
gh release download --repo ctkqiang/wifisec --pattern 'wifisec-linux-amd64' # 按文件名下载go install github.com/ctkqiang/wifisec/cmd/wifisec@latest
go install取包路径最后一段作为二进制名(cmd/wifisec→wifisec)。二进制默认写入$(go env GOPATH)/bin/(macOS/Linux/Termux 通常为~/go/bin/)。若安装后提示command not found,是该目录不在PATH中,一次性追加即可:echo 'export PATH=$PATH:$HOME/go/bin' >> ~/.bashrc # Termux/bash;zsh 用户写 ~/.zshrc source ~/.bashrc
- Go 1.26+,无 CGO 依赖
- 协处理器路径另需:一块 ESP8266/ESP32 开发板 + USB 数据线
make build # 编译至 build/wifisec
make list # 扫描无线接口与周边网络
make test # 运行测试
make help # 查看全部 make targetmacOS 的 make build 会产出 build/wifisec.app bundle 并建同名符号链接:定位授权(TCC)弹窗只对 LaunchServices 激活的 bundle 呈现,裸二进制的授权请求会被系统静默丢弃;符号链接保留 ./build/wifisec list 的 CLI 使用习惯。其他平台为单个二进制。
无需构建,直接打开或托管:
open docs/index.html # 本地浏览
# 或托管 docs/ 目录(GitHub Pages 等任意静态托管)固件源码 core/esp/esp.ino,一份源码经编译期条件分支覆盖 ESP8266 / ESP32 全系(仅 ESP32-C5 具备 5GHz 注入能力,主机按固件握手的能力位图自动识别,不猜板型)。
推荐 arduino-cli(完整流程与板型选型表见 wifi_deauth.md §5.4):
arduino-cli compile \
--fqbn esp8266:esp8266:nodemcuv2:baud=115200,xtal=80,eesz=4M2M \
--build-path /tmp/esp-build core/esp/esp.ino
arduino-cli upload --fqbn esp8266:esp8266:nodemcuv2 \
--input-dir /tmp/esp-build -p /dev/cu.usbserial-XXXX core/esp/esp.ino
⚠️ **板型必须与实际硬件一致。**板型携带晶振参数:选成 40MHz 晶振的板型而板子实为 26MHz 时,115200 实际跑成 74880——表现为「串口有数据但不是有效 PONG」。手动下载模式按键、--no-stub兜底等排错见 wifi_deauth.md §5.5。
测试集中在 tests/ 独立 package,仅访问各 package 导出标识符,以表驱动测试覆盖协议编解码、AP 解析去重、MAC 归一化、CLI 校验等关键逻辑:
make test- 仅 deauth 一种帧类型,帧构造收敛在
internal/ieee80211纯字节编解码层;不自动增加新的 packet type、credential collection、persistence 或 exploit 能力。 - 固件 payload 上限 512 字节,超长直接拒绝,防缓冲区溢出。
- 权限按 operation 判断(
internal/security),不无条件要求 root;错误信息说明实际所需权限。 - 命令一律参数列表执行(
exec.Command("iw", "dev", ...)),禁止 shell 拼接用户输入。 - 运行
list时不要加 sudo——root 在 GUI 会话之外弹不出定位授权窗。
本项目仅用于授权范围内的无线安全评估与教学实验。在中华人民共和国境内使用须遵守《中华人民共和国网络安全法》《中华人民共和国刑法》的相关规定(详见项目概述中的法律红线说明);对未授权网络使用属违法行为,后果由使用者自行承担。
本项目采用 GNU General Public License v3.0 开源许可证:
- 可自由使用、修改与分发源代码
- 修改后再分发须同样以 GPL-3.0 开源
- 分发时必须附许可证全文与版权声明
