Talos Vulnerability Report

TALOS-2026-2396

Totolink X2000R boa formIpv6Setup dhcp_dns stack-based buffer overflow vulnerabilities

October 20, 2026

CVE Number

CVE-2026-42025,CVE-2026-42026

Summary

Multiple exploitable stack-based buffer overflow vulnerabilities exist in the boa formIpv6Setup dhcp_dns functionality of X2000R (version(s): TOTOLINK-X2000R-Gh-V1.0.0-B20250421.1327). A specially crafted HTTP request can lead to arbitrary code execution. An attacker can make an authenticated HTTP request to trigger these vulnerabilities.

Confirmed Vulnerable Versions

The versions below were either tested or verified to be vulnerable by Talos or confirmed to be vulnerable by the vendor.

X2000R (version(s): TOTOLINK-X2000R-Gh-V1.0.0-B20250421.1327)

Product URLs

X2000R - https://www.totolink.net/home/menu/newstpl/menu_newstpl/products/id/242.html

CVSSv3 Score

9.1 - CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H

CWE

CWE-121 - Stack-based Buffer Overflow

Details

The Totolink X2000R is a popular budget gigabit home router primarly found in eastern markets. Supporting IPV6, WPA3, mesh capabilities among other features, the Totolink X2000R is a solid choice for the price point.

The Totolink X2000R mainly relies on the standalone boa binary for all web administration and subsequent configuration. While normally a security risk in itself due to the age, it appears that the version running on the X2000R has been patched. Regardless, for the current set of vulnerabilities we only pay attention to the Totolink-specific issues, so we start from the point where authentication has already occurred via the /boafrm/formLogin webpage, and then we can successfully interact with another /boafrm/form* page, each of which have a corresponding callback. For the current vulnerability we examine the /boafrm/formIpv6Setup page, which leads us into the formIpv6Setup() function:

We can skip looking at most of the code, it’s only really worth noting that the get_from_postbody() function lets the program read parameters that we pass in via HTTP post parameters. Also for this bug in particular, we read in the targetAPSsid HTTP POST parameter in at [1]. Continuing on to the portion of the function where the targetAPSsid is used:

00457884    int32_t formIpv6Setup(struct client* arg1, int32_t arg2, int32_t arg3)
// [..] 
0045790c        char* redirect-url = get_from_postbody(cli: arg1, "submit-url", &cgi_var_pref)
00457924        char* pram_update = get_from_postbody(cli: arg1, "update", &cgi_var_pref)

We only really need to note that the get_from_postbody function is the method through which the program reads in our HTTP POST parameters. Continuing on, we examine how to reach the dhcp networking configuration section of this function to hit our vulnerable parameters.

00457eb0        int32_t tmp_28 = atoi(str: get_from_postbody(cli: arg1, "wan_enable", &cgi_var_pref)) // [1]
00457eac        apmib_set(0x180, value: &tmp_28)
00457eb8        int32_t var_38
00457eb8        int32_t* out_1
00457eb8        
00457eb8        if (tmp_28 != 0)
004579fc            char* OriginType = get_from_postbody(cli: arg1, "OriginType", &cgi_var_pref)
00457a08            char* dnsMode = OriginType
00457a08            
00457a04            if (OriginType != 0)
00457a20                tmp_28 = atoi(str: OriginType)
00457a1c                apmib_set(MIB_IPV6_ORIGIN_TYPE, &tmp_28) // [3]

Rather obviously we need the WAN to be enabled at [1] before we can hit any of our vulnerable code paths. More specific is that the OriginType HTTP POST parameter [2] must be equal to 0x2, as this is stored within the MIB_IPV6_ORIGIN_TYPE flash configuration at [3], which will be utilized later to choose whether we’re configuring the WAN port for PPPOE, static networking, or dhcp. By setting OriginType to 0x2 we can hit the following code:

00457cb4            int32_t origin_type = apmib_get(MIB_IPV6_ORIGIN_TYPE, out: &tmp_28)
00457cc0            int32_t _origin_type = tmp_28
00457cc0            
00457cbc            if (origin_type == 0)
00457a40                return puts(str: "get MIB_IPV6_ORIGIN_TYPE failed")
// [...]
00457e50                else // [1]
00457e70                    strcpy(dest: &dnsoverflow_1, src: get_from_postbody(cli: arg1, "dhcp_dns1", &cgi_var_pref))  // [4]
00457dc8                    strcpy(dest: &dnsoverflow_2, src: get_from_postbody(cli: arg1, "dhcp_dns2", &cgi_var_pref))  // [5]
00457dd0                    value_4 = &dnsoverflow_1

