CVE-2025-30256
A denial of service vulnerability exists in the HTTP Header Parsing functionality of Tenda AC6 V5.0 V02.03.01.110. A specially crafted series of HTTP requests can lead to a reboot. An attacker can send multiple network packets to trigger this vulnerability.
The versions below were either tested or verified to be vulnerable by Talos or confirmed to be vulnerable by the vendor.
Tenda AC6 V5.0 V02.03.01.110
AC6 V5.0 - https://www.tendacn.com/product/ac6v5.html
8.6 - CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:N/A:H
CWE-772 - Missing Release of Resource after Effective Lifetime
The Tenda AC1200 AC6 is an IPv6 smart wifi router that supports multiple configuration types for home connectivity options. Extremely popular and affordable in online sellers, the Tenda AC1200 AC6 sees large usage in the home-networking space.
When parsing HTTP packets, we hit the websParseRequest(webs_t wp)
function from the GoAhead embedded web server code base. Since the source code for the exact version of GoAhead that the Tenda AC6 AC1200 uses is unavailable, we will instead examine the disassembly of this function:
800bb2c4 void* websParseRequest(webs_t wp)
800bb304 void* cur_headername = websSetVar(wp, var: "HTTP_AUTHORIZATION", varval: &NULLSTR)
800bb30c char* servp = wp->header.servp
800bb30c
800bb31c while (servp != 0)
800bb328 if (sx.d(*servp) == 0)
800bb328 break
800bb328
800bb330 char* $v0 = strchr(servp, '\n')
800bb348 void* servp_1 = (0 u< $v0 ? 1 : 0) + $v0
800bb344 cur_headername = gstrtok(outmb: servp, inpchr: ": \t\n") // [1]
800bb344
800bb34c if (cur_headername != 0)
800bb360 char* cur_hval = &NULLSTR
800bb35c int32_t cur_hval_1 = gstrtok(outmb: nullptr, inpchr: U"\n") // [2]
800bb35c
As expected, at [1], we call gstrtok
on our HTTP packet buffer to start iterating over each HTTP header, and we find the end of the HTTP header value with a second call to gstrtok
at [2]. The header is normalized, and then we begin matching to find the corresponding variable in our web session to set as such:
800bb40c if (strcmp(cur_headername, "accept-language") != 0)
800bb430 if (stricmp(cur_headername, "authorization") != 0)
800bb478 char* var
800bb478 void* varval
800bb478
800bb478 if (strcmp(cur_headername, "content-length") != 0)
800bb4c8 if (strcmp(cur_headername, "content-type") != 0)
800bb4f8 if (strcmp(cur_headername, "host") != 0)
800bb514 cur_headername = strcmp(cur_headername, "cookie") // [3]
800bb514
800bb51c if (cur_headername != 0)
800bb520 servp = servp_1
800bb520 continue
800bb51c else
800bb534 wp->flags |= 8 // cookie
800bb530 cur_headername = strdup(cur_hval) // [4]
800bb538 wp->cookie = cur_headername // [5]
800bb4f8 else
800bb500 // host
800bb500 cur_headername = strdup(cur_hval)
800bb50c wp->host = cur_headername
800bb4c8 else
800bb4d4 varval = cur_hval // cont-type
800bb4d8 var = "CONTENT_TYPE"
800bb4dc label_800bb4dc:
800bb4dc cur_headername = websSetVar(wp, var, varval)
800bb4e8 servp = servp_1
// [...]
800bb40c else
800bb414 cur_headername = strdup(cur_hval)
800bb420 wp->accept-language = cur_headername
800bb420
800bb540 servp = servp_1
800bb540
800bb63c return cur_headername
It suffices to only show the following portion of the code since our vulnerability is already present. Assuming our given HTTP header is ‘cookie’, ‘host’, ‘authorization’, or ‘accept-language’, a call to strdup
occurs on this HTTP header value, for instance the one shown at [4] for the “Cookie: “ header. This newly allocated string is then assigned to one of the wp->*
struct members, however, there is never any checking to see if the specific wp->*
struct member already has a given allocation assigned that needs to be freed before assigning a new one. As such, if we start sending HTTP packets with duplicates of any of the previously listed HTTP headers, our duplicate HTTP header values never get freed and we end up allocating as much memory on the device as we want, completely unauthenticated. As such, given the resource constraints of the device, we can take up all available memory in less than a second and cause allocations to subsequently start failing. Sending more HTTP packets after the device has run out of resources results in a one of multiple points of failure, for instance trying to free a NULL buffer if we keep sending HTTP packets. Since this device is an RTOS device and the exception is unhandled, it quickly crashes out from trying to access unmappable memory, resulting in a device reboot and denial of service.
--------- [httpd_main] get exception !! ---------
ptr:0x805d4908 base 0x805ccd48 size:32768
limit:0x805d4d48
--------- map symbol only ---------
updated stack ptr from R29 :0x805d49e0
[<800b3290>] [<800b7c48>] [<00000008>] [<00000065>] [<00000400>] [<8022acb0>] [<00000007>] [<00000008>]
[<00000065>] [<81f21dfc>] [<00000004>] [<800b7c48>] [<00000019>] [<8022acb0>] [<00000000>] [<00000000>]
[<81f21da0>] [<800b8704>] [<00000000>] [<8022f288>] [<00000000>] [<802227e4>] [<81f9f938>] [<00000000>]
[<00000000>] [<00000000>] [<805d4a54>] [<00000001>] [<00000000>] [<00000000>] [<00000000>] [<81f9ff80>]
[<000007ff>] [<00000000>] [<00000019>] [<00000018>] [<806f92a8>] [<81f36858>] [<805ccc50>] [<807007b8>]
[<00000001>] [<80700000>] [<00000001>] [<807007c0>] [<807007b8>] [<806fd6d8>] [<805d4b40>] [<802e0000>]
[<00000008>] [<00000065>] [<00000400>] [<8021ee30>] [<00000001>] [<80700000>] [<00000001>] [<806fcb94>]
[<81f36858>] [<802223a4>] [<806fd6d8>] [<805d4b40>] [<806fd6d8>] [<00000000>] [<805d4b40>] [<802e0000>]
[<00000008>] [<00000065>] [<00000400>] [<8022acb0>] [<81f9ff80>] [<000007ff>] [<00000000>] [<800b87cc>]
[<00000000>] [<8022db30>] [<67d17a14>] [<806fcb8c>] [<00000000>] [<8021f8b4>] [<805d4b38>] [<00000003>]
[<00000019>] [<800bd93c>] [<00000000>] [<00000001>] [<00000000>] [<800b9160>] [<81fba3d0>] [<00000004>]
[<00000000>] [<800b8ba4>] [<00000000>] [<802e0000>] [<00000008>] [<00000065>] [<81fba3d0>] [<800bc240>]
[<81fba3d0>] [<800b8524>] [<00000004>] [<802e0000>] [<00000008>] [<81fba3d0>] [<00000002>] [<800bcf00>]
[<00000008>] [<805d4ba0>] [<00000005>] [<805d4bac>] [<805d4ba8>] [<805d4bb0>] [<805d4bb8>] [<00000000>]
[<805d4ba4>] [<800b75e0>] [<00000000>] [<803469bc>] [<81f9a948>] [<81f9a930>] [<802c75fc>] [<802cdeb4>]
[<802de5ec>] [<800b9fec>] [<81fba3d0>] [<00000002>] [<00000004>] [<00000010>] [<00000001>] [<00000005>]
[<802e44e8>] [<80540000>] [<80540000>] [<800bd694>] [<00000064>] [<00000e6f>] [<81f21da0>] [<81f12174>]
[<00000004>] [<81f21da0>] [<00000004>] [<800b993c>] [<00000000>] [<00000000>] [<00000000>] [<00000000>]
[<00000000>] [<00000000>] [<82c80220>] [<c700a8c0>] [<00000000>] [<00000000>] [<00000000>] [<00000000>]
[<00000000>] [<00000000>] [<00000000>] [<00000000>] [<00000020>] [<00000000>] [<00000000>] [<00000000>]
[<00000000>] [<00000000>] [<00000000>] [<00000000>] [<00000000>] [<00000000>] [<00000001>] [<80540000>]
[<0005a33b>] [<00000010>] [<802f09a4>] [<00000001>] [<805d0000>] [<0000001e>] [<00000000>] [<11110017>]
[<805d4d10>] [<800b28c0>] [<11110010>] [<802f0998>] [<0000010e>] [<800b6788>] [<00000000>] [<11110013>]
[<0100a8c0>] [<11110015>] [<805d0000>] [<11110011>] [<11110012>] [<11110013>] [<11110014>] [<11110015>]
[<11110016>] [<800bda44>] [<00000000>] [<00000000>] [<deadbeef>] [<00000001>] [<805ccc50>] [<80220090>]
[<deadbeef>] [<deadbeef>] [<deadbeef>] [<deadbeef>] [<11110010>] [<80220064>] [<deadbeef>] [<deadbeef>]
[<deadbeef>] [<deadbeef>] [<deadbeef>] [<deadbeef>] [<deadbeef>] [<deadbeef>] [<deadbeef>] [<deadbeef>]
[<deadbeef>] [<deadbeef>] [<deadbeef>] [<deadbeef>]
Exception --------------------------------------------------------------
Type: TLB miss (Load or IFetch)
Data Regs:
R0 00000000 R8 FFFFFFFE R16 81F21DFC R24 00000000
R1 80000000 R9 0000FFFF R17 FFFFFFF8 R25 8010CAF8
R2 0FFF0000 R10 00000000 R18 00000000 R26 00000000
R3 00000000 R11 000043E0 R19 802E0000 R27 802E0000
R4 00000000 R12 00000019 R20 00000008 R28 8053FFE0
R5 806F9578 R13 00000000 R21 00000065 R29 805D49E0
R6 806F9578 R14 646D4E80 R22 00000400 R30 00000002
R7 806F9578 R15 0047075C R23 00000010 R31 800B7C48
HI 00000034 LO 00000000 SR 10000403 PC 800B3290
CAUSE 00000000 PRID 00019385 BADVR FFFFFFFC
------------------------------------------------------------------------
zero at v0 v1
$00 : 00000000 80000000 0fff0000 00000000
a0 a1 a2 a3
$04 : 00000000 806f9578 806f9578 806f9578
t0 t1 t2 t3
$08 : fffffffe 0000ffff 00000000 000043e0
t4 t5 t6 t7
$12 : 00000019 00000000 646d4e80 0047075c
s0 s1 s2 s3
$16 : 81f21dfc fffffff8 00000000 802e0000
s4 s5 s6 s7
$20 : 00000008 00000065 00000400 00000010
t8 t9 k0 k1
$24 : 00000000 8010caf8
gp sp fp ra
$28 : 8053ffe0 805d49e0 00000002 800b7c48
Hi : 00000034
Lo : 00000000
epc : 800b3290
ra : 800b7c48
Status: 10000403 KERNEL EXL IE
Cause : 40000008
BadVA : fffffffc
PrId : 00019385
Stack : 00000008 00000065 00000400 8022acb0 00000007 00000008 00000065 81f21dfc
00000004 800b7c48 00000019 8022acb0 00000000 00000000 81f21da0 800b8704
00000000 8022f288 00000000 802227e4 81f9f938 00000000 00000000 00000000
805d4a54 00000001 00000000 00000000 00000000 81f9ff80 000007ff 00000000
Call stack:
SP: 0x805d49e0, RA Offset: 36, Ret Address: 0x800b3290, Func Address: 0x800b3274
SP: 0x805d4a08, RA Offset: 20, Ret Address: 0x800b7c48, Func Address: 0x800b7c24
SP: 0x805d4a20, RA Offset: 284, Ret Address: 0x800b8704, Func Address: 0x800b8660
SP: 0x805d4b40, RA Offset: 20, Ret Address: 0x800b8ba4, Func Address: 0x800b8b5c
SP: 0x805d4b58, RA Offset: 28, Ret Address: 0x800bc240, Func Address: 0x800bc148
SP: 0x805d4b78, RA Offset: 108, Ret Address: 0x800bcf00, Func Address: 0x800bcda4
SP: 0x805d4be8, RA Offset: 28, Ret Address: 0x800bd694, Func Address: 0x800bd65c
SP: 0x805d4c08, RA Offset: 148, Ret Address: 0x800b993c, Func Address: 0x800b9558
SP: 0x805d4ca0, RA Offset: 60, Ret Address: 0x800b28c0, Func Address: 0x800b262c
SP: 0x805d4ce0, RA Offset: 20, Ret Address: 0x800bda44, Func Address: 0x800bda28
SP: 0x805d4cf8, RA Offset: 20, Ret Address: 0x80220090, Func Address: 0x80220064
Code: 2491fff8 1220001d 3c020fff <8c98fffc> 3442f000 03021024 3c180812 27184000 14580017
--------- [httpd_main] get exception !! ---------
ptr:0x805d4908 base 0x805ccd48 size:32768
limit:0x805d4d48
--------- map symbol only ---------
[<00000002>] [<800b7c48>] [<00000034>] [<00000000>] [<00000008>] [<10000403>] [<800b3290>] [<00000000>]
[<40000008>] [<fffffffc>] [<00019385>] [<022a3e10>] [<81a3e0d0>] [<00000000>] [<00000000>] [<8021f8b4>]
[<81a3e0d0>] [<00000002>] [<806f92a8>] [<81f9ff78>] [<00000000>] [<802e0000>] [<00000008>] [<00000001>]
[<00000400>] [<8021ee30>] [<00000000>] [<802568dc>] [<00000008>] [<00000065>] [<00000400>] [<802227e4>]
[<807007b8>] [<80700000>] [<00000000>] [<802e0000>] [<00000008>] [<00000065>] [<81f9ff78>] [<00000000>]
[<81f9ff80>] [<81f9ff78>] [<00000000>] [<802e0000>] [<00000008>] [<00000065>] [<00000400>] [<80222834>]
[<802e0000>] [<00000008>] [<00000000>] [<00000004>] [<00000000>] [<800b32d0>] [<00000008>] [<00000065>]
[<00000400>] [<8022acb0>] [<00000007>] [<00000008>] [<00000065>] [<81f21dfc>] [<00000004>] [<800b7c48>]
[<00000019>] [<8022acb0>] [<00000000>] [<00000000>] [<81f21da0>] [<800b8704>] [<00000000>] [<8022f288>]
[<00000000>] [<802227e4>] [<81f9f938>] [<00000000>] [<00000000>] [<00000000>] [<805d4a54>] [<00000001>]
[<00000000>] [<00000000>] [<00000000>] [<81f9ff80>] [<000007ff>] [<00000000>] [<00000019>] [<00000018>]
[<806f92a8>] [<81f36858>] [<805ccc50>] [<807007b8>] [<00000001>] [<80700000>] [<00000001>] [<807007c0>]
[<807007b8>] [<806fd6d8>] [<805d4b40>] [<802e0000>] [<00000008>] [<00000065>] [<00000400>] [<8021ee30>]
[<00000001>] [<80700000>] [<00000001>] [<806fcb94>] [<81f36858>] [<802223a4>] [<806fd6d8>] [<805d4b40>]
[<806fd6d8>] [<00000000>] [<805d4b40>] [<802e0000>] [<00000008>] [<00000065>] [<00000400>] [<8022acb0>]
[<81f9ff80>] [<000007ff>] [<00000000>] [<800b87cc>] [<00000000>] [<8022db30>] [<67d17a14>] [<806fcb8c>]
[<00000000>] [<8021f8b4>] [<805d4b38>] [<00000003>] [<00000019>] [<800bd93c>] [<00000000>] [<00000001>]
[<00000000>] [<800b9160>] [<81fba3d0>] [<00000004>] [<00000000>] [<800b8ba4>] [<00000000>] [<802e0000>]
[<00000008>] [<00000065>] [<81fba3d0>] [<800bc240>] [<81fba3d0>] [<800b8524>] [<00000004>] [<802e0000>]
[<00000008>] [<81fba3d0>] [<00000002>] [<800bcf00>] [<00000008>] [<805d4ba0>] [<00000005>] [<805d4bac>]
[<805d4ba8>] [<805d4bb0>] [<805d4bb8>] [<00000000>] [<805d4ba4>] [<800b75e0>] [<00000000>] [<803469bc>]
[<81f9a948>] [<81f9a930>] [<802c75fc>] [<802cdeb4>] [<802de5ec>] [<800b9fec>] [<81fba3d0>] [<00000002>]
[<00000004>] [<00000010>] [<00000001>] [<00000005>] [<802e44e8>] [<80540000>] [<80540000>] [<800bd694>]
[<00000064>] [<00000e6f>] [<81f21da0>] [<81f12174>] [<00000004>] [<81f21da0>] [<00000004>] [<800b993c>]
[<00000000>] [<00000000>] [<00000000>] [<00000000>] [<00000000>] [<00000000>] [<82c80220>] [<c700a8c0>]
[<00000000>] [<00000000>] [<00000000>] [<00000000>] [<00000000>] [<00000000>] [<00000000>] [<00000000>]
[<00000020>] [<00000000>] [<00000000>] [<00000000>] [<00000000>] [<00000000>] [<00000000>] [<00000000>]
[<00000000>] [<00000000>] [<00000001>] [<80540000>] [<0005a33b>] [<00000010>] [<802f09a4>] [<00000001>]
[<805d0000>] [<0000001e>] [<00000000>] [<11110017>] [<805d4d10>] [<800b28c0>] [<11110010>] [<802f0998>]
[<0000010e>] [<800b6788>] [<00000000>] [<11110013>] [<0100a8c0>] [<11110015>] [<805d0000>] [<11110011>]
[<11110012>] [<11110013>] [<11110014>] [<11110015>] [<11110016>] [<800bda44>] [<00000000>] [<00000000>]
[<deadbeef>] [<00000001>] [<805ccc50>] [<80220090>] [<deadbeef>] [<deadbeef>] [<deadbeef>] [<deadbeef>]
[<11110010>] [<80220064>] [<deadbeef>] [<deadbeef>] [<deadbeef>] [<deadbeef>] [<deadbeef>] [<deadbeef>]
[<deadbeef>] [<deadbeef>] [<deadbeef>] [<deadbeef>] [<deadbeef>] [<deadbeef>] [<deadbeef>] [<deadbeef>]
2025-04-29 - Initial Vendor Contact
2025-04-30 - Vendor Disclosure
2025-05-05 - Vendor Feedback Request
2025-05-08 - Vendor Feedback Request
2025-05-12 - Vendor Feedback Request
2025-06-11 - Vendor Feedback Request
2025-07-07 - Feedback Request / Announcement Of Upcoming Release Date
2025-07-23 - Feedback Request / Announcement Of Upcoming Release Date
2025-08-19 - Announcement Of Upcoming Release Date
2025-08-20 - Public Release
Discovered by Lilith >_> of Cisco Talos.