超高速Lチカ技術を応用したBadUSB自作入門

この記事は RECRUIT MARKETING PARTNERS Advent Calendar 2015 の投稿記事です。

先日、連載:池澤あやかとはてな大西の「エンジニアの働きやすい職場って?」で取材されたリクルートマーケティングパートナーズ技術フェローのtakesakoです。実は 2015年9月より、国立高等専門学校機構 高知工業高等専門学校(高知高専)の客員准教授も兼任していまして、2016年4月から新設されるソーシャルデザイン工学科情報セキュリティコースの教材作成協力などを行なっています。

高知高専の電気情報工学科5年生向けに開催したネットワーク工学演習「BadUSB自作入門」の様子

今回はRECRUIT MARKETING PARTNERS Advent Calendar 2015 2日目の記事ということで、高知高専の電気情報工学科5年生向けに開催したネットワーク工学演習〈BadUSB自作入門〉の様子をレポートいたします。

BadUSBとは?

badusb2

BadUSBとは、BlackHat USA 2014でKarsten Nohl氏とJakob Lell氏が発表したUSBメモリを改造してUSBキーボードとして認識させるハックのことです。
これを悪用するとUSBに挿し込むだけで意図しない自動キーボード入力が可能になり、ショートカットキーでコンソール画面を立ち上げて盗聴できるようにネットワークの設定を変更するコマンドを自動実行したり、バックドアをダウンロードして仕込んだりすることが可能になります。
キーボードとして認識されてしまうと任意のコマンドが実行可能となり、悪用されたときの危険度が高いので『BadUSBのコードは公開しない』と元々の発表者は明言していたのですが、別のセキュリティ研究者のAdam Caudill氏とBrandon Wilson氏は「BadUSBは公開すべきだ」として、特定のチップを搭載したUSBメモリの ファームウェアを書き換えるツール「Psychson」をgithubで公開しました。

USBキーボードとして認識

しかし、このPsychsonを使用するハックだと特定のチップPhison製2251-03(2303)搭載のUSBメモリ(例:Toshiba TransMemory-MX USB 3.0 16GB)を探して入手する必要があり、かつソフトウェアの書き換えだけになってしまい、電子工作的な楽しみがないので、BadUSBを回路レベルからもっと簡単に自作できる方法はないかと考えました。

格安PS/2キーボード変換USBアダプタを中国から輸入

PS/2キーボード変換USBアダプタ

そこで、個人的にeBayを使って中国深圳(シンセン)より1個160円で輸入したのが「PS/2キーボードとマウスの信号をUSBプロトコルに変換するチップを搭載したアダプタ」です。少し単価は230円と高くなりますが、Amazon.co.jpでも日本円で購入も可能です。
このUSB変換アダプタは他の民生品(約1,000円前後)に比べて格安で、かつ特定のドライバインストールなしでWindows、Linux、Mac OS Xで標準キーボードと認識する互換チップを搭載しています。
これを使うと、昔ながらのPS/2キーボードの信号をエミュレートする回路をこのアダプタに接続することでBadUSBが再現できるんじゃないかという着想で自作していきます。

PS/2キーボードの通信プロトコル

PS/2キーボードの通信プロトコルの仕様を調べてみました。クロックの周波数は10~16KHzで、許容電圧は5V、許容電流は275mAの電気信号で通信を行います。

PS/2通信の方法

スタートビット(S=0)のあと、8ビットの情報(0~7)を送り、奇数パリティ(P)を最後に付加して、ストップビット(E=1)を送ります。

PS/2信号のクロックタイミング

クロックパルスの立ち上がりからデータ信号を送信するまでは最低5μ秒の間隔をあけることになりますが、60μ~100μ秒の周期でクロック信号をON/OFFします。このクロック周波数だと、小さい8bitの組み込みマイコンを使ってキーボードの信号をエミュレートしてデータ送信ができそうです。

AVRマイコンを使用したBadUSB自作

というわけで、BadUSB自作のための材料を揃えてきます。秋月電子通商ですべて購入できる部品です。

  1. [I-02911] AVRマイコン ATTINY13A-PU 1個 ¥50(税込)
  2. [P-05155] ミニブレッドボード BB-601(白) 1個 ¥130(税込)
  3. [C-05159] ブレッドボード・ジャンパーコード(オス-オス)セット 1セット ¥220(税込)
  4. [I-06245] 抵抗内蔵5mm赤色LED(5V用)(10個入) 1パック ¥120(税込)

BadUSB自作の材料

AVRマイコンを扱うのが初めての人は、AVRライター「AVRISPmkII」を別途購入しておくのが無難です。マイコンにプログラムデータを書き込むときに使います。

自作BadUSBをブレッドボード上に配線しよう

BadUSB自作回路

回路図を作ってブレッドボード上に配線してみます。LEDはデバッグ用なので削除しても大丈夫です。最初にマイコンを買って来たらLEDをチカチカさせる〈Lチカ〉するプログラムをHello, world!的に書き込みますが、Lチカの入出力を60μ~100μ秒の間隔で高速に実行するとPS/2信号がエミュレートできるという原理です。

