← Back to Feed CACHED · 2026-11-04 16:38:01 · CACHE_KEY CVE-2026-107441
CVE-2026-107441 · CWE-787 · Disclosed 2026-11-03

Zyxel GS1900-24E CGI out-of-bounds write leading to unauthenticated OS command execution

ASSESSED — NOISGATE
Vendor
—
—
—
Reassessed
—
—
—
Verdict: —
Do you agree?
01 · The Real Story

A malicious neighbor rewires the switch's management brain through a malformed web request

The CGI program in Zyxel GS1900-24E firmware through 2.90(AAHK.2)C0 contains an out-of-bounds write (CWE-787). An unauthenticated attacker who is adjacent to the switch (same L2 broadcast domain) can send a crafted HTTP request that overwrites memory and potentially executes OS commands. CIRCL data suggests other GS1900 models, including GS1900-HPv2, GS1900-48, and GS1900-48HPv2, may share the affected firmware line.

The vendor's HIGH (8.8) rating is broadly accurate for impact, but the AV:A vector already embeds the key limitation: this is not an internet-facing remote exploit. With no KEV listing and an EPSS probability of 0.293%, real-world urgency is lower than a pure CVSS reading suggests. However, full OS command execution on a network switch is a high-value outcome, so the rating stays HIGH rather than MEDIUM.

"Adjacent attacker can fully own a Zyxel switch via a malformed HTTP request, but the L2 adjacency requirement dulls the edge"
02 · The Attack Path

5 steps from start to impact.

STEP 01

Obtain network adjacency to the switch's management interface

The attacker must be on the same L2 segment as the switch management IP. This can happen if the management VLAN is accessible to end-user ports, if the attacker compromises any host on that segment, or if they have physical access to an open switch port.
Conditions required:
  • Same broadcast domain as the switch management interface
  • No 802.1X/NAC preventing unauthorized devices
Where this breaks in practice:
  • Management VLAN isolation
  • NAC/802.1X or port security
  • Physical access controls
Detection/coverage: NAC logs or switch port-security alerts may show unrecognized devices
STEP 02

Discover the switch's web management endpoint

Zyxel GS1900 switches typically expose an HTTP/HTTPS management UI. The attacker enumerates the switch IP and confirms the web server is reachable. No authentication is needed for the initial request.
Conditions required:
  • Web management enabled (default on many SMB switches)
  • HTTP/HTTPS port reachable from adjacent segment
Where this breaks in practice:
  • Web UI disabled by admin
  • Management traffic on a separate ACL-restricted VLAN
  • Non-default port
Detection/coverage: Network monitoring of HTTP requests to switch IPs; switch access logs (if enabled)
STEP 03

Send crafted HTTP request to the vulnerable CGI program

The attacker submits a specially crafted request that causes an out-of-bounds write in the CGI handler. The request is unauthenticated, so no credentials are required.
Conditions required:
  • Firmware version ≤ 2.90(AAHK.2)C0
  • Exposed CGI endpoint
Where this breaks in practice:
  • Exploit reliability is uncertain on embedded MIPS/ARM with limited mitigations
  • Crash-only outcomes may be more likely than code execution
Detection/coverage: Unusual HTTP payloads or switch crash logs; IDS may flag malformed CGI requests
STEP 04

Achieve OS command execution on the switch

If the memory corruption is controlled, the attacker escapes the CGI process and runs commands with the privileges of the web server, typically root/admin on embedded devices.
Conditions required:
  • Successful exploitation of the OOB write
  • No exploit mitigations that block control flow
Where this breaks in practice:
  • No widely available public PoC (VulDB reports no exploit exists; SOCRadar notes a 'public exploit' but no observed use)
  • CPU architecture variability across GS1900 models
Detection/coverage: Endpoint detection on network devices is rare; file/process anomalies not typically monitored
STEP 05

Lateral movement and traffic interception via the compromised switch

With OS-level control, the attacker can mirror or redirect traffic, hop VLANs, inject DHCP/DNS responses, and use the switch as a pivot to other management networks.
Conditions required:
  • Switch forwards production or management traffic
  • No port mirroring anomaly alerts
