TP-Link SR20命令执行漏洞复现
Description
查阅相关资料可知,TDDP协议(TP-LINK Device Debug Protocol) 是TP-LINK申请了专利的一种在UPD通信的基础上设计的协议,而Google安全专家Matthew Garrett在TP-Link SR20设备上的TDDP协议文件中发现了一处可造成 “允许来自本地网络连接的任意命令执行” 的漏洞。
复现环境:Ubuntu-22.04
固件下载:https://blog.zer0ptr.icu/attachment/SR20(US)_V1_180518.zip
TDDP协议

其中,TDDP报头中的Ver字段是版本号,分为V1和V2两个版本,V1版本是不需要进行身份认证的;Type字段是报文类型,编号及类型的对照如下:
- 4:CMD_AUTO_TEST
- 6: CMD_CONFIG_MAC
- 7: CMD_CANCEL_TEST
- 8: CMD_REBOOT_FOR_TEST
- 0XA:CMD_GET_PROD_ID
- 0XC: CMD_SYS_INIT
- 0XD: CMD_CONFIG_PIN
- 0X30: CMD_FTEST_USB
- 0X31: CMD_FTEST_CONFIG
根据公开的漏洞信息,这个漏洞存在于V1版本下的0X31: CMD_FTEST_CONFIG类型处。
逆向分析
我们先用 binwalk -Me
这里我修改了下解包出来的目录名

squashfs-root 目录就是我们需要的固件文件系统。
在该文件系统目录下查找存在漏洞的 tddp 文件并查看文件类型可以看到该文件是一个 ARM 架构的小端(Small-Endian)32 位 ELF 文件
最高有效位 MSB(Most Significant Bit) 对应大端 (Big-endian) 最低有效位 LSB(Least Significant Bit) 对应小端 (Little-endian)

然后我们进到ida,由于我们找不到主函数所以去看一下 _start,然后这个地方跳转的 sub_971C就是主函数,我将其命名为 main

首先去分析第一个函数 sub_16C90,这个函数是对内存进行初始化分配:

1 | |
然后看 sub_16D40,这个函数是对分配的内存进行回收:
1 | |
那我们现在去看看中间的 sub_936C 函数:

上面圈出的一堆函数是对内存的初始化以及对 socket 套接字的初始化,其中值得关注的是 sub_16D68 函数:
1 | |
我们关注到这条:
1 | |
这里的 a2 是后面传入的 1040,htons 函数是将整型变量从主机字节顺序转变成网络字节顺序,而 bind 函数是将一个本地地址与一个套接口进行绑定,这个函数的目的就是将 socket 套接字绑定到了 1040 端口上。
继续往下走,这里的 sub_9340 是用于获取当前时间,然后往下是一些时间相关的校验,对于我们并不重要,我们往下走看到 sub_16418:


我们找到一个关键的函数 recvfrom(),这个函数的内部构造如下:
1 | |
该函数的原型是:
1 | |
该函数用于接收远程主机经指定的socket传来的数据,并把数据传到由参数 buf 指定的内润空间,也就是说是通过socket套接字传输TDDP包到目标IP的1040端口。

从上图可以看出,v2是接收到的TDDP数据包,其中 if (v2 == 1) 就是判断版本号是否等于1,而这个漏洞就是发生在 Version 1,也就是这个if分支,我们再进入接下来的 sub_15E74 函数,发现其是对 Type 类型的判断。

我们选择追踪 case 0x31 处:

进到 sub_A580 中:

从上图可以看到,当 TDDP 协议是 Version 1 的时候,v19 会从 TDDP 包的首地址往后移12个字节,也就是从“报头”移动到“数据”的首地址(见上面的TDDP协议结构图),接着就到了一个 sscanf 函数:

这个 sscanf 函数将传进来的 TDDP 包数据区按照分离符 ; 分为 s 和 v10 两个字符串,其中过滤了 s 中的 ;,然后字符串 s 拼接到了 cd /tmp;tftp -gr 后面,而这是一个shell命令,如果把 s 拼接上去那可能会导致命令执行,我们看看 sub_91DC 函数:

可见这里就是一个可以执行shell命令的地方。
我们再来看另一个地方:

这里把一个文件的路径保存在了 name 字符串中,然后通过 lual_loadfile 函数进行加载。
利用姿势
- 字符串
s在sscanf分离的时候仅过滤了;,而|和&也可以作为连接符,对两句独立命令进行连接。 tftp -gr ...命令是利用FTP协议,从...路径下载文件,在这里是保存到/tmp目录下,我们回想一下上面那张图,于是我们可以搭建一个 TFTP Server然后在某个目录下放置一个可执行恶意命令的Lua脚本文件。
Know it then hack it
搭建 TFTP Server
- 执行
sudo apt install atftpd命令安装atftpd - 将
/etc/default/atftpd文件改成如下内容:
1 | |
- 新建
/tftpboot目录,并赋予777权限,然后在/tftpboot目录下放一个可执行反弹shell命令的Lua脚本文件payload:
1 | |
执行
sudo systemctl start atftpd命令启动TFTP服务即可执行
sudo systemctl status atftpd命令可查看atftpd服务状态
QEMU 环境配置
下载这三个文件:
1 | |
启动脚本如下:
1 | |
然后将解包出来的 squashfs-root 文件上传到QEMU里面即可。
Exploit
这里就是根据我们上面分析的内容进行构造exp,我们尝试写入一个 test.txt 到 /tmp/ 目录下,内容为 h4ck_f0r_fun:
1 | |

(另一个案例因为我太懒了没截图也就懒得写了qwq