Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
MIPS-CVE-2014-9222 — 让我们一起深挖 Zyxel 路由器固件和 MIPS Arch | Kitploit
工具/GitHubGitHub/donfanning/mips-cve-2014-9222
嵌入式系统安全漏洞分析漏洞利用逆向工程硬件黑客二进制分析学习与教育固件分析
GitHubdonfanning/mips-cve-2014-9222

MIPS-CVE-2014-9222

让我们一起深挖 Zyxel 路由器固件和 MIPS Arch

查看仓库
277年前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

免责声明

本教程仅供信息参考和教育目的。我认为,对于任何使用数字信息和计算机的人来说,伦理黑客、信息安全与网络安全应当是熟悉的主题。我坚信,不了解黑客的攻击方式,就无法有效防御他们。

需求

root@kitploit:~
$ IDA Pro +7.0(由于 IDA 相当昂贵,你也可以使用 Radar2)
$ 运行 Rompager 4.07 的路由器:数量庞大,例如 TP-Link TD-W8951*、ZyXEL P-660R、Billion BiPAC 51**/52**
$ UART 转 USB 转换器

不幸的 Cookie 漏洞已存在一段时间,但公开层面仍缺乏阐述该漏洞技术细节的分析。根据 Check Point 的报告,受影响的软件是 AllegroSoft 的嵌入式 Web 服务器 RomPager。全网扫描表明,就可用端点数量而言,RomPager 很可能是全球最流行的 Web 服务器软件。RomPager 通常嵌入在设备发布的固件中。此特定漏洞于 2002 年引入代码库。此外,暴露的设备是那些使用版本低于 4.34(特别是 4.07)的 RomPager 服务的设备。

在本教程中,我将使用一台运行 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

设备

我使用 minicom,你也可以使用 screen 或 HyperTerminal 等任何工具,但我更偏爱前者,因为它稳定性更好 ;)

首先必须停用 硬件流控制

root@kitploit:~
$ sudo minicom -s
root@kitploit:~
    +-----------------------------------------------------------------------+
    | A -    串行设备       : /dev/modem                                |
    | B - 锁定文件位置     : /var/lock                                 |
    | C -   呼叫程序        :                                           |
    | D -  呼出程序         :                                           |
    | E -    波特率/校验/位数 : 115200 8N1                                |
    | F - 硬件流控制        : No                                        |
    | G - 软件流控制        : No                                        |
    |                                                                       |
    |    更改哪个设置?                                              |
    +-----------------------------------------------------------------------+
            | 屏幕与键盘      |
            | 将设置保存为 dfl        |
            | 将设置保存为..          |
            | 退出                     |
            | 退出 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:~
======= 调试命令列表 =======
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

< 按任意键继续 >

此固件包含一组隐藏命令,对我们的动态分析非常有用;问题在于我们无法查看寄存器或设置断点,但幸运的是,借助这些隐藏命令我们可以实现这些功能。为了更好地查看和使用它们,我们需要使用 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)   # 取种子部分,由 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

我们可以得出以下结论:

  • $v1 是种子值(由 ATSE 命令生成,如果未使用 ATSE 则为零)
  • $t8 初始包含 MAC 地址的最后一个字节(最后一个八位组)
  • 0xA11F5AC6 是我们一直在寻找的魔法值!
  • 这两条指令:"$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
======= 调试命令列表 =======
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)

< 按任意键继续 >
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

< 按任意键继续 >
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 部分:
  0: BootExt(RAMBOOT), start=80030000, len=18000
  1: HTPCode(RAMCODE), start=80048000, len=E0000
  2: RasCode(RAMCODE), start=80048000, len=420000
$ROM 部分:
  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
     (已压缩)
     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
     (已压缩)
     Version: ADSL ATU-R, start: bfcb7830
     Length: 321D2C, Checksum: 582D
     Compressed Length: 11E54B, Checksum: B30B
$USER 部分:
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 会启动路由器,因此我们可以跟踪它,找到将执行权传递给固件第二部分的指令。

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        # 跳转并链接到 $s0 中的地址
ROM:80011E98                 nop

现在我们需要问:$s0 中存储的是什么地址?显然我们仍然不能设置断点,也不能查看寄存器,所以我们需要通过一些技巧来泄露它。幸运的是,我们可以读写内存,看看下面的命令:

root@kitploit:~
ATWL 80011E94, ae30001c
ATGR

看起来,这条命令将 0x80011E94 处的指令修改为 ae30001c(MIPS 指令 sw $s0, 0x1C($s1) 的字节表示)。通过用 sw $s0, 0x1C($s1) 覆盖原始的 jalr $s0,我们强制程序将 $s0 寄存器的内容存储到内存地址 0x8001FF1C 中。这样,第二阶段的固件将不会执行,而是显示 "ERROR" 消息,并且我们仍然可以访问第一阶段的控制台,太棒了!那么让我们看看 0x8001FF1C 中存储了什么。

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

抓到你了!... 使用 0x80020000,我们可以转储并正确分析固件的第二部分。

待续……

下载工具