Like leaving the control-room door propped open — but only if someone changed the lock from the factory default
CVE-2026-28324 is an unauthenticated remote code execution flaw in SolarWinds Observability Self-Hosted (formerly Hybrid Cloud Observability) versions prior to 2026.2.3. The root cause is CWE-345 — insufficient verification of data authenticity — in the Web Performance Monitor (WPM) player communication channel. When the WPM player is configured in passive mode (server-initiated connections on TCP port 17781, a *non-default* and *non-secure* setting), the platform fails to validate the integrity of inbound data, allowing an unauthenticated, network-adjacent attacker to deliver a crafted request that results in arbitrary code execution on the underlying host. The sibling flaw CVE-2026-28325 (CVSS 8.8) targets deserialization in the same communication path. Both were reported by Kai Huang of Armadin and patched on 2026-09-22.
SolarWinds rated this 9.8 CRITICAL, and the CVSS:3.1 vector (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H) reflects a zero-click, no-auth, full-impact chain — which is *technically accurate for the vulnerable configuration*. But the advisory itself qualifies the score: exploitation requires a non-default, non-secure configuration (passive WPM player mode). Default installations — and the now-recommended active-player mode — are not vulnerable. That qualifier, combined with the fact that SolarWinds Observability servers almost never expose WPM ports to the internet, means the real-world attack surface is meaningfully narrower than a blanket 9.8 implies. The vendor severity oversells the risk for most environments while remaining directionally correct for the subset running passive WPM players on reachable network segments.
5 steps from start to impact.
Identify SolarWinds Observability host with passive WPM
- Network reachability to TCP/17781 on the SolarWinds Observability server or polling engine
- Target must be running a version prior to 2026.2.3
- Port 17781 is not internet-facing in standard enterprise deployments
- Passive WPM player mode is non-default — many orgs use active mode or do not deploy WPM at all
Confirm non-default passive-mode configuration
- Passive WPM player mode must be enabled (non-default)
- Non-secure (non-TLS) communication must be configured
- Organizations following SolarWinds hardening guides would have TLS enabled
- The 2026.2.3 patch auto-migrates passive players to active mode, shrinking the window
Send crafted malformed request exploiting CWE-345
- Attacker must craft a payload that passes minimal parsing but bypasses integrity checks
- No authentication or credentials required
- No public PoC or exploit code is available as of 2026-09-23
- Exact serialization format and protocol specifics are not publicly documented
Achieve arbitrary code execution on the Observability server
- Successful delivery of the exploit payload in step 3
- EDR on the SolarWinds host should detect anomalous child-process creation under the service process
- Application allowlisting would block unexpected binaries
SolarWinds.BusinessLayerHost.exe or equivalent Linux daemon. Windows Event ID 4688 / Sysmon Event ID 1 for process creation.Pivot across monitored infrastructure
- Credentials stored in the SolarWinds configuration database
- Network ACLs permitting monitoring traffic from the compromised host
- Credential vaulting or just-in-time access for monitoring credentials would limit stored secrets
- Network microsegmentation limiting egress from the monitoring VLAN
The supporting signals.
| In-the-Wild Exploitation | None observed as of 2026-09-23. CISA SSVC classifies exploitation as *automatable* with *total* technical impact, but no campaigns or threat-actor TTP linkages have been reported. |
|---|---|
| Proof-of-Concept | No public PoC available. Kai Huang of Armadin reported the flaw via responsible disclosure. No exploit code on GitHub, ExploitDB, or Nuclei templates as of assessment date. |
| EPSS Score | Not yet scored — CVE was published 2026-09-22, EPSS models typically require 30+ days of signal. Expect moderate-to-high EPSS given SolarWinds' history as a target. |
| KEV Status | Not listed on CISA KEV as of 2026-09-23. Given no observed exploitation, KEV addition is not imminent but should be monitored. |
| CVSS Vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H — Network vector, low complexity, no privileges, no interaction. All impact metrics high. The vector does not encode the non-default configuration prerequisite. |
| Affected Versions | SolarWinds Observability Self-Hosted all versions prior to 2026.2.3, specifically when WPM passive player mode with non-secure communication is enabled. |
| Fixed Version | 2026.2.3 (released 2026-09-22). The patch auto-migrates default passive players to active mode and generates strong passwords for remotely installed passive players. |
| Internet Exposure | Minimal. Shodan and Censys show no meaningful fingerprint for TCP/17781 or TCP/17782. SolarWinds Observability servers are overwhelmingly deployed on internal networks behind corporate firewalls. |
| Researcher / Disclosure | Kai Huang, Armadin — coordinated disclosure via SolarWinds PSIRT. Companion CVE-2026-28325 (CVSS 8.8, insecure deserialization) was reported in the same engagement. |
| Vendor Advisory | SolarWinds Trust Center advisory published 2026-09-22. Canadian Centre for Cyber Security issued alert AV26-549 (covers broader SolarWinds advisories in this cycle). |
Why this verdict
- Non-default configuration prerequisite: The vulnerability only fires when WPM passive player mode with non-secure communication is enabled — a deliberate deviation from the default. This materially shrinks the vulnerable population. CVSS cannot encode this; real-world risk is lower than the 9.8 label.
- No internet exposure: SolarWinds Observability servers are internal monitoring infrastructure. TCP/17781 is not exposed to the internet in any standard deployment. The attacker needs internal network position, which implies post-initial-access or insider threat — compounding the chain.
- No exploitation or PoC: Zero days post-disclosure, no public exploit code, no observed campaigns, no KEV listing. The exploit requires reverse-engineering the WPM passive-mode protocol, which is undocumented. Time-to-weaponization is non-trivial.
- CISA SSVC automatable flag: The SSVC assessment that exploitation is *automatable* with *total* technical impact warrants caution — once a PoC drops, mass internal exploitation is feasible. This prevents a further downgrade to MEDIUM.
- Role multiplier: SolarWinds Observability Self-Hosted is canonically a monitoring/observability plane component. Every installation sits in a high-value role by definition: it holds credentials for monitored nodes (SNMP, WMI, SSH, SQL), has broad network ACLs, and its compromise blinds the SOC while enabling fleet-wide lateral movement. On the subset of installations running passive WPM mode (estimated 5–15% of the installed base — WPM is an optional module and passive mode is non-default), the chain succeeds with blast radius = fleet-scale credential theft + monitoring evasion. This floors the verdict at HIGH despite the configuration friction.
Why not higher?
The vulnerability cannot be CRITICAL because it requires a non-default, non-secure configuration that the vendor explicitly warns against. Default installations are not vulnerable. There is no internet-facing exposure, no public exploit, and no active exploitation. The 9.8 CVSS vector is technically accurate for the narrow vulnerable configuration but overstates real-world risk for the broader installed base. A CRITICAL rating would imply patch-everything-now urgency that is not warranted for the majority of deployments.
Why not lower?
The vulnerability cannot be MEDIUM or below because SolarWinds Observability is a high-value monitoring platform with stored credentials and fleet-wide network access. Unauthenticated RCE on this class of target — even with a non-default config prerequisite — yields domain-scale impact. The CISA SSVC *automatable* classification means that once exploit details emerge, internal scanning and exploitation will be trivial. The blast radius on affected installations is too severe to treat as routine.
What to do — in priority order.
- Immediately audit WPM player communication mode across all Observability installations — Query the SolarWinds configuration database or Web Console (Settings > All Settings > WPM Settings > Player Communication) to identify any players running in passive mode on port 17781. Any passive-mode player with non-secure (non-TLS) communication is the vulnerable configuration. This is your triage gate — if no passive players exist, the CVE does not apply. Complete within 30 days per noisgate mitigation SLA for HIGH.
- Switch passive WPM players to active mode immediately on confirmed-vulnerable hosts — In the SolarWinds Web Console, navigate to WPM Player settings and switch all passive players to active mode (player-initiated on port 17782 over HTTPS). This eliminates the attack surface without requiring the full platform upgrade. Deploy within 30 days per noisgate mitigation SLA.
- Block TCP/17781 inbound at host firewall and network segmentation layer — If you cannot immediately switch to active mode, create firewall rules restricting TCP/17781 to only the known SolarWinds polling engine IPs. Deny all other sources. This limits the attacker's ability to reach the vulnerable listener even from an internal pivot point.
- Upgrade to SolarWinds Observability Self-Hosted 2026.2.3 — The definitive fix. Version 2026.2.3 auto-migrates passive players to active mode and generates strong passwords for remote passive players. Apply within 180 days per noisgate remediation SLA for HIGH severity. Test in a non-production SolarWinds environment first — the migration changes player communication behavior.
- Rotate all credentials stored in SolarWinds Observability — If you confirmed passive WPM mode was active, treat stored monitoring credentials (SNMP community strings, WMI accounts, SSH keys, SQL connection strings) as potentially exposed. Rotate them after patching to close the post-compromise pivot path.
- Deploy EDR monitoring rules for SolarWinds service processes — Create detection rules for unexpected child processes under
SolarWinds.BusinessLayerHost.exe,SolarWinds.Collector.Service.exe, or equivalent Linux daemons. Alert oncmd.exe,powershell.exe,bash, orpythonspawning from these parents.
- WAF / reverse proxy in front of SolarWinds — The vulnerable port (17781) is a proprietary binary protocol, not HTTP. A web application firewall cannot inspect or filter this traffic.
- Patching only the SolarWinds server without updating WPM players — The vulnerability is in the server-side processing of passive-mode communication. Updating only remote WPM player agents does not remediate the server-side code path. The server itself must be upgraded to 2026.2.3.
- Network-level TLS inspection — While enabling TLS on the WPM channel may raise the bar, the CWE-345 flaw is about data authenticity verification, not transport encryption. TLS protects the channel but does not validate the *content* of what arrives. The vendor patch is required.
Crowdsourced verification payload.
Run this script on each SolarWinds Observability Self-Hosted server (polling engines and additional web servers) as a local administrator. Execute: powershell -ExecutionPolicy Bypass -File .\Check-CVE-2026-28324.ps1. The script checks the installed product version and queries the WPM player communication mode from the registry and configuration database.
#Requires -RunAsAdministrator
<#
Check-CVE-2026-28324.ps1
Checks whether this SolarWinds Observability Self-Hosted server is
vulnerable to CVE-2026-28324 (unauthenticated RCE via passive WPM player).
Output: VULNERABLE / PATCHED / UNKNOWN
Exit codes: 1 = VULNERABLE, 0 = PATCHED, 2 = UNKNOWN
#>
$ErrorActionPreference = 'Stop'
$result = 'UNKNOWN'
$exitCode = 2
try {
# Step 1: Check installed SolarWinds Observability version
$swRegPaths = @(
'HKLM:\SOFTWARE\SolarWinds\Orion',
'HKLM:\SOFTWARE\WOW6432Node\SolarWinds\Orion'
)
$installedVersion = $null
foreach ($p in $swRegPaths) {
if (Test-Path $p) {
$v = (Get-ItemProperty -Path $p -Name 'Version' -ErrorAction SilentlyContinue).Version
if ($v) { $installedVersion = $v; break }
}
}
if (-not $installedVersion) {
Write-Host '[!] SolarWinds Observability Self-Hosted not detected on this host.'
Write-Host 'UNKNOWN'
exit 2
}
Write-Host "[*] Detected SolarWinds version: $installedVersion"
# Step 2: Parse version and compare against 2026.2.3
$patchedVersion = [Version]'2026.2.3'
try {
$currentVersion = [Version]$installedVersion
} catch {
Write-Host "[!] Could not parse version string: $installedVersion"
Write-Host 'UNKNOWN'
exit 2
}
if ($currentVersion -ge $patchedVersion) {
Write-Host '[+] Version is >= 2026.2.3 (patched).'
$result = 'PATCHED'
$exitCode = 0
} else {
Write-Host '[-] Version is < 2026.2.3 (potentially vulnerable).'
# Step 3: Check if WPM module is installed
$wpmPath = Join-Path $env:ProgramFiles 'SolarWinds\Orion\WPM'
$wpmInstalled = Test-Path $wpmPath
if (-not $wpmInstalled) {
Write-Host '[+] WPM module not installed - CVE-2026-28324 does not apply.'
$result = 'PATCHED'
$exitCode = 0
} else {
Write-Host '[*] WPM module detected. Checking player communication mode...'
# Step 4: Check for passive mode listener on port 17781
$listener = Get-NetTCPConnection -LocalPort 17781 -State Listen -ErrorAction SilentlyContinue
if ($listener) {
Write-Host '[-] PASSIVE MODE DETECTED: TCP/17781 is listening.'
Write-Host '[-] This host is running the non-default vulnerable configuration.'
$result = 'VULNERABLE'
$exitCode = 1
} else {
Write-Host '[*] TCP/17781 not listening (passive mode not active).'
Write-Host '[*] Checking TCP/17782 for active mode...'
$activeListener = Get-NetTCPConnection -LocalPort 17782 -State Listen -ErrorAction SilentlyContinue
if ($activeListener) {
Write-Host '[+] Active mode (TCP/17782) detected - not vulnerable to this CVE.'
$result = 'PATCHED'
$exitCode = 0
} else {
Write-Host '[?] Neither passive (17781) nor active (17782) port detected.'
Write-Host '[?] WPM may be installed but not configured. Verify manually.'
$result = 'UNKNOWN'
$exitCode = 2
}
}
}
}
} catch {
Write-Host "[!] Error during check: $_"
$result = 'UNKNOWN'
$exitCode = 2
}
Write-Host ""
Write-Host "=== RESULT: $result ==="
exit $exitCode- SolarWinds Trust Center — CVE-2026-28324 Advisory
- SecurityOnline — SolarWinds Observability Vulnerabilities Enable RCE
- Mallory AI — SolarWinds Observability Self-Hosted Patches Critical Unauth RCE
- OffSeq Threat Radar — CVE-2026-28324 Live Intelligence
- Strix AI — CVE-2026-28324 Detail
- SolarWinds Documentation — WPM Player Communication Settings
- Canadian Centre for Cyber Security — SolarWinds Advisory AV26-549
- CVEDetails — SolarWinds Vulnerability List
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.