This is a hidden reset button behind a locked closet door, not a street-facing break-in
CVE-2026-20185 is a heap-based SNMP parsing bug in Cisco SG350 and SG350X managed switches that can force an unexpected reload. Cisco says the known-affected population is narrower than the headline suggests: firmware 2.5.9.54 or 2.5.9.55, on listed SG350-28P / 28MP / 52P / 52MP and SG350X series devices, with two or more 60-watt PoE ports enabled, and with SNMP v1/v2c/v3 enabled.
Cisco's 7.7/HIGH baseline is technically fair for 'network-triggered outage on infrastructure gear,' but it overstates most enterprise exposure. The bug is authenticated-only, usually reachable only on the management plane, and gated by a specific hardware and PoE configuration; that makes it a post-initial-access, narrow-population DoS in real fleets. It still matters because a single successful trigger can bounce a branch or closet switch, and there is no vendor patch because the product line is past software maintenance.
5 steps from start to impact.
Reach the SNMP management plane
nmap or a basic SNMP client to confirm the service is listening.- Target is a Cisco SG350 or SG350X switch
- SNMP service is enabled
- Attacker can reach UDP/161 on the device
- Most enterprises keep switch SNMP off the public internet
- Management VRFs, ACLs, NGFW rules, and jump-host design often isolate UDP/161
- Branch switches may only answer SNMP from an NMS subnet
Obtain valid SNMP access
snmpwalk, snmpget, or any SNMP library once credentials are known.- Valid SNMPv1/v2c community string or SNMPv3 credentials
- The credential is accepted by the target switch
- This is not unauthenticated remote exploitation
- SNMPv3 with auth/privacy materially raises the bar
- Credential vaulting, AAA hygiene, and config management reduce credential leakage
Hit the narrow affected configuration
- Firmware version is 2.5.9.54 or 2.5.9.55
- Model is in the vulnerable SG350/SG350X set
- At least two interfaces are configured with
power inline limit 60000
- This is a small subset of the already-EOL product family
- Non-PoE or lower-power deployments do not meet the trigger condition
- Cisco's OID-exclusion mitigation blocks the vulnerable MIB path even without a patch
Send the crafted SNMP request
- All prior reachability, credential, and config prerequisites are satisfied
- Target has not implemented the OID-exclusion mitigation
- No public PoC was found in web or GitHub searches as of 2026-05-30
- The exact trigger is not published in Cisco's advisory
- Reliability outside lab-matched configurations is unproven publicly
Exploit the outage window
- Target switch is operationally important in the path
- Reload causes service interruption for attached endpoints or uplinks
- No confidentiality or integrity impact is documented
- Redundant uplinks, stack design, and resilient campus topology can blunt user impact
- Many SG350 deployments are edge/branch rather than central data-center switching
The supporting signals.
| In-the-wild status | Cisco PSIRT says it is not aware of any public announcements or malicious use of this flaw, and I found no KEV entry as of 2026-05-30. |
|---|---|
| Public exploit / PoC | I found no public GitHub PoC or weaponized write-up for CVE-2026-20185. Public coverage is mostly advisory aggregation and news summaries, not exploitation research. |
| EPSS | 0.00216 from the user-supplied intel block, which is a low exploitation-likelihood signal. Third-party mirrors around publication also showed EPSS in the same low band. |
| KEV / CISA status | Not KEV-listed. CISA's ADP enrichment on the CVE record marks Exploitation: none, Automatable: no, Technical Impact: partial. |
| CVSS vector reality check | CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:N/I:N/A:H says network reachable with low complexity and high availability impact, but the important real-world suppressor is PR:L on the SNMP management plane. |
| Affected versions | Cisco lists SG350-28P, SG350-28MP, SG350-52P, SG350-52MP, and SG350X series running firmware 2.5.9.54 or 2.5.9.55, with two or more 60W PoE ports enabled. |
| Fixed version | None. Cisco says these products are past End of Software Maintenance Releases and will not receive software updates for this issue. |
| Mitigation path | Cisco's mitigation is to create an SNMP view that excludes the vulnerable OID: snmp-server view SNMP_DOS iso included and snmp-server view SNMP_DOS rlPethPsePortTable excluded, then bind that view to all communities or SNMPv3 groups. |
| Scanning / exposure data | I found no product-specific Shodan/Censys/FOFA census for SG350/SG350X tied to this CVE. As a proxy, Censys reported 192,038 internet-accessible Cisco SNMP services for another Cisco SNMP advisory, which shows SNMP exposure exists broadly, but this exact flaw is still narrowed by valid SNMP auth and a specific EOL hardware/config match. |
| Disclosure / reporter | Published by Cisco on 2026-05-06. Cisco credits security researcher Ryan Moore for reporting the vulnerability. |
noisgate verdict.
The decisive factor is that exploitation requires valid SNMP access to the management plane, which usually implies prior credential theft or existing internal foothold rather than fresh internet compromise. The second big suppressor is the very narrow affected population: EOL SG350/SG350X hardware, two exact firmware builds, and a specific PoE configuration gate.
Why this verdict
- Start from Cisco's 7.7/HIGH baseline because a crafted network request can hard-reload infrastructure gear and cause real availability loss.
- Downgrade for attacker position: this is authenticated remote against the SNMP management plane, not unauthenticated edge exploitation. That implies prior compromise, stolen config/credential material, or legitimate management access.
- Downgrade again for population narrowing: exploitation only applies to a small EOL subset of SG350/SG350X devices on 2.5.9.54/2.5.9.55 with two or more 60W PoE ports enabled.
- Downgrade for threat signal: no KEV, no public PoC found, Cisco says no known malicious use, and EPSS is very low.
- Keep it above LOW because impact is still operationally meaningful**: once the prerequisites are met, a single trigger can bounce a switch and knock out a branch, closet, phones, cameras, or attached users.
Why not higher?
This is not a perimeter-breaker. There is no unauthenticated path, no code execution, no data theft, and no integrity impact in the published advisory. Requiring valid SNMP auth plus a narrow hardware/firmware/PoE match makes the reachable population much smaller than a normal network-device HIGH.
Why not lower?
If you do run these EOL switches in branch or access roles, the blast radius at the site can still be painful: voice, cameras, APs, and users can all drop together when the switch reloads. The lack of a vendor patch also means affected estates carry a durable residual risk until they mitigate or replace.
What to do — in priority order.
- Exclude the vulnerable OID — Implement Cisco's SNMP view mitigation by excluding
rlPethPsePortTableand bind that view to every SNMP community and SNMPv3 group. Because this is a MEDIUM finding there is no noisgate mitigation SLA; deploy it in the next approved network change window, then treat hardware replacement as the long-term fix. - Restrict SNMP to the NMS only — Enforce ACLs or management-plane filtering so UDP/161 is reachable only from your monitoring platform and admin jump segments. There is no noisgate mitigation SLA for MEDIUM, but reducing reachable attack surface should still happen at the next routine network policy change.
- Retire SNMPv2c where possible — Move remaining estates to SNMPv3 and rotate any long-lived community strings that may exist in config backups or legacy tooling. For a MEDIUM verdict, schedule during normal credential-rotation cadence; this reduces the odds that a stolen read-only string becomes an outage trigger.
- Disable SNMP on non-managed switches — If a switch is not actively polled or trapped by an NMS, turn SNMP off entirely and remove the attack path. There is no noisgate mitigation SLA here; fold this into cleanup work and configuration standardization.
- Plan hardware replacement — Cisco will not ship a fix because SG350/SG350X are past software maintenance, so replacement is the only true remediation. For a MEDIUM finding, complete migration within the 365-day remediation window and prioritize sites where these switches carry PoE-heavy access roles.
- A WAF does nothing here because the path is SNMP over UDP/161, not HTTP.
- Email security is irrelevant; this is a management-plane device flaw, not a user-delivered payload.
- Vulnerability scanners alone are not enough because most will miss the exact trigger gate: firmware build plus model plus two 60W PoE ports plus SNMP exposure.
- Upgrading the NMS does not fix the switch. The vulnerable parser is on the device itself unless you apply Cisco's OID-exclusion mitigation or replace the hardware.
Crowdsourced verification payload.
Run this from an auditor workstation or jump host that can SSH to the switch CLI. Invoke it as python3 check_cve_2026_20185.py [email protected] or python3 check_cve_2026_20185.py [email protected] --ssh-opt=-i --ssh-opt=/path/key; read-only CLI access is sufficient because the script only runs show commands.
#!/usr/bin/env python3
# check_cve_2026_20185.py
# Determine likely exposure to CVE-2026-20185 on Cisco SG350 / SG350X switches.
# Output: VULNERABLE / PATCHED / UNKNOWN
# Exit codes: 0=PATCHED(or not affected/mitigated), 1=VULNERABLE, 2=UNKNOWN
import re
import sys
import subprocess
USAGE = "Usage: python3 check_cve_2026_20185.py user@host [--ssh-opt=<value> ...]"
def run_ssh(target, cmd, extra_opts):
base = ["ssh", "-o", "BatchMode=yes", "-o", "ConnectTimeout=10"]
for opt in extra_opts:
base.extend([opt] if opt.startswith("-") and " " not in opt else [opt])
full = base + [target, cmd]
try:
p = subprocess.run(full, capture_output=True, text=True, timeout=25)
except Exception as e:
return None, f"ssh execution failed: {e}"
if p.returncode != 0:
err = (p.stderr or p.stdout or "ssh returned non-zero").strip()
return None, err
return p.stdout, None
def main():
if len(sys.argv) < 2:
print("UNKNOWN - " + USAGE)
sys.exit(2)
target = sys.argv[1]
extra_opts = []
for arg in sys.argv[2:]:
if arg.startswith("--ssh-opt="):
extra_opts.append(arg.split("=", 1)[1])
else:
print(f"UNKNOWN - unrecognized argument: {arg}")
sys.exit(2)
commands = {
"version": "show version",
"snmp_community": "show running-config | include snmp-server community",
"snmp_group": "show running-config | include snmp-server group",
"snmp_user": "show snmp user",
"poe": "show running-config | include interface|power inline limit 60000",
"view": "show running-config | include snmp-server view",
}
out = {}
for key, cmd in commands.items():
data, err = run_ssh(target, cmd, extra_opts)
if err is not None:
print(f"UNKNOWN - failed '{cmd}': {err}")
sys.exit(2)
out[key] = data or ""
version_text = out["version"]
model_match = re.search(r"\bSG350X?[-A-Z0-9]*\b", version_text, re.IGNORECASE)
version_match = re.search(r"\b2\.5\.9\.(54|55)\b", version_text)
if not model_match:
print("PATCHED - target does not appear to be an SG350/SG350X switch")
sys.exit(0)
model = model_match.group(0).upper()
affected_version = bool(version_match)
snmp_v12 = "snmp-server community" in out["snmp_community"].lower()
snmp_v3 = ("snmp-server group" in out["snmp_group"].lower()) and ("user name:" in out["snmp_user"].lower())
snmp_enabled = snmp_v12 or snmp_v3
poe_60w_count = len(re.findall(r"power inline limit 60000", out["poe"], re.IGNORECASE))
poe_gate = poe_60w_count >= 2
view_text = out["view"]
oid_excluded = bool(re.search(r"snmp-server view\s+\S+\s+rlPethPsePortTable\s+excluded", view_text, re.IGNORECASE))
view_created = bool(re.search(r"snmp-server view\s+\S+\s+iso\s+included", view_text, re.IGNORECASE))
# Try to identify whether a mitigated view is actually applied.
applied_to_v12 = bool(re.search(r"snmp-server community\s+\S+\s+view\s+\S+\s+RO", out["snmp_community"], re.IGNORECASE))
applied_to_v3 = bool(re.search(r"snmp-server group\s+\S+\s+v3\s+\S*\s*read\s+\S+\s+write\s+\S+", out["snmp_group"], re.IGNORECASE))
mitigation_present = oid_excluded and view_created and (applied_to_v12 or applied_to_v3)
reasons = []
reasons.append(f"model={model}")
reasons.append(f"affected_version={'yes' if affected_version else 'no'}")
reasons.append(f"snmp_enabled={'yes' if snmp_enabled else 'no'}")
reasons.append(f"60w_poe_ports={poe_60w_count}")
reasons.append(f"mitigation_present={'yes' if mitigation_present else 'no'}")
if not affected_version:
print("PATCHED - not on firmware 2.5.9.54/2.5.9.55; " + ", ".join(reasons))
sys.exit(0)
if not snmp_enabled:
print("PATCHED - SNMP not enabled; " + ", ".join(reasons))
sys.exit(0)
if not poe_gate:
print("PATCHED - fewer than two 60W PoE ports configured; " + ", ".join(reasons))
sys.exit(0)
if mitigation_present:
print("PATCHED - Cisco OID-exclusion mitigation detected; " + ", ".join(reasons))
sys.exit(0)
print("VULNERABLE - SG350/SG350X on affected firmware with SNMP enabled and >=2 60W PoE ports, no mitigation detected; " + ", ".join(reasons))
sys.exit(1)
if __name__ == "__main__":
main()
If you remember one thing.
Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.