Where this breaks in practice:
  • Encrypted traffic limits direct credential capture
  • Proper segmentation and NGFW east-west controls can contain the blast radius
  • NetFlow/IDS may detect unusual mirroring or VLAN changes
Detection/coverage: Port mirror configuration changes, SNMP traps, NetFlow anomalies
03 · Compensating Control

1
HIGH 7.8→MEDIUM 5.5
SEVERITY REDUCED
Segment switch management onto a dedicated out-of-band VLAN with strict ACLs — This breaks the attacker's adjacency assumption for most endpoints. Deploy within 30 days per noisgate mitigation SLA for HIGH severity. Only administrators on the management VLAN can reach the CGI, eliminating the adjacent attacker condition.
2
HIGH 7.8→LOW 3.0
SEVERITY REDUCED
Disable the web CGI/HTTP management interface where possible — If web management is not required, turn it off and use SSH/SNMP with strong credentials. This removes the vulnerable attack surface entirely. Apply within 30 days.
3
HIGH 7.8→MEDIUM 5.0
SEVERITY REDUCED
Deploy 802.1X/NAC on all switch ports — Prevents unauthorized devices from joining the L2 segment in the first place, blocking the initial adjacency requirement. Roll out within 30 days.
4
HIGH 7.8→LOW 1.5
SEVERITY REDUCED
Apply the vendor fixed firmware when available — Patch the underlying OOB write. This is the remediation action and should be completed within 180 days per noisgate remediation SLA for HIGH, unless a fixed version is released earlier.
What doesn't work
  • Perimeter firewalling alone won't help because the attack originates from an adjacent LAN segment, not the internet.
  • Endpoint EDR/AV won't detect the switch compromise because the code runs on the network device itself, not a monitored host.
  • HTTPS alone does not stop the OOB write; the vulnerability is in the CGI program's input handling, not the transport layer.
04 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo known active exploitation; not KEV-listed. SOCRadar notes 'no use observed'.
Proof-of-concept availabilityConflicting: VulDB says *No exploit exists*; SOCRadar mentions *public exploit code published, no use observed*. Treat as low-confidence PoC.
EPSS0.00293 (0.293% probability) — very low likelihood of exploitation in next 30 days.
KEV statusNot listed in CISA KEV as of assessment date.
CVSS vectorCVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H — Adjacent, low complexity, no privileges, no user interaction, unchanged scope, high CIA impact.
Affected versionsGS1900-24E firmware ≤ 2.90(AAHK.2)C0; CIRCL lists related models GS1900-24EP, GS1900-HPv2, GS1900-48, GS1900-48HPv2 as potentially affected.
Fixed versionsVendor advisory indicates upgrade to a fixed release, but specific fixed version is not shown in available sources.
Scanning/exposureNo GreyNoise/Shodan/Censys data in sources; these switches are typically internal-only, reducing internet attack surface.
Disclosure date2026-11-03 (MITRE/NVD record).
Reporting researcherNot publicly attributed in the sources reviewed.

Sources.

  1. VulDB CVE-2026-107441
  2. VulDB GS1900 Series Switches CGI OOB Write
  3. SOCRadar CVE-2026-107441
  4. Glexia CVE-2026-107441
  5. CIRCL Vulnerability-Lookup
  6. NVD CVE-2026-107441
05 · The Call

Final Verdict
= UNCHANGED to HIGH (7.8/10)

Why this verdict

  • Adjacent-only access (AV:A): The attacker must already be on the same L2 segment or have compromised an adjacent host to reach the management interface. This eliminates pure internet-facing exploitation and pushes the likelihood down.
  • No KEV or observed exploitation: Despite public exploit chatter, CISA KEV does not list it and EPSS is 0.293%, lowering real-world urgency.
  • Role multiplier: GS1900 switches are network infrastructure. In any deployment where they forward production traffic, gaining OS-level control is a high-value outcome — traffic sniffing, VLAN hopping, and lateral movement — so the floor stays HIGH.
  • Vendor CVSS is structurally sound: The 8.8 HIGH score already uses AV:A, so the base severity is appropriate; we keep the same bucket but apply downward pressure from the low EPSS.

Why not higher?

Not CRITICAL because the attack requires network adjacency (AV:A), there is no confirmed active exploitation or reliable public PoC, and the GS1900-24E is a small-business access switch rather than a perimeter security appliance or core datacenter chassis. The EPSS of 0.293% and absence from KEV further argue against a critical-rush posture.

Why not lower?

Not MEDIUM because an unauthenticated attacker on the same segment can gain full OS command execution on a network switch. That level of control can be leveraged for widespread traffic interception, DHCP/DNS poisoning, and pivoting to other VLANs. Even with low likelihood, the impact is severe enough to demand the HIGH patching window.

06 · Verification

Crowdsourced verification payload.

Run this script from an auditor workstation with L2 adjacency to the switch management IP. It attempts to retrieve the firmware version from the web UI over HTTP and prints whether the device is VULNERABLE, PATCHED, or UNKNOWN. Invoke with python3 check_zyxel_gs1900.py <switch_ip>. No special privileges are needed beyond network access to the switch's management VLAN.

noisgate-verify.py
PYTHONREAD-ONLYSAFE
#!/usr/bin/env python3
"""Check Zyxel GS1900-24E firmware for CVE-2026-107441.
Outputs VULNERABLE, PATCHED, or UNKNOWN.
"""
import sys
import re
import urllib.request
import urllib.error

def get_body(url):
    req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0'})
    try:
        with urllib.request.urlopen(req, timeout=5) as resp:
            return resp.read(30000).decode('utf-8', errors='ignore')
    except Exception:
        return None

def extract_version(body):
    if not body:
        return None
    # Zyxel GS1900 web UI often displays firmware in the footer or about page
    patterns = [
        r'(?:Firmware Version|FW Version|Software Version)[^\d]{0,10}(\d+\.\d+\([^\)]+\))',
        r'(\d+\.\d+\([A-Z]+\.\d+\)C\d+)'
    ]
    for pat in patterns:
        m = re.search(pat, body, re.IGNORECASE)
        if m:
            return m.group(1)
    return None

def is_vulnerable(version):
    # Compare against vulnerable threshold 2.90(AAHK.2)C0.
    # We do a conservative parser: if the major/minor is lower, vulnerable;
    # if equal and build code is lexicographically <= 'AAHK.2', vulnerable.
    m = re.match(r'(\d+)\.(\d+)\(([^\)]+)\)C(\d+)', version)
    if not m:
        return False
    major, minor, build, cnum = int(m.group(1)), int(m.group(2)), m.group(3), int(m.group(4))
    if major < 2:
        return True
    if major == 2 and minor < 90:
        return True
    if major == 2 and minor == 90:
        # build code comparison: AAHK.2 vs AAHK.2; if lower => vulnerable
        if build < 'AAHK.2':
            return True
        if build == 'AAHK.2' and cnum <= 0:
            return True
    return False

def main():
    if len(sys.argv) != 2:
        print('Usage: python3 check_zyxel_gs1900.py <switch_ip>')
        sys.exit(2)
    ip = sys.argv[1]
    urls = [
        f'http://{ip}/',
        f'http://{ip}/index.htm',
        f'http://{ip}/cgi-bin/about.cgi',
        f'http://{ip}/web/version'
    ]
    found_version = None
    for url in urls:
        body = get_body(url)
        if body:
            ver = extract_version(body)
            if ver:
                found_version = ver
                break
    if not found_version:
        print('UNKNOWN: could not detect firmware version from web UI')
        sys.exit(3)
    print(f'Detected firmware: {found_version}')
    if is_vulnerable(found_version):
        print('VULNERABLE')
        sys.exit(0)
    else:
        # If version is above threshold, report PATCHED (manual validation still recommended)
        print('PATCHED')
        sys.exit(0)

if __name__ == '__main__':
    main()