Talos Vulnerability Report

TALOS-2026-2389

Totolink X2000R boa formMapDelDevice hostname stack-based buffer overflow vulnerability

October 20, 2026

CVE Number

CVE-2026-28763

Summary

A stack-based buffer overflow vulnerability exists in the boa formMapDelDevice hostname 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 this vulnerability.

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/formMapDelDevice page, which leads us into the formMapDelDevice() function:

0045de48    int32_t formMapDelDevice(struct client* arg1)

0045de78        char* macstr = get_from_postbody(cli: arg1, "macstr", &cgi_var_pref)
0045de90        char* $v0 = get_from_postbody(cli: arg1, "bandstr", &cgi_var_pref)
0045dea8        char* clientoff = get_from_postbody(cli: arg1, "clientoff", &cgi_var_pref)
0045dec0        char* hostnameAdd = get_from_postbody(cli: arg1, "hostnameAdd", &cgi_var_pref) // [1]
0045ded0        int32_t hnameadd_val
0045ded0        
0045ded0        if (sx.d(*clientoff) == 0)
0045ded4            hnameadd_val = sx.d(*hostnameAdd)
0045ded0        else
0045dedc            char* var_d0_1 = $v0
0045deec            p2_vfork_execve("/bin/map_del_device", 2, 0, macstr)
0045def4            hnameadd_val = sx.d(*hostnameAdd)
0045def4        
0045def8        if (hnameadd_val != 0)    // [2]
0045df48            char var_70[0x40]
0045df48            memset(str: &var_70, c: 0, n: 0x46)
0045df5c            char* str = get_from_postbody(cli: arg1, "hostname", &cgi_var_pref)  // [3]
0045df68            puts(str)
0045df68            
0045df74            if (sx.d(*str) != 0)
0045df80                strcpy(dest: &var_70, src: str)  // [4]

We’re immediately presented with a very straightforward vulnerability. Assuming we’ve provided an HTTP Post hostnameAdd parameter [1] that’s non-zero, we hit the branch at [2] and the program reads in our HTTP POST hostname variable if one has been provided. Assuming it’s non-zero and present, the program uses an unchecked strcpy to copy this value onto the stack, which extremely quickly leads to a return address overwrite and arbitrary code execution.

Crash Information

Breakpoint 1, 0x0045df80 in ?? ()

***********************************************************************************
***********************************************************************************
v0         : 0x00000041                         | s3[H]      : 0x004afc78
v1         : 0x00000001                         | s4[H]      : 0x004afc98
a0[S]      : 0x7fad71f0                         | s5[H]      : 0x004afcb8
a1         : 0x00480000                         | s6[H]      : 0x004c03cc
a2         : 0x00000000                         | s7         : 0x00000010
a3         : 0x00000000                         | t8         : 0x00000003
t0         : 0x00000000                         | t9[L]      : 0x76de7a70
t1         : 0x00000003                         | k0         : 0x0000000a
t2         : 0x00000001                         | k1         : 0x00000000
t3         : 0x42414141                         | gp[L]      : 0x76e64400
t4         : 0x00000080                         | sp[S]      : 0x7fad7180
t5[L]      : 0x76e64400                         | ra[X]      : 0x0045df70
t6         : 0x00000000                         | status     : 0x0000f413
t7         : 0x41414141                         | badvaddr   : 0x76e5f450
s0         : 0x00480000                         | pc[X]      : 0x0045df80
s1[H]      : 0x004bfaf0                         | fcsr       : 0x00000000
s2[H]      : 0x004afea8                         | restart    : 0x00000000
***********************************************************************************
   0x45df74:    beqz    v0,0x45df8c
   0x45df78:    lui     a1,0x48
   0x45df7c:    addiu   a0,sp,112
=> 0x45df80:    jal     0x47bf60
   0x45df84:    move    a1,s2
   0x45df88:    lui     a1,0x48
   0x45df8c:    addiu   a2,s0,-32576
   0x45df90:    addiu   a1,a1,-23344
***********************************************************************************
#0  0x0045df80 in (0x400000 0x47c000 0x7c000 0x0 r-xp /bin/boa)(+0x5df80)
***********************************************************************************

[>_>]> x/1s $s2
0x4afea8:       'A' <repeats 112 times>, "BBBB"

[<_<]> c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()

[^_^] SIGSEGV

***********************************************************************************
***********************************************************************************
v0         : 0x0000000d                         | s3         : 0x41414141
v1         : 0x00000001                         | s4         : 0x41414141
a0[L]      : 0x76e5c1dc                         | s5         : 0x41414141
a1         : 0x76e5f450                         | s6[H]      : 0x004c03cc
a2         : 0x00000000                         | s7         : 0x00000010
a3         : 0x00000000                         | t8         : 0x00000003
t0         : 0x00000000                         | t9[L]      : 0x76de7a70
t1         : 0x00000003                         | k0         : 0x0000000a
t2         : 0x00000001                         | k1         : 0x00000000
t3         : 0x2063616d                         | gp[L]      : 0x76e64400
t4         : 0x00000080                         | sp[S]      : 0x7fad7260
t5[L]      : 0x76e64400                         | ra         : 0x41414141
t6         : 0x00000000                         | status     : 0x0000f413
t7[L]      : 0x76e5c190                         | badvaddr   : 0x41414140
s0         : 0x41414141                         | pc         : 0x41414141
s1         : 0x41414141                         | fcsr       : 0x00000000
s2         : 0x41414141                         | restart    : 0x00000000
***********************************************************************************
Invalid $pc @ 0x41414141
#0  0x41414141 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