UARTで懲りずにルーターをハックした。あと間違えて殺した。2

はじめに

こんにちは。morimolymolyです。
今回はもっと深くハックするつもりだったんですけど、物理的にボードを壊してしまったので途中までの解析結果を記事にまとめます。(なので記事タイトルがUARTなのです)
はじめに結論を述べると、オチは一つもありません。
またこの記事を読むにあたっては、最初に以下の記事を読むのがいいと思います。
morimolymoly.hateblo.jp

今回ハックしたルーターCorega社のCG-WLRGNXW-Uです。
Coregaといえば最近、サポートの終了したルーターに複数の脆弱性が見つかり話題になりましたね。
JVN#00719891: CG-WLR300NM における複数の脆弱性

下調べ

f:id:morimolymoly:20170914142902j:plain
いつものようにまずはボードを眺めます。

f:id:morimolymoly:20170914180639j:plain
オッ。RT3050Fだ。

怪しいポートを探す

f:id:morimolymoly:20170914175240j:plain
すぐみつかりますね。
ただ今回はポートの数が多いので少し大変そうです。

UARTのピンアウトとボーレートを特定する

UARTのピンアサインで重要なのはTx, Rx, Vcc, GNDです。
今回は9個のポートがあるので見つけるのは少し大変でした。
今回もロジックアナライザは使用していません。
本当は使いたかったのですが、試す前に壊してしまったのでいずれ紹介できたらと思います。

GNDを探す

GNDを探すのはかんたんです。
マルチメーターの導通チェック機能を使えば一発でわかります。
まずはルーターの電源を落とします。
次に、メーターの黒い方を金属(今回は基板のシールド)に触れさせて、赤い方をポートに一つづつ触れていきます。
ビープ音がなったところがGNDです。
今回は左下の2つがGNDでした。

VccとTxを探す

Vccも割りとかんたんに見つかります。
ルーターの電源を入れて、マルチメーターでGND以外のピンの電圧を測定します。
すると3.3Vを示すポートが3つ見つかりました。
大体この中にTxが隠れていることが多いので一緒に探してしまいます。
TxはBoot中の10秒ほどは電圧値が安定しないという性質があるので、これを使ってTxを探します。
すると明らかに不安定な電圧値を示すポートが見つかりました。
これがおそらくTxでしょう。
今までで9個中5つのポートの特定ができました。(Vcc*2, GND*2, Tx)
UARTに必要なポートは残すところRxのみです

ボーレートを当てる

謎のポートが4つある中で手作業でRxを探すのは大変なので、とりあえずボーレートを当てます。
今回もブルートフォースで57600とわかりました。
これでUARTの通信ができるようになりました。

Rxを探す

BusPirate等のUARTが話せる装置でUARTの対話モードを使って、Rxをブルートフォースして探します。
入力値によって何かしらの変化が出力(Tx)に見られれば、それがRxということです。
するとかんたんにRxが見つかりました。

UART Exploit

では早速UARTで対話してみます。

Linuxのシェルを取る

gist.github.com

linuxのシェルが取れました。
しかしrootではありませんでした。
コマンド自体の数も制限されているし、普通のlinuxに含まれているpasswdファイルとかその他諸々も存在していませんでした。
またファイルの書き込みに関しても制限がかかっており、wgetコマンドは存在するものの、バックドアダウンロードするとかexploitコードをダウンロードするのも難しいのではないかと思います。
とりあえずそのシェルからrootを取るのは難しそうです。

U-bootのシェルを取る

試しにU-bootのシェルが取れるか試してみました。
U-bootが自由に操作できればカスタムファームウェアを焼くなど好きにいじることができるようになります。
試してみたところ1秒でシェルが取れました。
なぜかこのルーターはu-bootのモード選択をユーザが自由に操作することができました。
flashからbootするのが3番でこれがデフォルトになっているのですが、起動してからすぐ4番を押すとシェルがとれます。

gist.github.com

このように環境変数を出力してみました。
みてみるとシステムが読み取り専用であることや、ファイルシステムが最小限になっていた理由等もわかってきました。
おそらくこのbootイメージは組み込み向けの読み取り専用ファイルシステムcramfsを採用しているからでしょう。

まとめ

この機器の唯一の問題はブート中のシリアル入力を無効にしなかったことです。
まあwebコンソールについてはノーコメントですが(ノーコメントですよ!!(後々エミュするときにこれに触れるかもしれない))

最後に

このルーターはUARTで弄ったあとに、ピンヘッダをつけようとして色々やってたら間違ってぶっ壊してしまいました。
そんなわけで情報量が減っているというわけです。(はんだ付けする前にきちんとログを取っておけばよかった)
JTAGも試してみたかったですが、未確定のピンの数が3つしかないのでこれはJTAGではない気がします。
次はJTAG101かファームウェア解析でもやろうと思います。

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ルーターを扱います。
AtermWR6670S|製品情報|AtermStation

ボード観察

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

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させていたらすべてのランプを点滅したまま、絶命しました。


最後に

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

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

*2:そんな訳はない

セキュリティ・キャンプ2017全国大会に参加したという話

  • はじめに
  • セキュリティ・キャンプ全国大会とは?
  • 参加するまで
  • 参加決定から当日までの過ごし方
  • キャンプ一日目
    • セキュリティ基礎
    • 特別講義1
    • 特別講義2
    • チューター紹介
  • キャンプ二日目
  • キャンプ3日目
    • B4.Embedded System Reverse Engineering 101
    • B5.信じて送り出した家庭用ルータがNetBSDにドハマリしてloginプロンプト を返してくるようになるわけがない
    • BoF
  • キャンプ4日目
    • D6. LSMから見た Linux カーネルのセキュリティ
    • A7.ファジング実習
  • キャンプ5日目
    • グループワーク
  • さいごに

はじめに

こんにちは。
morimolymolyです。
セキュリティ・キャンプに参加したのでその感想文を投下します。
技術的な内容というよりかはポエム寄りです。

続きを読む