
ZyxelルーターのファームウェアとMIPSアーキテクチャを掘り下げて楽しもう
チュートリアルは情報提供および教育目的のみです。私は、デジタル情報やコンピュータを利用するすべての人にとって、倫理的ハッキング、情報セキュリティ、サイバーセキュリティが身近なテーマであるべきだと考えています。ハッカーから身を守るには、ハッキングがどのように行われるかを知らなければ不可能だと考えています。
$ IDA Pro +7.0(IDAは非常に高価なので、Radar2を使用することもできます)
$ Rompager 4.07を実行しているルーター:TP-Link TD-W8951*、ZyXEL P-660R、Billion BiPAC 51**/52**など、膨大な数が存在します
$ UART to USB
ミスフォーチュンクッキーの脆弱性はしばらく前から存在していましたが、その技術的詳細を一般に示した分析はまだ不足しています。Check Pointによると、影響を受けるソフトウェアはAllegroSoftの組み込みWebサーバーRomPagerです。インターネット全体のスキャンによると、RomPagerは利用可能なエンドポイントの数に関して、世界で最も人気のあるWebサーバーソフトウェアである可能性があります。RomPagerは通常、デバイスに付属するファームウェアに組み込まれています。この特定の脆弱性は2002年にコードベースに導入されました。さらに、影響を受けるデバイスは、バージョン4.34より前(特に4.07)のRomPagerサービスを使用しているものです。
このチュートリアルでは、Rompager 4.07を使用するZXHN H108Lを使用します。
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="ZXHN H108L"
Content-Type: text/html
Transfer-Encoding: chunked
Server: RomPager/4.07 UPnP/1.0
EXT:
それではシリアルポートを使用しましょう。まずボーレートを特定する必要があります。
$ sudo stty -F /dev/ttyUSB0
出力:
speed 115200 baud; line = 0;
-brkint -imaxbel
デバイス
私は minicom を使用しています。screen から HyperTerminal まで何でも使えますが、安定性の面でこれが好みです。
$ sudo minicom -s
+-----------------------------------------------------------------------+
| A - シリアルデバイス : /dev/modem |
| B - ロックファイルの場所 : /var/lock |
| C - 発呼プログラム : |
| D - 応答プログラム : |
| E - Bps/パリティ/ビット : 115200 8N1 |
| F - ハードウェアフロー制御 : いいえ |
| G - ソフトウェアフロー制御 : いいえ |
| |
| どの設定を変更しますか? |
+-----------------------------------------------------------------------+
| 画面とキーボード |
| 設定をdflとして保存 |
| 名前を付けて保存.. |
| 終了 |
| Minicomを終了 |
+--------------------------+
これで準備完了です:
$ sudo minicom -D /dev/ttyUSB0 -b 115200
Bootbase Version: VTC_SPI1.26 | 2012/12/26 16:00:00
RAM: Size = 8192 Kbytes
Found SPI Flash 2MiB GD25Q16 at 0xbfc00000
SPI Flash Quad Enable
Turn off Quad Mode
RAS Version: ZXHN H108LV4.0.0a_ZRQ_MA
System ID: $2.12.162.0(G94.BY.2)3.20.19.0| 2014/03/21 20140321_v006 | 2014
Press any key to enter debug mode within 3 seconds.
..........
使用可能なコマンドを表示するには:
$ ATHE
======= デバッグコマンド一覧 =======
AT 単にOKを返答
ATHE ヘルプを表示
ATBAx ボーレートを変更。1:38.4k, 2:19.2k, 3:9.6k 4:57.6k 5:115.2k
ATENx,(y) BootExtensionデバッグフラグを設定 (y=パスワード)
ATSE パスワードジェネレータのシードを表示
ATTI(h,m,s) システム時刻を時:分:秒に変更、または現在時刻を表示
ATDA(y,m,d) システム日付を年/月/日に変更、または現在日付を表示
ATDS RASスタックをダンプ
ATDT ブートモジュール共通領域をダンプ
ATDUx,y アドレスxから長さy分のメモリ内容をダンプ
ATRBx アドレスxの8ビット値を表示
ATRWx アドレスxの16ビット値を表示
ATRLx アドレスxの32ビット値を表示
ATGO(x) アドレスxでプログラムを実行、またはルーターを起動
ATGR ルーターを起動
ATGT ハードウェアテストプログラムを実行
ATRTw,x,y(,z) RAMテストレベルw、アドレスxからyまで(z回反復)
ATSH ROM内の製造元関連データをダンプ
ATDOx,y アドレスxから長さyまでをXMODEMでPCにダウンロード
ATTD ルーター設定をXMODEMでPCにダウンロード
ATUR ルーターファームウェアをフラッシュROMにアップロード
< 任意のキーを押して続行 >
このファームウェアには、動的分析に非常に役立つ隠しコマンドのセットがあります。問題はレジスタを表示したりブレークポイントを設定できないことですが、幸いにもこれらの隠しコマンドを使用すればその機能が得られます。それらを表示して使用するには、ATEN を使用する必要があります。ただし、このコマンドにはパスワードが必要です。ではどうすればよいでしょうか? ファームウェアをリバースエンジニアリングして、パスワードジェネレータのアルゴリズムを見つけましょう。
(静的解析) まずファームウェアファイルを見てみましょう:
$ binwalk ras
binwalk1
$ dd if=ras of=rom1.lzma bs=1 skip=85043 count=66696
$ dd if=ras of=rom2.lzma bs=1 skip=350259 count=3350556
$ lzma -d <rom1.lzma> rom1
$ lzma -d <rom2.lzma> rom2
抽出したファイルのシグネチャを見てみましょう:
$ binwalk -Y rom1
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 MIPS executable code, 32/64-bit, big endian, at least 1250 valid instructions
string はバイナリファイルが何であるか、または何を含んでいるかの概要を得るのに優れたツールです。パスワードアルゴリズムが見つかるかどうか見てみましょう:
$ strings rom1 | grep -i aten
$ strings rom2 | grep -i aten
どうやらファームウェアはまだ圧縮されているため見つかりません。つまり、デバッグモードを使用してルーターからダンプする必要があります:
$ ATDO bfc00000, 1f0000
xmodem
最初に思い浮かぶのは、ディスパッチテーブルを探し始めることです。なぜなら?単なる直感です。唯一の代替案は if-elif ですが、それらは長いセットになるでしょう。ユーザーが提供したパスワードの有効性を確認するために、以下の結果を得ました:
ROM:800158A0 CmdTable: .word unk_80015C20 # DATA XREF: sub_8000E3D8+4Co
ROM:800158A0 # sub_8000E3D8+90o ...
ROM:800158A4 .word sub_8000E6D0
ROM:800158A8 .byte 0
ROM:800158A9 .byte 0
ROM:800158AA .byte 0
ROM:800158AB .byte 0
ROM:800158AC .word aJustAnswerOk # " just answer OK"
ROM:800158B0 .word aAthe # "ATHE"
ROM:800158B4 .word CMD_SHOW_HELP_ATHE
ROM:800158B8 .byte 0
ROM:800158B9 .byte 0
ROM:800158BA .byte 0
ROM:800158BB .byte 0
ROM:800158BC .word aPrintHelp # " print help"
ROM:800158C0 .word aAtba # "ATBA"
ROM:800158C4 .word CMD_ATBA
...
ROM:800158D0 .word aAten # "ATEN"
ROM:800158D4 .word CMD_ATEN
MIPSのワードは4バイトであることに注意してください。では CMD_ATEN を見てみましょう:
ROM:8000FF84 lw $a0, 8($s0)
ROM:8000FF88 jal sub_80013654
ROM:8000FF8C li $a1, 0
ROM:8000FF90 jal passwd_generator
そして passwd_generator:
ROM:80010A2C passwd_generator: # CODE XREF: CMD_ATEN+50p
ROM:80010A2C lui $t9, 0xA11F
ROM:80010A30 lw $v1, ptrDO_GTABLE
ROM:80010A34 lw $t8, dword_80017050
ROM:80010A38 lw $v1, 0x18($v1) # シード部分を取得、ATSEコマンドで生成される
ROM:80010A3C lbu $t8, 0x6D($t8) # MACアドレスの最終バイトを取得
ROM:80010A40 sll $v1, 8 # $v1 = v1 << 8
ROM:80010A44 andi $t7, $t8, 7 # $t7 = t8 & 0x7
ROM:80010A48 li $t8, 0 # $t8 = 0
ROM:80010A4C srl $v1, 8 # $v1 = v1 >> 8
ROM:80010A50 li $t9, 0xA11F5AC6 # $t9 = MAGIC
ROM:80010A54 j loc_80010A68
ROM:80010A58 addu $t9, $v1, $t9 # $t9 = $v1 + $t9
ROM:80010A5C # ---------------------------------------------------------------------------
ROM:80010A5C
ROM:80010A5C loc_80010A5C: # CODE XREF: passwd_generator+40j
ROM:80010A5C sll $t9, 31 # $t9 = $t9 << 31
ROM:80010A60 or $t9, $t6, $t9 # $t9 = $t6 | $t9
ROM:80010A64 addiu $t8, 1 # $t8 = $t8 + 1
ROM:80010A68
ROM:80010A68 loc_80010A68: # CODE XREF: passwd_generator+28j
ROM:80010A68 sltu $t6, $t8, $t7 # $t6 = (t8 < t7? 1:0)
ROM:80010A6C bnez $t6, loc_80010A5C # $t6 != 0 ならジャンプ
ROM:80010A70 srl $t6, $t9, 1 # $t6 = $t9 >> 1
ROM:80010A74 jr $ra # 完了、終了
ROM:80010A78 xor $v0, $t9, $v1 # $v0 = $t9 ^ $v1
結論:
では、同じことを行うCプログラムを作成してコンパイルしましょう: