本教程仅供信息参考和教育目的。我认为,对于任何使用数字信息和计算机的人来说,伦理黑客、信息安全与网络安全应当是熟悉的主题。我坚信,不了解黑客的攻击方式,就无法有效防御他们。
$ 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
我们可以得出以下结论:
现在让我们编写一个执行相同操作的 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;
}