在2019年6月,我们发布了一篇关于Belkin SURF N300路由器上进行硬件调试的博客文章。 在本博客中,我们将研究Josep Pi Rodriguez和PedroGuillénNúñez在此平台上所报告的10多个漏洞。 Belkin已接受我们的漏洞报告,但Belkin表示该产品已停产,相关漏洞不再进行修补。 这些漏洞影响了Belkin SuperTask! RTOS,特别是UPnP功能。 它包括AddPortMapping,GetSpecificPortMappingEntry和DeletePortMapping SOAP操作中的多个基于堆栈的缓冲区溢出以及upgrade.exe,dnsproxy和dhcpd中的缓冲区溢出。
这些错误最初是由提交者通过分析Belkin N150(型号F9K1001)和Belkin N300(型号F9K1002)的硬件而发现的。 我们验证了Belkin N300(型号F7D2301v1)路由器的相关漏洞报告。
UPnP
UPnP旨在简化一般消费者的网络配置,旨在实现“正常工作”。其允许本地客户端配置路由器。 但是,这种方法的前提是需要假设所有本地客户都值得信赖。 恶意软件可以轻松利用此功能在启用UPnP的路由器的防火墙上进行渗透。 UPnP通常被认为是不安全的。包括FBI,都建议消费者禁用并停止使用此功能。
研究人员发现UPnP WANPPPConnection:1Service容易受到多个堆栈缓冲区溢出漏洞的影响。 当路由器处理AddPortMapping SOAP操作时,路由器调用strcpy()将攻击者控制的NewRemoteHost参数复制到固定大小为0x20字节的堆栈缓冲区中,而不验证参数的大小。
当路由器处理图中的请求时,过长的NewRemoteHost参数被strcpy()盲目地复制到尺寸不足的堆栈缓冲区。 结果strcpy()写入堆栈缓冲区的末尾并用攻击者控制的数据覆盖函数的返回地址。 当易受攻击的函数返回时,它会尝试返回到覆盖的返回地址0x41414141。 然后将崩溃记录在串行终端中,路由器将重新启动。
在下图中,我们可以看到易受攻击的strcpy()函数调用。在0x80178C90位置,固定大小的堆栈缓冲区指针存储在寄存器$ a0中。 在0x80178C98处攻击者控制的缓冲区指针存储在$ a1寄存器中。 即使该指令位于jal strcpy指令之后,该延迟指令也会在分支之后执行,因为我们的目标是MIPS CPU架构。
此UPnP服务处理程序中存在13个错误,并且所有错误都具有相似的根本原因。 实际上,在上图中,我们可以在0x80178CCC处看到另一个易受攻击的strcpy()调用。 通过跟随级联if-else块可以找到更多strcpy()调用。 在图中,每个易受攻击的strcpy()调用都以红色着色:
没有观察到堆栈缓冲区溢出利用缓解,例如ASLR和堆栈canary。这些漏洞的利用是十分简便的。利用者编写器可以简单地用shellcode地址覆盖程序计数器地址以执行任意代码。
后门账户
除了缓冲区溢出漏洞外,研究人员还发现嵌入在固件中的硬编码后门帐户。
总共有三个后门帐户:“engineer”,“wlan_config”和“wlan_power”。 这些帐户不会暴露给Web界面,最终用户无法删除或修改它们。 当攻击者发出以下请求时,攻击者IP将被标记为“已登录”。 然后,攻击者可以从经过身份验证的IP访问特权页面。
绕过身份验证后,攻击者可能会利用其他身份验证后的漏洞,即特权upgrade.exe CGI脚本中的缓冲区溢出。 此缓冲区溢出漏洞是由使用strcpy()将攻击者控制的多部分HTTP POST请求边界标头值复制到全局变量中引起的。
在上图中,攻击者控制的数据存储在$ a1中,易受攻击的全局缓冲区存储在地址0x802965CA。 发送恶意请求时,路由器将以下错误记录到串行终端并重新启动。
特制DNS数据包
此堆栈缓冲区溢出漏洞会影响路由器的DNS代理。 处理特制DNS数据包时,路由器使用memcpy()将攻击者控制的数据复制到大小为80字节的堆栈缓冲区中。 由于目标缓冲区大小不匹配以及传递给memcpy()的字节数参数,导致缓冲区溢出。
当上述DNS消息发送到易受攻击的路由器时,以下异常日志将输出到串行终端,设备将重新启动:
同样,我们可以看到程序计数器已被攻击者控制的地址(0x42424242)覆盖。 我们可以在下图中看到易受攻击的memcpy()调用:
在0x80119D48,传递给memcpy()的字节数通过减去两个指针来计算。 结果值大于目标缓冲区的大小,因此,memcpy()盲目地复制到目标缓冲区的末尾并导致溢出