CVE-2026-20182: Critical authentication bypass in Cisco Catalyst SD-WAN Controller (FIXED)

CVE-2026-20182: Unauthenticated vHub Bypass in the Cisco Catalyst SD-WAN Controller

Original text: “CVE-2026-20182: Critical authentication bypass in Cisco Catalyst SD-WAN Controller (FIXED)”Jonah Burgess & Stephen Fewer, Rapid7 (May 14, 2026). Vendor advisory: cisco-sa-sdwan-rpa2-v69WY2SW. Code, tables and figures below are reproduced verbatim with attribution captions.

Executive Summary

CVE-2026-20182 is a critical (CVSS 10.0, CWE-287) authentication bypass in the Cisco Catalyst SD-WAN Controller — historically called “vSmart” — that lets an unauthenticated remote attacker promote themselves to a fully authenticated peer of the controller. The bug lives in vdaemon, the DTLS control-plane service running on UDP 12346, and is triggered by a single missing branch in vbond_proc_challenge_ack(): when a CHALLENGE_ACK message arrives with device_type = 2 (vHub), the function falls through every verification path and unconditionally sets the per-peer authenticated flag.

From there the attacker is a peer of the SD-WAN control plane and can send MSG_VMANAGE_TO_PEER (type 14) requests that the controller treats as legitimate vManage automation. The handler for those messages opens /home/vmanage-admin/.ssh/authorized_keys in append mode and writes the attacker’s public key into it — no sanitisation, no validation. The attacker then SSHes in as the high-privileged vmanage-admin service account on TCP 830 (NETCONF-over-SSH) and runs arbitrary configuration commands against the entire SD-WAN fabric. Discovered by Stephen Fewer and Jonah Burgess at Rapid7 and disclosed in coordination with Cisco; a Metasploit module (auxiliary/admin/networking/cisco_sdwan_vhub_auth_bypass) shipped alongside the writeup. Fixed releases are available across every supported branch — upgrade now.

CVE-2026-20182: Critical authentication bypass in Cisco Catalyst SD-WAN Controller (FIXED)
Hero image accompanying the Rapid7 advisory. Source: original article.

At a Glance

