日常跟踪漏洞情报,看到 Vigor3900
最新版本固件 1.5.1.6
存在多处后台命令注入漏洞(CVE-2024-44844/CVE-2024-44845)[1]。正好最近看到几个固件仿真小工具,一并试试效果。
Vigor3900
是 DrayTek
推出的一款高性能、多功能的企业级路由器,专为满足中大型企业、跨国公司及组织机构的网络需求而设计。支持多 WAN
冗余和负载均衡,具备强大的 VPN
功能和高级防火墙,适合复杂网络环境中的远程办公和分支机构互联,提供稳定、安全的网络解决方案。
DrayTek
官网提供固件下载[2]
](https://fw.draytek.com.tw/)
尝试 binwalk
提取压缩包中 .all
文件,只获取到一个 .ubi
文件。
一般情况下使用 ubireader
提取 .ubi
文件,可惜失败。
通过了解得知[3],ubi_reader
工具对于 ubi
文件要求较为严格,它并不能处理所有厂商定制的 UBI
镜像。ubidump
具备更强的兼容性,在处理特定固件格式时做了更多定制化处理。
使用 ubidump.py
[4]进行提取。
判断架构为 32位arm 小端
firmwalker
简单扫一下找找 web
服务,发现 lighttpd
服务。
固件仿真可以尝试一下 Sevnup
[5] (根据文件系统信息自动下载相关的内核文件、配置ip地址、打包上传文件系统等,懒狗福音了属于是)。
只需要在 qemu
里运行框中四条命令就行(qemu
里不能复制粘贴有些麻烦所以我运行完 ifconfig
后使用 ssh
连上去)。
执行完四条命令后直接进入 shell
并修改权限。
前文已经提到过 web
服务是 lighttpd
,尝试运行 /etc/init.d/httpd
,报错。
看看 /etc/init.d/lighttpd
和 /etc/lighttpd/serverport.conf
,lighttpd
如何解析 serverport.conf
。
可以看到 lighttpd
会根据当前 web_Port
变量的值(http
服务器端口) 向 serverport.conf
写入内容,配置 lighttpd
服务器的监听端口,看来并没有获取到 web_port
的值。
grep -r "web_port"
匹配关键字发现端口应该是 80
。
将 /etc/init.d/lighttpd
中 web_Port
改成 80
成功启动。
访问却出现 404
。
继续看看 /www
目录下都有什么文件,发现 /www/mobile
目录下存在 idnex.html
。并且访问 ip/mobile
即可访问到 /www/mobile/index.html
。
用户手册上说默认后台地址就是 192.168.1.1
(我仿真的环境是 10.10.10.2
) 而不是 /www/mobile
目录下,所以 /www
目录下应该同样存在 idnex.html
文件。并且从用户手册得知默认账户密码 admin/admin
。
发现 /www/ajax.zip
包含 index.html
,unzip
解压得到 index.html
并成功访问。
接下来你就会发现,哈哈登陆又失败啦,因为是后台洞所以必须拿到 cookie
,抓包看看怎么个事。
登陆认证请求的 /www/cgi-bin/mainfunction.cgi
文件,拖进 ida
搜索关键字 fail
(第一时间想的 patch
掉得了)。
Web UI Log-in Failure
应该就是这,交叉引用看看。
分析代码可知 sub_2BDE4
接收了用户名、密码、远程 IP 并返回登录状态 v30
。
进行跟进 sub_2C15C
,程序会将用户输入密码与系统中存储的密码进行匹配。
所以继续回到 shell
,搜索 passwd
相关文件,find . -name "*passwd*"
。
系统中存了密码但是认证还是失败,证明可能有脚本操作 /etc/data-default/passwd
,继续搜索关键字 grep -r /etc/data-default/passwd
。
运行 /etc/data-default/passwd
后成功登陆。
成了,可以复现漏洞了。
情报描述 name
参数通过 run_command
函数导致命令注入,我的 ida
并没有成功将 sub_21F28
识别为 run_command
,我这里手动改了一下。
先来看看 run_command
,run_command
接收输入为 a1
,代表一个字符串。并没有对 a1
进行任何的输入验证即调用 popen
执行。
漏洞触发在 sub_24764
函数 cgiGetValue(dword_44D3c,"name")
cgiGetValue(dword_44D3C, "type")
从请求中获取参数 name
type
, name
被传递给了 sub_ACD4
函数,返回值 v3
被作为证书文件的名字使用。因为 name
值用户可控且没有任何过滤,导致可能插入恶意系统命令。对type
进行验证,只有符合预期合法值才可通过。
漏洞复现
情报描述 option
参数通过filter_string
函数进行过滤,因为 filter_string
过滤不当并传入 system
导致命令注入,我的 ida
又没有成功将 sub_ACD4
识别为 filter_string
,我这里手动改了一下。
先看看 filter_string
,filter_string
作用是将特定字符(;
%
|
>
'
"
$
\t
\n
\r
)替换为 +
,也会将 &&
替换为 +
。但是并不会处理单独一个 &
。
漏洞触发在 sub_1DB3C
函数 cgiGetValue(dword_44D3C, "option")
从请求中获取参数,虽然 option
参数会先通过 filter_string
进行除了,但是前文已经提到黑名单中并不包含 &
,仍存在绕过可能,导致插入恶意系统命令。
固件仿真就这些招,以后学点新技术再来与诸君分享。
[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
固件版本:Vigor3900 v1.
5.1
.
6
https:
/
/
fw.draytek.com.tw
/
Vigor3900
/
Firmware
/
v1.
5.1
.
6
/
Vigor3900_v1.
5.1
.
6.zip
固件版本:Vigor3900 v1.
5.1
.
6
https:
/
/
fw.draytek.com.tw
/
Vigor3900
/
Firmware
/
v1.
5.1
.
6
/
Vigor3900_v1.
5.1
.
6.zip
$ 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
$ 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_extract_files _V3900_1516.
all
.extracted
/
20030.ubi
UBI Fatal: Less than
2
layout blocks found.
$ ubireader_extract_files _V3900_1516.
all
.extracted
/
20030.ubi
UBI Fatal: Less than
2
layout blocks found.
$ 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 var
boot data etc mnt rom sys usr www
$ 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
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2024-10-28 18:56
被摆烂星君编辑
,原因: