目录导航
TP-Link TL-WR841N 设备上的漏洞
漏洞编号 | 描述 |
---|---|
CVE-2020-8423 | 数据解析 |
CVE-2022-24355 | 文件扩展名处理 |
CVE-2022-30024 | 分配数据 |

CVE-2020-8423
描述
TP-LINK 型号为 TL-WR841N V10 的路由器设备上的漏洞被分配 ID CVE-2020-8423。该漏洞允许经过身份验证的攻击者通过向 wifi 网络配置发送 GET 请求来远程执行设备上的任意代码。
修复
修复版本:3.16.9 Build 150310。
漏洞分析
在入坑之前,我将分析Dispatcher()
以了解程序如何分配功能以正确处理其功能。
提交请求时,httpGenListDataGet()
将调用该函数以返回一个LIST_ENTRY
指针,该指针指向一个列表,该列表依次包含处理每个先前分配的 URL 的函数的函数指针。接下来,程序将调用该函数httpGenListFuncGet()
返回列表中的函数指针,并查找分配给处理函数的URL是否在提交的REQUEST中找到。直到有一个函数将被调用,否则检查将继续列表中的下一个函数指针。


该程序将使用该函数为每个 URL 字符串分配一个处理httpRpmConfigAdd()
函数。

扯了一点,大致了解一下,现在我将重点分析这个漏洞。在名为 stringModify(char * dst, int size, char * src)
的函数中处理转义字符时会发生此错误。当遇到字符\,/,<,> "
时,函数将添加字符\
,如果下一个字符不是\n
和\r
,将添加<br>
,当缓冲区满时,进程将停止。

问题是添加<br>
到dst buffet
,数据被添加4 bytes
,但程序只处理1 byte
。

所以,只要找一个地方调用这个函数,使用src buffer
作为用户输入,这个漏洞是完全可能的。
在反向跟踪中,我得到一个writePageParamSet()function
具有 gen page 函数将值返回给用户,其中dst[512]
创建一个缓冲区并传递给以stringModify()
接收句柄转义字符中的值。

此外,我们得到一个回调函数来处理包含/userRpm/popupSiteSurveyRpm.htm
在 address的 URL 字符串0x45FA94
。

该函数将获取 GET 请求的参数并调用包含漏洞的函数

我们可以根据ssid
输入的可选参数来控制这个漏洞。


漏洞验证
使用Payload = “/%0a” * 0x55 + “A” * 100
. 设置断点并观察。
至此漏洞得到验证,$ra寄存器值被改变,3个寄存器$s0, $s1, $s2
被覆盖。

利用
检查并看到没有启用保护机制,因此我们可以将shellcode传递到堆栈以执行任意代码。

MIPS架构有一个问题,我们需要Icache
在执行shellcode之前清除缓存,解决这个问题我们会控制程序跳转到Sleep()
函数中。查看程序的库,我发现了与旧漏洞利用库匹配的 Ropchain ,这需要一些调试和调整。适合我的情况。


完善shellcode
我有一个shellcode引用在这里,但它不工作。通过调试,我意识到当shellcode被传递给stringModify()函数时,如果它包含\x3c, \x3e, \x2f, \x22, \x5c的字节,程序将添加1字节的\x5c在\x5c\x3c或\x5c\x3e前,并破坏shellcode。检查这个shellcode包含2个坏字节\x3c和\x2f。我将修复一些命令,通过替换其他命令来删除这些坏字节。
修复字节 0x3c
这个字节在lui
指令中,作者的逻辑会在栈上保存4个字节。

我将lui
指令更改为li
在堆栈上保存 2 个字节而不是 4 个字节的指令。

修复字节 0x2f
在这个命令字符串中,shellcode包含2个坏字节,0x3c和0x2f,当作者想把字符串//bin/sh放到堆栈上时。

我将使用li指令删除0x3c,使用xori指令使用中间值修复0x2f字节。

这样,当我们修改 shellcode 时,我们就可以控制路由器。

我的下一个任务是评估这个设备的整个固件,在这里我发现了更多的 1day 和 0day 存在。
CVE-2022-24355
漏洞信息
我发现的第一个漏洞 (1day) 是一个严重漏洞CVE-2022-24355,它允许网络攻击者在没有基于缓冲区溢出的身份验证的情况下执行任意代码。我的一个队友在这里分析了这个漏洞,所以我不再赘述。
CVE-2022-30024
描述
这是一个基于堆栈的缓冲区溢出漏洞,存在于ipAddrDispose
二进制 httpd 上运行的 Web 服务的功能中。该漏洞发生在将GET请求的参数值赋值给堆栈变量的过程中,允许用户将大量数据输入堆栈内存,攻击者可以控制。
发现漏洞
首先,输入我觉得对我来说容易理解的函数,即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
绕过.

用 Burp Suite测试,在ping_addra$ra输入一个大约 200 字节的长度以供娱乐,结果。程序崩溃了。返回地址寄存器被覆盖,因此漏洞被确认。

我写了一个快速的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
时间线
- 2022 年 4 月 14 日:我向他们发送了一份包含漏洞的报告
- 27/04/2022: TP-Link 安全团队给我发了一个修复补丁来检查.
- 04/08/2022: TP-Link 发布新补丁
转载请注明出处及链接