Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
MIPS-CVE-2014-9222 — ZyxelルーターのファームウェアとMIPSアーキテクチャを掘り下げて楽しみましょう | Kitploit
ツール/GitHubGitHub/mercul1ninna/mips-cve-2014-9222
組み込みシステムセキュリティ脆弱性分析エクスプロイトリバースエンジニアリングハードウェアハッキングバイナリ解析学習と教育ファームウェア解析
GitHubmercul1ninna/mips-cve-2014-9222

MIPS-CVE-2014-9222

ZyxelルーターのファームウェアとMIPSアーキテクチャを掘り下げて楽しみましょう

リポジトリを見る
7年前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

免責事項

本チュートリアルは、情報提供および教育目的のみで作成されています。倫理的ハッキング、情報セキュリティ、サイバーセキュリティは、デジタル情報やコンピュータを利用するすべての人にとって馴染みのある題材であるべきだと考えています。ハッキングがどのように行われるかを知らなければ、ハッカーから身を守ることは不可能だと考えています。

要件

root@kitploit:~
$ IDA Pro +7.0 (you can use Radar2 since IDA is quite expensive)
$ Router running Rompager 4.07 : there're immense number of them such as TP-Link TD-W8951*, ZyXEL P-660R, Billion BiPAC 51**/52**
$ UART to USB

Misfortune Cookie の脆弱性はかなり前から存在していますが、その技術的な詳細を解説した分析は今だに公開されていません。Check Point によると、影響を受けるソフトウェアは AllegroSoft 製の組み込み Web サーバ RomPager です。インターネット全体を対象にしたスキャンによれば、利用可能なエンドポイントの数という点で RomPager はおそらく世界で最も普及している Web サーバソフトウェアです。RomPager は通常、デバイスに同梱されるファームウェアに組み込まれています。この特定の脆弱性は 2002 年にコードベースに導入されました。さらに、露出しているデバイスは RomPager の 4.34 より前のバージョン(特に 4.07)を使用しているものです。

このチュートリアルでは、Rompager 4.07 を使用している ZXHN H108L を使います。

root@kitploit:~
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:

ではシリアルポートを使ってみましょう。まず、ボーレートを確認する必要があります。

root@kitploit:~
$ sudo stty -F /dev/ttyUSB0

出力:

root@kitploit:~
speed 115200 baud; line = 0;
-brkint -imaxbel

device

私は minicom を使っています。screen から HyperTerminal まで何でも使えますが、安定性の点で私はこれを好みます ;)

最初に ハードウェアフロー制御 を無効にする必要があります

root@kitploit:~
$ sudo minicom -s
root@kitploit:~
    +-----------------------------------------------------------------------+
    | A -    Serial Device      : /dev/modem                                |
    | B - Lockfile Location     : /var/lock                                 |
    | C -   Callin Program      :                                           |
    | D -  Callout Program      :                                           |
    | E -    Bps/Par/Bits       : 115200 8N1                                |
    | F - Hardware Flow Control : No                                        |
    | G - Software Flow Control : No                                        |
    |                                                                       |
    |    Change which setting?                                              |
    +-----------------------------------------------------------------------+
            | Screen and keyboard      |
            | Save setup as dfl        |
            | Save setup as..          |
            | Exit                     |
            | Exit from Minicom        |
            +--------------------------+

これで準備完了です:

root@kitploit:~
$ sudo minicom -D /dev/ttyUSB0 -b 115200
root@kitploit:~
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

root@kitploit:~
======= Debug Command Listing =======
AT          just answer OK
ATHE          print help
ATBAx         change baudrate. 1:38.4k, 2:19.2k, 3:9.6k 4:57.6k 5:115.2k
ATENx,(y)     set BootExtension Debug Flag (y=password)
ATSE          show the seed of password generator
ATTI(h,m,s)   change system time to hour:min:sec or show current time
ATDA(y,m,d)   change system date to year/month/day or show current date
ATDS          dump RAS stack
ATDT          dump Boot Module Common Area
ATDUx,y       dump memory contents from address x for length y
ATRBx         display the  8-bit value of address x
ATRWx         display the 16-bit value of address x
ATRLx         display the 32-bit value of address x
ATGO(x)       run program at addr x or boot router
ATGR          boot router
ATGT          run Hardware Test Program
ATRTw,x,y(,z) RAM test level w, from address x to y (z iterations)
ATSH          dump manufacturer related data in ROM
ATDOx,y       download from address x for length y to PC via XMODEM
ATTD          download router configuration to PC via XMODEM
ATUR          upload router firmware to flash ROM

