UARTでルーターのハッキングを試みてぶっ殺した話

はじめに

こんにちは。
morimolymolyです。
最近、自分の中でかなりIoTのハッキングが熱くて、実際に部屋に転がっていたルーターにハッキングを試みて殺害してしまったので、その軌跡を記したいと思います。
実行環境はOSXとbus pirate v3.6です。

UARTとは?

UART(Universal Asynchronous Receiver/Transmitter)とは非同期式シリアル信号をパラレル信号にしたり、その逆をおこなう回路です。
例えばCPUからのパラレル信号をシリアルで出力したり、シリアルの入力をパラレルに変換して送ったりできるみたいです。
UART同士で通信するときは非同期シリアル通信を行います。
UARTの扱う信号にはパリティビットやスタートビットなどの、メッセージ本体とは別の重要なフラグがありますが、本記事では詳しく扱いません。
詳しくUARTが勉強したいなら以下の動画や記事を読むといいと思います。
www.youtube.com
www.circuitbasics.com

さて、UARTで通信を行うときに抑えて置かなければならない要素が大きく2つあります。
それはUARTのピンとボーレートです。

UARTのピンアサイ

まずはピンについて説明します。
UARTには大まかにTx, Rx, GND, Vccという4つのポートが存在します。
TxとRxはそれぞれ、Transmit(送信)、Receive(受信)を表します。
2つのデバイスをUARTで接続する場合は以下の様になります。
f:id:morimolymoly:20170907171005p:plain
TxとRxが反転して接続されていますが、ポートの意味を考えれば当然ですね。

ボーレート

ボーレートとは一秒間に副変調できる回数を指します。
UARTは非同期式でクロックがない代わりに、これを指標に通信しています。
またボーレートはデータ通信速度のbpsと勘違いされることがよくありますので、しっかりと区別しましょう。(1回の副変調が1bitであるとは限らない)

下調べ

それでは早速、ハックするためにいろいろな情報を集めていきましょう。
今回はAterm WR6670SというNECルーターを扱います。
https://121ware.com/product/atermstation/product/warpstar/wr6670s/

ボード観察

まずはボードを眺めます。

f:id:morimolymoly:20170907172428j:plain
実際のボード
ボードを眺めるといろいろなICチップや抵抗、コンデンサがみえますね。
まずはICを眺めて、RAMやCPUやROMを特定します。
このボードには以下のICが含まれていました。
割とどうでもいいものは省いたので、下のリストにあるのはそこそこな大きさの石ということです。

  • 29LV320CTTC-90G : ROM
  • LFE8731 : Lan filter
  • 88E6060-RCJ1 : Ethernet Switch
  • M12L128324A : SDRAM
  • AR2313A001 : あまり詳しい情報がなかったのですがおそらく無線lanチップ

これらの石に関しては名前をそのままググればデータシートなどが読めます。
今回は石を触らないので詳細は省きます。

次にあやしいポートとかピンを探します。

f:id:morimolymoly:20170907174621j:plain
あやしいぞ

かなりUARTっぽいポートが目につきます。(Tx, Rx, GND, Vccの4つのピン)
JTAGっぽいのもある気がします。

ということでボードを眺めるだけでもかなりの情報が得られました。

UARTピンの見極め

UARTっぽいポートが本当にUARTであるとして、これのピンアサインを特定する必要があります。
UARTは簡単な構成をしているので特定は容易です。
ピンを探すにはどのご家庭にも一つはあるマルチメーターを使用します。
まずはGNDを探します。
マルチメーターの導通チェック機能を使います。
黒い方をGNDに接続し(単に金属に触れていれば良いらしい)、赤い方を順番に並んだピンに繋いでいく。(別に赤がGNDにつながっていてもいい)

f:id:morimolymoly:20170907175958j:plain

ビープ音がなったらそこがGNDだとわかる。(GNDとGNDがつながるということ)

次にVccを探します。
Vccはコンスタントに高い電圧を示す場所を探せばいいだけです。
ルーターの電源を入れて、先程のGND以外の電圧を測定します。
黒い方をGNDに赤い方を他のピンに接続します。
予定ではさくっとわかるはずだったのですが、3.3v近くの電圧値を示すピンが2つありました。

そこで方針を変えて、まずTxピンを探すことにしました。
Txピンは電源を入れてからboot間の10~15秒ほどは電圧値の変動が観測されるので、それを目印に探しました。
するとその通り、目まぐるしく電圧値を変化させるピンがあったのでそれがTxで残る3.3vを示すピンがVccだとわかりました。
これで3/4のピンが確定したので、必然的に残る一つのピンはRxとなります。

以上でピンアサインが特定できました。
このような面倒くさいことをしなくてもロジックアナライザを使えばもっとかんたんに特定できるようです。

ボーレートを当てる

ボーレートは先述の通り、UARTでは重要な要素の一つです。
ボーレートがわからない状態で通信を行えば、めちゃくちゃな文字列が降ってきてまともに対話ができません。
本来ならば以下のようなツールがあるのですが、今回はそれを使わず手作業でボーレートを特定しました。

github.com

より温かみのあるボーレートが分かりました。
作業工程ですが、これはBus pirateを使って特定したので詳細は次の項で説明します。

Bus PirateでUARTを扱ってみる

UARTを操るためにはUSB TTLケーブルなどが必要ですが、僕はbus pirateという偉大な道具を持っているのでこれを使いたいと思います。

Bus Pirate - DP

bus pirateはI2C, JTAG, UARTなど各種通信プロトコルをサポートしており、またロジックアナライザ機能も有しているまるでハードウェアハッキングにおけるスイスアーミーナイフとも言えるツールです。*1

bus pirateとボードを接続する

まずbus pirateのピンからUARTで使うピンを抜き出し、ボードのUARTポートに接続します。

f:id:morimolymoly:20170907210125p:plain
Dangerous prototypesより

上の画像のように灰色がTxなのでこれをボードのRxにつなぎ、黒がRxなのでTxにつなぎます。
またGNDの茶色をボードのGNDに接続します。
ここで注意が必要なのはVccはどこにも接続しないことです。

このように接続が完了すると以下のようになるはずです。
手前に見える赤い基盤がbus pirateです。よくみるときちんと指定した色のジャンパ線が接続されていることがわかります。

f:id:morimolymoly:20170907172434j:plain
シルバーのダサいアダプタはMBPを使うがゆえ

UART通信をしてみる

まずはbus pirateの中に入ります。
screenコマンドなどをつかえばかんたんに入れます。

screen /dev/tty.usbserial-AL03NOF9 115200

/dev/hogehogeはデバイスファイルです。
115200はbus pirateのボーレートです。
bus pirateのなかに入ったら以下のようにコマンドを打って進んでいきます。

HiZ>m <- モード選択
1. HiZ
2. 1-WIRE
3. UART
4. I2C
5. SPI
6. 2WIRE
7. 3WIRE
8. LCD
9. DIO
x. exit(without change)

(1)>3 <- 今回はUARTの3を選択

Set serial port speed: (bps)
 1. 300
 2. 1200
 3. 2400
 4. 4800
 5. 9600
 6. 19200
 7. 38400
 8. 57600
 9. 115200
10. BRG raw value

(1)>5 <-ボーレートを選択

Data bits and parity:
 1. 8, NONE *default
 2. 8, EVEN
 3. 8, ODD
 4. 9, NONE
(1)>1 <-デフォルト
Stop bits:
 1. 1 *default
 2. 2
(1)>1 <-デフォルト
Receive polarity:
 1. Idle 1 *default
 2. Idle 0
(1)>1 <-デフォルト
Select output type:
 1. Open drain (H=Hi-Z, L=GND)
 2. Normal (H=3.3V, L=GND)

(1)>2 <-ノーマル
Ready
UART>(0) <-マクロ0番(マクロ一覧表示)
 0.Macro menu
 1.Transparent bridge
 2. Live monitor
 3.Bridge with flow control
UART>(1) <-Transparent bridge
UART bridge
Reset to exit
Are you sure? y

コマンドは見た通りです。
基本的にはデフォルトに忠実です。
しかし重要なコマンドが2つあります。
ボーレートとマクロ操作です。
ボーレートはご存知の通り重要な値ですが、今回はこれを昇順でひとつひとつ変動させてボーレートを特定していきました。今回は9600で通信が成功したので、ボーレートは9600とわかりました。

次にマクロ操作ですが、今回はマクロ0番でマクロ一覧表示を表示させたあと、Transparent bridgeを実行しています。
Live monitorはTransparent bridgeから入力機能をオミットしたもので、今回は適しません。
Bridge with flow controlはTransparent bridgeにRTS/CTSというフロー制御を加えたモードで、これも今回は使いません。

通信結果

さて、ボーレートも特定し、bus pirateでUARTが制御できるようになったので、早速通信してみました。

UART>(1)
UART bridge
Reset to exit
Are you sure? y

IPL:HARD-RESET
memory test ... ok

boot version: 0.0.2
Boot:post start
DRAM test ...
PASS
Timer test ...
PASS
post success
now booting Firmware ...

Aterm system software start

BASE LEVEL CONTROL START

welcome to debug console

Loop Forever
debug> help
support commands ...
reboot           reboot system
macaddr          macaddr read/write
errorlog         errorlog command
configid         configid read/write
additional       additional command
exit             close debug telnet cli
debug            debug command
help             help command
?                help command
dfs2             dfs2 bangradar[rssi][dur][rx_tsf][tsf_h][tsf_l]

デバッグモードが起動しました。どうやらいきなりshellが降ってくるものではなかったみたいです。
使えるコマンドもかなり制限されているのでここから権限昇格は厳しそうだとわかります。
NECルーター、結構セキュアでした。

flash romに対するglitch attack

root取る気満々で手を動かしたのにどうにもならなかったので、もういっそ破壊してしまおうという気持ちがむくむくと湧き上がってきたので、少し危険な攻撃をすることにしました。今回はflash romに対するglitch attackを試してみることにしました。
glitch attackの定義が自分の中ではかなり曖昧なんですが、特定の信号を落としたり、上げたりして不正な動作を引き起こす攻撃と認識しているのですが、間違っていたらマサカリぶん投げてください。
glitch attackの例としてはとある機器のハッキングでnand glitchという攻撃が使われていました。この時はu-bootがnandからkernelを読み込むときに、nandのoutputをGNDに接続して妨害することでu-bootがshellを出すというものです。
その他にもrhme2という組み込み機器のCTFでもglitch attackが出題されたりしたようです。

www.youtube.com

とりあえずシンプルかつ特別な機器がなくてもできる攻撃なので、今回はこれを試してみました。
早速、ルーターのボードに搭載されている29LV320CTTC-90Gのデータシートを読み、攻撃できそうなポートを探しました。
ちょっと著作権とか怖いのでデータシートは載せませんが、A16というアドレスの入力箇所とQ5,12,13というデータI/Oに対して攻撃しました。

攻撃方法

一本のオスーオスのジャンパケーブルを使って攻撃をします。
一方をGNDに接続し、もう片方を攻撃箇所に接続します。

アドレス入力ポートへの攻撃

アドレスポートは攻撃していてすごく楽しかったです。

debug> reboot
IPL:HARD-RESET
memory test ... ok

boot version: 0.0.2
Boot:post start
DRAM test ...
PASS
Timer test ...
PASS
post success
now booti.g F.rmw.re ...
system load fait
wait console .ece.ve...net cot olt mot

exi@pti@n!�
xiept�on!�
ExcCode:4 "Address error exception (load or instruction fetch)"

0000ffd0 (param1) 0000ffd1 (param2) 0000ffd2 (param3)
0000ffd3 (param4) 0000ff10 (errno) 30000010 (cause)
0000ff10 (ctx) 0000ff10 (fpcsr) 0000ff54 (badvaddr)
0000ff54 (pad) 10006054 (sr) 8000c254 (epc)
00000002 (lo) 00000008 (hi)
00000008 (zero) a0040008 (at) 80020001 (v0) 80020001 (v1)
80020701 (a0) 00000001 (a1) 80020740 (a2) 80020740 (a3)
80020b48 (t0) 8000c440 (t1) 8000a0e4 (t2) 8000a1e4 (t3)
80009ce4 (t4) 800126e4 (t5) 80020065 (t6) b8200065 (t7)
80030000 (s0) 00000065 (s1) 000000e0 (s2) 800207e0 (s3)
00000000 (s4) 800211e0 (s5) 80020850 (s6) 80020000 (s7)
80cda400 (t8) 00000000 (t9) 000000ff (k0) 000000ff (k1)
ffffffff (gp) 800207ff (sp) 80020000 (fp) 80012300 (ra)

call trace
pc: 8000c254



IPL:HARD-RESET
memory test ... ok

boot version: 0.0.2
Boot:post start
DRAM test ...
PASS
Timer test ...
PASS
post success
now booting Firmware ...

etception�!
���������������������������������@����
...
以下メチャクチャなデータが続く、解析していないんですがファームとかRAMのデータが吐き出されているような感じでした。
...
exception!!
ExcCode:4 "Address error exception (load or instruction fetch)"

0000ffd0 (param1) 0000ffd1 (param2) 0000ffd2 (param3)
0000ffd3 (param4) 00000010 (errno) 10008010 (cause)
00000010 (ctx) 00000010 (fpcsr) 000045e4 (badvaddr)
000045e4 (pad) 10006002 (sr) 800145e4 (epc)
00190000 (lo) 00000000 (hi)
00000000 (zero) a0040000 (at) 00000010 (v0) bc000014 (v1)
00000000 (a0) 00000240 (a1) 8002a810 (a2) 10006002 (a3)
ffffffff (t0) 00000001 (t1) 80020000 (t2) 00008000 (t3)
80020000 (t4) 80021b18 (t5) 80020000 (t6) 00000008 (t7)
0000ffca (s0) 0000ffcb (s1) a0030040 (s2) 80030040 (s3)
100000ff (s4) a003ff44 (s5) 000000ff (s6) 800200ff (s7)
80cda4a4 (t8) 00000001 (t9) 00000010 (k0) 0000007c (k1)
ffffffff (gp) a003ff40 (sp) 80020000 (fp) 8000007c (ra)

call trace
pc: 800145e4

まあ思った通り不正なアドレスに飛ばされたことでめちゃくちゃ怒ってます。
というか吐き出されたレジスタっぽい内容から察するにmipsなんですかね。
そういえばこのルーターのACアダプタをなくしていたので、同じくMIPSを採用しているPSPのACアダプタで代用していたのですが、運命ですかね!?*2

データI/Oに対する攻撃

これは少し興味深い結果が得られました。

IPL:HARD-RESET
memory test ... ok

boot version: 0.0.2
Boot:post start
DRAM test ...
PASS
Timer test ...
PASS
post success
now booting Firmware ...
system load fail
wait console receive...net console mode

カーネルの読み込みに失敗したのはわかるのですが、"net console mode"とは一体。
nmapしてもホストが落ちていたので、glitchのタイミングが悪かったりしたんですかね。

めちゃくちゃにglitch!

一通り遊んで満足したのでもうめちゃくちゃに攻撃しました。
ひたすらジャンパケーブルでピンをなぞりまくりました。

breakpoint errorを吐いたり

now booting Firmware ...

Aterm system software start

exception!!
ExcCode:9 "Breakpoint exception"

2442ffff (param1) acc21b0c (param2) 326200ff (param3)
02021004 (param4) 02228825 (errno) 90000024 (cause)
8e421afc (ctx) 8fc31b10 (fpcsr) 90530000 (badvaddr)
24420001 (pad) 10000002 (sr) 80268bc8 (epc)
ffffffff (lo) 00000001 (hi)
00000000 (zero) a0010000 (at) 00000001 (v0) 00000001 (v1)
00000000 (a0) 00000000 (a1) 00000000 (a2) 00000000 (a3)
804c6aa8 (t0) 804c6aac (t1) 804c7c44 (t2) 804c72f0 (t3)
bfc00000 (t4) 80021b18 (t5) 80020000 (t6) 00000009 (t7)
80600000 (s0) 804c7c30 (s1) 00000000 (s2) 80271924 (s3)
00000000 (s4) 804c7e11 (s5) 804c7e20 (s6) 00000201 (s7)
ffffffff (t8) 00000001 (t9) 00000024 (k0) 0000007c (k1)
ffffffff (gp) 80608a08 (sp) 804c7e30 (fp) 80267a50 (ra)

call trace
pc: 80268bc8
00: 80041b24
01: 80041b68
02: 80041b98
03: 80041fdc
04: 80041e94
05: 80041bcc
06: 801409ec
07: 80140964
08: 80267124
09: 8014085c

変な命令だと怒ったり。

now booting Firmware ...

exception!!
ExcCode:10 "Reserved instruction exception"

0000ffd0 (param1) 0000ffd1 (param2) 0000ffd2 (param3)
0000ffd3 (param4) 0000ffd4 (errno) eptiepti
ptiepti
tiept
iepti
epti
pti
exception!!
ExcCode:4 "Address error exc

そして5,6回rebootさせていたらすべてのランプを点滅したまま、絶命しました。
https://twitter.com/morimolymoly/status/905692123655110656

最後に

結局ルーターは死ぬし、rootは取れないしで散々でしたが、かなり楽しかったです。
ただ死んでも僕のIC取り修行とかROM吸い出しとかに活用するつもりなのでまだまだ頑張ってもらいます。

*1:スイスアーミーナイフっていう言葉が使いたかっただけだろ

*2:そんな訳はない