Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
Pi-Zero-2W-Bad-USB — Configure your Pi Zero 2W to be a BadUSB | Kitploit
工具/GitHubGitHub/psycostea/pi-zero-2w-bad-usb
Embedded Systems SecurityExploitationScripting & AutomationHardware HackingCTFPenetration TestingLearning & EducationRed TeamingPayload Development
GitHubpsycostea/pi-zero-2w-bad-usb

Pi-Zero-2W-Bad-USB

Configure your Pi Zero 2W to be a BadUSB

3722个月前Kitploit 审核通过

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
查看仓库

Raspberry Pi Zero 2 W BadUSB HID 工具包

一个基于 Raspberry Pi Zero 2 W 构建的可编程 BadUSB / HID 攻击平台。 Pi 枚举为 USB 复合设备(键盘加一个可选的只读大容量存储卷),并在插入的主机上执行 Ducky-Script 风格的载荷。专为授权的红队演练、渗透测试和 CTF 设计。

⚠️ 法律声明。 仅在您拥有或已获得明确书面许可测试的系统上使用。未经授权的访问在大多数司法管辖区是非法的,声称不知道也无济于事。


目录

  1. 功能特点
  2. 工作原理
  3. 硬件要求
  4. 软件要求
  5. 安装
  6. 日常操作
  7. 编写载荷
  8. 配置参考
  9. 架构说明
  10. 测试
  11. 故障排除
  12. 仓库结构
  13. 致谢

功能特点

  • 可编程按键载荷,使用与 Ducky-Script 兼容的方言。
  • 可靠的主机连接检测,通过 UDC configured 状态实现——不会在启动时错误触发载荷。
  • 真正的“攻击间重置”,在 Pi Zero 2 W 硬件上有效。拔下、重新插入、再次触发——无需断电。
  • 可配置的安全防护,防止设备长时间插入导致失控循环:每次触发最小间隔和每分钟触发次数限制,均可通过环境变量覆盖。
  • 可选的大容量存储复合小工具,由平面镜像文件支持(默认为只读——暴露 live SD 卡是过去难以调试的文件系统损坏陷阱)。
  • 美国和 UK 键盘布局,可通过 LAYOUT 分别为每个载荷选择。
  • 支持变量、IF / ELSE、WHILE、HOLD / RELEASE、INJECT_MOD、RANDOM_* 生成器、STRING_BLOCK / STRINGLN_BLOCK、DEFINE。
  • systemd 集成,使用 ExecStop 干净地拆除小工具。不会遗留 configfs 状态,无需重启即可重新启动。
  • udev 管理的权限,用于 /dev/hidg0——没有全局可写的设备节点。
  • 34 个测试的 pytest 套件,用于 Ducky 解析器,可在任何主机上运行,无需连接 Pi。
  • 每次载荷运行后的 ACT LED 状态指示。

工作原理

root@kitploit:~
+----------------+        USB 数据线        +-------------+
|  Raspberry Pi  | ===================>>>  |  主机 PC     |
|  Zero 2 W      |   (Pi 模拟 HID + 可选驱动) |  (目标)     |
|  (本设备)      |                         |             |
+----------------+                         +-------------+
        |
        |  /home/pi/pi-badusb/
        |
        +-- badusb.service ----> monitor_and_run.py
                                   |
                                   |  当 `state == configured` 时:
                                   v
                                 run_payload.py
                                   |
                                   v
                                 /dev/hidg0  (USB HID 小工具)
  1. 启动时,badusb.service systemd 单元运行 gadget_setup.sh,它使用 configfs/libcomposite 组合一个 USB 小工具,包含 HID 键盘功能和(可选)由 /var/badusb/storage.img 平面镜像文件支持的大容量存储 LUN。
  2. 然后该单元运行 monitor_and_run.py。它轮询 /sys/class/udc/<udc>/state 并等待 configured——这是 USB 规范状态,表示主机已成功枚举小工具。(我们不使用 /dev/hidg0 的存在作为信号:因为小工具在启动时绑定到 UDC 时该节点就已存在,无论是否插入任何设备。)
  3. 当主机连接时,监听器执行 run_payload.py,解析 payload.txt 并将 HID 报告写入 /dev/hidg0。
  4. 载荷完成后,监听器主动解除小工具与 UDC 的绑定(Pi Zero 2 W 无法通过软件检测物理断开——请参阅架构说明),休眠冷却时间,然后重新绑定。设备随后等待下一次 configured 状态转换。

硬件要求

组件说明
Raspberry Pi Zero 2 W已在 2026-05 硬件版本上测试。较旧的 Pi Zero W 使用 BCM2835 dwc_otg 驱动程序理论上也可行,但本文档假设使用带 dwc2 的 2 W。
micro-USB 转 USB-A 数据线或“U 盘”形式适配器,使 Pi 可直接插入主机端口。
可选:独立充电器如果希望从非主机源为 Pi 供电,以便监听器在插入目标之前启动(否则主机端口提供电源)。

Pi Zero 2 W 有两个 micro-USB 端口:

  • PWR IN — 仅供电,不向 dwc2 OTG 模块暴露 USB 数据线。
  • USB — OTG 数据端口;此处插入目标。

软件要求


安装

克隆或复制仓库到 Pi,然后运行安装程序:

root@kitploit:~
git clone http://your-gitea/admin/Pi-Zero-2W-Bad-USB.git /home/pi/pi-badusb
cd /home/pi/pi-badusb
sudo ./install.sh
sudo reboot

重启后,启用并启动服务:

root@kitploit:~
sudo systemctl enable --now badusb.service
journalctl -u badusb -f

install.sh 是幂等的——每当更改项目文件时重新运行即可。它会:

  • 检测 /boot/firmware(Bookworm+)与 /boot(旧版)。
  • 确保在 config.txt 的 [all] 块下启用 dtoverlay=dwc2,dr_mode=otg。Raspberry Pi Imager 默认将此行放在 [cm5] 过滤器中,该过滤器不适用于 Pi Zero 2 W;安装器会附加一个带标记的覆盖项,以便重新运行时不会重复。
  • 确保在 cmdline.txt 中包含 modules-load=dwc2。
  • 如果 cmdline.txt 中仍然存在 g_ether 则发出警告(它会从 libcomposite 中抢占 UDC 并破坏小工具模式)。
  • 安装 systemd 单元到 /etc/systemd/system/badusb.service。
  • 安装 udev 规则到 /etc/udev/rules.d/99-badusb-hidg.rules,使 /dev/hidg0 对 组可写。

日常操作

root@kitploit:~
# 启动 / 停止 / 重启
sudo systemctl start badusb
sudo systemctl stop badusb
sudo systemctl restart badusb              # 插入时安全操作

# 实时查看日志
journalctl -u badusb -f

# 禁用开机自启
sudo systemctl disable badusb

# 调整时间参数(创建覆盖配置)
sudo systemctl edit badusb
# (粘贴一个包含 Environment="BADUSB_REARM_COOLDOWN_S=8" 等的 [Service] 块)
sudo systemctl restart badusb

该服务依赖于 sys-kernel-config.mount 和 UDC 的存在,因此在小工具实际准备就绪之前无法触发载荷。

编辑载荷无需重启——payload.txt 每次插入时都会重新读取。


编写载荷

payload.txt 位于安装目录中。完整命令参考位于 payload_commands.md。

最小示例

root@kitploit:~
REM 打开运行对话框并通过记事本输入问候语
LAYOUT US
GUI r
DELAY 1500
STRING notepad
ENTER
DELAY 2500
STRINGLN 来自 Raspberry Pi Zero 2 W 的问候

变量、条件和循环

root@kitploit:~
VAR $USER="alice"
VAR $COUNT=0
WHILE $COUNT < 3
  STRINGLN 你好 $USER (第 $COUNT 次迭代)
  VAR $COUNT = $COUNT + 1
