Maku-hub/BadUSB
GitHub: Maku-hub/BadUSB
面向 ATMEGA32U4 的开源 USB HID 键盘模拟器固件,从 microSD 卡读取 DuckyScript 风格脚本并重放按键序列,用于授权渗透测试和安全教育。
Stars: 0 | Forks: 0
# BadUSB — ATMEGA32U4 键盘模拟器
用于 **CJMCU-32 (ATMEGA32U4)** 开发板的固件,可将其变成一个可编程的 USB 键盘模拟器 (HID)。一旦插入计算机,该设备将使用类似于 **DuckyScript** (Rubber Ducky) 的语法,重放存储在 microSD 卡上的按键序列。
本项目仅用于**授权的安全测试、红蓝对抗演练、教育与学术研究** — 请参阅[法律免责声明](#legal-disclaimer)。
## 目录
- [硬件](#hardware)
- [依赖项](#dependencies)
- [构建与烧录](#build-and-flash)
- [SD 卡内容](#sd-card-contents)
- [运行模式 (`MODE.cfg`)](#operating-modes-modecfg)
- [Payload 语法](#payload-syntax)
- [管理模式](#management-mode)
- [字符映射表 (`LANG.cfg`)](#character-map-langcfg)
- [LED 信号说明](#led-signalling)
- [故障排除](#troubleshooting)
- [法律免责声明](#legal-disclaimer)
- [许可证](#license)
## 硬件
| 组件 | 描述 |
| -------------------- | ----------------------------------------------------------- |
| 微控制器 | CJMCU-32 / ATMEGA32U4 (原生 USB HID) |
| microSD 读卡器 | SPI 模块 |
| `chipSelect` | 引脚 **4** (SD 读卡器的 SPI CS) |
| 状态 LED | 引脚 **8** (`led2`) — payload/错误指示 |
| 内置 LED | `LED_BUILTIN` |
SD 模块通过 SPI (MISO/MOSI/SCK) 连接,CS 线连接到引脚 4。
如有需要,请修改 [`badusb.ino`](badusb.ino) 中的 `const int chipSelect`。
## 依赖项
Arduino AVR Core 提供的标准库:
- `Keyboard.h`
- `SPI.h`
- `SD.h`
## 构建与烧录
### Arduino IDE
1. 安装 **Arduino AVR Boards**。
2. 选择兼容 ATMEGA32U4 的开发板(例如 *Arduino Leonardo* / *Micro*)。
3. 打开 [`BadUSB.ino`](BadUSB.ino),编译并上传。
### arduino-cli
```
# 指向 sketch 文件夹(推荐)或 BadUSB/BadUSB.ino
arduino-cli compile --fqbn arduino:avr:leonardo BadUSB
arduino-cli upload --fqbn arduino:avr:leonardo -p COM3 BadUSB
```
已通过 `arduino:avr` core 1.8.6 (arduino-cli 1.5.1) 验证:编译无误,在 ATMEGA32U4 上占用约 77% 的 flash 和约 72% 的 RAM。
## 仓库结构
| 文件 | 描述 |
| --------------- | ------------------------------------------------------------------ |
| `BadUSB.ino` | 主 sketch:初始化/循环、管理模式、payload 解析与分发。 |
| `keys.h` | HID 按键代码常量(使用 `#ifndef` 进行保护,防止与 `Keyboard.h` 冲突)。 |
| `keymap.h` | 字符映射模块的公开接口。 |
| `keymap.cpp` | `LANG.cfg` 加载器与字节转换 (`loadKeymap`, `convertLangChar`)。 |
| `SD/` | 可直接复制到 SD 卡的内容(配置文件和 payload)。 |
| `SD/examples/` | 针对不同操作系统的额外 payload 示例 (`WIN.txt`, `LINUX.txt`, `MAC.txt`)。 |
| `tools/` | `payload_lint.py` — 离线 payload 验证工具(见下文)。 |
这四个源文件都位于 sketch 文件夹中,因此 Arduino IDE / `arduino-cli` 会自动将它们一起编译 — 无需额外配置。
## SD 卡内容
microSD 卡(FAT/FAT32)的根目录应包含:
| 文件 | 必需 | 描述 |
| ------------- | -------- | ------------------------------------------------------------ |
| `MODE.cfg` | 是 | 运行模式:`c`、`a` 或 `m`(见下文)。 |
| `EXEC.cfg` | 是 | 要运行的 payload 文件名(例如 `PAYLOAD.txt`)。 |
| `LANG.cfg` | 否 | 用于非美式键盘布局的可选字符映射表。 |
| *payload* | 是 | 包含脚本的文本文件(文件名在 `EXEC.cfg` 中指定)。 |
[`SD/`](SD/) 目录中提供了一组可直接复制的内容 — 请将其内容复制到 SD 卡的根目录。默认的 `PAYLOAD.txt` 是一个用于展示解析器功能的示例。
额外的操作系统专属 payload 位于 [`SD/examples/`](SD/examples/):`WIN.txt` (Windows)、`LINUX.txt` (Linux) 和 `MAC.txt` (macOS)。要运行其中一个,请将其作为 `PAYLOAD.txt` 复制到 SD 卡根目录(替换默认文件),这样 `EXEC.cfg` 就会继续指向它旁边的 payload。
## 运行模式 (`MODE.cfg`)
`MODE.cfg` 包含单个字符:
| 值 | 模式 | 行为 |
| ----- | ------------------- | ------------------------------------------------------------------------- |
| `c` | **持续运行 (continuous)** | 每次连接时重放 payload。 |
| `a` | **自动解除 (auto-disarm)** | 重放 payload **一次**,然后自动将 `MODE.cfg` 切换为 `m`。 |
| `m` | **管理 (management)** | 不重放 payload — 而是通过串口启动配置菜单。 |
模式 `a` 便于安全测试:设备在首次运行后会自动“解除”,并在下次连接时等待配置。
## Payload 语法
payload 是一个文本文件,每行一条命令。支持所有常见的换行符 — **LF** (`\n`)、**CRLF** (`\r\n`) 和旧版 **CR** (`\r`)。空行将被忽略。
### 时间控制
| 命令 | 描述 |
| -------------------------- | ----------------------------------------------------------- |
| `DELAY ` | 暂停时间(毫秒)。 |
| `DEFAULT_DELAY ` | 在**每条**后续命令之前固定的暂停时间(别名 `DEFAULTDELAY`)。 |
| `REM ` | 注释 — 该行将被忽略。 |
### 文本输入
| 命令 | 描述 |
| ------------------ | ------------------------------------------------------------------- |
| `STRING ` | 输入给定的字符串(末尾不按回车键)。 |
| `STRINGLN ` | 输入给定的字符串,然后按回车键。 |
### 修饰键 / 组合键
修饰键可以链式组合,后跟一个可选的最终按键,该按键可以是**单个字符**或**具名按键**(参见下方的特殊按键列表)。
| 修饰键 | 发送 |
| ------------------- | -------------------------------------------------- |
| `CTRL` / `CONTROL` | 左 Ctrl |
| `ALT` | 左 Alt |
| `SHIFT` | 左 Shift |
| `GUI` / `WINDOWS` | 左 Super (Windows 键) |
| `CTRLALT` | 左 Ctrl + 左 Alt (`CTRL ALT` 的旧版快捷方式) |
示例:
```
GUI r # Win + R
CTRL c # copy
ALT F4 # close window (named key as the final key)
CTRLALT t # open a terminal (Linux)
CTRL ALT DELETE # chained modifiers + named key
GUI # tap the Windows key alone (no argument)
```
### 特殊按键(无参数)
`ENTER`, `MENU`/`APP`, `SPACE`, `TAB`, `ESC`/`ESCAPE`, `CAPSLOCK`, `DELETE`, `INSERT`, `HOME`, `END`, `PAGEUP`, `PAGEDOWN`, `NUMLOCK`, `SCROLLLOCK`, `PRINTSCREEN`, `BREAK`/`PAUSE`, `UP`/`UPARROW`, `DOWN`/`DOWNARROW`, `LEFT`/`LEFTARROW`, `RIGHT`/`RIGHTARROW`, `F1`–`F12`。
### 示例
```
DELAY 2000
GUI r
DELAY 500
STRING notepad
ENTER
DELAY 800
STRING Hello from BadUSB!
```
### 验证 payload
`tools/payload_lint.py` 可以在将 payload 复制到 SD 卡之前,**在你的电脑上**对其进行检查。它复刻了固件的 token 语法([`BadUSB.ino`](BadUSB.ino) 中的 `dispatchCommand`、`delivery` 和 `runCombo`),因此通过 lint 检查的 payload 将不会触发设备端的未知命令错误标志。
```
python tools/payload_lint.py SD/PAYLOAD.txt
# 同时检查多个:
python tools/payload_lint.py SD/PAYLOAD.txt SD/examples/*.txt
```
它会报告三个级别的问题,并在出现任何 **ERROR** 时以非零状态退出(方便在 CI 中使用):
- **ERROR** — 固件会拒绝该行(未知命令、将单个裸字符作为命令使用、无效的组合键)。
- **WARN** — 该行会运行,但可能不符合预期(超过 16 个字符的命令名会被截断、`DELAY` 参数不是整数、组合键最终按键之后的 token 被忽略、`STRING` 包含非 ASCII 字节)。
- **note** — 无害,仅供参考。
仅需 Python 3(无需外部包)。
## 管理模式
当 `MODE.cfg` = `m` 时,插入后设备会等待串口打开(**9600 波特率**)。一旦连接,串口监视器将显示:
1. 卡上可用文件(payload)的列表,
2. 可用的模式,
3. 当前模式和 payload,
4. 提示输入**新模式**(`c`/`a`/`m`),保存到 `MODE.cfg`,
5. 提示输入**新 payload 的名称**,保存到 `EXEC.cfg`。
这让你无需拔出 SD 卡即可重新配置设备。
## 字符映射表 (`LANG.cfg`)
默认情况下,固件会按照主机使用**美式 (US)** 布局来发送字符。
对于其他布局,你可以在 `LANG.cfg` 文件中重新映射各个字节。
格式:每行一个条目,由逗号分隔的三个十进制数字组成:
```
in,modifier,out
```
- `in` — 输入字节代码 (0–255),如 payload 中的字节(例如来自 `STRING`),
- `modifier` — 与 `out` 一起按下的修饰键(`0` = 无;例如 `134` = 右 Alt / AltGr),
- `out` — 实际发送到主机的字节/按键代码。
修饰键代码:
| 代码 | 按键 | 代码 | 按键 |
| ---- | ---------------- | ---- | --------------------- |
| 128 | KEY_LEFT_CTRL | 132 | KEY_RIGHT_CTRL |
| 129 | KEY_LEFT_SHIFT | 133 | KEY_RIGHT_SHIFT |
| 130 | KEY_LEFT_ALT | 134 | KEY_RIGHT_ALT (AltGr) |
| 131 | KEY_LEFT_GUI | 135 | KEY_RIGHT_GUI |
规则:
- 忽略空行和以 `#` 开头的行,
- 最多支持 **64** 个有效条目,
- 文件缺失或无条目 ⇒ *passthrough* 模式(不进行重新映射)。
请参阅示例:[`SD/LANG.cfg`](SD/LANG.cfg)。
## LED 信号说明
- payload 执行完毕后,引脚 8 上的 LED 会亮起约 0.5 秒。
- 在管理模式下,等待串口连接时 LED 保持常亮;
闪烁(200 毫秒)表示在上一个 payload 中检测到解析错误。
## 故障排除
| 症状 | 可能的原因 / 修复方法 |
| --------------------------------------- | ---------------------------------------------------------------- |
| `Card failed, or not present` | CS 线接错、卡丢失/损坏、格式错误(请使用 FAT32)。 |
| `No payload configured` | `EXEC.cfg` 为空或缺失。 |
| payload 行为异常 | 检查主机键盘布局和 `LANG.cfg`;确保 payload 为 ASCII 字符。 |
| 无法重新烧录固件 | 设置模式为 `m` 或使用 bootloader(双击复位)。 |
| 出现错误字符而非预期字符 | 键盘布局不匹配 — 请配置 `LANG.cfg`。 |
## 法律免责声明
这是一个**双用途**工具,**仅**出于合法目的提供:授权的渗透测试、红蓝对抗演练、安全研究与教育。
**仅在你拥有的硬件上使用,或获得所有者明确的书面授权后使用。** 未经授权访问计算机系统和拦截数据在大多数司法管辖区都是非法的(在波兰及其他地区,参见《刑法典》第 267 及 269b 条)。作者对任何损害或滥用本软件的行为不承担责任。所有责任完全由用户承担。
## 许可证
基于 **MIT** 许可证发布 — 请参阅 [`LICENSE`](LICENSE) 文件。
© 2026 Mateusz "Maku" Mączewski
标签:ATMEGA32U4, BadUSB, DuckyScript, USB HID键盘模拟, 嵌入式开发, 硬件安全, 逆向工具