FieldValue
CVECVE-2026-20182
CVSS v3.1 base score10.0 (Critical)
CVSS vectorAV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
CWECWE-287 (Improper Authentication)
Affected productCisco Catalyst SD-WAN Controller (formerly vSmart)
Affected componentvdaemon — UDP 12346 (DTLS control plane)
Vulnerable functionvbond_proc_challenge_ack()
Attack vectorRemote, network, unauthenticated
Post-auth primitiveMSG_VMANAGE_TO_PEER — arbitrary ~vmanage-admin/.ssh/authorized_keys append
DiscoverersStephen Fewer & Jonah Burgess (Rapid7)
Public exploitMetasploit: auxiliary/admin/networking/cisco_sdwan_vhub_auth_bypass (PR #21463)
Vendor advisorycisco-sa-sdwan-rpa2-v69WY2SW
Patch statusFIXED — see remediation table below
CVE-2026-20182 advisory at a glance. Source: original article.

Overview

The Cisco Catalyst SD-WAN Controller is the control-plane brain of a Catalyst SD-WAN deployment: it runs OMP, distributes routing state to the data-plane edge devices, and is the trust anchor that the rest of the fabric peers with. The advisory describes a previously-unknown bypass in the controller’s DTLS-based inter-controller peering service. It is distinct from the earlier CVE-2026-20127 issue — same module, different bug, not a patch bypass — and the attack is reachable from any host that can deliver UDP packets to port 12346 on the controller.

Once authenticated as a peer, the attacker can pivot to MSG_VMANAGE_TO_PEER — a message type intended for automated vManage-to-controller administration — and use it to write SSH public keys directly into the vmanage-admin account’s authorized_keys file. vmanage-admin is a high-privileged service account exposed by NETCONF-over-SSH on TCP 830, so the SSH-key write turns into full configuration-level control of the SD-WAN fabric. Net effect: any host with network reach to UDP 12346 on the controller can become a privileged operator of the entire SD-WAN deployment.

Technical Analysis

The SD-WAN controller exposes a small, well-defined attack surface on the network: OpenSSH on TCP 22, NETCONF-over-SSH on TCP 830, and the vdaemon DTLS control plane on UDP 12346. The first two are authentication-gated; the third is the one that goes wrong here.

PortProtocolService
22TCPSSH (OpenSSH)
830TCPNETCONF over SSH
12346UDPvdaemon DTLS control plane
External attack surface of the SD-WAN controller. Source: original article.

UDP 12346 carries inter-controller peering: OMP routing updates, control-plane peer state, and the handshake by which a new device is admitted as a recognised peer. The peering protocol is multi-phase. After a DTLS handshake (during which the certificate is parsed but, per the writeup, errors are logged and the connection continues), the controller sends a CHALLENGE message containing 256 random bytes. The peer responds with a CHALLENGE_ACK that the controller is supposed to verify against the peer’s claimed device type. The controller then sends CHALLENGE_ACK_ACK, the peer sends Hello, and the peer transitions to UP — an active member of the SD-WAN control plane.

Attacker                                    vSmart
   |                                           |
   |──── DTLS Handshake (any cert) ───────────>|  ← cert verify logs error but returns OK
   |                                           |
   |<──── CHALLENGE (msg_type=8) ──────────────│  ← 256 random bytes + TLVs
   |                                           |
   |──── CHALLENGE_ACK (msg_type=9) ──────────>|  ← device_type=2 (vHub) → NO VERIFICATION
   |                                           |
   |<──── CHALLENGE_ACK_ACK (msg_type=10) ─────│  ← peer->authenticated = 1
   |                                           |
   |──── Hello (msg_type=5) ──────────────────>|  ← passes auth check, peer goes UP
   |                                           |
   |<──── Hello (msg_type=5) ──────────────────│  ← peer-type:vhub, new-state:up

The vdaemon wire format is a 12-byte header followed by the message-specific payload. The first byte’s low nibble identifies the message type (CHALLENGE, CHALLENGE_ACK, Hello, etc.); the second byte’s high nibble carries the claimed device type, which is the field at the centre of this vulnerability.

Byte offsetByte sizeFieldNotes
01msg_typeLow nibble = type, high nibble = version
11device_infoHigh nibble = device_type, low nibble = flags
21flagsStandard value of 0xA0
31paddingAlways 0x00
4–74domain_idBig-endian uint32
8–114site_idBig-endian uint32
The 12-byte vdaemon protocol header. Source: original article.
ValueDevice typeRole
1vEdgeData-plane router
2vHubHub router
3vSmartControl-plane controller
4vBondOrchestrator (trust anchor)
5vManageManagement plane
6ZTPZero-touch provisioning
Catalyst SD-WAN device-type encoding. Source: original article.

The vulnerability is in vbond_proc_challenge_ack(), the function that processes the CHALLENGE_ACK message and decides whether to mark the peer as authenticated. The function uses a chain of if statements keyed on device_type; each branch performs the verification appropriate to that type. The decompilation below makes the structure obvious — and the gap obvious too.

// vdaemon!vbond_proc_challenge_ack()
// After extracting serial number from peer certificate via
// X509_get_serialNumber() / ASN1_INTEGER_to_BN() / BN_bn2hex()

// ...snip...

if ( *(_DWORD *)(a3 + 8) == 3 || *(_DWORD *)(a3 + 8) == 5 ) // <--- [1]
{
// vSmart (type 3) or vManage (type 5): Certificate chain verification
v24 = is_serial_duplicate(v22, *(_DWORD *)(a3 + 8), ...);
if ( v24 )
    {
if ( (unsigned __int8)vbond_peer_dup_check(a1, a2, v24, ...) ) // <--- [2]
{
            v19 = 36;  // ERR: Duplicate Serial
goto LABEL_179;  // REJECT
}
    }
}
// ...snip...

// Second verification block - additional cert & state checks
if ( *(_DWORD *)(a3 + 8) == 3 && *(_DWORD *)(a1 + 8) == 3 // <--- [3]
|| *(_DWORD *)(a3 + 8) == 5 && *(_DWORD *)(a1 + 8) == 3
|| *(_DWORD *)(a3 + 8) == 5 && *(_DWORD *)(a1 + 8) == 5
|| *(_DWORD *)(a3 + 8) == 5 && *(_DWORD *)(a1 + 8) == 4
|| *(_DWORD *)(a3 + 8) == 3 && *(_DWORD *)(a1 + 8) == 4 )
{
    v19 = vdaemon_dtls_verify_peer_cert(a2);  // Full certificate verification
if ( v19 )
        v18 = 0;
    vdaemon_send_challenge_ack_ack(a1, *(_QWORD *)(a2 + 1232), a2, v18);
if ( v18 != 1 )
goto LABEL_179;  // REJECT on verification failure
vbond_send_ssh_keys_to_vmanage_peer(a1, a2);
}

if ( *(_DWORD *)(a3 + 8) == 1 // <--- [4]
&& (dword_2A1A28 == 4 || dword_2A1A28 == 3 || dword_2A1A28 == 5) )
{
// vEdge (type 1): Hardware/virtual edge certificate verification
    // ... challenge signature, board ID, OTP verification ...
if ( vdaemon_verify_peer_bidcert(a2, ...) )
goto LABEL_179;  // REJECT on failure
}

// *** NO CODE PATH FOR device_type == 2 (vHub) *** // <--- [5]

*(_BYTE *)(a2 + 70) = 1;   // peer->authenticated = true // <--- [6]
return 0LL;                // Success

The pattern is clean: each device class has its own verification branch, but vHub (type 2) has none. Whether by deliberate “vHubs are trust-anchored elsewhere” logic or by a missing else-branch, the practical effect at runtime is that a CHALLENGE_ACK declaring device_type = 2 skips every guard and falls through to the unconditional peer->authenticated = 1 at marker [6].

Device typeValueVerificationResult
vEdge1HW cert, challenge signature, board ID, OTPVerified
vHub2NoneFalls through to peer->authenticated = 1
vSmart3Cert chain, serial lookup, duplicate checkVerified
vBond4N/A (trust anchor — handled elsewhere)
vManage5Cert chain, serial lookup, duplicate checkVerified
Verification coverage by claimed device type. Source: original article.

The next question is whether the attacker can reach vbond_proc_challenge_ack() without being authenticated already. The dispatch gate inside vbond_proc_msg() explicitly allows the CHALLENGE family of messages (and Hello, Data, TEAR_DOWN, a few more) on a peer whose authenticated flag is still 0 — precisely because those messages are how the peer becomes authenticated.

// vdaemon!vbond_proc_msg()
// Pre-dispatch authentication gate:

if ( *(_BYTE *)(v100 + 70) != 1 // <--- [1]
&& *(_DWORD *)(a3 + 4) != 5      // msg != Hello
&& *(_DWORD *)(a3 + 4) != 8      // msg != CHALLENGE
&& *(_DWORD *)(a3 + 4) != 9      // msg != CHALLENGE_ACK
&& *(_DWORD *)(a3 + 4)           // msg != NEW_CHALLENGE_ACK
&& *(_DWORD *)(a3 + 4) != 10     // msg != CHALLENGE_ACK_ACK
&& *(_DWORD *)(a3 + 4) != 7      // msg != Data
&& *(_DWORD *)(a3 + 4) != 11     // msg != TEAR_DOWN
  // ...snip...
)
{
// ...snip...
    // "Received an unexpected message from an un-authenticated device"
return 20;
}

Hello is also in that allowlist, but Hello itself has a secondary check inside its handler: after a CHALLENGE_ACK_ACK has been processed, the Hello handler verifies that peer->authenticated is 1 before transitioning the peer to UP. So the sequence the attacker needs is exactly the natural one: CHALLENGE_ACK to flip the flag, then Hello to advance the peer state machine.

// Case 5 (Hello) in vbond_proc_msg - line 20362
case 5:
// ...snip...
if ( *(_BYTE *)(v100 + 70) != 1 ) // <--- [2]
{
// "Received an unexpected HELLO from un-authenticated device"
        // ... cleanup and reject ...
return 0LL;
    }
// Process Hello normally - peer transitions to UP

Once the peer is UP, the attacker has access to the messages the dispatcher gates behind authentication. The most useful of those is MSG_VMANAGE_TO_PEER (message type 14), the channel by which vManage automates peer configuration. Its handler, vbond_proc_vmanage_to_peer(), opens /home/vmanage-admin/.ssh/authorized_keys for append and writes the supplied key buffer with fputs() — no sanitisation, no per-call authorisation, no rate limit.

// vdaemon!vbond_proc_vmanage_to_peer()

// ...snip...

stream = fopen("/home/vmanage-admin/.ssh/authorized_keys", "a+"); // <--- [1]
if ( stream )
  {
if ( (unsigned __int8)read_key_data((const char *)(a3 + 32), stream) != 1 && *(_BYTE *)(a3 + 32) )
    {
if ( dword_241120 > 6 )
        syslog(
191,
"%s[%d]: %%%s-%d: sshkey not present, writing to file",
"vbond_proc_vmanage_to_peer",
2368LL,
          aVdaemonDbgMisc,
7LL);
      fputs((const char *)(a3 + 32), stream); // <--- [2]
}
    fclose(stream);
  }

// ...snip...

The on-the-wire MSG_VMANAGE_TO_PEER body is laid out as 768 bytes of key buffer followed by a one-byte TLV count of 0; the key buffer itself is wrapped in a leading newline, the literal SSH public-key bytes, a trailing newline, a null terminator, and zero padding to the end of the field.

OffsetSizeField
0–767768Key buffer ("n" + ssh_pubkey + "n" + "x00" + zero padding)
7681TLV count = 0
The MSG_VMANAGE_TO_PEER body layout used for SSH-key injection. Source: original article.

Exploitation

Rapid7 published a Metasploit auxiliary module — auxiliary/admin/networking/cisco_sdwan_vhub_auth_bypass — that performs the bypass end-to-end against a target Catalyst SD-WAN Controller. The walk-through in the advisory targets v20.12.6.1 running at 192.168.80.11 from an attacker at 192.168.80.130.

Metasploit module options for cisco_sdwan_vhub_auth_bypass
Figure 1: Metasploit module options for cisco_sdwan_vhub_auth_bypass. Source: original article.
msf6 auxiliary(admin/networking/cisco_sdwan_vhub_auth_bypass) > set RHOSTS 192.168.80.11
msf6 auxiliary(admin/networking/cisco_sdwan_vhub_auth_bypass) > run

The module generates an RSA key-pair on the fly, walks the DTLS-handshake-into-CHALLENGE_ACK-with-device_type=2 path to flip peer->authenticated to 1, sends a Hello to bring the peer UP, then issues a MSG_VMANAGE_TO_PEER request carrying the attacker’s public key. The private key is dropped into the Metasploit loot directory.

Metasploit module output showing the vHub authentication bypass and SSH key injection
Figure 2: Module output showing the vHub authentication bypass and SSH key injection. Source: original article.

With the injected key in vmanage-admin’s authorized_keys, a standard SSH client connects to the NETCONF-over-SSH service on TCP 830:

ssh -i /home/cryptocat/.msf4/loot/20260501115947_default_192.168.80.11_cisco.sdwan.sshk_491665.pem [email protected] -p 830
Successful SSH connection to the NETCONF service as vmanage-admin
Figure 3: Successful SSH connection to the NETCONF service as vmanage-admin. Source: original article.

From the NETCONF session, a textbook <get-config> RPC pulls the controller’s running configuration. At this point the attacker has authoritative configuration control over the SD-WAN fabric.

<?xml version="1.0" encoding="UTF-8"?><hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><capabilities><capability>urn:ietf:params:netconf:base:1.0</capability></capabilities></hello>]]>]]><rpc message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><get-config><source><running/></source></get-config></rpc>]]>]]>
NETCONF get-config output from the compromised Cisco Catalyst SD-WAN Controller
Figure 4: NETCONF get-config output from the compromised controller. Source: original article.

Remediation

Cisco has released fixed software for every supported release branch; there is no workaround. Upgrade to the relevant first-fixed release for your branch:

Cisco Catalyst SD-WAN releaseFirst fixed release
Earlier than 20.9*Migrate to a fixed release
20.920.9.9.1
20.1020.12.7.1
20.11*20.12.7.1
20.1220.12.5.4, 20.12.6.2, 20.12.7.1
20.13*20.15.5.2
20.14*20.15.5.2
20.1520.15.4.4, 20.15.5.2
20.16*20.18.2.2
20.1820.18.2.2
26.1.126.1.1.1
* These releases have reached end of software maintenance. Source: Cisco advisory, reproduced from the original article.

Vendor Statement

Cisco values the role of the security research community in helping maintain a secure ecosystem and we appreciate the collaboration with Rapid7. We have released a software update to remediate the identified vulnerability. We remain committed to transparent communication and to providing our customers with the robust security and resilience they expect.

Cisco, via the Rapid7 advisory

Credit

CVE-2026-20182 was discovered and reported by Stephen Fewer (Senior Principal Security Researcher) and Jonah Burgess (Senior Security Researcher) at Rapid7, and disclosed in accordance with Rapid7’s vulnerability disclosure policy.

Disclosure Timeline

DateEvent
2026-03-09Initial Rapid7 outreach to Cisco; technical writeup & exploit code disclosed.
2026-03-11Cisco confirms receipt; suggests May 7, 2026 disclosure date.
2026-03-20Cisco confirms findings; CVE will be reserved.
2026-04-21Cisco provides CVE identifier & remediation guidance.
2026-04-24Cisco provides fix versions, CWE/CVSS alignment, requests May 14 disclosure date.
2026-05-14Public disclosure (this advisory).
2026-05-15Metasploit module link added to the advisory.
Coordinated-disclosure timeline. Source: original article.