< press any key to continue >

このファームウェアには、動的解析に非常に役立つ隠しコマンドのセットがあります。問題は、レジスタを表示したりブレークポイントを設定したりできないことですが、幸いにもこれらの隠しコマンドを使えばその機能が得られるはずです。それらを表示して使うには ATEN を使う必要があります。ただし、このコマンドはパスワードを必要とします。ではどうすればいいのでしょうか? パスワードジェネレータのアルゴリズムを見つけるためにファームウェアをリバースエンジニアリングしましょう。

(静的解析)まずファームウェアファイルを見てみましょう:

root@kitploit:~
$ binwalk ras

binwalk1

root@kitploit:~
$ 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

次に、抽出したファイルのシグネチャを確認してみましょう:

root@kitploit:~
$ binwalk -Y rom1
root@kitploit:~
DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             MIPS executable code, 32/64-bit, big endian, at least 1250 valid instructions

string は、バイナリファイルが何であるか、何を含んでいるかの概要をつかむのに最適なツールです。パスワードアルゴリズムが見つかるかどうか見てみましょう:

root@kitploit:~
$ strings rom1 | grep -i aten
$ strings rom2 | grep -i aten

どうやら、ファームウェアがまだ圧縮されているため、それを見ることはできません。つまり、デバッグモードを使ってルータからダンプする必要があります:

root@kitploit:~
$ ATDO bfc00000, 1f0000

xmodem

最初に思い浮かぶのは、ディスパッチテーブルを探すことです。なぜかって? ただの直感です。もう一つの選択肢は if-elif ですが、それは長い連続になるでしょう。ユーザーが提供したパスワードの妥当性をチェックするためにです。そして、私が得た結果は次のとおりです:

root@kitploit:~
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 を見てみましょう:

root@kitploit:~
ROM:8000FF84                 lw      $a0, 8($s0)
ROM:8000FF88                 jal     sub_80013654
ROM:8000FF8C                 li      $a1, 0
ROM:8000FF90                 jal     passwd_generator

そして次は:passwd_generator

root@kitploit:~
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)   # take the seed part, generated by the ATSE command
ROM:80010A3C                 lbu     $t8, 0x6D($t8)   # take the last byte of the MAC Address
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    # take jump if $t6 != 0
ROM:80010A70                 srl     $t6, $t9, 1    # $t6 = $t9 >> 1
ROM:80010A74                 jr      $ra      # all done, exit
ROM:80010A78                 xor     $v0, $t9, $v1    # $v0 = $t9 ^ $v1

ここから結論付けられること:

  • $v1 はシード値です(ATSE コマンドで生成されます。ATSE が使われていない場合はゼロ)
  • $t8 は最初に MAC アドレスの最後のバイト(最終オクテット)を保持しています
  • 0xA11F5AC6 は、私たちが探していたマジック値です!
  • これら 2 つの命令「$v1 = v1 << 8」と「$v1 = v1 >> 8」は「seed = seed & 0x00FFFFFF」と同じです
  • (sll-or-srl) によるループは ROR 命令にすぎません(MIPS の ROR 命令は擬似命令なので、通常は sll-or-srl のシーケンスでエミュレートされます)
  • $v0 が結果です

では、同じことを行う C プログラムを作成してコンパイルしましょう:

root@kitploit:~
U32 passwd_generator(U32 seed, U8 last_mac_octet)
{
      U32 b = seed & 0x00FFFFFF;
      U32 r = ROR(b + 0xA11F5AC6, last_mac_octet & 7);
      return r^b;
}