END_WHILE

IF $USER == "alice"
  STRINGLN 匹配
ELSE
  STRINGLN 未匹配
END_IF

VAR 中的数学表达式通过 ast 遍历安全求值器处理——不允许名称、函数调用、属性访问,仅允许数字字面量和 + - * / // % **。

按住修饰键

root@kitploit:~
HOLD SHIFT
STRINGLN 这一行都是大写
RELEASE SHIFT

发送任意修饰键组合

root@kitploit:~
REM 按住 Ctrl+Shift (0x01 + 0x02) 并敲击 A
INJECT_MOD 0x03
STRING a
REM 释放所有修饰键
INJECT_MOD 0x00

随机数

root@kitploit:~
RANDOM_LETTER 12      # 12 个随机大小写字母
RANDOM_NUMBER 6       # 6 个随机数字
RANDOM_SPECIAL 4      # 4 个随机 ASCII 符号

键盘布局

root@kitploit:~
LAYOUT UK             # 切换为 UK ISO 映射,用于后续的 STRING/STRINGLN
STRING @ " # ~ £ \ |  # 在 UK 语言环境的主机上正确输入

将另一个文件放入 keymaps/ 目录(与 us.py 和 uk.py 一起),LAYOUT <name> 指令将通过 importlib 加载它。


配置参考

大容量存储小工具(gadget_setup.sh 顶部)

这些值可以通过在手动运行 gadget_setup.sh 时设置环境变量来覆盖,或者通过单元的 Environment= 指令全局设置。

监听器可调参数(monitor_and_run.py)

覆盖示例:

root@kitploit:~
sudo systemctl edit badusb
# 在编辑器中:
# [Service]
# Environment="BADUSB_REARM_COOLDOWN_S=8"
# Environment="BADUSB_MIN_INTER_FIRE_S=20"
sudo systemctl restart badusb

架构说明

为什么监听器使用 UDC state 而不是 /dev/hidg0

之前的实现通过测试 /dev/hidg0 的存在性和可写性作为“主机已连接”的信号。该设备节点在小工具在启动时绑定到 UDC 的那一刻就创建了——远在任何主机实际枚举它之前。因此,无论 Pi 是否插入,载荷都会在上电后立即触发。

可靠的信号是 /sys/class/udc/<udc>/state,它报告 USB 规范设备状态。只有 configured 意味着主机已发出 SetConfiguration(1)——设备现在可以发送 HID 报告。

为什么我们在每次载荷后强制解除绑定

在 Pi Zero 2 W 上检测物理断开在软件层面是不可能的:该板没有将 VBUS 检测连接到 SoC 的 dwc2 OTG 模块。物理拔出后:

  • /sys/class/udc/<udc>/state 保持 configured。
  • current_speed 保持 high-speed。
  • dwc2 GOTGCTL 寄存器保持 0x000d0000(BSesVld 位设置)。
  • 没有 udev 事件触发。

因此,监听器不等待永远不会到来的信号,而是主动引起断开:每次载荷后,它将 "" 写入小工具的 UDC configfs 文件(内核解释为解除绑定),休眠 BADUSB_REARM_COOLDOWN_S 秒,然后将 UDC 名称写回以重新绑定。下次主机插入会产生一个干净的 configured 状态转换,监听器可以检测到。

如果操作员在载荷后将 Pi 保持插入状态,重新绑定会导致主机重新枚举小工具。为防止失控的触发循环,两个安全机制生效:

  1. BADUSB_MIN_INTER_FIRE_S——如果在上次触发后的这个时间窗口内发生 configured 转换,则抑制该触发并再次解除绑定。小工具在后台静默循环。
  2. BADUSB_MAX_FIRES_PER_MINUTE——滑动窗口硬上限。超过上限时,监听器暂停 BADUSB_RATELIMIT_PAUSE_S 秒并记录警告。

