0x0 前言
来自GRIMM的安全研究人员Adam Nichols和来自越南互联网服务提供商VNPT 的研究人员d4rkn3ss分析报告了一个影响Netgear路由器的严重的栈缓存溢出远程代码执行漏洞,漏洞CVSS 评分为8.8分,漏洞影响79种不同型号的Netgear路由器的758种固件版本,受影响的固件中最早的版本是2007年发布的。远程攻击者利用该漏洞可以以root权限执行代码,并接管设备。
影响路由器:
AC1450D6220D6300D6400D7000v2D8500DC112ADGN2200DGN2200v4DGN2200MDGND3700EX3700EX3800EX3920EX6000EX6100EX6120EX6130EX6150EX6200EX6920EX7000LG2200DMBM621MBR624GUMBR1200MBR1515MBR1516MBRN3000MVBR1210CR4500R6200R6200v2R6250R6300R6300v2R6400R6400v2R6700R6700v3R6900R6900PR7000R7000PR7100LGR7300R7850R7900R8000R8300R8500RS400WGR614v8WGR614v9WGR614v10WGT624v4WN2500RPWN2500RPv2WN3000RPWN3100RPWN3500RPWNCE3001WNDR3300WNDR3300v2WNDR3400WNDR3400v2WNDR3400v3WNDR3700v3WNDR4000WNDR4500WNDR4500v2WNR834Bv2WNR1000v3WNR2000v2WNR3500WNR3500v2WNR3500LWNR3500Lv2XR300
0x1 简介
1.关键点:Netgear R7000,版本1.0.11.100_10.2.100及之前,未认证绕过获取到ROOT权限。
2.PoC代码参见:https://github.com/grimm-co/NotQuite0DayFriday/tree/master/2020.06.15-netgear
0x2 准备
版本 V1.0.11.208_10.2.101(已经修复):http://support.netgear.cn/Upfilepath/R7000-V1.0.11.208_10.2.101.chk
版本 V1.0.11.100_10.2.100(存在漏洞):https://www.downloads.netgear.com/files/GDC/R7000/R7000-V1.0.11.100_10.2.100.zip
调试的程序:httpd
0x3 工具
1.静态分析:IDA
2.获取文件系统:binwalk
3.程序调试工具:gdbserver、IDA
4.串口调试工具:Hyper Terminal软件、TTL转USB转接板
0x4 测试环境
Netgear R7000路由器真机测试,可以在某宝上或者某鱼上购买,价格不贵(学到的知识是无价的)。
0x5 串口调试
1.Netgear R7000路由器自身带有串口引脚,所以就没必要太过于费劲寻找串口引脚。如下图所示,是已经连接好的串口。
2.如下图是USB转TTL转接板,本人为什么先把这个工具插入到USB口,而不是USB转TTL转接板连接杜邦线(正常是提前连接杜邦线,USB转TTL转接板连接USB口,再打开Hyper Terminal,最后开启路由器,数据就会在Hyper Terminal显示),再去连接USB口,是有原因的,主要是因为,如果提前连接好杜邦线,再插入到USB口,那就获取不到信息(不信可以自行尝试,本人之前也遇到过类似的坑,脱坑后一直想着这个点)。
3.打开Hyper Terminal软件,调整好信息(Netgear R7000路由器使用默认信息即可,不用修改信息),点击确定。
4.开启路由器,等待几秒钟,再将杜邦线插入到TTL转USB转接板上(按着GND-GND、RXD-TXD、TXD-RXD的接法接),如下图所示。
5.此时就会在Hyper Terminal上打印信息。当打印启动完成后,获取到ROOT权限,便可以进行下一步的调试工作。
0x6 httpd程序调试
1.进入到路由器后,使用wget下载gdbserver程序进行调试(由于Netgear R7000是arm架构,所以需要下载arm架构的gdbserver)。
2.根据网上曝光的poc来看,漏洞点是在如下图的地址所示,只要能控制v9的大小,便可以溢出s的值。但是想触碰到漏洞点,必须要绕过 strcmp(src,”#$^”) ,而 src 必须是#$^,否则无法绕过,src是我们可以控制的数据,所以绕过这个函数并不难。只要在 *#$^ 数据的后面放入00便可以轻松绕过。
3.想要到达漏洞点,还有两个点需要绕过,s1(全部的数据) 必须存在name=”mtenFWUpload”,而且name=”mtenFWUpload”的数据之后需要存在 \r\n\r\n,所以在构造数据的时候必须是name=”mtenFWUpload” … \r\n\r\n。
4.可以看到R1寄存器(src的值)的值是我们控制的长度,而且这个长度是可以溢出到返回值地址处。
5.没有执行memcpy之前R0的值(s的值)是没有数据的,执行之后,就覆盖了构造好的数据。
6.运行到POP处,此时的SP的地址是0XBE911E54,就是已经被覆盖成了BBBB,由于ARM架构的特性,它会先将BBBB…IIII的数据存放到R4-R11的寄存器中,真正复制给PC的值是0X003D000,所以最终的返回值地址是0X003D000。
7.经过构造,程序会跳转到0X003D000地址处,将SP(此时的SP已经是0xBE911E78,所以是utelnetd -p 8888 -l /bin/sh的值)赋值给R0,并传给system函数执行命令,达到任意命令执行漏洞的效果。
0x7补丁比较
1.图7.1(V1.0.11.208_10.2.101)是已经打过补丁的,限制了v9的长度,而图7.2(V1.0.11.100_10.2.100)并没有对v9的长度进行限制,才导致溢出漏洞。
图 7.1
图 7.2
0x8 小结
这个漏洞原理相对来说比较简单,挺适合入门的大白。
1.串口调试时要注意TTL转USB转接板接入。
2.构造的poc中必须有*#$^,而且后面必须跟00,否则无法绕过strcmp。
3.0X003D000是很好的执行点,不需要跳转到libc库中,相对来说利用还是比较简单的。
4.导致溢出的原因,没有限制用户数据的长度。
















