Netgear R6400 Router Vulnerability Discovery
Created August 10, 2023
本文内容仅用于个人存档和技术交流学习,禁止使用文中内容进行未授权或恶意的攻击行为。
1. 背景
研一暑假在家相对没那么忙,而刚过去的这学期又是漏洞挖掘课的助教,于是决定尝试挖一下家里面的Netgear路由器,锻炼一下动手能力。
基本信息如下:
- 设备型号:R6400 — AC1750 Smart WiFi Router 802.11ac Dual Band Gigabit / R6400
- 设备固件版本:1.0.1.78
- 固件下载链接
2. 攻击面分析
用BinWalk将固件解包后,发现存在/usr/sbin/httpd
,此为web服务对应的二进制,以此为主要分析对象。
首先,根据实验室先前论文工作SaTC[1]的经验,在后端httpd二进制中找到了用于获取前端输入数据的函数。如下图高亮(该函数原本没有符号,我将其重命名为了web_get_var
),web_get_var
的第二个参数为前后端共享关键字、第三个参数为目的buffer、第四个参数为buffer长度,这样根据该函数的交叉引用就可以初步确定httpd处理用户数据的起始点。

其次,IoT设备中通常还会存在一些数据共享范式,常见的有NVRAM读写(如下图)、环境变量读写、配置文件读写等[2],其一般会以一个关键字作为键值实现数据的存储和恢复。根据关键字字符串的交叉引用,我们可以将两段控制流衔接起来,提高分析的完整性。
(我们还发现有些NVRAM配置是通过shell命令进行设置的,还有些NVRAM配置则是直接在libnvram.so
中硬编码初始值的。)
基于上述观察,可以跟踪外部输入数据在httpd中的数据流,检查其是否存在操作不当之处,同时关注常见sink函数调用点(如strcpy
、system
等),从而发现潜在的漏洞。此外,还在逆向分析的过程中发现了该httpd中两个重要的实现机制。
2.1 CGI机制
嵌入式设备在实现web服务时可能会以CGI的方式实现:web server只负责对用户请求做简单地处理,然后将请求转发给 CGI 程序,CGI 程序处理请求后会将结果发给web server,最后web server再在包装数据后将其返回给用户。
CGI(Common Gateway Interface,通用网关接口)是一种标准,它定义了Web服务器与外部程序之间进行交互的接口规范。通过 CGI,Web服务器可以调用外部程序处理客户端请求,并将处理结果返回给客户端。CGI 最初是用于创建动态内容的一种技术。
Netgear R6400的CGI程序并不都以单独二进制程序的形式存在,而是在实现httpd时直接在其中嵌入了一些CGI处理函数。通过搜索".cgi"关键字并定位相关字符串引用点,我们发现了一个记录了CGI名称和对应处理函数的数组(如下图),比如"upgrade.cgi"的对应处理函数就是sub_2CD24
。
以此类CGI处理函数为分析起点,可以更好地确保发现漏洞的可触发性。

2.2 ASP cmd机制
在分析前端文件时,发现htm文件里会有一些形如<%num%>
的代码,查阅资料后发现此类标签其实是ASP command。
ASP(Active Server Pages)是一种由微软开发的服务器端脚本技术,用于创建动态的、交互性强的网页。ASP 页面包含嵌入在 HTML 中的服务器端脚本,这些脚本由服务器执行,并生成在浏览器中呈现的最终页面。<% %> 是用于包裹服务器端脚本的标记。
在httpd二进制中,发现了以下两个结构(符号名称均是我自己命名的):
-
ASP_cmd_list
数组:记录一条条完整的ASP command。 -
ASP_handlers_list
数组:记录每种ASP操作与handler函数的映射关系。
对于前端htm文件里的<%num%>
,后端httpd在解析时会以num
作为index,从ASP_cmd_list
中找到对应的完整ASP command字符串,再根据ASP_handlers_list
的映射关系,交给对应操作的handler函数处理并传递参数。对于ASP_handlers_list
数组中的处理函数,其实现的功能多是通过get类函数获取数据,然后再插入到前端htm文件里。
由此可知,对于ASP_handlers_list
里的handler函数中的sink点,其触发条件为:前端文件中有<%num%>
,且num
对应的ASP command需要以正确的ASP操作和满足约束的参数去触发sink点。
了解这些有助于我们更好地确定路由器的攻击面,避免在难以触发的代码片段上花费时间。
3. 漏洞描述
经过数天的逆向分析,辅助一些简单的IDA、Ghidra脚本,初步发现了一个Post-Auth的缓冲区溢出漏洞,可导致拒绝服务攻击。
漏洞点位于 sub_83A90
,该函数是 usb_device.cgi
的处理函数,如下图所示。


函数 sub_83A90
中使用 web_get_var
接收用户数据,并将 share_name
数据存储在变量 v44
中,其长度最多可以达到2048字节。然后,该函数使用 strcpy
将接收到的数据复制到由 v52
指向的栈缓冲区中,导致栈溢出。
相关信息已上报CNVD,并获得编号CNVD-2023-87691。
4. 小结
整个漏洞挖掘、分析的过程还算比较常规。但事实上,现有的一些自动化漏洞挖掘工作并不能很好地发现此类漏洞,因为函数指针和间接调用等情况,自动化分析仍存在一些困难。后面自己实践的过程中,需要尽量去发现一些共性问题,从而提炼出通用且有效的方法。
此外,Netgear与bugcrowd有合作,有一些漏洞激励计划,后续可以尝试挖一下有bonus的型号。
后记:后面发现ISSTA 2023一篇论文[3]的motivation example和本文中的case具有一定的共性,都是需要处理函数指针、间接调用的问题。但自己就没能以此为切入点提炼、总结出一个较完整的工作,还是值得反思的。
参考
[1] Sharing More And Checking Less: Leveraging Common Input Keywords to Detect Bugs in Embedded Systems (USENIX Security 2021)
[2] Karonte: Detecting insecure multi-binary interactions in embedded firmware (S&P 2020)
[3] Detecting Vulnerabilities in Linux-Based Embedded Firmware with SSE-Based On-Demand Alias Analysis (ISSTA 2023)