BadUSB接続回路図

PS/2コネクタの電気信号は、ピン1に+DATA信号、ピン5に+CLK信号がありますので、マイコンのGPIO端子にそれぞれ接続します。ピン3、ピン4はそれぞれGND(接地)とVcc(5V)につなぎます。

AVRアセンブラの書き込み

C言語でプログラミングできるので、AVRマイコンの5VのGPIO端子の入力状態を確認しながら出力をON/OFFさせてPS/2通信をエミュレーションするプログラム(a.c)を書いていきます。

#define F_CPU    960000UL
#include <avr/io.h>
#include <util/delay.h>
#define SBI(B,V)  B|= _BV(V)
#define CBI(B,V)  B&=~_BV(V)
#define SBIS(B,V) (uint8_t) (B&_BV(V))
#define SBIC(B,V) (uint8_t)!(B&_BV(V))
#define LED0  PB0
#define LED1  PB1
#define LED2  PB2
#define CLK   PB3
#define DATA  PB4
#define ERR   -1
#define ERR2  -2

uint8_t a, b, c, i, j, x, data, parity;

uint8_t clock(void)
{
  CBI(DDRB, CLK);
  if (bit_is_clear(PINB, CLK)) return 0;
  SBI(DDRB,  CLK);
  CBI(PORTB, CLK);
  _delay_us(30);
  SBI(PORTB, CLK);
  _delay_us(30);
  return 1;
}
/* 以下省略 */

C言語プログラムをavr-gccでコンパイルして16進ダンプa.hexファイルを作成します。

$ avr-gcc -mmcu=attiny13a -Wall -Os -o a.elf a.c
$ avr-objcopy -j .text -j .data -O ihex a.elf a.hex

AVRライター(AVRISP mkII)とPC本体を接続して書き込みを行う準備をします。

AVRISP mkII とPC本体をUSBで接続する

こうして出来上がった16進ダンプa.hexファイルをAVRライターを使ってマイコンに焼きこみます。

:1000000009C021C020C01FC01EC01DC01CC01BC015
:100010001AC019C011241FBECFE9CDBF10E0A0E661
:10002000B0E0E4E4F3E002C005900D92AA36B10717
:10003000D9F710E0AAE6B0E001C01D92A237B107DF
:10004000E1F718D17DC1DCCFBB98B39902C080E045
:100050000895BB9AC39889E0982F9A95F1F7C39AAF
/* 中略 */
:10030000BEDE88E893E1F8013197F1F70197D9F75C
:1003100080916C008F5F80936C0080916C008A30BC
:10032000F8F2809171009F2D981B90937100992392
:1003300011F0C09A01C0C098CE010197F1F7CDCF5E
:04034000F894FFCF5F
:0A0344001C322123242B3433295AE4
:00000001FF

書き込みには、avrdude-GUIを使いました。Flashの内容を全部消して、16進ダンプの値を書き込んで、正常に書き込めたかどうかを読み込んで検証する「Erase–Write-Verify」を押して書き込み実行です。

メモ帳を開いて自作BadUSBを挿してみよう

マイコンへの書き込みが終了したらAVRライターを外し、自作BadUSBをPCに接続してみましょう。

メモ帳を開いて、自作BadUSBを挿してみよう

USBキーボードとして認識され、自動でキー入力が行われたら成功です。

余談:自作BadUSBのデバッグに失敗するとこうなる

ちなみに、PS/2信号をエミュレートする際、デバッグに失敗して意図しない信号を作ってしまい、PCをクラッシュさせてしまったこともありました。注意が必要です。

自作BadUSBのデバッグに失敗するとこうなる

というわけで、BadUSB自作には危険が伴います。自己責任でBadUSB自作を試したいという方には、ソースコード一式と自作手順のマニュアルを送付いたしますので、@takesakoまでご連絡ください。

takesako

Lv.
5
EXP.
1,813

株式会社リクルートマーケティングパートナーズ ラーニングプラットフォーム推進室 技術フェロー。日本発のCTF大会「SECCON」の実行委員長、事務局、問題作成者として、大規模な国際オンライン大会や日本各地での大会などを運営。CODEBLUEレビューボードメンバーの他、OWASP Japanアドバイザリーボードメンバー、Shibuya Perl Mongersリーダーを務める。Microsoft MVP of Developer Security部門受賞。情報セキュリティカンファレンスでの講演は、『Disassembling Flash Lite 3.0 SWF Files』(HITCON 2011)、『Secure escaping method for the age of HTML5』(OWASP AppSec APAC 2014)など。『ECMA-262 Edition 5.1を読む』(秀和システム)や 『x86 JITコンパイラ上で任意コードを実行する方法』ほか、著書/文書を出版。

この執筆者の記事一覧

コメントはこちらのに同意の上、投稿ください。