DrayTek研究之CVE-2024-41592详细分析
字数 2625 2025-08-29 22:41:10

DrayTek路由器漏洞分析:CVE-2024-41592详细研究

1. 固件解密与分析

1.1 固件解密方法

DrayTek Vigor2962路由器固件(v2962_4326.all)是加密的,解密步骤如下:

  1. 分析加密特征

    • 使用binwalk -E分析固件加密情况
    • 加密特征标识为"0204"
    • nonce(加密随机数)位于enc_signature后的12位
  2. 解密方法

    • 从旧版未加密固件(如3931版本)或GPL源码中获取解密程序
    • 关键解密程序路径:/draytek/drayapp/chacha20
    • 解密脚本位置:./Vigor2962_431_GPL_release/drayrt-release-gpl/output/rootfs/draytek/drayapp/runcommand/fw_upload
  3. 解密执行

    • 在Kali/Ubuntu中使用多架构环境执行解密
    • 解密后获得完整固件内容

1.2 文件系统提取

解密后固件提取可能遇到的问题及解决方案:

  1. 常规提取问题

    • 直接使用binwalk -Me可能无法完整提取EXT文件系统
    • 原因:存在LZ4压缩格式
  2. 解决方案

    • 方法一:使用unblob工具
    • 方法二:修改binwalk配置支持LZ4:
      • 编辑extract.conf文件(使用find定位正确路径)
      • 添加LZ4解压支持
      • 安装LZ4工具
  3. 挂载问题

    • 挂载/ext-root时空间不足的解决:
    • 使用cp命令复制内容
    • 重新挂载

2. 符号恢复技术

2.1 符号恢复方法

两种主要方法恢复无符号固件(soho2962.bin)的符号:

方法一:利用早期有符号固件

  1. 从Vigor早期版本固件中获取有符号的soho.bin
  2. 使用IDA插件:
    • rizzo.py(兼容IDA 7.x)
    • 需要shims包支持
  3. 操作步骤:
    • 从有符号固件导出符号表(.riz文件)
    • 导入到目标无符号固件中

方法二:部分符号恢复

  1. 参考Draytek3910符号表修复方法
  2. 优点:加载速度快
  3. 缺点:恢复符号较少

2.2 符号恢复工具

3. 仿真环境搭建

3.1 仿真准备

  1. 参考脚本

    • 修改原有qemu.sh适配高版本
    • 网络配置参考:drayrt-release-gpl/output/rootfs/draytek/drayrc/rc.d/rc.41.setupif.sh
  2. 常见问题解决

    • 报错:"efi-virtio.rom"缺失
    • 解决:找到并拷贝efi-virtio.rom到当前目录

3.2 网络配置

  1. 网络架构

  2. 网络设置文件

    • 系统网络配置文件位置需参考固件内容

4. CVE-2024-41592漏洞分析

4.1 漏洞概述

  • 类型:栈溢出漏洞
  • 影响程序:soho2962.bin
  • 关键函数:getcgi()makeword()
  • 修复版本:Vigor2962_v4.3.2.8

4.2 漏洞成因

  1. 根本原因

    • getcgi(a1,a2)函数未检测&符号数量边界
    • 循环读取内容时向栈变量a2写入,导致上层栈帧被覆盖
  2. 关键函数分析

    • makeword()功能:
      • 开辟空间存储key=value对
      • 返回p_key指针
      • 移动指针保存ptr_key和ptr_value
  3. 溢出机制

    • a2是栈上数据
    • while循环基于&数量向a2写入
    • 最终覆盖上一层栈帧内容

4.3 补丁比对

漏洞版本(V4.3.2.6)

  • 仅由v25控制循环,无边界检查

修复版本(V4.3.2.8)

  • 添加对*(_DWORD *)(a1 + 0x10LL)的长度校验
  • 防止&符号导致的溢出

5. 漏洞利用技术

5.1 利用条件

  1. 寻找可利用CGI

    • 未授权访问的CGI接口
    • 处理后不会破坏溢出布局
    • 关键特征:能在栈上写入0值
  2. 已发现的未授权接口

    • /cgi-bin/wlogin.cgi

