TL-Link WR841n 路由器多个缓冲区溢出漏洞复现
0x01 前言
最近看到了关于TL-Link 一个古老的路由器 WR841n 的漏洞披露文章,都是关于缓冲区溢出的漏洞,虽然设备老,但是漏洞的发现过程都挺有学习价值的。在平时对设备的漏洞挖掘过程中,可能会比较倾向于对设备的工作流程进行分析,然后逆向一些关键的函数和代码,在这些代码和函数中,找到可能存在的漏洞函数,拿缓冲区溢出漏洞来说,会分析strcpy、sprintf 、strcat、gets 诸如此类的函数,查看局部变量在拷贝字符串的时候是否对字符串的长度进行限制。但是比较少的对通过指针或者地址的拷贝字符串的方式进行分析,通过指针拷贝字符串也经常的会出现缓冲区溢出漏洞。接下来我将WR841n 设备中存在的三个缓冲区溢出的漏洞进行分析,记录,整理。所以这是一篇学习记录的文章。漏洞的披露链接在参考章节。
0x02 http流程分析
固件版本: 3.16.9 Build 150310(https://www.tp-link.com/vn/support/download/tl-wr841n/v10/#Firmware)
首先通过main 函数调用httpd() 和 httpBasicRpmInit() 函数对设备的http服务进行初始化,这个函数会将设备的一些功能进行初始化,并且路由器的相关http 功能处理的函数在这个函数中进行配置,初始化。

在httpd() 函数初始化的时候,会创建httpServerCreate()函数,来用以创建http Server,

在经过 httpServerCreate() -->sub_4F5CD0 --> httpDispatcher() 之后。会经过httpDispatcher()函数,这个函数会处理为各个不同的url 调用httpGenListFuncGet()函数进行函数注册绑定,以保证传入的request 请求数据包中的url 有对应的注册函数进行处理传入的对应数据包。

最终httpRpmConfAdd 函数会获取 request_url 对应的函数指针,然后调用函数。

具体的使用方式如httpPingIframeInit()函数。

0x03 第一个漏洞分析CVE-2020-8423
该函数在遇到字符\、/、<、>"时添加字符\,或者如果下一个字符不是\n和\r,则添加<br>,当缓冲区满时进程将停止。


现在我们要考虑是的stringModify() 那里会被调用并可以传入字符串,查看交叉引用可以看到writepageParamSet()函数在调用。

然后继续查看writepageParamSet() 函数的交叉引用,可以看到在sub_45FA94() line 308 中传入v53 变量中的字符串。

在这个函数的line 240 会获取ssid 的值。然后将值复制给v53。

0x04 第二个漏洞分析 CVE-2022-30024
这个产生的原因 isAddrDispose()在处理ping_addr 的时候对ping value 长度的限制设置并没有起到效果,这种问题在缓冲区溢出中是很常见的,我们可以看到在 line28 行会对 ping value 的调用strlen 进行计算长度。这个长度的大小在于我们输入value 的大小而确定的,比如我输入一千多个字符,那么这个len_ping_addr 长度就是一千。
这就造成了在line 35 中并没有起到对输入字符长度起到任何的作用。在line 32~line 40 中是将ping value 的字符逐个传递给v23局部变量,而v23 定义的数据大小仅仅为52个字节 。因此会造成又一个buffer overflow

这个函数会在sub_44A530() 中进行处理,

当请求的url中是“ /userRpm/PingIframeRpm.htm ” 时,httpGetEnv() 会获取ping_addr 的value 。

然后回调用 isAddrDispose() 函数来处理 ping_addr 的value,也就是我们前面分析过程了。

0x05 第三个漏洞分析 CVE-2022-24355
前面我们知道了httpRpmConfAdd 函数会根据请求数据包的url 中的路径来确定调用相应的注册函数,在httpd初始化的时候,会把httpRpmFS() 函数和 url 的字符串"/loginFs/","/fs/" 进行绑定并注册函数。接下来分析httpRmpFs函数是如何处理请求URL 中带有"/loginFs/" 的数据包。

首先会函数的形参a1 是获取到的请求数据包,然后回获取到数据包的header 信息以及数据包的中的url,然后和/tmp/或者/web/文件路径进行拼接,判断是否是这两个文件夹中的文件,在判断的过程中,还做了过滤“..” ,以免请求的文件url 存在路径穿越的漏洞。

接下来程序会走到sub_4EE210函数中。

函数 sub_4EE210() 通过创建指向文件路径末尾的指针来查找文件扩展名之后,该点将向后移动,直到遇到“.”字符。最后,sub_4EE210() 会一个接一个地复制‘.’之后的所有字符,直到遇到空字节,复制的字符将更改为大写字母并保存到堆栈中。在我们的例子中,passwd 没有文件扩展名,指针向后移动,传递文件路径,到达保存的请求头区域,只有在遇到 Referer 部分的 ip 地址中的最后一个“.”时才停止,结果,将其复制到堆栈并覆盖保存的寄存器值之后的所有内容。 sub_4EE210() 完成后,这些值被弹回寄存器并导致程序崩溃。
我们来到函数sub_4EE2210() 中,这个本来是为了提取文件后缀的。但是由于首先会判断v2 的值是为空。我们知道v2 的值是 /tmp/loginfs/passwd ,接下来在line 21 获取文件路径的指针,然后一直往指针在往低地址移动,匹配是否有 “.” 。找到了之后就会把 "." 字符的下一个字符地址赋给v4。其实由于file_path 中是passwd ,因此没有 " . " 字符,因此会继续移动指针,会导致指针移动到 header 中 referer 中的 url中的 "."。因此会获取referer 中“.” 的下一个指针地址给v4。并且在line28 的循环中将后面的每个字符进行转成大写字母,然后写入到file_extension 从而造成了 buffer overflow。

0x06 疑似漏洞
在分析前面的漏洞的时候,看到获取ssid 的值,这一段代码中,strncpy 函数会造成缓冲区溢出的漏洞,因为在v22 将ssid 的值复制给v53 的过程中,复制的字符串的长度是由v21 进行设置的,而v21 字符的数量恰好是我们可以输入的。因此复制给v53的字符串我们可以自己控制,当输入的字符串长度超过了局部变量v53 分配的内存大小的收,就会造成缓冲区溢出的漏洞,和前面CVE-2022-30024 中ping_addr 是一样的。由于手头上没有这一款设备,因此如果有设备的师傅,希望能帮忙验证一下。

0x07 总结
这三个漏洞的成因都是通过在指针拷贝和处理字符串的时候,并没有考虑内存的问题,比如CVE-2020-8423 漏洞在转义字符的之后,并没有对转义后的字符串进行长度的限制。在CVE-2022-3024漏洞中,ping_addr的长度限制没有固定,反而是由传入的参数进行计算。
0x08 参考
https://blog.viettelcybersecurity.com/1day-to-0day-on-tl-link-tl-wr841n/
https://blog.viettelcybersecurity.com/tp-link-tl-wr940n-httpd-httprpmfs-stack-based-buffer-overflow-remote-code-execution-vulnerability/
C program 通过指针复制字符串
https://cloud.tencent.com/developer/article/1687616
end
招新小广告
ChaMd5 Venom 招收大佬入圈
新成立组IOT+工控+样本分析 长期招新
欢迎联系admin@chamd5.org


关注公众号:拾黑(shiheibook)了解更多
[广告]赞助链接:
四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/
关注网络尖刀微信公众号随时掌握互联网精彩
- 1 中法元首相会都江堰 7903929
- 2 日方军机滋扰擅闯或被视为训练靶标 7808660
- 3 马斯克公开呼吁:废除欧盟 7713373
- 4 国际机构看中国经济 关键词亮了 7615881
- 5 《老人与海》作词者称仅分成1000元 7520967
- 6 罪犯被判死缓破口大骂被害人一家 7425104
- 7 男子海洋馆内抽烟被白鲸喷水浇灭 7333887
- 8 中国VS日本!陪看混团世界杯决赛 7237746
- 9 五粮液降价到800多元?公司回应 7138598
- 10 千吨级“巨无霸”就位 7040804

Chamd5安全团队
