0x00 绪论
经过一整天的辛苦研究,放松下来,做点容易的事是件消遣。与10到15年前相比,现代软件开发流程极大地改善了商业软件的质量,但消费级网络设备却大为落后。因此,当需要找点乐子增强信心时,我喜欢分析SOHO设备。本文将审计 Netgear R7000路由器 ,分析其产生的漏洞以及随后的漏洞利用开发过程。可以在我们的 NotQuite0DayFriday 仓库中找到此博客文章中描述的漏洞的writeup和代码。0x01 初步分析
分析SOHO设备的第一步是获取固件。幸运的是, Netgear的支持网站 提供了R7000的所有固件。可以从该网站下载此博客文章中使用的Netgear R7000版本1.0.9.88固件。解压固件后,我们将使用 binwalk 从固件映像中提取root文件系统: 尽管路由器可能具有许多值得分析的服务,但Web服务器通常最有可能包含漏洞。在R7000之类的SOHO设备中,Web服务器必须解析来自网络的用户输入,并运行一些复杂的CGI函数,其中要用到这些输入。此外,Web服务器是用C编写的,并且几乎没有经过测试,因此经常容易受到很简单的内存破坏bug的影响。因此,我决定首先分析Web服务器httpd。 由于我们对Web服务器如何(错误地)处理用户输入感兴趣,因此从recv
函数着手分析Web服务器。
recv
函数用于从连接中获取用户输入。因此,通过查看Web服务器中
recv
函数的引用,我们可以看到用户输入从哪里开始。该Web服务器有两个调用
recv
的辅助函数,一个用于http解析器中,另一个用于读取发送到oemdns.com的动态DNS请求的响应。我们将重点关注前者,如下面的Hex-Rays反编译结果所示:
调用
read_content
(调用
recv
的辅助函数)之后,解析器进行一些错误检查,将接收到的内容与之前接收到的内容拼接在一起,然后在用户输入中查找字符串
name="mtenFWUpload"
和”
rnrn
“。如果用户输入包含这些字符串,则将这些字符串之后的其余用户输入传递给
abCheckBoardID
函数。在固件的root文件系统上运行grep,我们可以看到字符串
mtenFWUpload
是从文件
www/UPG_upgrade.htm
和
www/Modem_upgrade.htm
中引用的,因此我们可以得出结论,这是路由器升级功能的一部分。
0x02 上世纪漏洞的穿越
在用户输入之后,我们接下来看abCheckBoardID
函数。如下所示,该函数期望用户输入的是R7000的chk固件文件。它解析用户输入以验证魔术值(字节0-3),获取头部大小(字节4-7)和校验和(字节36-49),然后将头部复制到栈上一个缓冲区。复制通过
memcpy
函数执行,size参数由用户输入中的大小指定。因此,进行栈缓冲区溢出很容易。
在大多数现代软件中,此漏洞将无法利用。现代软件通常包含会阻止利用的 栈cookie 。但是,R7000不使用栈cookie。实际上,在所有共享通用代码库的Netgear产品中,只有D8500固件版本1.0.3.29和R6300v2固件版本1.0.4.12-1.0.4.20使用栈cookie。但是,D8500和R6300v2的更高版本却又不再使用栈cookie,从而使此漏洞再次可利用。与其他现代软件相比,这仅仅是SOHO设备安全性落后的一个例子。
0x03 开发利用程序
除了缺少栈cookie外,Web服务器还没有被编译为位置无关的可执行文件(PIE),因此无法充分利用ASLR。这就使得在httpd
二进制文件中找到一个ROP gadget很容易,如下图所示,它将使用从溢出的栈中获取的命令来调用
system
。
GRIMM的 NotQuite0DayFriday 仓库中的利用程序就借助此gadget以root用户身份启动telnet守护程序,监听TCP端口8888,且无需输入密码即可登录。
由于漏洞是在检查 跨站请求伪造 (CSRF)令牌之前发生的,因此也可以通过CSRF攻击来利用此漏洞。如果某个使用易受攻击的路由器的用户访问恶意网站,则该网站可能会利用该用户的路由器。所开发的漏洞利用程序通过发送一个HTML页面来演示漏洞,页面会将包含漏洞利用代码的AJAX请求发送到目标设备。但是,由于CSRF网页无法从目标服务器读取任何响应,因此无法对设备进行远程指纹识别。攻击者必须已经知道他们所试图利用的设备型号和版本,如下所示。
0x04 自动化利用
许多SOHO设备共享一个公共代码库,尤其是在同一制造商生产的设备之间常常共享代码。因此,通常来说在某设备中发现一个漏洞,同厂商的其他类似设备里也会有同样的漏洞。本文的案例中,我发现79种不同的Netgear设备和758个固件映像中包含着易受攻击的Web服务器。此漏洞早在2007年就已经影响固件(WGT624v4,版本2.0.6)。考虑到固件映像数量之大,手动寻找合适的gadget是不可行的。因此,这是尝试自动化检测gadget的好机会。find_arm_gadget.sh
和
find_mips_gadget.sh
两个Shell脚本包含在GRIMM的NotQuite0DayFriday仓库中。
find_arm_gadget.sh
脚本使用objdump和grep查找所需的gadget,如下所示。尽管R7000配备ARM处理器,但其他一些易受攻击的设备用的是MIPS处理器。与ARM不同,objdump无法轻松解析MIPS二进制文件中正在调用的函数的函数名。因此,MIPS gadget识别脚本使用IDAPython来识别二进制文件的gadgets。使用这些脚本,我成功为758个易受攻击的固件映像写出了利用程序。之后,我手动测试了28个易受攻击的设备的漏洞利用程序,以确保识别出的gadgets能够按预期工作。
0x05 版本检测
距离可靠地实现利用,还差最后一步:远程检测路由器的型号和版本。值得庆幸的是,几乎所有易受攻击的版本都监听对URL/currentsetting.htm
的请求,并返回设备的型号和版本。因此,对设备进行远程指纹识别轻而易举。仓库中发布的利用程序可以通过此方法自动确定目标型号和版本。
0x06 总结
路由器和调制解调器往往构成重要的安全边界,可防止攻击者直接利用网络中的计算机。但是,不良的代码质量和缺乏适当的测试已导致成千上万的易受攻击的SOHO设备 暴露在互联网 上长达十年之久。这篇博客文章说明了消费级网络设备安全性极其落后于时代。 2020年6月15日,ZDI发布了来自VNPT ISC的d4rkn3ss关于此漏洞的公告。我们独立发现了此问题,并于2020年5月7日直接向Netgear报告了此漏洞。关于ZDI的公告,请访问 https://www.zerodayinitiative.com/advisories/ZDI-20-712/ 戳“阅读原文”查看更多内容