本教程仅供信息参考和教育目的。我认为,任何使用数字信息和计算机的人都应该熟悉道德黑客、信息安全及网络安全的相关知识。我相信,不了解黑客的手法,就无法有效防御黑客攻击。
$ IDA Pro +7.0(由于IDA价格昂贵,也可以使用Radar2)
$ 运行Rompager 4.07的路由器:数量众多,例如TP-Link TD-W8951*、ZyXEL P-660R、Billion BiPAC 51**/52** 等
$ UART转USB
"不幸的饼干"漏洞已存在一段时间,但公开的技术细节分析仍然缺乏。根据Check Point的报告,受影响的软件是来自AllegroSoft的嵌入式Web服务器RomPager。互联网范围的扫描表明,就可用端点数量而言,RomPager很可能是全球最流行的Web服务器软件。RomPager通常嵌入在设备固件中。该特定漏洞于2002年引入代码库。此外,暴露的设备使用RomPager服务的版本低于4.34(特别是4.07版本)。
本教程将使用一台运行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 仅回复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 通过XMODEM从地址x下载长度为y的数据到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可执行代码, 32/64位, 大端序, 至少1250条有效指令
strings 是一个很好的工具,可以了解二进制文件的内容。让我们看看能否找到密码算法:
$ strings rom1 | grep -i aten
$ strings rom2 | grep -i aten
显然看不到,因为固件仍然被压缩,这意味着我们必须使用调试模式从路由器中转储出来:
$ ATDO bfc00000, 1f0000
xmodem
想到的第一件事就是寻找调度表(dispatch table)。为什么?只是直觉,另一种可能性是使用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中的字(word)是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;
}
现在运行 ATSE 获取种子并使用它(例如,我得到 088521A78838):
$ ./gen_pass 088521A78838
现在运行我们刚刚破解的神奇命令 :p
$ ATEN1, A12F5AC6