
Pi Zero 2W を BadUSB として設定する
Raspberry Pi Zero 2 W 上に構築されたプログラマブルな BadUSB / HID 攻撃プラットフォーム。 Pi は USB 複合デバイス(キーボードと、オプションの読み取り専用 マスストレージボリューム)として認識され、接続先のホストに対して Ducky Script スタイルのペイロードを実行します。許可を得たレッドチーム 演習、ペネトレーションテスト、CTF 向けに設計されています。
⚠️ 法的通知。 所有しているシステム、または明示的な書面による テスト許可を得たシステムでのみ使用してください。無許可のアクセスは ほとんどの法域で違法であり、知らなかったと主張しても助けにはなりません。
configured 状態による信頼性の高いホスト接続検出 — 起動時に
誤ってペイロードが発火することはありません。LAYOUT でペイロードごとに選択可能な米国および英国のキーボードレイアウト。IF / ELSE、WHILE、HOLD / RELEASE、INJECT_MOD、
RANDOM_* ジェネレーター、STRING_BLOCK / STRINGLN_BLOCK、DEFINE。ExecStop でガジェットをクリーンに破棄する systemd 統合。configfs の
状態が残らず、再起動なしで再スタートできます。/dev/hidg0 の udev 管理によるパーミッション — 全ユーザー書き込み
可能なデバイスノードはありません。+----------------+ USB cable +-------------+
| Raspberry Pi | ===================>>> | Host PC |
| Zero 2 W | (Pi emulates HID + | (target) |
| (this device) | optional drive) | |
+----------------+ +-------------+
|
| /home/pi/pi-badusb/
|
+-- badusb.service ----> monitor_and_run.py
|
| on `state == configured`:
v
run_payload.py
|
v
/dev/hidg0 (USB HID gadget)
badusb.service が gadget_setup.sh を実行します。
configfs / libcomposite を使用して、HID キーボード機能と(オプションで)
/var/badusb/storage.img のフラットイメージファイルをバックエンドとする
マスストレージ LUN を備えた USB ガジェットを構成します。monitor_and_run.py を実行します。これは
/sys/class/udc/<udc>/state をポーリングし、configured — ホストが
ガジェットの列挙に成功したことを示す USB 仕様の状態 — を待ちます。
(シグナルとして /dev/hidg0 の存在は使用しません: これは起動時に
ガジェットが UDC にバインドした瞬間に真となるためで、何かが接続されて
いるかどうかとは無関係です。)run_payload.py を実行し、payload.txt
をパースして HID レポートを /dev/hidg0 に書き込みます。configured
遷移を待ちます。| コンポーネント | 備考 |
|---|---|
| Raspberry Pi Zero 2 W | 2026-05 ハードウェアリビジョンでテスト済み。BCM2835 dwc_otg ドライバーを搭載した旧型の Pi Zero W も原理的には動作しますが、この README は dwc2 を搭載した 2 W を前提としています。 |
| micro-USB - USB-A ケーブル | または、Pi をホストポートに直接挿せる「USB スティック」型フォームファクタのアダプター。 |
| オプション: 別の充電器 | ターゲットに挿す前にリスナーを起動させたい場合に、Pi をホスト以外の電源から給電するために使用します(そうでない場合はホストポートが電源を供給します)。 |
Pi Zero 2 W には 2 つの micro-USB ポートがあります:
PWR IN — 電源専用で、dwc2 OTG ブロックに USB データラインを公開しません。USB — OTG データポート。ここをターゲットに接続します。| 要件 | 理由 |
|---|---|
| Raspberry Pi OS(Debian Bookworm または Trixie、64 ビット Lite 推奨) | インストールスクリプトは Bookworm 以降では /boot/firmware/... に書き込み、古いイメージでは /boot/... にフォールバックします。 |
| Python 3 | Pi OS に付属しています。 |
mkfs.vfat | 初回実行時にマスストレージのバックエンドイメージをフォーマットするため。マスストレージを無効にする場合は不要です。 |
| セットアップ用の root 権限 | systemd、udev、/boot/firmware/config.txt に触れるため。 |
リポジトリを Pi にクローンまたはコピーし、インストーラーを実行します:
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
再起動後、サービスを有効化して起動します:
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 のデフォルトではこの行は
Pi Zero 2 W には適用されない [cm5] フィルター内に置かれるため、
インストーラーはセンチネルマーク付きのオーバーライドを追記し、再実行時に
重複しないようにします。cmdline.txt に modules-load=dwc2 が含まれるようにします。cmdline.txt に g_ether が残っている場合は警告します
(libcomposite から UDC を奪い、ガジェットモードを壊します)。/etc/systemd/system/badusb.service にインストールします。/dev/hidg0 が plugdev グループによってグループ書き込み可能になるよう、
udev ルールを /etc/udev/rules.d/99-badusb-hidg.rules にインストールします。pi ユーザーを plugdev グループに追加します。/var/badusb/ を作成します。# Start / stop / restart
sudo systemctl start badusb
sudo systemctl stop badusb
sudo systemctl restart badusb # safe to do while plugged in
# Watch live
journalctl -u badusb -f
# Disable autostart on boot
sudo systemctl disable badusb
# Tune timings (creates an override drop-in)
sudo systemctl edit badusb
# (paste an [Service] block with Environment="BADUSB_REARM_COOLDOWN_S=8" etc)
sudo systemctl restart badusb
このサービスは sys-kernel-config.mount と UDC の存在に依存するため、
ガジェットが実際に準備できるまでペイロードを発火できません。
ペイロードの編集に再起動は不要です — payload.txt はプラグインのたびに
毎回新しく読み込まれます。
payload.txt はインストールディレクトリにあります。完全なコマンド
リファレンスは payload_commands.md にあります。
REM Open Run dialog and type a greeting via Notepad
LAYOUT US
GUI r
DELAY 1500
STRING notepad
ENTER
DELAY 2500
STRINGLN Hello from the Pi Zero 2 W
VAR $USER="alice"
VAR $COUNT=0
WHILE $COUNT < 3
STRINGLN Hello $USER (iteration $COUNT)
VAR $COUNT = $COUNT + 1
END_WHILE
IF $USER == "alice"
STRINGLN matched
ELSE
STRINGLN missed
END_IF
VAR 内の数式は ast ウォーカーによる安全な評価器を通過します —
名前、呼び出し、属性アクセスは不可で、数値リテラルと
+ - * / // % ** のみが許可されます。
HOLD SHIFT
STRINGLN this line is in capitals
RELEASE SHIFT
REM Hold Ctrl+Shift (0x01 + 0x02) and tap A
INJECT_MOD 0x03
STRING a
REM Release all modifiers
INJECT_MOD 0x00
RANDOM_LETTER 12 # 12 random mixed-case letters
RANDOM_NUMBER 6 # 6 random digits
RANDOM_SPECIAL 4 # 4 random ASCII symbols
LAYOUT UK # switch to UK ISO mappings for subsequent STRING/STRINGLN
STRING @ " # ~ £ \ | # types correctly on a UK-locale host
keymaps/(us.py と uk.py と同じ場所)に別のファイルを置くと、
LAYOUT <name> ディレクティブが importlib 経由でそれを読み込みます。
gadget_setup.sh の先頭)| 変数 | デフォルト | 説明 |
|---|---|---|
ENABLE_MASS_STORAGE | 1 | 0 にすると HID のみのガジェットになります。 |
BACKING_FILE | /var/badusb/storage.img | ホストに公開されるフラットイメージ。 |
BACKING_SIZE_MB | 64 | 存在しない場合、初回実行時に作成されます。 |
BACKING_LABEL | BADUSB | FAT ボリュームラベル。 |
MASS_STORAGE_RO | 1 | デフォルトで読み取り専用。 |
これらは、gadget_setup.sh を手動で実行するときに環境変数として
設定することで呼び出しごとに上書きできるほか、ユニットの Environment=
ディレクティブでグローバルに上書きできます。
monitor_and_run.py)| 環境変数 | デフォルト | 説明 |
|---|---|---|
BADUSB_POST_PAYLOAD_FLUSH_S | 0.5 | アンバインド前にペイロード後スリープし、HID 書き込みをフラッシュします。 |
BADUSB_REARM_COOLDOWN_S | 5 | アンバインドと再バインドの間、ガジェットがホストから見えない状態を維持する時間。 |
BADUSB_MIN_INTER_FIRE_S | 10 | 2 回のペイロード発火の間隔の最小秒数。これを下回ると発火は抑制され、ガジェットは再アンバインドされます。 |
BADUSB_MAX_FIRES_PER_MINUTE | 6 | ハードキャップ。これを超えると BADUSB_RATELIMIT_PAUSE_S の間一時停止します。 |
BADUSB_RATELIMIT_PAUSE_S | 60 | レート制限トリガー後の一時停止時間。 |
上書きするには: