TP-LINK 型号为 TL-WR841N V10 的路由器设备上的漏洞被分配 ID CVE-2020-8423。该漏洞允许经过身份验证的攻击者通过向 wifi 网络配置发送 GET 请求来远程执行设备上的任意代码。
发现固件的版本:3.16.9 Build 150310。
在深入之前,我将分析 Dispatcher(), 以理解程序如何分配函数来正确地处理它的函数。
当一个 REQUEST 被提交时,httpGenListDataGet() 函数将被调用以返回一个 LIST_ENTRY 指针,该指针指向一个列表,该列表依次包含处理每个先前分配的 URL 的函数的函数指针。接下来,程序将调用函数httpGenListFuncGet()返回列表中的函数指针,并找出分配给处理函数的URL是否在提交的REQUEST中找到。如果有一个函数将被调用,否则将继续检查列表中的下一个函数指针。
该程序将使用 httpRpmConfigAdd() 函数为每个 URL 字符串分配一个处理函数。
所以,只要找到一个地方调用这个函数,使用src缓冲区作为用户输入,这个漏洞是完全可能的。
在逆向跟踪中,我得到一个 writePageParamSet() 函数,该函数具有 gen page 函数将值返回给用户,其中创建缓冲区 dst[512] 并传递给 stringModify() ,以接收句柄转义字符中的值。
此外,我们得到一个回调函数,它处理包含地址 0x45FA94 的 /userRpm/popupSiteSurveyRpm.htm 的 URL 字符串。
这个函数将接受GET请求的参数,并调用包含漏洞的函数。
我们可以根据输入的可选ssid参数来控制这个漏洞。
使用Payload = “/%0a” * 0x55 + “A” * 100。设置断点并观察。
因此验证了漏洞,修改了$ra寄存器值,覆盖了3个寄存器$s0, $s1, $s2。
检查并查看是否启用保护机制,这样我们就可以将shellcode传递给堆栈来执行任意代码。
MIPS架构有一个问题,我们需要在执行shellcode之前清除Icache缓存,为了解决这个问题,我们将控制程序跳转到Sleep()函数中。查看程序的库,我发现了与旧漏洞利用库匹配的 Ropchain,这需要一些调试和调整。
我在这里有一个 shellcode 参考,但它不起作用。通过调试发现,当shellcode传递给stringModify()函数时,如果包含字节\x3c, \x3e, \x2f, \x22, \x5c,程序将添加1字节的\x5c在\x5c\x3c或\x5c\x3e前,并破坏shellcode。检查这个shellcode包含2个坏字节\x3c和\x2f。我将通过替换其他命令来修复一些命令以删除这些坏字节。
这个字节在lui指令中,开发者的逻辑将在堆栈上保存4个字节。
我将把lui指令改为li指令,以保存堆栈上的2字节,而不是4字节。
在这个命令字符串中,shellcode包含2个坏字节,0x3c和0x2f,此时开发者想把字符串//bin/sh放到堆栈上时。
我将使用 li 指令删除 0x3c,并使用带有中间值的 xori 指令来修复 0x2f 字节。
这样,当我们修改shellcode时,我们就可以控制路由器。
我的下一个任务是评估这个设备的整个固件,这里我发现有更多的一日漏洞和零日漏洞。
我发现的第一个漏洞 (一日漏洞) 是一个严重漏洞 CVE-2022-24355,它允许网络攻击者在没有基于缓冲区溢出的身份验证的情况下执行任意代码。具体分析请点此。
这是运行在二进制httpd上的Web服务的ipAddrDispose函数中存在的一个基于堆栈的缓冲区溢出漏洞。该漏洞发生在将GET请求的参数值赋值给堆栈变量的过程中,允许用户向堆栈内存中输入大量数据,从而使攻击者获得控制权限。
首先,输入一个我觉得很容易理解的函数,ping。
通过发送字符串 aaaaaaaaa....aaa 开始检查程序是否允许溢出导致任何错误,结果,只能在 UI 上输入 50 个字符并收到消息 ping request could not find host .....请检查名称并重试。
似乎什么也没发生,我们一直在寻找处理程序并逆向。结果,我们打开了 burp 套件,得到了包含 /userRpm/PingIframeRpm.htm 的 的请求。
打开 IDA 查找此 URL 字符串,并在 0x44A530 处找到处理此 URL 的函数。
这里调用httpGetEnv函数来获取通过get REQUEST参数传递的值ping_addr, doType, isNew …
通过一个进程,调用 ipAddrDispose 函数并传递 ping _addr 参数。此时,漏洞就会出现。
初始化一个大小为52字节的堆栈变量buf_ip,并接收来自ping_addr的每个字符值,直到字符串结束。问题是ping_addr的长度在代码的验证中没有被处理,而是被限制在web UI中,使用Burp Suite可以很容易地绕过这个问题。
使用 Burp Suite 进行测试,输入长度为 200 字节左右的 ping_addr,结果。程序崩溃了。返回地址寄存器$ra被覆盖,此时可以确认是漏洞。
我编写了一个快速的python脚本来启用这个漏洞。
下一个目标是RCE是设备,因为设备没有启用任何保护机制,ASLR也被关闭,所以我们可以控制$ra寄存器跳到shellcode中,执行代码并获得控制权。
查看程序开头和程序结尾的汇编语句,堆栈变量buf_ip的位置,我们可以计算出要覆盖到$ra的偏移量:(0xD4 + 8) - (0xD4 - 0xA0) = 168字节,同时可以控制另外两个寄存器 $s0 和 $s1。
为了建立一个漏洞利用模型,我制作了一个图。
在 MIPS 架构中,我们不能直接跳转到 shellcode 中执行代码,我们必须先跳转到 sleep() 函数中清除 Icache(指令缓存)内存。由于它在同一个固件上,我将在上述漏洞利用中再次使用 ROP。
构建完整的ROP链,我们将得到如下所示的堆栈模型。
因此,我们成功地利用了带有Stack Overflow漏洞的设备,因为我们正在进行固件模拟,所以逆向shell将打印日志,不过在真实的设备上,这种情况不会出现。
我发现此漏洞存在于 TL-WR841N V12 及以下版本中,该漏洞的ID为CVE-2022-30024。用户应从 TP-Link 官网下载最新固件以更新。
参考及来源:https://www.tp-link.com/en/support/download/tl-wr841n/v12/#Firmware