原创 Paper | Vigor3900 固件仿真及漏洞分析(CVE-2024-44844、CVE-2024-44845)

原创 Paper | Vigor3900 固件仿真及漏洞分析(CVE-2024-44844、CVE-2024-44845)

原创 404实验室 知道创宇404实验室 2024-11-13 15:36

作者:fan@知道创宇404实验室

时间:2024年11月13日

1.前言

参考资料

我在日常跟踪漏洞情报的过程中,看到 Vigor3900
 最新版本固件 1.5.1.6
 存在多处后台命令注入漏洞(CVE-2024-44844/CVE-2024-44845)[1]
。正好最近看到几个固件仿真小工具,我打算一并试试效果。

2.产品介绍

参考资料

Vigor3900
 是 DrayTek
 推出的一款高性能、多功能的企业级路由器,专为满足中大型企业、跨国公司及组织机构的网络需求而设计。支持多 WAN
 冗余和负载均衡,具备强大的 VPN
 功能和高级防火墙,适合复杂网络环境中的远程办公和分支机构互联,提供稳定、安全的网络解决方案。

3.环境模拟

参考资料

3.1 固件提取

DrayTek
 官网提供固件下载
[2]

固件版本:Vigor3900 v1.5.1.6https://fw.draytek.com.tw/Vigor3900/Firmware/v1.5.1.6/Vigor3900_v1.5.1.6.zip

首先尝试 binwalk
 提取压缩包中 .all
 文件,只获取到一个 .ubi
 文件。

$ binwalk -e V3900_1516.all DECIMAL       HEXADECIMAL     DESCRIPTION--------------------------------------------------------------------------------131120        0x20030         UBI erase count header, version: 1, EC: 0x0, VID header offset: 0x200, data offset: 0x800$ ls _V3900_1516.all.extracted/20030.ubi

一般情况下使用 ubireader
 提取 .ubi
 文件,可惜失败了。

$ ubireader_extract_files _V3900_1516.all.extracted/20030.ubi UBI Fatal: Less than 2 layout blocks found.

通过了解得知
[3]
,ubi_reader
 工具对于 ubi
 文件要求较为严格,它并不能处理所有厂商定制的 UBI
 镜像。ubidump
 具备更强的兼容性,在处理特定固件格式时做了更多定制化处理。

使用 ubidump.py

[4]
进行提取。

$ cd _V3900_1516.all.extracted/$ python3 ubidump.py -s . 20030.ubi ==> 20030.ubi <==1 named volumes found, 2 physical volumes, blocksize=0x20000== volume b'rootfs' ==saved 3402 files$ ls rootfs/bin   config_backup  dev  lib  proc  sbin  tmp  varboot  data           etc  mnt  rom   sys   usr  www

判断架构为 32位arm 小端。

$ file rootfs/bin/busybox rootfs/bin/busybox: ELF 32-bit LSB executable, ARM, EABI4 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.3, stripped

firmwalker
 简单扫一下找找 web
 服务,发现 lighttpd
 服务。

$ ./firmwalker.sh /home/iot/Desktop/vigor/_V3900_1516.all.extracted/rootfs***Search for web servers***##################################### search for web servers##################################### apache##################################### lighttpds/usr/sbin/lighttpds/usr/lib/lighttpds/etc/lighttpds/etc/init.d/lighttpd

3.2 固件仿真

固件仿真可以尝试一下 Sevnup
[5]
 (根据文件系统信息自动下载相关的内核文件、配置ip地址、打包上传文件系统等)。

图1 Senvup 模拟固件

图2 Senvup 模拟固件

只需要在 qemu
 里运行框中四条命令就行(qemu
 里不能复制粘贴,所以我运行完 ifconfig
 后使用 ssh
 连上去)。

ifconfig eth0 10.10.10.2/24ping 10.10.10.1wget http://10.10.10.1:8000/load_in_mips.shsh load_in_mips.sh

图3 Senvup 模拟固件

执行完四条命令后直接进入 shell
 并修改权限。

图4 Shell

前文已经提到过 web
 服务是 lighttpd
,尝试运行 /etc/init.d/httpd
,出现报错。

图5 运行 lighttpd 报错

看看 /etc/init.d/lighttpd
 和 /etc/lighttpd/serverport.conf
,lighttpd
 如何解析 serverport.conf

图6 /etc/init.d/lighttpd 源码

图7 /etc/lighttpd/serverport.conf 源码

可以看到 lighttpd
 会根据当前 web_Port
 变量的值(http
 服务器端口) 向 serverport.conf
 写入内容,配置 lighttpd
 服务器的监听端口,看来并没有获取到 web_port
 的值。

grep -r “web_port”
 匹配关键字发现端口应该是 80

图8 grep -r “web_port”

将 /etc/init.d/lighttpd
 中 web_Port
 改成 80
 成功启动。

图9 修改 /etc/init.d/lighttpd web_port

图10 启动 lighttpd

访问却出现 404

图11 访问报错

