漏洞描述
这是一个基于堆栈的缓冲区溢出漏洞,存在于ipAddrDispose二进制 httpd 上运行的 Web 服务的功能中。该漏洞发生在将GET请求的参数值赋值给堆栈变量的过程中,允许用户将大量数据输入堆栈内存,攻击者可以控制。
影响版本
TP-Link TL-WR841N V12
漏洞分析
首先,输入我觉得对我来说容易理解的函数,即ping.
通过发送字符串开始检查程序是否允许溢出导致任何错误,aaaaaaaaa....aaa结果只能在 UI 上输入 50 个字符并收到消息ping request could not find host ….. Please check the name and try again.
似乎什么也没发生,我们一直在寻找处理程序并反转。结果,我们打开了 burp 套件并获得了包含/userRpm/PingIframeRpm.htm
打开 IDA 查找此 URL 字符串,并在以下位置找到处理此 URL 的函数0x44A530
这里httpGetEnv调用函数来获取ping_addr, doType, isNew通过 GET REQUEST 参数传递的值。
通过一个过程,使用传递ipAddrDispose的参数调用函数。ping _addr这里会出现漏洞。
buf_ip初始化一个大小为 52 字节的堆栈变量,并从ping_addr字符串的末尾接收每个字符值。问题是代码中没有通过验证来处理长度,ping_addr而是仅限于 Web UI,这可以很容易地绕过使用Burp Suite.
用 测试,输入一个大约 200 字节Burp Suite的长度以供娱乐,结果。程序崩溃了。返回地址寄存器被覆盖,因此漏洞被确认。ping_addra$ra
我写了一个快速的python脚本来启用这个漏洞。结果如我们所料。
开发
下一个目标是RCE是设备,因为设备没有开启任何保护机制,ASLR也被关闭了,所以我们可以控制$ra寄存器跳转到shellcode中执行代码并取得控制权。
看程序开头和程序结尾的汇编语句,栈变量的位置buf_ip,我们可以计算出要覆盖的偏移量,$ra: (0xD4 + 8) - (0xD4 – 0xA0) = 168 bytes同时可以控制另外两个寄存器$s0和$s1
为了有一个心智模型并建立一个漏洞利用,我开始制作记忆图。
在 MIPS 架构中,我们不能直接跳转到 shellcode 中执行代码,必须Icache (Instruction cache)先跳转到sleep()函数中清除内存。由于它在同一个固件上,我将在上述漏洞利用中再次使用 ROP。
构建完整的 ROP 链,我们将拥有如下的堆栈模型。
结果,我们成功利用了存在Stack Overflow漏洞的设备,因为我们在进行固件模拟,所以反向shell会打印日志,在真机上,不会出现这种情况。
解决版本
我发现此漏洞存在于 TL-WR841N V12 及以下版本中,并且 IDCVE-2022-30024已分配给此漏洞。用户应从 TP-Link 官网下载最新固件以更新补丁。
https://www.tp-link.com/en/support/download/tl-wr841n/v12/#Firmware