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

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

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

查看仓库
2237年前尚未审核

最受欢迎

查看全部 →

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

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

免责声明

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

需求

$ 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。

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 -    波特率/校验/位数 : 115200 8N1                                |
    | F - 硬件流控制        : No                                        |
    | G - 软件流控制        : No                                        |
    |                                                                       |
    |    更改哪个设置?                                              |
    +-----------------------------------------------------------------------+
            | 屏幕与键盘      |
            | 将设置保存为 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          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。然而,该命令需要密码;那么我们该怎么办呢?让我们逆向工程固件以找到密码生成算法。

(静态分析)先看看固件文件:

$ 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

我们可以得出以下结论:

  • $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 程序并编译它:

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;
}
下载工具