继续看看 /www
 目录下都有什么文件,发现 /www/mobile
 目录下存在 idnex.html
 。并且访问 ip/mobile
 即可访问到 /www/mobile/index.html

图12 ls /www

图13 访问 /www/mobile

用户手册上说默认后台地址就是 192.168.1.1
 (我仿真的环境是 10.10.10.2
) 而不是 /www/mobile
 目录下,所以 /www
 目录下应该同样存在 idnex.html
 文件。并且从用户手册得知默认账户密码 admin/admin
 。

图14 用户手册

发现 /www/ajax.zip
 包含 index.html
,unzip
 解压得到 index.html
 并成功访问。

图15 grep -r “index.html”

图16 解压 ajax.zip

图17 访问成功

接下来我们发现,登录又失败了,因为是后台漏洞所以必须拿到 cookie
 ,我们来抓包看看怎么回事。

图18 登录失败

图19 抓包

登录认证请求的 /www/cgi-bin/mainfunction.cgi
 文件,拖进 ida
 搜索关键字 fail

图20 ida 搜索关键字 fail

Web UI Log-in Failure
 应该就是这,交叉引用看看。

图21 交叉引用

分析代码可知 sub_2BDE4
 接收了用户名、密码、远程 IP 并返回登录状态 v30

图22 sub_2C15C 伪代码

继续跟进 sub_2C15C
 ,程序会将用户输入密码与系统中存储的密码进行匹配。

图23 sub_2BDE4 伪代码

所以继续回到 shell
,搜索 passwd
 相关文件,find . -name “passwd
 。

图24 find . -name “passwd

系统中存了密码但是认证还是失败,证明可能有脚本操作 /etc/data-default/passwd
,继续搜索关键字 grep -r /etc/data-default/passwd

图25 grep -r /etc/data-default/passwd

运行 /etc/data-default/passwd
 后成功登录。

图26 登录成功

图27 登录成功

成功了,可以复现漏洞了。

4.漏洞分析

参考资料

4.1 CVE-2024-44844

图28 CVE-2024-44844 漏洞描述

情报描述 name
 参数通过 run_command
 函数导致命令注入,我的 ida
 并没有成功将 sub_21F28
 识别为 run_command
,我这里手动改了一下。

先来看看 run_command
 ,run_command
 接收输入为 a1
,代表一个字符串。并没有对 a1
 进行任何的输入验证即调用 popen
 执行。

图29 run_command 伪代码

漏洞触发在 sub_24764

图30 sub_24764 伪代码

函数 cgiGetValue(dword_44D3c,”name”)
 cgiGetValue(dword_44D3C, “type”)
 从请求中获取参数 name
 type
 , name
 被传递给了 sub_ACD4
 函数,返回值 v3
 被作为证书文件的名字使用。因为 name
 值用户可控且没有任何过滤,导致可能插入恶意系统命令。对type
 进行验证,只有符合预期合法值才可通过。

name = "a & touch test &"cat /etc/ipsec.d/certs/a & touch test & | grep "BEGIN CERTIFICATE" -A 50

漏洞复现:

图31 CVE-2024-44844 漏洞复现

图32 CVE-2024-44844 漏洞复现

4.2 CVE-2024-44845

图33 CVE-2024-44845 漏洞描述

情报描述 option
 参数通过filter_string
 函数进行过滤,因为 filter_string
 过滤不当并传入 system
 导致命令注入,我的 ida
 又没有成功将 sub_ACD4
 识别为 filter_string
,我这里手动改了一下。

先看看 filter_string
 ,filter_string
 作用是将特定字符(;
 %
 |
 >
 ‘
 “
 $
 \t
 \n
 \r
 )替换为 +
 ,也会将 &&
 替换为 +
 。但是并不会处理单独一个 &
 。

图34 filter_string 伪代码

漏洞触发在 sub_1DB3C

图35 sub_1DB3C 伪代码

函数 cgiGetValue(dword_44D3C, “option”)
 从请求中获取参数,虽然 option
 参数会先通过 filter_string
 进行除了,但是前文已经提到黑名单中并不包含 &
 ,仍存在绕过可能,导致插入恶意系统命令。

option = a & touch test2024 &/sbin/logread >/tmp/a & touch test2024 &

图36 CVE-2024-44845 漏洞复现

图37 CVE-2024-44845 漏洞复现

5.相关链接

参考资料

[1] 漏洞详情

https://github.com/advisories/GHSA-2pmm-55vx-qrxv

[2] 固件下载

https://fw.draytek.com.tw/

[3] ubi文件解包

https://fw.draytek.com.tw/

[4] ubidump

https://github.com/the-modem-distro/pinephone_modem_sdk/blob/d5af451a7fa3c791a992a2d658131cb6db1f96d5/tools/ubidump/ubidump.py#L4

[5] Sevnup

https://github.com/N1nEmAn/Sevnup

作者名片****

往 期 热 门****

(点击图片跳转)




“阅读原文”
更多精彩内容!