5.2 利用技巧

  1. 绕过FreeCtrlName

    • FreeCtrlName会释放GET/POST请求数据
    • 解决方案:找到特殊CGI,其栈布局能使FreeCtrlName提前终止
  2. Shellcode构造

    • 使用unescape_url()绕过坏字符限制
    • URL编码传输:%DE%AD%BE%EF => Þ­¾ï
    • ROP链构造示例:
      movk x30, #0xbaad, lsl #16
      
  3. 命令执行限制

    • recvCmd限制命令长度<64字节
    • 绕过方法:分步执行命令

5.3 调试分析

  1. 关键问题解答

    • 溢出点:getcgi()的a2参数
    • 受影响栈帧:上层函数栈帧(非当前栈帧)
    • 原因:ARM架构特性,需控制上层函数返回地址
  2. 调试技巧

    • 使用gdb验证栈覆盖情况
    • 分析freeCtrlName对利用的影响
    • 确定真正可控的返回地址位置

6. 相关漏洞(CVE-2024-41585)

  1. OS命令注入漏洞

    • 触发点:特定CGI处理程序
    • 支持命令拼接执行
  2. 利用示例

    • 通过特定参数构造命令注入
    • 注意命令分隔符等细节

7. 网络服务分析

7.1 端口与服务定位

  1. 分析方法

    • 监听网络socket反推服务
    • 分析sockaddr_in结构体
    • 理解client-server通信机制
  2. IDA中定位技巧

    • IP地址以HEX形式表示
    • 端口号需结合上下文分析

7.2 网络架构特点

  1. 三层架构

    • Host层:基础Linux系统
    • Guest层:DrayOS专有系统
    • User层:用户空间
  2. 网络配置

    • 参考固件中的网络设置脚本
    • 理解DrayTek特有的网络管理方式

8. 总结与防御建议

  1. 漏洞总结

    • CVE-2024-41592:未授权栈溢出
    • CVE-2024-41585:命令注入
    • 影响版本:< V4.3.2.8
  2. 防御措施

    • 升级到最新固件版本
    • 限制未授权CGI访问
    • 实施输入严格验证
  3. 研究价值

    • 展示了IoT设备固件分析方法
    • 提供了ARM架构漏洞利用思路
    • 揭示了DrayTek路由器安全机制
DrayTek路由器漏洞分析:CVE-2024-41592详细研究 1. 固件解密与分析 1.1 固件解密方法 DrayTek Vigor2962路由器固件(v2962_ 4326.all)是加密的,解密步骤如下: 分析加密特征 : 使用 binwalk -E 分析固件加密情况 加密特征标识为"0204" nonce(加密随机数)位于enc_ signature后的12位 解密方法 : 从旧版未加密固件(如3931版本)或GPL源码中获取解密程序 关键解密程序路径: /draytek/drayapp/chacha20 解密脚本位置: ./Vigor2962_431_GPL_release/drayrt-release-gpl/output/rootfs/draytek/drayapp/runcommand/fw_upload 解密执行 : 在Kali/Ubuntu中使用多架构环境执行解密 解密后获得完整固件内容 1.2 文件系统提取 解密后固件提取可能遇到的问题及解决方案: 常规提取问题 : 直接使用 binwalk -Me 可能无法完整提取EXT文件系统 原因:存在LZ4压缩格式 解决方案 : 方法一:使用 unblob 工具 方法二:修改binwalk配置支持LZ4: 编辑 extract.conf 文件(使用 find 定位正确路径) 添加LZ4解压支持 安装LZ4工具 挂载问题 : 挂载/ext-root时空间不足的解决: 使用 cp 命令复制内容 重新挂载 2. 符号恢复技术 2.1 符号恢复方法 两种主要方法恢复无符号固件(soho2962.bin)的符号: 方法一:利用早期有符号固件 从Vigor早期版本固件中获取有符号的soho.bin 使用IDA插件: rizzo.py(兼容IDA 7.x) 需要shims包支持 操作步骤: 从有符号固件导出符号表(.riz文件) 导入到目标无符号固件中 方法二:部分符号恢复 参考Draytek3910符号表修复方法 优点:加载速度快 缺点:恢复符号较少 2.2 符号恢复工具 rizzo.py最新版: GitHub链接 兼容IDA 7.x的版本: grayhatacademy版本 需要配合bindiff等工具使用 3. 仿真环境搭建 3.1 仿真准备 参考脚本 : 修改原有qemu.sh适配高版本 网络配置参考: drayrt-release-gpl/output/rootfs/draytek/drayrc/rc.d/rc.41.setupif.sh 常见问题解决 : 报错:"efi-virtio.rom"缺失 解决:找到并拷贝efi-virtio.rom到当前目录 3.2 网络配置 网络架构 : 三层关系:host(linuxOS)-guest(drayOS)-user 参考文档: Local Network Setup and Management Routing Fundamentals IPsec VPN配置指南 网络设置文件 : 系统网络配置文件位置需参考固件内容 4. CVE-2024-41592漏洞分析 4.1 漏洞概述 类型:栈溢出漏洞 影响程序:soho2962.bin 关键函数: getcgi() 和 makeword() 修复版本:Vigor2962_ v4.3.2.8 4.2 漏洞成因 根本原因 : getcgi(a1,a2) 函数未检测&符号数量边界 循环读取内容时向栈变量a2写入,导致上层栈帧被覆盖 关键函数分析 : makeword() 功能: 开辟空间存储key=value对 返回p_ key指针 移动指针保存ptr_ key和ptr_ value 溢出机制 : a2是栈上数据 while循环基于&数量向a2写入 最终覆盖上一层栈帧内容 4.3 补丁比对 漏洞版本(V4.3.2.6) : 仅由v25控制循环,无边界检查 修复版本(V4.3.2.8) : 添加对 *(_DWORD *)(a1 + 0x10LL) 的长度校验 防止&符号导致的溢出 5. 漏洞利用技术 5.1 利用条件 寻找可利用CGI : 未授权访问的CGI接口 处理后不会破坏溢出布局 关键特征:能在栈上写入0值 已发现的未授权接口 : /cgi-bin/wlogin.cgi 5.2 利用技巧 绕过FreeCtrlName : FreeCtrlName会释放GET/POST请求数据 解决方案:找到特殊CGI,其栈布局能使FreeCtrlName提前终止 Shellcode构造 : 使用 unescape_url() 绕过坏字符限制 URL编码传输: %DE%AD%BE%EF => Þ­¾ï ROP链构造示例: 命令执行限制 : recvCmd 限制命令长度 <64字节 绕过方法:分步执行命令 5.3 调试分析 关键问题解答 : 溢出点: getcgi() 的a2参数 受影响栈帧:上层函数栈帧(非当前栈帧) 原因:ARM架构特性,需控制上层函数返回地址 调试技巧 : 使用gdb验证栈覆盖情况 分析 freeCtrlName 对利用的影响 确定真正可控的返回地址位置 6. 相关漏洞(CVE-2024-41585) OS命令注入漏洞 : 触发点:特定CGI处理程序 支持命令拼接执行 利用示例 : 通过特定参数构造命令注入 注意命令分隔符等细节 7. 网络服务分析 7.1 端口与服务定位 分析方法 : 监听网络socket反推服务 分析 sockaddr_in 结构体 理解client-server通信机制 IDA中定位技巧 : IP地址以HEX形式表示 端口号需结合上下文分析 7.2 网络架构特点 三层架构 : Host层:基础Linux系统 Guest层:DrayOS专有系统 User层:用户空间 网络配置 : 参考固件中的网络设置脚本 理解DrayTek特有的网络管理方式 8. 总结与防御建议 漏洞总结 : CVE-2024-41592:未授权栈溢出 CVE-2024-41585:命令注入 影响版本: < V4.3.2.8 防御措施 : 升级到最新固件版本 限制未授权CGI访问 实施输入严格验证 研究价值 : 展示了IoT设备固件分析方法 提供了ARM架构漏洞利用思路 揭示了DrayTek路由器安全机制