D-Link DIR‑645 A1 在 ssdpcgi 中存在远程任意命令执行漏洞
前言
记一次漏洞挖掘,借鉴的是D-Link DIR 615645815 service.cgi远程命令执行漏洞的思路,定位system危险函数,然后去看看能否控制参数等。
漏洞分析
首先就是定位ssdpcgi_main这个关键函数

然后我们发现他也会调用lxmldbc_system这个函数,并且最终可以调用system函数,这意味着,只要我们可以控制他的参数,就可以实现任意命令执行


然后我们回头去看他的参数是怎么来的,这里的思路基本和service.cgi的命令执行漏洞一样

开始这个检测==2,是指命令要有两个,然后就是直接解析参数的内容没有任何检测,最终将内容直接赋值给%s_ssdpall_%s:%s_%s_&,这里我们就是可以直接控制参数

同时这里有好多选择,最终都会去执行system,直接用;{cmd}拼接来执行命令

漏洞验证
可以用qemu用户态进行验证
这里最终实现
1 | from pwn import* |
成功命令执行

最后的时候才发现已经被提交过了

补丁分析(DIR-850L)
然后想着去看看其他版本的ssdpci函数是否存在命令执行漏洞,最后是定位到DIR-850L,这个固件是有加密的,用在线网站可以直接解压缩,然后我们就ida反编译去看ssdpcgi函数
首先也是定位危险函数,lxmldbc_system函数还是存在的,然后就是看看能否去控制他的参数

然后我们从头开始分析,重点关注lxmldbc_system的参数是如何赋值的,getenv来获取参数,然后发现对v2,v3进行了处理,nptr的长度需要<6,这样439f60才为真
函数才能完成if判断

sub_40FE70,其实就是加了一个白名单的限制,先将参数赋值给hackstack_0,如果只是进行到这里的话,意味着我们可以控制参数,进而可以命令执行,但是,后续还有对hack_stack0的处理,最后会按照”uuid:%08llX-%04llX-%04llX-%04llX-%012llX”赋值给hackstack_0,我们的字符串会被转换为数字再传给hackstack_0,所以这个参数是没办法控制的,然后去看第二个
1 | int __fastcall sub_40FE70(const char *a1) |
sub_41011C,这个就是去检测ip,是ipv4还是ipv6,这里经过测试,如果不是这两个的形式会直接报错,也就是这个参数我们没办法控制,也就是说hackstack_0和buf目前没办法控制,然后去看s0和s1
1 | int __fastcall sub_41011C(const char *cp) |
s0也是数字,没办法拼接命令,

s1这里是有白名单检测的,这个参数也没办法控制,所以这个版本的漏洞已经被修复了,这里白名单限制的很死,没法绕过