CVE-2026-42025 - dhcp_dns1

A stack-based buffer overflow exists in the dhcp_dns1 parameter which is is directly copied to the stack at [4] without any checks or restrictions whatsoever. As such, this easily leads to arbitrary code execution

Crash Information

Breakpoint 1, 0x00457e70 in ?? ()

[>_>]> !ls
***********************************************************************************
***********************************************************************************
v0[H]      : 0x004afea0                         | s3         : 0x00000000
v1         : 0x00000000                         | s4         : 0x00000000
a0[S]      : 0x7fc5f8a8                         | s5         : 0x00000001
a1         : 0x00000001                         | s6[H]      : 0x004c566c
a2[L]      : 0x7782e2d0                         | s7         : 0x0000000d
a3         : 0x00000001                         | t8[X]      : 0x0048c0dc
t0         : 0x77834628                         | t9[L]      : 0x77cff8bc
t1         : 0x77834628                         | k0         : 0x00000000
t2[H]      : 0x004afde0                         | k1         : 0x00000000
t3         : 0xfffffffc                         | gp[L]      : 0x77d1b020
t4         : 0x00000020                         | sp[S]      : 0x7fc5f850
t5         : 0x00000001                         | ra[X]      : 0x00457e6c
t6         : 0x000000a0                         | status     : 0x0000f413
t7[H]      : 0x00490000                         | badvaddr[H] : 0x004980f0
s0[H]      : 0x004c4d90                         | pc[X]      : 0x00457e70
s1         : 0x00480000                         | fcsr       : 0x00000000
s2         : 0x00000002                         | restart    : 0x00000000
***********************************************************************************
   0x457e64:    jal     0x40f600
   0x457e68:    move    a0,s0
   0x457e6c:    addiu   a0,sp,88
=> 0x457e70:    jal     0x47bf60
   0x457e74:    move    a1,v0
   0x457e78:    lui     a1,0x48
   0x457e7c:    addiu   a2,s1,-32576
   0x457e80:    b       0x457dbc
   0x457e84:    addiu   a1,a1,-30260
***********************************************************************************
#0  0x00457e70 in (0x400000 0x47c000 0x7c000 0x0 r-xp /bin/boa)(+0x57e70)
***********************************************************************************

[<_<]> x/1s $v0
0x4afea0:       'A' <repeats 200 times>...

[x.x]> c
Continuing.
warning: GDB can't find the start of the function at 0x457e70.
warning: GDB can't find the start of the function at 0x457e70.
[Detaching after fork from child process 9582]

Program received signal SIGBUS, Bus error.
0x42424242 in ?? ()
[?.?] uhhhh...? Unhandled signal, gg. SIGBUS

[^~^]> !ls
***********************************************************************************
***********************************************************************************
v0         : 0x00000000                         | s3         : 0x41414141
v1         : 0x00000001                         | s4         : 0x41414141
a0         : 0x00000002                         | s5         : 0x41414141
a1[S]      : 0x7fc5f804                         | s6         : 0x41414141
a2[S]      : 0x7fc5f7e8                         | s7         : 0x0000000d
a3         : 0x00000000                         | t8         : 0x00323a3a
t0         : 0x00000000                         | t9[L]      : 0x777b4830
t1         : 0x0230a72f                         | k0         : 0x00000000
t2         : 0xfffffffc                         | k1         : 0x00000000
t3         : 0x00109412                         | gp[L]      : 0x77836400
t4         : 0x00000000                         | sp[S]      : 0x7fc5f9a0
t5         : 0x00000000                         | ra         : 0x42424242
t6         : 0x00000000                         | status     : 0x0000f413
t7         : 0x31303032                         | badvaddr   : 0x42424242
s0         : 0x41414141                         | pc         : 0x42424242
s1         : 0x41414141                         | fcsr       : 0x00000000
s2         : 0x41414141                         | restart    : 0x00000000
***********************************************************************************
Invalid $pc @ 0x42424242
#0  0x42424242 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
***********************************************************************************

CVE-2026-42026 - dhcp_dns2

