CVE-2018-18708
Last Update:
Word Count:
Read Time:
CVE-2018-18708 复现
该题在nu1lctf2020 的pwn中已经出现,为babyrouter,不妨来复现复现该cve。
工具+环境
cutter
ida
gdb + pwndbg
qemu-arm
python
远程实验环境
docker + qemu-arm
漏洞分析
简要概述
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版本。
漏洞点
sub_BE73C
1 |
|
从以上可以很容易看出漏洞点在strcpy函数, 那str是通过参数一传入的,进行逆向跟踪。
sub_BDA1C
1 |
|
字符串也是该函是第二个参数进行传入的,继续逆跟踪。
sub_BD758
1 |
|
字符串是该函数的二个参数进行传入的,继续逆跟踪。
formSetMacFilterCfg
1 |
|
进入目标分支后,再从deviceList获取传入v39变量,根据上一节的分析该值将被用作strcpy的参数。
然而这里有个判断,要想执行到前面我们所跟踪到的内容,必须先绕过一个if判断,也就是我们必须要得使v41这个变量值为0,然而该值是调用sub_BD34C函数的一个返回值,咱们先跟进sub_BD34C函数看看。
sub_BD34C
1 |
|
以上逻辑是,根据传入的参数来进行字符串判断,若传入参数字符串为black
或者white
就会使返回值为0,那么就可以执行到漏洞点。
然而sub_2B794函数是解析字符串返回对应的字符串,类似与json解析,根据key值找value。
sub_2B794
1 |
|
那么什么函数会调用formSetMacFilterCfg函数呢?继续跟踪调用函数。
sub_41F18
1 |
|
好像没发现啥,继续往上跟踪
sub_2E6F4
1 |
|
通过gdb下断点确定访问“/goform/setMacFilterCfg”时会进入formSetMacfiltercfg函数。
再继续网上跟踪就是必须运行的代码块了,如下。
sub_2E128
1 |
|
触发链
sub_2E128 -> sub_2E6F4 ->sub_41F18 -> formSetMacFilterCfg -> sub_BD758 -> sub_BDA1C -> sub_BE73C
那么现在我们就可以访问“/goform/setMacFilterCfg”时会进入formSetMacfiltercfg函数,传入类似与json的数据进行解析,则会将value值传入漏洞触发点。
payload
post 数据, rur = ‘/goform/setMacFilterCfg’
1 |
|
漏洞调试
准备
编写qemu-arm启动脚本
1 |
|
启动log
1 |
|
启动后gdb远程调试
1 |
|
设置 架构为arm
远程调试端口为1234
1 |
|
在漏洞函数0xC2FD4处下短点
1 |
|
exp
1 |
|
log输出如下
1 |
|
发现不能运行到我们的位置,进行再调试调试看看是那块没有绕过。重新下断电在formSetMacFilterCfg函数,偏移为: 000BCB9C
发现能够调用到formSetMacFilterCfg函数,但没法继续调用下一个函数,再来分析分析还有什么条件没有绕过。
1 |
|
执行到GetValue的时候, 会出现http响应错误,然而该函数是调用lib的,只能先分析一下lib。
通过分析lib中的GetValue函数,会议cookie值检测,需要包含password等字段,内容随便伪造。
poc如下
触发poc
1 |
|
漏洞触发如下
1 |
|
这时发现,已经修改了PC寄存器,实现了劫持。
漏洞利用
接下来就计算便宜找system函数了。
1 |
|
1 |
|
堆栈数据如上,由于是如下进行弹堆栈的,需要再填充(0x238 - 0x1d4)个字节才可以修爱pc寄存器,实现劫持。
1 |
|
重新修改poc
1 |
|
运行如下,那么就可以知道在哪可以实现修改pc寄存器了。
1 |
|
由于程序没有开启alsr与pie那么glibc中的基址是固定的。
直接算获取system地址。vmmap获取glibc基址为0xf659b000
在libc中找到system函数偏移
1 |
|
这里记得检查下CPSR寄存器的T位,因为栈上内容弹出到PC寄存器时,其最低有效位(LSB)将被写入CPSR寄存器的T位,而PC本身的LSB被设置为0。如果T位值为1,需要在地址上加一还原。
1 |
|
寻找gadgets
gadget1
用于修改r3寄存器
1 |
|
gadget2
1 |
|
payload结构为[offset, gadget1, system_addr, gadget2, cmd]
先将system函数地址储存在r3寄存器中,执行到gadget2将sp的值赋给r0,也就是将sp作为system的参数,而这时sp指向的是cmd。
poc
1 |
|
修改url 为docker所转发的端口,现在试试在docker上是否已经创建test文件
1 |
|
可以看到已经创建了test文件。
那么如何实现交互呢?就采用bash下来反弹sehll 吧。
先在自己的服务器上使用nc来监听。
1 |
|
在poc中的命令填写为
1 |
|
192.168.43.13是我物理机的ip,4444是我nc监听的端口。
现在poc为
1 |
|
反弹shell大全
在服务器上开启监听:
1 |
|
目标机器开启反弹
bash版本:
1 |
|
perl版本:
1 |
|
php版本:
1 |
|
ruby版本:
1 |
|
python版本:
1 |
|
nc版本:
1 |
|
java版本:
1 |
|
lua版本:
1 |
|
NC版本不使用-e参数:
1 |
|
参考: