Cisco Catalyst SD-WAN Manager CVE-2026-76504 Active Authentication-Bypass Hunt

Threat Overview

Cisco disclosed CVE-2026-76504 on September 30, 2026, a critical (CVSS 9.8) authentication bypass in the API session-management logic of Cisco Catalyst SD-WAN Manager. Improper handling of URI encoding lets an unauthenticated remote attacker send a crafted HTTP request that bypasses an endpoint authentication rule and reaches the API with the privileges of the built-in admin user. Cisco PSIRT confirmed active exploitation in September 2026. The vendor has not published an actor, victim count, or post-compromise objective.

Cisco’s confirmed forensic pivots are URI-encoded variants of j_security_check in serviceproxy-access.log and related vmanage-server.log entries involving usernames beginning viptela-reserved-. Cisco cautions that these events can occur during normal operations and that %6a is only one example: any one character in the request may be URI encoded. Accordingly, the highest-value detection combines an encoded login path, an unknown source, a successful response, and corroborating reserved-account or follow-on management activity.

References

Impacted Systems

  • Vendor/product: Cisco Catalyst SD-WAN Manager (formerly vManage); network-management/control-plane role.
  • Deployment/configuration: Affected regardless of configuration. Internet- or otherwise untrusted-network-reachable Manager API/administrative interfaces have the greatest exposure. No credentials or user interaction are required.
  • Affected/fixed trains: Releases earlier than 20.9 must migrate. First fixed releases are 20.9.10.1, 20.12.8.2, 20.15.6.1, 20.18.4.1, 26.1.2.1, and 26.2.1.
  • Cloud: Cisco SD-WAN Cloud (Cisco Managed) is fixed in 20.15.605 and Cisco states no customer action is required. Cisco says its access-restriction mitigation is already deployed in Cloud Hosted environments.
  • Unaffected: Cisco states that only Catalyst SD-WAN Manager is known to be affected.

Why this matters

The flaw is remotely exploitable without authentication, grants administrative API access, affects a high-impact network-control component, and is confirmed exploited. A compromised Manager can expose configuration, credentials, topology, and control of the managed SD-WAN fabric. The hunt prioritizes Cisco’s narrow forensic indicators before broader exposure and follow-on behavior.

Exploitation Status

Confirmed active exploitation. Cisco PSIRT became aware of exploitation during a TAC case in September 2026. Cisco has not attributed the activity or described attacker objectives. The known evidence is limited to encoded j_security_check access and associated reserved service-account handling; a match is not independently proof of compromise because Cisco says similar log entries can occur legitimately.

What this hunt looks for

URI-encoded j_security_check requests, viptela-reserved service-account activity, rare and bursty authentication sources, exposure of Manager administrative ports, request timelines, and new controller egress.

Required logs

Cisco Catalyst SD-WAN Manager serviceproxy-access.log and vmanage-server.log forwarded to Syslog; reverse-proxy, WAF, or firewall HTTP telemetry in CommonSecurityLog; and network-security telemetry for Manager administrative ports and controller egress.

Hunt 1 — High-confidence encoded j_security_check requests in Cisco logs

let lookback = 30d;
Syslog
| where TimeGenerated >= ago(lookback)
| where SyslogMessage has "_security_check"
| where SyslogMessage matches regex @'(?i)(post\s+)?/[^\s"]*%[0-9a-f]{2}[^\s"]*_security_check'
| project TimeGenerated, Computer, HostName, ProcessName, SyslogMessage
| order by TimeGenerated desc

Hunt 2 — Reserved service account tied to encoded authentication path

let lookback = 30d;
Syslog
| where TimeGenerated >= ago(lookback)
| where SyslogMessage has "_security_check" and SyslogMessage has "viptela-reserved-"
| where SyslogMessage matches regex @"(?i)/[^\s\)]*%[0-9a-f]{2}[^\s\)]*_security_check"
| project TimeGenerated, Computer, HostName, ProcessName, SyslogMessage
| order by TimeGenerated desc

Hunt 3 — CommonSecurityLog encoded authentication requests

let lookback = 30d;
CommonSecurityLog
| where TimeGenerated >= ago(lookback)
| extend Url = tostring(coalesce(RequestURL, DestinationHostName)), Method = tostring(RequestMethod)
| where Url has "_security_check"
| where Url matches regex @"(?i)/[^\s]*%[0-9a-f]{2}[^\s]*_security_check"
| project TimeGenerated, DeviceVendor, DeviceProduct, SourceIP, DestinationIP, DestinationPort, Method, Url, DeviceAction, Message
| order by TimeGenerated desc

Hunt 4 — Rare sources requesting the SD-WAN authentication endpoint

let baseline = 30d;
let recent = 2d;
let oldSources = CommonSecurityLog
| where TimeGenerated between (ago(baseline) .. ago(recent))
| where RequestURL has "_security_check"
| summarize by SourceIP;
CommonSecurityLog
| where TimeGenerated >= ago(recent)
| where RequestURL has "_security_check"
| where SourceIP !in (oldSources)
| summarize FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated), Requests=count(), URLs=make_set(RequestURL, 20), Actions=make_set(DeviceAction, 10) by SourceIP, DestinationIP
| order by Requests desc

Hunt 5 — External access to Manager administrative ports

let lookback = 14d;
CommonSecurityLog
| where TimeGenerated >= ago(lookback)
| where DestinationPort in (22, 443, 830)
| where isnotempty(SourceIP) and not(ipv4_is_private(SourceIP))
| where DeviceAction !in~ ("block", "blocked", "deny", "denied", "drop", "dropped")
| summarize FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated), Sessions=count(), SourcePorts=make_set(SourcePort, 20), Actions=make_set(DeviceAction, 10) by SourceIP, DestinationIP, DestinationPort
| order by Sessions desc

Hunt 6 — Authentication-path request bursts against one Manager

let lookback = 14d;
CommonSecurityLog
| where TimeGenerated >= ago(lookback)
| where RequestURL has "_security_check"
| summarize Requests=count(), EncodedRequests=countif(RequestURL matches regex @"(?i)%[0-9a-f]{2}"), URLs=make_set(RequestURL, 30) by bin(TimeGenerated, 5m), SourceIP, DestinationIP
| where EncodedRequests > 0 or Requests >= 10
| order by TimeGenerated desc

Hunt 7 — Cisco Manager logs from a source first seen in encoded requests

let lookback = 30d;
let suspiciousSources = CommonSecurityLog
| where TimeGenerated >= ago(lookback)
| where RequestURL has "_security_check" and RequestURL matches regex @"(?i)%[0-9a-f]{2}"
| summarize First=min(TimeGenerated), Last=max(TimeGenerated) by SourceIP, DestinationIP;
CommonSecurityLog
| where TimeGenerated >= ago(lookback)
| join kind=inner suspiciousSources on SourceIP, DestinationIP
| where TimeGenerated between (First - 5m .. Last + 2h)
| project TimeGenerated, SourceIP, DestinationIP, DestinationPort, RequestMethod, RequestURL, DeviceAction, Message
| order by SourceIP asc, TimeGenerated asc

Hunt 8 — New outbound destinations from a potential Manager

let baseline = 30d;
let recent = 2d;
let known = CommonSecurityLog
| where TimeGenerated between (ago(baseline) .. ago(recent))
| where isnotempty(SourceIP) and isnotempty(DestinationIP)
| summarize by SourceIP, DestinationIP;
CommonSecurityLog
| where TimeGenerated >= ago(recent)
| where isnotempty(SourceIP) and isnotempty(DestinationIP)
| where not(ipv4_is_private(DestinationIP))
| join kind=leftanti known on SourceIP, DestinationIP
| summarize FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated), Connections=count(), Ports=make_set(DestinationPort, 20), Actions=make_set(DeviceAction, 10) by SourceIP, DestinationIP
| order by Connections desc

Detection Notes

  • Hunts 1 and 2 are the highest-signal queries because they implement Cisco’s published log pivots. %6a alone is insufficient; the regex intentionally accepts any URI-encoded character in the login path.
  • Hunt 3 depends on a proxy, WAF, or network security product populating RequestURL. Confirm field mapping before treating a null result as meaningful.
  • Hunts 5 and 8 require a scoped list of Manager IPs in production. As written, they are broad triage queries and will include unrelated management systems.
  • Cisco explicitly warns that j_security_check and reserved-account events may occur normally. Validate the source against authorized jump hosts and correlate access and server logs.
  • If the two Cisco log files are not forwarded, the exploit boundary may be invisible even when perimeter traffic exists. NetFlow alone generally cannot distinguish encoded URI paths.