BadUSBでリバースシェルをやってみた

この記事はセキュリティキャンプ修了生用Advent Calendar 19日目の記事になります。
自分のサイトに最初は投稿しましたが、Adventarの仕様(?)でURLが反映されなかったのでQiitaに投稿。

1, BadUSBとは
---------------
**BadUSBがどんなものかくらい知っている!!という方は読み飛ばして構いません**

BlackHat USA 2014にて発表された、USBデバイス内のファームウェアを更新する仕組みを悪用できて
しまうというUSBの規格に存在する脆弱性です。
(BlackHat USA 2014での発表の様子: https://youtu.be/nuruzFqMgIw)
BadUSBと類似するものにPsychsonというツールが存在します。
PsychsonというのはBadUSBをリバースエンジニアリングしたものです。
現在もソースコードがGitHub上にて公開されていて、ビルドすることによりツールを使用できます。
それでは次にBadUSBの定義について書いていきたいと思います。
ここは本題とあまり関係がないので正直どうでもいいのですが、BadUSBには複数の定義が存在します。
これは人によって変わるので、多数派な印象の最後のものを今回は採用します。

+ 本当に厳密にBadUSBだと考えた場合の定義

要するにBlackHat USA 2014で発表された本家『だけ』をBadUSBだと捉えるものです。
正直、これが正しさという観点では一番なのですが一般的ではありません。

+ BadUSBは本家とPsychsonだけと考えた場合の定義

これも的を得ている考え方です。何故かというと一般的にBadUSBと呼ばれるものでファームウェアの
書き換えというexploitを行っているものはこの二つだけです。
この二つ以外はBadUSB擬きと言えるものなので確かに正しいと言えます。

+ BadUSBみたいな事ができれば全部BadUSBだと考えた場合の定義

これが一番一般的だと思います。要するにこの考え方は
「USBデバイスを自分で作って悪い事をすればBadUSB」
「ArduinoでUSB出力して悪い事をすればBadUSB」
というUSBデバイスを使って悪い事ができればBadUSBだという考え方です。
人それぞれ考え方は色々あると思いますが、これが一番一般的(だと思います)です。
何故これが一般的なのか考えてみましたが、理由という理由はこれしか思いつきませんでした。
『なんて悪いUSBデバイスなんだ、名前をつけよう。そうだ、英語で悪いはBad、それにUSBを』
要するに名前が被ったんだと思います、あくまで推測ですが。（多分違います）
BadUSBを使ってどんな事ができるのかですが、USB入出力により操作可能なコンピュータの機能は
なんでも操作できてしまいます。だからマウスもキーボードも全部操作できてしまいます。
ここまでの説明だけでBadUSBがどれだけ怖いか、もう十分わかっていただけたと思います。

2, BadUSBのデメリット
---------------
万能攻撃ツールであるBadUSBですが、実際に攻撃に使うには致命的なデメリットがあります。
それはUSBデバイスを接続する、もしくは接続させなければいけないということです。
つまり物理面でのセキュリティの強化、そしてちょっとユーザが気をつけるだけで防げます。
ドラマでよく見ま...せんかもしれませんが、会社のビルに入る前に身体検査をするアレです。
USBデバイスを社内に持ち込んではいけない、持ち出してはいけないというアレです。
これさえあればBadUSBなど何も怖くありません、ただしもちろん......
「お、USBデバイスが落ちてるな.....中に持ち主につながる情報が入っているかもしれない、
とりあえず会社のPCで調べてみるか」
という人や
「どうしたの、その箱」
「駅前で配ってたUSB扇風機だよ、これで快適に仕事ができる！！」
という人はかなり要注意です。
あとこれは工夫次第で改善可能な私のBadUSBプログラムのデメリットなのですが、
どうしてもスクリプトをダウンロードする箇所でコマンドプロンプトかTerminalか端末を使用する必要があります。
そしてこの部分はどうしてもOS依存になってしまいます。
なので、どのOSなのか判別する機能をinit()関数に書くのもいいんじゃないでしょうか。
(ただ、それでもデスクトップ環境の入ってないArch Linuxなどは判別できないので、
  やっぱりこれもデメリットのうちの一つに入ってしまうかもしれません。)

3, Attack
---------------
まずは大雑把な仕組みの解説ですね。
言ってしまえば単なるソケット通信を利用した遠隔操作アプリケーションです。
攻撃側(以後attacker)から送られてくるコマンドを被攻撃側(以後victim)がsubprocessを使って
実行します。ちょっと難しいので図を用意しました。

<img src="https://moppoi5168.github.io/docshelf/docs/seccamp/img/attack_flow.png" width="500">

本当に大雑把ですが、攻撃の全体図はこんな感じです。
ここからはこれらのステップ一つ一つを詳しく書いていこうと思います。

3-1, USBを拾わせて使用させる/拾って使用する
---------------
少し導入の部分が無理矢理な感じはしますが、そこはご想像にお任せします。
肝心のBadUSBですが、今回はArduinoの互換機を使用したいと思います。
理由は非常に簡単で、Psychsonをexploitできるデバイスを用意できなかったからです(orz)。
デバイスの名前はAdafruit Itsy Bitsy 32u4 - 5V 16MHzです。
確かSwitch Scienceさんから購入させていただいたものです。
もちろんArduino自体(互換機ではない)を使われても問題はありません。
ただしBadUSB実験だけの為にお金をそんなに使いたくないという方には互換機をオススメいたします。
本題に入りますが、このデバイスにはUSB出力を行うチップがあります。
これを使うことにより、自由自在にキーボードやマウスを操作することができるのです。
更に、Arduinoの公式ドキュメントもあるのでPsychsonのpayloadを一から書くよりハードルが少しは
低いかもしれません。もちろん開発にはArduino IDEを使うことができます。
というわけでTerminalを起動してpythonプログラムをダウンロード、実行させる処理を書きました。
これで攻撃の下地は整ったわけです。

3-2, victimの接続を待つ/attackerに接続する
---------------

![接続ログ](https://moppoi5168.github.io/docshelf/docs/seccamp/img/log_first.png)

やっと攻撃ツールの紹介に入ることができますね。
今回は二つのとてもシンプルなpythonプログラムを書きました。
(attacker側が70行ちょっと、victim側が20行程度です。
  ただしattacker側はログ出力のコードも入っているので最低限動く状態にすれば60行程度になるかも。)
わかりやすいようにattacker.pyとvictim.pyというファイル名にしています。
victimの接続を待つですが、特に解説の必要もないソケット通信のコードです。
ただしここが一番のポイントだったりします。
この攻撃はリバースシェルです、つまりvictimからattackerに接続します。
わかりやすく例えると、本来はattackerがvictimに接続するものを、victimからattackerに接続することにより
ファイアウォールを突破しています。(ファイアウォールは外から中への通信には強いけど中から外へは弱い)
わかりませんが、要するにファイアウォールを無視して攻撃するための手法というわけです。
(普通はhttpとかの開いてるポートから入り込んで回避するけど、こういう回避方法もあるくらいに認識しておいてください)

3-3, 接続されたらコマンドを送信/attackerの送信したコマンドを実行
---------------
subprocessは便利ですね......はい、というわけで攻撃です。

![攻撃](https://moppoi5168.github.io/docshelf/docs/seccamp/img/attack.png)

画像の方はちょっと次の段階の方まで行っていますが、こんな感じで攻撃します。
地味.....かもしれませんがこんなものです。以下のようにコマンドを実行することができます。
victim>> ls
内部処理的な話をすると、ここで実行したコマンドが変数に格納されてvictimに送信されます。
victim側ですが、受け取ったコマンドをsubprocess.check_outputで実行します。

3-4, 実行結果を見る/実行結果を送信する
---------------
(スクリーンショットは3-3のものを参照)
まずvictim側がsubprocess.check_outputで入手した実行結果をattackerに送信します。
そしてattacker側のプログラムは受け取った実行結果を出力します。
あとはattackerが飽きる(?)まで3-3と3-4の繰り返しです。
以上で解説は終わりです。とてもシンプルですよね。

3-5, 発展
---------------
書きながら思ったんですけど、結構BadUSB側もPythonスクリプト側も改善点が多いんですよね。
例えばvictim.pyですが、確かに攻撃は成立しますが痕跡が残ってしまいますよね。
そこでclean_upという関数を作って終了時に痕跡を消す....とかありだと思うんです。
あと、攻撃している最中に気が付かれて電源切られる可能性(?)があるのでバックグラウンドで動作するようにしても良さそうです。
このように拡張性が高いのもBadUSBの怖いところなのかな、と思います。
あと対象プラットフォームがWindowsなら普通に実行形式にしてやったほうが幅広い環境に対応可能だと思います。

4, え、怖い
---------------
まずは最初に、後半の攻撃フローの解説が雑になってしまいすみません。
普通に学校帰りで更に(これとは関係ない)コードをずっと書いていて疲れてしまいました。
ちなみに今回のAdvent Calendarの内容ですが、今年のセキュキャンのLT大会で私が発表した内容です。
ただLTということもあり、かなり急ぎ足での解説とデモだったので今回こうして記事を書かせていただきました。
(**あの時のやつはncでやってた手抜きリバースシェル笑だったとか口が裂けても言えない......**)
さっそく本題ですが、BadUSBって怖くないですか？
こんなものがセキュリティソフトに検知されないんですよ。
リバースシェルじゃなくて普通にsudo rm -rf /やるだけ....とかもできてしまいます。
あともっと複雑なプログラムを書けば更に高機能にもできそうですよね。
(カーネルの脆弱性を利用してroot権限を取得するなど.....え、怖い)
果たしてBadUSBに対処する方法はあるんでしょうか？

5-1, 現在のUSB規格を全て使用できないようにして新しい規格を確立
---------------
ある意味、これが正しい回答と言えるのかもしれません。
何故かというと、BadUSBをBlackHat USA 2014で発表した方々はこれを促していたからです。
促して、新しい規格が普及するまではBadUSBのexploitツールを公開しないと決めていたわけです。
しかし残念ながら、世の中がそう簡単に変わることもありませんでした。
業を煮やしたのかはわかりませんが、それを受けて公開されたのがPsychsonです。
公開されないと油断していたから新しい規格が確立されなかった。
なら公開してしまえばいいじゃないか、というのがPsychsonを公開した方々の意見です。
しかし、まあ、残念(?)なことにそれでも世界はUSBを使い続けました。
というわけでこの対処法は現実的ではありませんよね。

5-2, セキュリティソフト的対策
---------------
結構有効なんですけど、一部の法人向けセキュリティソフトにしか実装されていないんですよね.......。
つまり接続されたらUSBデバイスのホワイトリストのようなもので照合して接続させるかさせないかを
プログラム側が判断するわけです。
セキュリティソフト的対策の他の例として実際にこんな研究があったりします。
**Defending Against Malicious USB Firmware with GoodUSB [D. Tian et al., 2015]**
この論文のGoodUSBというのは、BadUSB対策をLinuxカーネルに実装したというものです。
例えば、キーボードを接続されたとします。するとコンピュータの内部では
接続〜デバイスからホストを操作orホストからデバイスを操作〜などなど様々な情報がやり取りされます。
(私も解説できるほど詳しくないので、知りたい方は是非自作OSにUSBドライバを実装してみてください)
とか言っていると
「え？今年のセキュキャンでどこのコースに参加したの？確かOS開発ゼミだった気が....」
とか色々文句言われそうなので頑張って解説してみます....(泣)
私のとても浅い理解の元での解説なので詳しく知りたい方は@uchan_nos先生の書かれた
USB3.0ホストドライバ自作入門という本を是非読んでください！！
まず、接続されるとUSBポートの初期化が行われます。そしてスロットの割り当てが行われます。
そしてそこからデバイスにアドレスが割り当てられてデバイスディスクリプタというものを取得します。
そしてコンフィギュレーションディスクリプタの取得が行われます。
次ですが、ここではHIDクラスというものが出てきます。HIDはHuman Interface Deviceの略です。
ここでHIDかどうかを判断するためにインターフェイスディスクリプタ(bInterfaceClass)というものを使用します。
ここにあるクラスコードでHIDかどうかを判断します。
そして更にその中のサブクラスとプロトコルでキーボードかマウスかなどを判断します。
(この辺りはOSレベルの低レイヤな話なのでBadUSBを理解することに知っておく必要はありません、
  というか私自身大して知らなかったりするわけで......)
というわけで簡単に言ってしまうと低いレイヤの部分でどういうデバイスなのか判断されるわけです。
Windowsをお使いの方は特によくわかるかもしれませんが、OSってどのデバイスがどんな権限というか
どんな影響をコンピュータに及ぼすか把握しているんですよね。
それを利用したのがGoodUSBです。
接続時に「このデバイスはキーボード操作しますよ〜」と視覚的に表示してくれるわけです。
もしUSB扇風機を接続したのにキーボード操作されると書いてあれば異変に気付けますよね。

5-3, 結局は個々人のセキュリティに対する意識でしょ
---------------
学校の先生みたいなこと言っていることは重々承知ですが、この通りです。
コンピュータが如何に完璧でも人間がミスしたら全部台無しになんですよね.....
(あ、でもコンピュータも人間の作ったものだから完璧とかありえないですね)
だから企業さんとか学校さんとか色々な組織さんとかでも、USBデバイスの管理には気をつけましょう。

6, まとめ and 自己紹介 and なんでこの記事を書いたのか
---------------
今回の記事は別にBadUSB対策は大事なのにされてない、という問題提起をしたいわけじゃありません。
デメリットの部分に書いた通り、この攻撃を成功させるのはあまり現実的ではありません。
実際に攻撃者がマシンを触るか、誰かにUSBを上手く接続させなければいけません。
というわけで危険性は高いのですが、気をつけておけば大丈夫程度のものなのかな....と考えています。
それでは、以上でこのAdvent Calendarの記事を締めようと思います。
最後まで読んでいただき、ありがとうございました。

**興味のない方はここで閉じていただいて全然構いません**

どうも、普段はセキュリティとか低レイヤとか色々やってる人です。
最近はハニーポットが気になってるのでやってみたいなと考えています。
自己紹介といっても......自作OS作ってたり.....あとはWeb開発くらいですね。
....書くことが早々になくなってしまったので今回の記事を書いた理由を一応書いておきます。
記事の中で書いた通り、これは今年のseccampの初日のLT大会で私が発表した内容なんですけど、
このテーマを決めるまでが結構長かったりしました。
何故かは忘れましたがBadUSBの存在をキャンプ前の私は知っていて、これをLT大会で発表したいと思ったんですね。
(ちょっとLTで喋るには内容が濃すぎるテーマだったと今では思います)
でもBadUSBの仕組みを解説してデモして終わりって......なんとなく面白くないと感じました。
案があればTwitterで投票でもしようかと思ったんですけど選択肢にする案がなかったんですよね。
そして「悩んでる〜」とTwitterに書き込んだところmegumishさん(すごい人)が意見をくれたんです。
**megumishさん「リバースシェルとかどうですか？私も気になるし....」**
確かこんな感じのリプライが飛んできたんですよね(多少は違うかも)。
リバースシェル.....は存在は知ってたんですけどまだ自分もよく知らない分野だったので張り切りました。
まずは適当にリバースシェルの方法を検証しながら考えました。
bashのリダイレクト使ったやつでいいかー(という手抜き)をしつつスライドを作り始めました。
そして作り終わったんですけど、ここからが一番長かったと思います。
スライトver.1を使ってLTやってみたんですけど20分弱喋っちゃったんですよね。
LTは5分が当たり前です、つまり長さを1/4にしなくてはいけません。
しかし同時に、全く前提知識のない人でもわかるように解説しなくてはいけません。
これに多分一番労力を費やしました、が失敗しました。
発表当日、致命的なミスをしてしまったんですよね....リバースシェルってネットワーク環境の構築大事なんですけど....
**会場内のネットワーク構成が発表1秒前までよくわからなくて困惑してた**
（というより、変なことやってNOCの方に怒られないかなぁ.....と心配でした。）
これが原因....かはわかりませんが発表中はずっと緊張しててかなりドキドキしていました。
あと流石に五分でこの二つのテーマを語り切るのは無理があったのでどうしても軽い話になってしまいました。
それが今回の記事を書いた動機ですね。というわけで、これで本当に最後になります。
**次の日のアドベントカレンダーはuint256_tさんの『JavaScriptエンジンの進捗』です。**
是非こちらも読んでください!!!
何か感想等ありましたらTwitter([at]naogramer)までDMでも何でもいいのでお寄せください。
最後まで読んでいただき、本当にありがとうございました。