A stack-based buffer overflow exists in the dhcp_dns2 parameter which is is directly copied to the stack at [5] without any checks or restrictions whatsoever. As such, this easily leads to arbitrary code execution

Crash Information

Breakpoint 1, 0x00457dc8 in ?? ()

[o.o]> !ls
***********************************************************************************
***********************************************************************************
v0[H]      : 0x004afd00                         | s3         : 0x00000000
v1         : 0x00000000                         | s4         : 0x00000000
a0[S]      : 0x7fc90568                         | s5         : 0x00000001
a1         : 0x00000001                         | s6[H]      : 0x004b5e8c
a2[L]      : 0x76e162d0                         | s7         : 0x0000000d
a3         : 0x00000001                         | t8[X]      : 0x0048c0dc
t0         : 0x76e1c628                         | t9[L]      : 0x772e78bc
t1         : 0x76e1c628                         | k0         : 0x00000000
t2[H]      : 0x004afc78                         | k1         : 0x00000000
t3         : 0xfffffffc                         | gp[L]      : 0x77303020
t4         : 0x00000020                         | sp[S]      : 0x7fc90550
t5         : 0x00000001                         | ra[X]      : 0x00457dc4
t6         : 0x00000070                         | status     : 0x0000f413
t7[H]      : 0x00490000                         | badvaddr   : 0x76d25139
s0[H]      : 0x004b55b0                         | pc[X]      : 0x00457dc8
s1         : 0x00480000                         | fcsr       : 0x00000000
s2         : 0x00000002                         | restart    : 0x00000000
***********************************************************************************
   0x457dbc:    jal     0x40f600
   0x457dc0:    move    a0,s0
   0x457dc4:    addiu   a0,sp,24
=> 0x457dc8:    jal     0x47bf60
   0x457dcc:    move    a1,v0
   0x457dd0:    addiu   a1,sp,88
   0x457dd4:    jal     0x47b8d0
   0x457dd8:    li      a0,10088
***********************************************************************************
#0  0x00457dc8 in (0x400000 0x47c000 0x7c000 0x0 r-xp /bin/boa)(+0x57dc8)
***********************************************************************************

[>_>]> x/1s $v0
0x4afd00:       'A' <repeats 200 times>...

[<_<]> c
Continuing.
[Detaching after fork from child process 9919]
[<_<]>
Program received signal SIGBUS, Bus error.
0x42424242 in ?? ()
[?.?] uhhhh...? Unhandled signal, gg. SIGBUS

[x.x]> !ls
***********************************************************************************
***********************************************************************************
v0         : 0x00000000                         | s3         : 0x41414141
v1         : 0x00000001                         | s4         : 0x41414141
a0         : 0x00000002                         | s5         : 0x41414141
a1[S]      : 0x7fc90504                         | s6         : 0x41414141
a2[S]      : 0x7fc904e8                         | s7         : 0x0000000d
a3         : 0x00000000                         | t8         : 0x41414141
t0         : 0x00000000                         | t9[L]      : 0x76d9c830
t1         : 0x87c98b80                         | k0         : 0x00000000
t2         : 0xfffffffc                         | k1         : 0x00000000
t3         : 0x87c98b81                         | gp[L]      : 0x76e1e400
t4         : 0x00000000                         | sp[S]      : 0x7fc906a0
t5         : 0x00000000                         | ra         : 0x42424242
t6         : 0x00000000                         | status     : 0x0000f413
t7         : 0x41414141                         | badvaddr   : 0x42424242
s0         : 0x41414141                         | pc         : 0x42424242
s1         : 0x41414141                         | fcsr       : 0x00000000
s2         : 0x41414141                         | restart    : 0x00000000
***********************************************************************************
Invalid $pc @ 0x42424242
#0  0x42424242 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
***********************************************************************************

***********************************************************************************

Timeline

2026-06-16 - vulndev@cisco.com - Initial Vendor Notification
2026-06-23 - vulndiscovery@external.cisco.com - Follow-up sent
2026-06-25 - fae_hardware@zioncom.net - Vendor Acknowledged
2026-06-25 - vulndiscovery@external.cisco.com - Resent all notifications
2026-07-16 - vulndiscovery@external.cisco.com - Follow-up sent
2026-09-15 - vulndiscovery@external.cisco.com - Follow-up sent

Credit

Lilith Wyatt of Cisco Talos