Talos Vulnerability Report

TALOS-2026-2433

Totolink X2000R boa formIpQos mac stack-based buffer overflow vulnerability

October 20, 2026

CVE Number

CVE-2026-10132

Summary

A stack-based buffer overflow vulnerability exists in the boa formIpQos mac 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/formIpQos page, which leads us into the formIpQos() function:

0041b864    size_t formIpQos(struct client* arg1)
0041b8a4        struct client* cli = arg1
0041b8b4        char* addQos = get_from_postbody(cli: arg1, "addQos", &cgi_var_pref)
0041b8b8        char* applyQos = get_from_postbody(cli, "applyQos", &cgi_var_pref)
0041b8b8        
0041b8c8        if (sx.d(*addQos) == 0)
0041b8e4            addQos = get_from_postbody(cli, "addQosFlag", &cgi_var_pref)
0041b8e4        
0041b8f4        char* deleteSel = get_from_postbody(cli, "deleteSel", &cgi_var_pref)
0041b90c        char* deleteAll = get_from_postbody(cli, "deleteAll", &cgi_var_pref)
0041b924        char* sqosadvAdd = get_from_postbody(cli, "sqosadvAdd", &cgi_var_pref)            // [1]
0041b93c        char* smartQosAdvanced = get_from_postbody(cli, "smartQosAdvanced", &cgi_var_pref)
0041b954        char* smartQosAdvancedDeleteSel = get_from_postbody(cli, "smartqosAdvanceddeleteSel", &cgi_var_pref)
// [...]
0041b994        
0041b994        if (sx.d(*smartQosAdvancedDeleteSel) != 0) ...
0041b994        else
0041b9a4        label_41b9a4:
0041b9a4            char* applyQos_1 = applyQos
0041b9a4            
0041b9a0            if (sx.d(*sqosadvAdd) == 0) ...
0041b9a0            else
0041b9ac                puts(str: "set smart qos adv add rule")
0041b9c0                char* device_name = get_from_postbody(cli, "deviceName", &cgi_var_pref)   // [2]
0041b9d0                int32_t $v0_7
0041b9d0                
0041b9d0                if (sx.d(*device_name) != 0)
0041b9e0                    $v0_7 = strlen(str: device_name) u< 0x40 ? 1 : 0
0041b9e0                
0041b9e4                if (sx.d(*device_name) == 0 || $v0_7 == 0)
0041bb64                    $a1_2 = "Set smartQos devicename  error!"
0041bb60                    goto err
0041bb60                
0041b9f0                strcpy(dest: &dname, src: device_name)
0041ba04                char* mac = get_from_postbody(cli, "mac", &cgi_var_pref)  // [3]
0041ba04                
0041ba14                if (mac == &cgi_var_pref)
0041ba24                label_41ba24:
0041ba24                    $a1_2 = "<script>dw(MM_qos_msg1)</script>"
0041ba20                    goto err
0041ba20                
0041bb68                char overflowed[0x22]
0041bb68                strcpy(dest: &overflowed, src: mac)  // [4]

For today’s vulnerability we only really have to care about our sqosadvAdd HTTP POST parameter [1], which needs to be equal to 0x1, which then lets us read in the deviceName parameter at [2], which only needs to be a string less than 0x40 in length. Assuming both these conditions are met we then hit the line at [3] in which our mac HTTP POST parameter is read in and finally gets copied via strcpy to the stack at [4], resulting in a stack-based buffer overflow and subsequent command execution.

Crash Information

***********************************************************************************
***********************************************************************************
v0[X]      : 0x004780c0                         | s3[H]      : 0x004ad538
v1         : 0x00000000                         | s4[X]      : 0x00464994
a0[S]      : 0x7f969530                         | s5[X]      : 0x004780c0
a1         : 0x00000001                         | s6[H]      : 0x004ca90c
a2[L]      : 0x76b502d0                         | s7[H]      : 0x004ad4f8
a3         : 0x00000001                         | t8[X]      : 0x0048c0dc
t0         : 0x76b56628                         | t9[L]      : 0x770218bc
t1         : 0x76b56628                         | k0         : 0x0000000a
t2[H]      : 0x004ad530                         | k1         : 0x00000000
t3         : 0xfffffffc                         | gp[L]      : 0x7703d020
t4         : 0x00000020                         | sp[S]      : 0x7f969290
t5         : 0x00000001                         | ra[X]      : 0x0041ba0c
t6         : 0x00000e40                         | status     : 0x0000f413
t7[H]      : 0x00490000                         | badvaddr   : 0x76b53450
s0[H]      : 0x004ca030                         | pc[X]      : 0x0041bb68
s1         : 0x00480000                         | fcsr       : 0x00000000
s2[H]      : 0x004ae9d0                         | restart    : 0x00000000
***********************************************************************************
   0x41bb5c:    addiu   s6,s6,-1
   0x41bb60:    b       0x41ba40
   0x41bb64:    addiu   a1,a1,-26536
=> 0x41bb68:    jal     0x47bf60
   0x41bb6c:    move    a1,s3
   0x41bb70:    addiu   a1,sp,808
   0x41bb74:    li      a0,10130
   0x41bb78:    jal     0x47b7d0
   0x41bb7c:    li      s4,1
***********************************************************************************
#0  0x0041bb68 in (0x400000 0x47c000 0x7c000 0x0 r-xp /bin/boa)(+0x1bb68)
***********************************************************************************

[x.x]> info reg s3
s3: 0x4ad538

[^~^]> x/1s $s3
0x4ad538:       'A' <repeats 200 times>...

[~.~]> c
Continuing.

Program received signal SIGBUS, Bus error.
0x42424242 in ?? ()

[o.O]> !ls
***********************************************************************************
***********************************************************************************
v0         : 0x00000083                         | s3         : 0x41414141
v1[H]      : 0x00490000                         | s4         : 0x41414141
a0[H]      : 0x004c8372                         | s5         : 0x41414141
a1[S]      : 0x7f968af3                         | s6         : 0x42424242
a2         : 0x00000002                         | s7         : 0x42424242
a3[S]      : 0x7f968af3                         | t8[X]      : 0x0048c074
t0         : 0x0000003e                         | t9[L]      : 0x76b086d0
t1         : 0x6d74682f                         | k0         : 0x00000000
t2         : 0x6c622f3c                         | k1         : 0x00000000
t3         : 0x716b636f                         | gp[L]      : 0x76b58400
t4         : 0x65746f75                         | sp[S]      : 0x7f969640
t5         : 0x622f3c3e                         | ra         : 0x42424242
t6         : 0x3e79646f                         | status     : 0x0000f413
t7[H]      : 0x00490000                         | 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