Key Takeaways

  • The vulnerability is structural: every other device type in vbond_proc_challenge_ack() has an explicit verification branch, and device_type = 2 (vHub) has none. Missing-else-branch bugs in trust-boundary state machines are a recurring class — not a Cisco-specific accident.
  • An unauthenticated remote attacker reaching UDP 12346 can become a fully authenticated SD-WAN peer with a single CHALLENGE_ACK and a single Hello. No race condition, no timing, no special token.
  • The post-auth primitive (MSG_VMANAGE_TO_PEER → raw fputs() append to /home/vmanage-admin/.ssh/authorized_keys) is itself an unsanitised write to a privileged credentials file. Once the auth gate falls, the rest of the chain is mechanical.
  • The pivot from the bypass to vmanage-admin NETCONF is a deliberate use of the controller’s own automation surface — the attacker becomes a vManage automation peer, not a shell user, and the SD-WAN fabric treats their RPCs as legitimate.
  • The vmanage-admin account is a high-privileged service identity, not a human admin role. Its presence on TCP 830 widens the blast radius far beyond a single controller box.
  • Public exploitation is one Metasploit module away. auxiliary/admin/networking/cisco_sdwan_vhub_auth_bypass drops the SSH key, returns the loot path, and connects you. Asset owners should assume opportunistic scanning.
  • Cisco fixed it; no workarounds. Patch state, not configuration state, is the only mitigation that matters for this bug.

Defensive Recommendations

  • Upgrade now. Move every Catalyst SD-WAN Controller to the first fixed release for its branch (table above). End-of-software-maintenance branches (20.11, 20.13, 20.14, 20.16, and anything earlier than 20.9) need a migration, not a patch.
  • Restrict UDP 12346 reachability. The controller’s vdaemon DTLS port should only be reachable from the legitimate inter-controller peer set. Audit the upstream ACLs / security-zone policies; treat any host outside that set that can reach UDP 12346 as a CVE-2026-20182 exposure.
  • Audit /home/vmanage-admin/.ssh/authorized_keys. Inspect the file on every controller you operate. Any key whose fingerprint you do not recognise should be treated as an injection IoC. Capture the file before patching and again after.
  • Hunt for NETCONF sessions on TCP 830 by source IP. Legitimate NETCONF traffic should come from a small, well-known set of vManage hosts. Any TCP 830 session originating outside that set is high-fidelity.
  • Watch vdaemon syslog for the “sshkey not present, writing to file” message. That string is emitted by vbond_proc_vmanage_to_peer() at debug level 7 immediately before the SSH-key write. It is a high-signal detection if you can elevate logging in the rollout window.
  • Treat any peer-type:vhub, new-state:up log entry on a controller as suspect. A vHub coming online unexpectedly — especially from a peer IP not in your topology — is the exact UP-transition fingerprint of the exploit chain.
  • Rotate vmanage-admin credentials and SSH host keys after patching. Treat any controller that was on a vulnerable build as potentially keyed by a third party; a post-patch SSH-key inventory + rotation pass closes that loop.
  • Add Rapid7 InsightVM / Nexpose authenticated check. If you operate one of those products, the May 14, 2026 content release ships an authenticated check for CVE-2026-20182 — turn it on and confirm clean across the fleet before declaring the rollout done.

Conclusion

CVE-2026-20182 is the rarer kind of network-protocol bug: it is not a parser overflow, a heap corruption, or a chained logic flaw — it is a single missing branch in a per-device-type verification ladder, sitting at the front of the SD-WAN control plane’s authentication state machine, and the consequences cascade all the way to NETCONF-over-SSH control of the entire fabric. The structural lesson is one network engineers know well: if your auth ladder enumerates device types, the “else” branch matters as much as the explicit ones. The operational lesson is shorter: upgrade now, audit authorized_keys on every controller, and assume any peer reachable from outside your trusted inter-controller set may have used the window. The canonical reference remains the Rapid7 advisory together with Cisco’s cisco-sa-sdwan-rpa2-v69WY2SW.

References

Original text: “CVE-2026-20182: Critical authentication bypass in Cisco Catalyst SD-WAN Controller (FIXED)” by Jonah Burgess & Stephen Fewer at Rapid7 (May 14, 2026).

Comments are closed.