This page looks best with JavaScript enabled

勝手に僕のサイトを開くUSBデバイスをつくる

 ·  ☕ 4 min read  ·  🐶 odanny · 👀... views

完成したもの

PCに接続すると勝手にブラウザが立ち上がり、ぼくのWebサイトに誘導する。なんか悪いことをしている気分になるが、接続時以外の動作は実装していないので安心。


はじまり

Pocketのあとで読むを消化していたら少し古い次の記事が出てきた。

「BadUSB」をやってみた - JH1LHVの雑記帳

上の記事では市販の東芝製USBメモリのファームウェアを書き換えて、キーボード化している。こうした市販のデバイスのファームウェアを書き換えて悪いことをすることを BadUSB と呼ぶようだ。「見知らぬUSBデバイスをパソコンに接続してはいけない」という注意喚起はよく見るものの、こうした悪意あるUSBデバイスがどれくらい簡単につくれるのか試してみたくなった

本記事では以下のことをやる/やらない。

  • ファームウェアの書き換えは大変そうなのでやらない
    • ATmega 32U4を積んだデバイスでカンタンにやる
  • 接続すると特定のコマンドを実行させる
    • 今回は、ぼくのwebサイトを開かせる

使用したもの

Amazonでオタクが好きそうなデザインのものを購入した。ATmega 32U4を積んだデバイスであれば何でもよく、Arduino Leonardo やArduino micro などでもいい。

Aideepen Beetle BadUSBキーボードプロマイクロATMEGA32U4モジュール Mini開発拡張ボードArduinoレオナルドR3用

init

また今回使用したPCは、Windows 10 Education である。Mac や Linux での動作は確認していない。

そして最後にぼくのノートパソコンはJIS配列キーボードである。この影響が本記事の後半に現れる。


実装

Arduino 編

がんばって書いた。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include "Keyboard.h"

void setup() {
  // put your setup code here, to run once:
  delay(1000);
  // 「ファイル名を指定して実行」を起動
  Keyboard.press(KEY_LEFT_GUI); 
  Keyboard.press('r');
  Keyboard.releaseAll();
  delay(1000);
  
  // コマンドプロンプト起動	
  Keyboard.print("cmd");
  Keyboard.write(KEY_RETURN);
  delay(1000);
  
  // 既定のプログラムでWebサイトを開く
  Keyboard.print("start https://odanny.com");
  Keyboard.write(KEY_RETURN);
  delay(100);
  Keyboard.releaseAll();
}

void loop() {
  // put your main code here, to run repeatedly:
}

(書きこむときチョットカッコイイ。)

connected

JIS配列キーボードを使用している場合は、このままでは動かないので、次の修正が必要になる。


Keyboardライブラリの書き換え

上のコードを普通に実行するとコロンを正しく打つことができずhttps+//odanny.comのようになってしまう。そこでめんどくさいが、Keyboard.cppをいじる必要がある。85行目あたりから抜き出す。

1
2
3
4
5
6
7
#define SHIFT 0x80
const uint8_t _asciimap[128] =
{
	0x00,             // NUL
    // 各文字に対するマッピングがたくさん定義されている
    0x33|SHIFT,      // :
    // まだまだ続いていく。

コロンは0x33|SHIFTと定義されていて、これは「0x33に対応するキーとSHIFTを同時押しする」ことを意味する。キー配置とIDの対応を次の図に示す。( DigiKeyboardが日本語キーボード搭載PCで記号を正しく出力しない問題を解決する - Qiita より)

keymap

0x33は10進数で51なので、今のコードでは確かに+が入力されてしまうことが確認できる。日本語配列でコロンは52を押せば入力できるので次のように修正する。

1
2
3
4
5
6
7
#define SHIFT 0x80
const uint8_t _asciimap[128] =
{
	0x00,             // NUL
    // 各文字に対するマッピングがたくさん定義されている
    0x34;      // :
    // まだまだ続いていく。

ここまで来ればKeyboard.cppを保存し、再度先ほどのArduinoスケッチを書きこめばよい。なおKeyboard.cppはWindows環境では、C:\Program Files (x86)\Arduino\libraries\Keyboard\src配下にあった。


トラブルシューティング

デバイスが認識されない

ATmega 32u4がUSB認識しなくなった場合の対処を参考にする。


「Keyboard」が存在しません。のエラー

コンパイル時「「Keyboard」が存在しません。スケッチに「#include <Keyboard.h>」という行を含めていますか?」と出る場合、「ツール→ボード」をみて、Arduino UNOなどHID向けのものになっていないか確認する。

error


最後に

意外にカンタンにパソコンのターミナルを操作するデバイスをつくれた。このデバイスを作ったせいで、ぼくがUSBメモリを人に貸そうとすると拒否される未来が見える。知らないUSBデバイスと過去の自分は信用してはいけないことを理解できた。

Share on

odanny
WRITTEN BY
odanny
自作キーボードはまり中