では、ATSE を実行してシードを取得し、それを使いましょう(例:私は 088521A78838 を得ました):

root@kitploit:~
$ ./gen_pass 088521A78838

ハッキングしたばかりの魔法のコマンドを実行してみましょう :p

root@kitploit:~
$ ATEN1, A12F5AC6
root@kitploit:~
ATEN1, A12F5AC6
OK
ATHE
======= Debug Command Listing =======
AT          just answer OK
ATHE          print help
ATBAx         change baudrate. 1:38.4k, 2:19.2k, 3:9.6k 4:57.6k 5:115.2k
ATENx,(y)     set BootExtension Debug Flag (y=password)
ATSE          show the seed of password generator
ATTI(h,m,s)   change system time to hour:min:sec or show current time
ATDA(y,m,d)   change system date to year/month/day or show current date
ATDS          dump RAS stack
ATDT          dump Boot Module Common Area
ATDUx,y       dump memory contents from address x for length y
ATWBx,y       write address x with  8-bit value y
ATWWx,y       write address x with 16-bit value y
ATWLx,y       write address x with 32-bit value y
ATRBx         display the  8-bit value of address x
ATRWx         display the 16-bit value of address x
ATRLx         display the 32-bit value of address x
ATGO(x)       run program at addr x or boot router
ATGR          boot router
ATGT          run Hardware Test Program
AT%Tx         Enable Hardware Test Program at boot up
ATBTx         block0 write enable (1=enable, other=disable)

< press any key to continue >
ATRTw,x,y(,z) RAM test level w, from address x to y (z iterations)
ATWEa(,b,c,d) write MAC addr, Country code, EngDbgFlag, FeatureBit to flash ROM
ATCUx         write Country code to flash ROM
ATCB          copy from FLASH ROM to working buffer
ATCL          clear working buffer
ATSB          save working buffer to FLASH ROM
ATBU          dump manufacturer related data in working buffer
ATSH          dump manufacturer related data in ROM
ATWMx         set low 6 digits MAC address in working buffer
ATMHx         set hight 6 digits MAC address in working buffer
ATBS          show the bootbase seed of password generator
ATLBx         xmodem upload bootbase,x is password
ATSMx         set 6 digits MAC address in working buffer
ATCOx         set country code in working buffer
ATFLx         set EngDebugFlag in working buffer
ATSTx         set ROMRAS address in working buffer
ATSYx         set system type in working buffer
ATVDx         set vendor name in working buffer
ATPNx         set product name in working buffer
ATFEx,y,...   set feature bits in working buffer
ATMP          check & dump memMapTab
ATDOx,y       download from address x for length y to PC via XMODEM

< press any key to continue >
ATTD          download router configuration to PC via XMODEM
ATUPx,y       upload to RAM address x for length y from PC via XMODEM
ATUR          upload router firmware to flash ROM
ATDC          hardware version check disable during uploading firmware
ATLC          upload router configuration file to flash ROM
ATUXx(,y)     xmodem upload from flash block x to y
ATERx,y       erase flash rom from block x to y
ATWFx,y,z     copy data from addr x to flash addr y, length z
ATXSx         xmodem select: x=0: CRC mode(default); x=1: checksum mode
ATLD          Upload Configuration File and Default ROM File to Flash
ATBR              Reset to default Romfile
ATCD          Convert Running ROM File to Default ROM File into Flash

OK

ついに、メモリをダンプできるまったく新しいコマンドセットを手に入れました。

root@kitploit:~
$ ATMP
root@kitploit:~
ROMIO image start at bfc30000
code version: 
code start: 80008000
code length: 1A5D4E
memMapTab: 18 entries, start = bfc44000, checksum = 9770
$RAM Section:
  0: BootExt(RAMBOOT), start=80030000, len=18000
  1: HTPCode(RAMCODE), start=80048000, len=E0000
  2: RasCode(RAMCODE), start=80048000, len=420000
$ROM Section:
  3: BootBas(ROMIMG), start=bfc28000, len=4000
  4: DbgArea(ROMIMG), start=bfc2c000, len=2000
  5: RomDir2(ROMDIR), start=bfc2e000, len=2000
  6: BootExt(ROMIMG), start=bfc30030, len=13FD0
  7: MemMapT(ROMMAP), start=bfc44000, len=C00
  8: HTPCode(ROMBIN), start=bfc44c00, len=8000
     (Compressed)
     Version: HTP_TC V 0.05, start: bfc44c30
     Length: 10488, Checksum: CB32
     Compressed Length: 41CF, Checksum: D5A5
  9: termcap(ROMIMG), start=bfc4cc00, len=400
 10: RomDefa(ROMIMG), start=bfc4d000, len=2000
 11: LedDefi(ROMIMG), start=bfc4f000, len=400
 12: LogoImg(ROMIMG), start=bfc4f400, len=2000
 13: LogoImg2(ROMIMG), start=bfc51400, len=2000
 14: StrImag(ROMIMG), start=bfc53400, len=32000
 15: StrImag2(ROMIMG), start=bfc85400, len=32000
 16: Rt11nE2p(ROMIMG), start=bfcb7400, len=400
 17: RasCode(ROMBIN), start=bfcb7800, len=246C00
     (Compressed)
     Version: ADSL ATU-R, start: bfcb7830
     Length: 321D2C, Checksum: 582D
     Compressed Length: 11E54B, Checksum: B30B
$USER Section:
Msecs   128
Heap0   16   300 16
Heap1   32   64  4
Heap2   64   64  4
Heap3   128  160 4
Heap4   192  256 4
Heap5   256  80  4
Heap6   320  20   4
Heap7   384  4   2
Heap8   448  20  2
Heap9   512  34  2
Heap10  1024 52  4
Heap11  2048 20  2
Heap12  3172 4   2
Heap13  4096 2   2
Heap14  0 0
...

先ほど学んだことは、以前抽出した ROM ファイルを解析する際に役立ちます。

root@kitploit:~
code start: 80008000
code length: 1A5D4E

これで、次のコマンドを使って新しい ROM ファイルをダンプした後、ROM 開始アドレス と 読み込みアドレス を 0x80008000 に設定できます:

root@kitploit:~
$ ATDO 80008000, 1A5D4E

ATGR がルータを起動することがわかっているので、実行をファームウェアの第 2 部に渡す命令を見つけるために、それを追跡するという方法が取れます。

atgr1

root@kitploit:~
ROM:80011E8C loc_80011E8C:            # CODE XREF: LoadAndRunImage+D8j
ROM:80011E8C                 jal     sub_80009B24
ROM:80011E90                 li      $a0, 0x1F4
ROM:80011E94
ROM:80011E94 execute_image:           # execute image
ROM:80011E94                 jalr    $s0        # jump and link to address in $s0
ROM:80011E98                 nop

ここで、$s0 に格納されているアドレスは何かと問う必要があります。明らかに、まだブレークポイントを設定できず、レジスタも表示できないため、何らかのトリックを使ってそれを漏えいさせる必要があります。幸い、メモリの読み書きはできるので、次のコマンドを見てみましょう:

root@kitploit:~
ATWL 80011E94, ae30001c
ATGR

見たところ、このコマンドは 0x80011E94 の命令を ae30001c(MIPS の sw $s0, 0x1C($s1) 命令のバイト表現)でパッチしています。元の jalr $s0 を sw $s0, 0x1C($s1) で上書きすることで、プログラムに $s0 レジスタの内容を 0x8001FF1C メモリアドレスに格納するよう強制しました。これにより、第 2 段階のファームウェアは実行されず、代わりに「ERROR」メッセージが表示されますが、第 1 段階のコンソールには引き続きアクセスできます。やったー! それでは、0x8001FF1C に何が格納されたか見てみましょう。

root@kitploit:~
ATRL 8001FF1C
8001FF1C: 80020000

やった! ... 0x80020000 を使えば、ファームウェアの第 2 部をダンプして適切に解析できます。

続く ...

ツールをダウンロード