1. 前言
CVE-2018-5767是Tenda-AC15路由器所产生的漏洞,由于未对用户的输入进行合理的限制,直接使用了sscanf函数拷贝到栈上,从而导致了栈溢出的情况。
2. 实验环境
1 | Ubuntu 16.04 |
固件下载地址
1 | https://drivers.softpedia.com/dyn-postdownload.php/d27e8410d32cd9de63a3506c47ded1bc/61ff85c5/75eb7/4/1 |
3. 固件模拟
使用binwalk分离固件系统,在分离过程中可以看出是小端序
1 | binwalk -Me US_AC15V1.0BR_V15.03.1.16_multi_TD01.bin |
通过对squashfs-root
文件系统中的/bin/busybox
查看可得,程序为ARM架构
其实在文件系统中选哪个可执行文件都无所谓,这里的buxybox选取也只是方便。busybox是一个集成了一百多个常用Linux命令和工具的软件,在嵌入式Linux应用中,busybox应用非常广泛,同时大多数Linux发行版的安装程序中都含有busybox。
这里采用qemu配合chroot命令来启动./bin/httpd文件
1 | sudo apt install qemu-user-static libc6-arm* libc6-dev-arm* |
chroot,即 change root directory (更改 root 目录)。在 linux 系统中,系统默认的目录结构都是以 /,即以根 (root) 开始的。而在使用 chroot 之后,系统的目录结构将以指定的位置作为 / 位置。
运行后程序启动失败,输出下列错误
1 | connect: No such file or directory |
不太清楚是不是环境有问题,第一次调试的时候程序直接断在了Welcome to …那里,后面反而没有这个问题了,不过这里也写下解决方法
IDA搜索WeLoveLinux字符串,查找索引
共计三处索引和WeLoveLinux相关,先看第一处
R3小于等于0陷入死循环,patch掉给R3赋值那行即可
1 | MOV R3, R0 |
保存patch后的文件
1 | Edit --> Patch program --> Apply patches to input file... |
覆盖原httpd文件,赋予权限后,再次运行
再次报错,R3等于0时走左侧,程序结束,同样的方法patch掉
覆盖掉再次运行,成功模拟到环境
这里的IP如果没有模拟br0的话,会是一个随机IP,由于我提前配好了环境,所以直接成功了。这里我们来看下br0网卡的配置
1 | sudo apt install uml-utilities bridge-utils |
1 | # /etc/network/interfaces |
1 | # /etc/qemu-ifup |
1 | # /etc/qemu-ifdown |
配置成功后,ens33地址应该已经不显了,br0成功配置IP
当然,如果这些配置不成功的话,可以去网上找找资料。环境配的时间太久了,已经记不清当初怎么配的了。。。
4. 漏洞利用
根据CVE公布的poc可知,漏洞位于R7WebsSecurityHandler
函数中,未对用户的请求进行合理的限制直接只用sscanf函数将用户的输入复制到栈上。
想要到达溢出点,我们只需满足上面的if条件判断即可
从if中可以看出,我们只需要构造一个不在上述路径之内的一个虚假路径即可,比如/goform/helloworld
1 | import requests |
修改程序启动命令
1 | sudo chroot ./ ./qemu-arm-static -g 1234 ./bin/httpd |
使用gdb-multiarch调试程序,gdb-multiarch是一种支持调试多种架构程序的gdb
1 | gdb-multiarch ./bin/httpd |
断点位置在R7WebsSecurityHandler
函数的正常退出点
运行脚本,程序没有正常断在函数结束处
使用bt查看调用路径,0x2c5cc
在溢出后被执行
此时说明0x2c5cc
处的函数影响了我们程序的正常执行,回到漏洞函数分析可知。如果我们的请求中包含如下几种字样之一就可以直接令漏洞函数返回,比如”.png”
修改python脚本,重新执行
1 | import requests |
成功执行到函数结束
ni,单步执行
执行后发现填充的字符串最低位和往常不太一样,被置0了。按照师傅的解释,是因为arm模式与thumb模式的切换问题。在函数退出时执行了pop pc的操作,而最低有效位(LSB)将会被写入到CPSR寄存器的T位中,而pc本身的最低位则会被置零。
下面的流程涉及到了rop链的利用等等,这点我也不熟悉,所以下面的流程我会直接按照师傅的解释来。
pwntools的checksec模块,查看下httpd的保护机制,可以看到httpd开启了NX保护机制
因为httpd开启了NX保护机制的原因,所以我们需要构造rop链来完成利用。使用ropper工具从/lib/libc.so.0中查找所要用到的gadget,同时因为QEMU未开启基址随机化,因此我们可以在gdb中使用vmmap命令找到libc的基址从而计算出我们需要的gadget。
这两条指令的选取需要对应,即mov r3、pop r3,虽然不太清楚为啥。。。猜测是blx跳转指令集的原因,跳转后应该还是要pop回来的。
1 | 0x00040cb8 mov r0, sp; blx r3; |
编写exp时我们还需要libc的基址,这里使用gdb中的vmmap。使用vmmap的前提是我们的程序需要处于运行状态,即如下状态。
下完断点,输入continue运行后,程序会保持运行态。这时运行脚本,程序就会成功断在断点处,我们可以开心的输入vmmap查看基址了。
另外,这里为了防止跑飞,断点我选在了R7WebsSecurityHandler
函数退出的前几行b *0x002de94
运行vmmap后,我们可以看到我们的libc基址如下(每个人的基址可能都不相同,因此需要自己查一下)
另外,关于两段gadget也可以在IDA中看到
5. EXP
1 | import requests |
程序运行结束,成功输出hello
6. 关于偏移
关于最终脚本中的偏移,大家可能会有些疑问,在这里简单解释下。
为了方便计算偏移,这里我采用了pwntools中的cyclic小工具,首先cyclic 1024
,生成1024个随机数
接着,我们在第二个脚本基础上修改下
1 | import requests |
其实就是将脚本填充的0x400个a给改为了这串字符而已。
然后,用上面同样的方法去运行我们的程序
在这里大家可以看到,我们溢出的字符最后的是paae
,这个字符所代表的位置就是我们的偏移,也就是460
到了这里脚本中的偏移地址就很好理解了
444*a
4位的”.png”
4位的pop_r3
4位的puts
4位的mov_r0
之所以是4位也很好理解,32位程序嘛,栈空间中自然是4位4位的相加啦。
计算一下就会发现,我们最终的结果就是444+4+4+4+4=460
是不是和我们上面的偏移相等呢。
7. 关于getshell
单纯执行puts输出只是为了验证漏洞存在与否,真正利用的话,我们还是需要利用system来执行命令。
1 | import requests |
这里修改脚本,通过libc基址查找system函数并调用,相同的方法运行
在这里可以看到我们的system函数确实被调用了,并且写入了/bin/sh
,但是真正执行下去发现没个锤子用。。。。
当场宣告GG,但是我贼心不死,查找多方攻略后,看到有师傅这样写
很好,我也来试下
继续修改脚本
1 | import requests |
很好,再次宣告失败。。。。
呼~~~冷静,不生气,让我再去找些参考资料回来
多方查找发现并没有解决办法,有个师傅猜测是qemu模拟环境的问题,导致找不到/bin/sh
。。。
贫穷使我命途多舛,穷人家的孩子买不起设备,告辞。或许以后摸到了设备可能会再来更新这篇帖子,所以~~~
未完待续。。。
8. 补充
时隔数月,我又回来了。偶然间回想起这里还有个东西没收尾,来解决下这个问题。
首先,我们先对上次的原因做个说明,说来很坑爹,是我libc的基址搞错了。。。。记不得当时怎么找的地址了,后来有空时重新复现这个漏洞的时候发现,我两次libc基址不一样,当场就裂开了。这次换了基址后倒是可以直接执行命令了。
脚本先贴在这里了
1 | import requests |
执行结果如上图所示,不过大家应该也发现了,没几个能用的命令。
关于这点其实是因为模拟的固件环境的问题,我们可以看下解包出来的固件的bin目录
大家仔细看下就会发现,那些命令之所以执行不了,是因为压根就没有这几个命令。
在sh
里执行busybox
也可以发现,好多命令根本就没有
至于如何解决这个问题,我也没什么好的办法,除非重新打包一个指令集来用。但是实际环境上压根不可能让你去把人家的指令集给替换掉。
或者也可以考虑在system态
模拟环境,然后将系统的指令加给mount挂载
到这个固件的环境中来用。但是因为这个固件实际上是patch后在运行的,必须使用虚拟网桥来获得真正可以访问的IP,就导致我的环境模拟总是会有问题,没办法获取到一个可用的IP,最后不得已放弃挣扎。
至于实体设备的话,还是那句话,没有。如果有师傅有实体设备上手测试了的话,还请带带我,看看命令是否有出入。那么这篇文章就到这了,告辞。
9. 参考链接
1 | https://mp.weixin.qq.com/s/mRq3n3jDM0zvR15JAsLYSA |
发布时间: 2022-08-04
最后更新: 2023-06-22
本文标题: Tenda-AC15栈溢出漏洞复现(CVE-2018-5767)
本文链接: https://foxcookie.github.io/2022/08/04/Tenda-AC15栈溢出漏洞复现(CVE-2018-5767)/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!