分析Belkin SURF路由器中的多个漏洞

 

0x00 前言

2019年6月,我们发布了一篇文章,介绍如何在Belkin SURF N300路由器上设置硬件调试环境。在本文中,我们将分析由Josep Pi Rodriguez以及Pedro Guillén Núñez在该平台上发现的十多个漏洞。虽然Belkin已确认我们的报告,但表示该产品已经停产,不再提供支持服务。这些漏洞会影响Belkin SuperTask! RTOS,特别是其中的UPnP功能。这些漏洞包括多个基于栈的缓冲区溢出问题,涉及AddPortMappingGetSpecificPortMappingEntryDeletePortMapping SOAP接口以及upgrade.exednsproxydhcpd中的缓冲区溢出问题。

研究人员最开始通过分析Belkin N150(Model F9K1001)以及Belkin N300(Model F9K1002)固件发现这些问题,我们也在Belkin N300(Model F7D2301v1)路由器上验证了这些漏洞报告。

 

0x01 UPnP问题

UPnP(Universal Plug and Play,通用即插即用)是为了简化一般用户的网络配置过程而提出的一种协议,方便各组件“正常工作”,该协议允许本地客户端配置路由器。然而,这个过程的前提是假设所有本地客户端都是可信的单元,但恶意软件可以轻松利用该功能,在启用UPnP的路由器上打洞穿透防火墙。因此UPnP通常被认为是不安全协议,包括FBI在内的各单位都建议用户禁用并不再使用该功能。

研究人员发现路由器UPnP功能的WANPPPConnection:1Service中存在多个栈缓冲区溢出漏洞。当路由器处理AddPortMapping SOAP请求时,会调用strcpy()将攻击者可控的NewRemoteHost参数拷贝至大小固定为0x20字节的栈缓冲区中,同时没有去验证参数的大小。

图1. 利用恶意UPnP请求触发漏洞

路由器在处理图1中的请求时,会使用strcpy()将过长的NewRemoteHost参数盲目地拷贝到空间不足的栈缓冲区中。因此,strcpy()会超出栈缓冲区执行越界写操作,使用攻击者控制的数据覆盖函数返回地址。存在漏洞的函数返回时,会尝试返回到被覆盖的返回地址(0x41414141),最终串行终端会记录崩溃信息,路由器会重启。

图2. 串行终端崩溃日志

在下图中,我们可以看到存在漏洞的strcpy()函数调用。在0x80178C90地址处,大小固定的栈缓冲区指针存放在$a0寄存器中。在0x80178C98处,攻击者控制的缓冲区指针存放在$a1寄存器中。即便该指令位于jal strcpy指令之后,由于我们目标采用的是MIPS CPU架构,因此也会在该分支后执行这条延迟指令。

图3. 存在漏洞的strcpy()函数调用

这个UPnP服务处理逻辑中存在13个bug,每个bug都存在相似的原因。实际上,在上图中我们可以看到0x80178CCC处由存在漏洞的另一个strcpy()调用。我们还可以在其他if-else分支块中找到更多的strcpy()调用。在图4中,我们使用红色高亮标出了存在漏洞的每个strcpy()调用:

图4. 高亮标记函数中存在漏洞的strcpy()调用

这里我们没有看到目标设备部署了能够缓解栈缓冲区溢出漏洞的措施,例如ASLR以及Stack Canary。因此这些漏洞利用起来非常直接,攻击者只需要简单使用shellcode地址覆盖程序计数器地址就能执行任意代码。

 

0x02 后门账户

除了栈缓冲区漏洞之外,研究人员还发现固件中内置了后门账户凭据。

图5. 固件中硬编码的后门账户

固件中总共有3个后门账户:engineerwlan_config以及wlan_power。这些账户并不能通过Web接口访问,终端用户也没有办法修改或移除这些账户。当攻击者发送如下请求时,路由器会将攻击者IP标记为“logged in”(已登录)。随后攻击者可以通过已授权的IP地址访问高权限页面。

图6. 使用内置的wlan_config凭据发送授权HTTP请求

一旦绕过授权认证,攻击者就可以利用另一个已授权漏洞,即高权限upgrade.exe CGI脚本中的缓冲区溢出漏洞。这个缓冲区溢出漏洞的根本原因在于路由器会使用strcpy()将攻击者可控的multipart HTTP POST请求头部中的boundary字段值拷贝到一个全局变量中。

图7. 带有过长boundary头部值的恶意HTTP POST请求

图8. 存在漏洞的strcpy()调用周围的反汇编代码

在上图中,攻击者可控的数据存放在$a1中,存在漏洞的全局缓冲区位于0x802965CA地址处。当攻击者发送恶意请求时,串行终端中会记录如下崩溃信息,然后路由器会重启。

图9. 串行终端中的崩溃日志

 

0x03 精心构造的DNS报文

这个缓冲区溢出漏洞会影响路由器的DNS代理功能。路由器在处理精心构造的某个DNS报文时,会使用memcpy()将攻击者控制的数据拷贝到大小为80字节的一个栈缓冲区。由于目的缓冲区大小与传递给memcpy()的大小参数不匹配,因此会出现栈缓冲区溢出问题。

图10. 恶意DNS请求

当如上DNS消息发送给存在漏洞的路由器时,串行终端中就会看到如下异常日志,目标设备也会重启:

图11. 串行终端崩溃日志

这里我们可以看到攻击者控制的地址(0x42424242)会成功覆盖程序计数器,存在漏洞的memcpy()调用如下图所示:

图12. 存在漏洞的memcpy()调用附近的反汇编代码

0x80119D48处,代码会执行两个指针的减法操作,计算传递给memcpy()的字节数参数大小。计算出的结果值会大于目标缓冲区大小,因此memcpy()会盲目地在目标缓冲区末尾处执行拷贝操作,导致缓冲区溢出。

 

0x04 总结

这个路由器固件的多个不同组件中存在大量漏洞,而这些漏洞的根本成因都非常相似,这表明厂商在产品开发过程中缺乏安全的软件研发生命周期实践,这很有可能表明固件中可能存在更多漏洞,实际上这一点我们猜测地非常准确。在这些漏洞的披露过程中,研究人员又提交了关于该产品的其他问题。然而,我们发现厂商已经不再为该产品提供补丁支持,因此我们拒绝了这些漏洞提交报告。即便如此,探索这些漏洞对研究人员来说也是非常有趣的一个过程,可以以此类推研究嵌入式系统中的其他问题。

我们建议终端用户升级存在漏洞的路由器,使用目前仍在厂商支持周期内的设备。

(完)