为什么我们从不使用 rm -rf 处理 configfs

configfs 的内核管理属性文件(bcdUSB、idVendor、webusb/*、os_desc/*……)不能通过 rm(2) 删除——内核返回 EPERM。它们仅在其父目录被 rmdir 时释放。gadget_setup.sh 和 teardown_gadget.sh 都按规范的 libcomposite 顺序遍历 configfs 树——仅使用 rmdir,从不使用 rm 处理属性文件——内核会自动清理其余内容。

为什么 Python 辅助脚本使用 os.write 而不是 file.write

通过 open(path, "w").write("") 写入空字符串不会调用 write(2) 发送零字节——CPython 的 TextIOWrapper 会省略它。对于 configfs 解除绑定(内核从移除换行符后的零长度写入解释),我们直接使用 os.write(fd, b"\n"),这样系统调用总是会发出至少一个字节。


测试

Ducky 解析器有一个 34 个测试的 pytest 套件,它针对 MockHIDEngine(一个内存中的真实 HID 编写器替代品)运行,因此不需要 Pi 或 USB 硬件。

root@kitploit:~
cd /home/pi/pi-badusb
python3 -m pytest tests/

覆盖范围包括:

  • safe_eval_math 接受算术运算,拒绝名称/函数调用/属性访问/字符串常量。
  • evaluate_condition 用于数值和区分大小写的字符串比较。
  • VAR 支持 =、+=、-=、*=、/=。
  • IF / ELSE / END_IF 正确选择分支。
  • WHILE / END_WHILE 对 < 和 <= 的迭代次数。
  • RANDOM_* 长度正确性; 无操作并警告。

故障排除

“插入后载荷从未触发”

  1. cat /sys/class/udc/*/state——主机枚举时必须达到 configured。如果保持 not attached,则主机未通信:尝试不同的数据线(有些仅充电)或不同的主机端口。
  2. lsmod | grep dwc2——必须已加载。如果只有 dwc_otg,说明 dtoverlay=dwc2,dr_mode=otg 未生效;重新运行 install.sh 并重启。
  3. 插入时运行 journalctl -u badusb -f——应在主机枚举后约 2 秒内显示 Host attached. Running payload.。

“载荷循环触发,LED 闪烁,即使拔出后也是如此”

这是一个现已修复的实际 bug。如果发生,说明您已回退到旧版 os.write 之前的版本。确保 monitor_and_run.py 与当前主分支匹配(搜索 os.write(fd, payload))。

“服务无法重启——Operation not permitted”

修复前的 gadget_setup.sh 对 configfs 使用了 rm -rf。当前版本使用 teardown_gadget()——如果看到这些错误,说明您有旧版本。从主分支重新部署。

“/dev/hidg0 权限拒绝”

udev 规则需要热插拔才能生效,或者运行 sudo udevadm trigger 并重新登录,以便 pi 用户获得 plugdev 组身份。

“安装时出现 g_ether 警告”

从 cmdline.txt 中移除 g_ether;它会在 libcomposite 绑定之前占用 UDC。

“主机显示一个 USB 驱动器,但大小不是我预期的”

大容量存储大小由 BACKING_SIZE_MB 设置,仅在首次创建后备镜像时生效。要调整大小:

root@kitploit:~
sudo systemctl stop badusb
sudo rm /var/badusb/storage.img
sudo BACKING_SIZE_MB=256 /home/pi/pi-badusb/gadget_setup.sh
sudo systemctl start badusb

“我想让 Pi 保持插入状态而不向主机发送垃圾信息”

这正是 BADUSB_MIN_INTER_FIRE_S 和 BADUSB_MAX_FIRES_PER_MINUTE 的作用。通过 systemctl edit badusb 调高它们。使用默认值时,保持插入状态的 Pi 会在第一分钟内大约每 15 秒触发一次,然后暂停 60 秒,再继续。


仓库结构

root@kitploit:~
.
├── README.md                   本文件
├── LICENSE                     MIT
├── install.sh                  幂等安装器(固件配置、systemd、udev、plugdev)
├── gadget_setup.sh             通过 configfs/libcomposite 组合 USB 小工具
├── teardown_gadget.sh          规范的 configfs 拆除(作为 ExecStop 接入)
├── reload_gadget.sh            手动 UDC 解除绑定/重新绑定辅助脚本
├── autorun.sh                  传统手动启动包装器(推荐使用 systemd)
├── monitor_and_run.py          监听器:等待主机连接,运行载荷,强制重新准备
├── run_payload.py              Ducky-Script 风格解释器
├── payload.txt                 您的载荷——自由编辑;每次插入时重新读取
├── payload_commands.md         完整命令参考
├── etc/
│   ├── badusb.service          systemd 单元
│   └── 99-badusb-hidg.rules    /dev/hidg0 所有权的 udev 规则
├── keymaps/
│   ├── __init__.py             动态布局加载器
│   ├── us.py                   美国 ANSI(默认)
│   └── uk.py                   英国 ISO
└── tests/
    ├── __init__.py
    ├── conftest.py              pytest 路径设置
    └── test_parser.py          34 个解析器测试(针对 MockHIDEngine)

致谢

  • 原始项目脚本和灵感:Psycostea。
  • USB 小工具研究:USB Rubber Ducky、Hak5、libcomposite 文档、dwc2 内核驱动。
  • 2026-05 正确性改进:重写主机连接检测、使大容量存储安全、修复多个解析器 bug、添加键盘布局抽象、将启动迁移到 systemd、添加单元测试框架,并解决了 Pi Zero 2 W 硬件层面无法检测物理断开的问题。

许可证

MIT——参见 LICENSE。

下载工具
要求原因
Raspberry Pi OS(推荐 Debian Bookworm 或 Trixie,64 位 Lite)安装脚本在 Bookworm+ 上写入 /boot/firmware/...,在旧镜像上回退到 /boot/...。
Python 3Pi OS 自带。
mkfs.vfat用于首次运行时格式化大容量存储后备镜像。如果禁用大容量存储则无需。
安装需要 root 权限涉及 systemd、udev 和 /boot/firmware/config.txt。
plugdev
  • 将 pi 用户添加到 plugdev。
  • 创建 /var/badusb/ 用于大容量存储后备镜像。
  • 变量默认值含义
    ENABLE_MASS_STORAGE1设为 0 仅使用 HID 小工具。
    BACKING_FILE/var/badusb/storage.img暴露给主机的平面镜像文件。
    BACKING_SIZE_MB64首次运行时创建,如果文件不存在。
    BACKING_LABELBADUSBFAT 卷标。
    MASS_STORAGE_RO1默认为只读。
    环境变量默认值含义
    BADUSB_POST_PAYLOAD_FLUSH_S0.5载荷执行后、解除绑定前休眠的时间,以便 HID 写入完成。
    BADUSB_REARM_COOLDOWN_S5小工具在解除绑定和重新绑定之间对主机保持“不活跃”的时间。
    BADUSB_MIN_INTER_FIRE_S10两次触发之间的最小秒数;低于此值时,触发被抑制,小工具重新解除绑定。
    BADUSB_MAX_FIRES_PER_MINUTE6硬上限;超过时,暂停 BADUSB_RATELIMIT_PAUSE_S 秒。
    BADUSB_RATELIMIT_PAUSE_S60达到速率限制后的暂停持续时间。
    RANDOM_<unknown>
  • INJECT_MOD 修饰键字节在后续按键中的持久性。
  • HOLD SHIFT 将 STRINGLN abc 中的每个字符大写。
  • LAYOUT US 与 LAYOUT UK 对 @ 和 " 产生不同报告;未知布局回退到前一个布局。
  • STRING_BLOCK 连接行;STRINGLN_BLOCK 遵守最小缩进。