CVE-2025-27129
An authentication bypass vulnerability exists in the HTTP authentication functionality of Tenda AC6 V5.0 V02.03.01.110. A specially crafted HTTP request can lead to arbitrary code execution. An attacker can send 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
9.8 - CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
CWE-288 - Authentication Bypass Using an Alternate Path or Channel
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.
As common to most home routers, the main management interface for the Tenda AC6 AC1200 is via the web portal on TCP port 80. In the setup httpd_mainloop
function, a series of callbacks is registered to a set of URLs, and these callbacks are accessed in series if they match on the URL of a given HTTP request:
int32_t httpd_mainloop()
// [...]
800b2724 setup_web_server(port: 80, retries: 5)
800b2744 websUrlHandlerDefine(urlPrefix: &NULLSTR, webDir: nullptr, arg: 0, handler: http_auth_control_function, flags: 1) // [1]
800b2764 websUrlHandlerDefine(urlPrefix: "/cgi-bin", webDir: nullptr, arg: 0, handler: cgi_bin_http_handler, flags: 0) // [2]
800b2780 int32_t $s1 = 0
800b277c do_log3(fmt: "-----------%s------------%d-----…", "initWebs", 0x10e)
800b279c websUrlHandlerDefine(urlPrefix: "/goform", webDir: nullptr, arg: 0, handler: websFormHandler, flags: 0) // [3]
800b27bc websUrlHandlerDefine(urlPrefix: &NULLSTR, webDir: nullptr, arg: 0, handler: websHandler, flags: 2)
800b27c4 setup_goform_callbacks() // [4]
800b27cc setup_ate_cb()
800b27ec websUrlHandlerDefine(urlPrefix: &slash, webDir: nullptr, arg: 0, handler: minimal_resp_cb, flags: 0)
To start, the authentication function is registered at [1], which verifies that either a correct password
POST parameter is given, or that the ecos_pw
cookie matches to a logged in admin. Since this registration occurs with a NULL
urlPrefix, it is hit on every HTTP request. Next up at [2], we can see a callback registered for the /cgi-bin
directory which will only hit if our HTTP request’s URL starts with /cgi-bin
. For the current vulnerability, we only particularly care about the authentication callback at [1], the /goform
callback at [3], and then the particular functions that handle each particular goform which are registered within [4]. Let us first look briefly at the http_auth_control_function
:
800c1814 int32_t http_auth_control_function(webs_t wp, char* uri)
// [...]
800c1968 if (strnstr(s1: uri, needle: "/public", len: 7) != 0 &&
wp->host != 0 && // [5]
strnstr(s1: uri, needle: "/favicon.ico", len: 0xc) != 0 &&
strnstr(s1: uri, needle: "/goform/getproductInfo", len: 0x16) != 0) {
}
800c25ac return 0
Our requested URL is pointed to by the uri
parameter, and within the line at [5], we clearly see a curious conditional. Assuming that the passed in webs_t wp
structure contains a NULL host, we end up completely bypassing the authentication process.
It’s unknown why this conditional exists, but we need to understand the webs_t
structure and how its fields are populated in order to actually utilize this check. Without dumping the lengthy webs_t
struct itself, it suffices to say that every HTTP request is allocated a struct to keep track of all of the fields - the URL, the POST params, the HTTP headers, etc. By default, some of these fields are set by the router itself, such as the IP address of the request, and assuming that we do not include a “Host:” HTTP header field in our request, wp->host
is normally populated with the IP address that the HTTP request originates from. However, due to how the parsing of the HTTP headers works, if we manually include an empty HTTP Host header like so: “Host: \r\n” , our resultant webs_t
structure will have its wp->host
field overwritten with a NULL entry. Thus, we can hit the conditional at [5] and bypass authentication for all URLs and have full unauthenticated admin access, allowing us to do anything a normal admin could, including flashing unsigned firmware, resulting in arbitrary code execution.
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.