← Back to Feed CACHED · 2026-09-23 16:47:50 · CACHE_KEY CVE-2026-28325
CVE-2026-28325 · CWE-502 · Disclosed 2026-09-22

SolarWinds Observability Self-Hosted was found to be affected by an unauthenticated remote code execution…

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

Someone left the back door to the security-camera control room unlocked, but you have to be inside the building to reach it

CVE-2026-28325 is an unauthenticated remote code execution flaw in SolarWinds Observability Self-Hosted (all versions before 2026.2.3) caused by classic CWE-502 deserialization of untrusted data. The vulnerability lives in the WPM (Web Performance Monitor) passive-player communication channel — specifically port 17781, used when WPM players operate in server-initiated (passive) mode. An attacker on the adjacent network can send a crafted serialized payload to this listener and achieve code execution as the SolarWinds service account, with no authentication required. The companion flaw CVE-2026-28324 (CVSS 9.8) addresses a related insufficient-integrity-check issue in a separate non-default configuration. Both were reported by Kai Huang of Armadin and patched on 2026-09-22.

SolarWinds rates this HIGH at 8.8, and the CVSS vector is honest: AV:A correctly reflects adjacent-network-only reachability, which is a significant constraint. However, the vector uses AC:L despite the exploit requiring a *specific non-default communication mode* (passive WPM players) — CVSS 3.1 doesn't model configuration prerequisites well, so the 8.8 slightly overstates real-world likelihood. That said, SolarWinds Observability is a monitoring platform that stores polling credentials (SNMP, WMI, SSH, SQL) for potentially every managed device on the network; compromising it gives an attacker a credential vault and a topology map of the entire environment. The post-SUNBURST world means SolarWinds compromise carries outsized reputational and operational blast radius. The vendor severity is directionally correct but numerically generous by about one point.

"Adjacent-network deser RCE in SolarWinds monitoring — config-gated but blast radius is fleet credentials"
02 · The Attack Path

5 steps from start to impact.

STEP 01

Adjacent network position

The attacker must be on the same Layer 2 segment or VLAN as the SolarWinds Observability server or a network path that can reach port 17781. The CVSS vector specifies AV:A, meaning this is not exploitable from the public internet. In practice this means a compromised workstation, VPN foothold, or rogue device on the management VLAN.
Conditions required:
  • Adjacent network access to the SolarWinds server or its polling engine
Where this breaks in practice:
  • Requires prior compromise or physical access to the management network
  • Most enterprises isolate monitoring infrastructure on a dedicated management VLAN with ACLs
Detection/coverage: Network IDS rules monitoring for anomalous traffic to port 17781; VLAN segmentation audit via NAC logs
STEP 02

Identify passive WPM player listener

The attacker scans for TCP port 17781 on the SolarWinds server or Additional Polling Engines (APEs). This port is only open when WPM passive players are configured in server-initiated mode. If the deployment uses player-initiated (active) mode on port 17782, this attack surface does not exist. A simple nmap -p 17781 reveals the target.
Conditions required:
  • WPM module installed and at least one passive player configured in server-initiated mode
Where this breaks in practice:
  • Passive mode is not universally adopted — player-initiated mode is recommended for distributed/MSP deployments
  • Deployments without WPM module are not affected at all
Detection/coverage: Asset inventory should flag port 17781 listeners; Nessus plugin or Qualys QID for SolarWinds version detection
STEP 03

Craft deserialization payload

The attacker constructs a malicious serialized object targeting the .NET deserialization endpoint exposed on the passive-player communication channel. .NET deserialization gadgets (e.g., via ysoserial.net) are well-documented. The payload is sent directly to port 17781 without any authentication handshake. No public PoC exists for this specific CVE as of 2026-09-24, but the underlying technique is commodity-grade for anyone familiar with .NET deser exploitation.
Conditions required:
  • Knowledge of the deserialization format used by the WPM passive channel
  • No public PoC yet — attacker must develop or reverse-engineer the protocol
Where this breaks in practice:
  • No public PoC or exploit code available as of 2026-09-24
  • Protocol-specific serialization format requires reverse engineering of the SolarWinds binary
Detection/coverage: Application-layer inspection for known .NET deserialization gadget signatures; Sysmon Event ID 1 for suspicious child processes of the SolarWinds service
STEP 04

Code execution as SolarWinds service account

Successful deserialization executes attacker-controlled code in the context of the SolarWinds Platform service account. This account typically runs as NT AUTHORITY\SYSTEM or a high-privilege service account with access to the SolarWinds configuration database, credential store, and the ability to communicate with all managed nodes via polling protocols (SNMP, WMI, SSH, SQL).
Conditions required:
  • Successful delivery of the deserialization payload to the vulnerable endpoint
Where this breaks in practice:
  • EDR on the SolarWinds server should detect anomalous process creation from the SolarWinds service
  • Application whitelisting would block unexpected binaries
Detection/coverage: EDR behavioral detection for process injection or LOLBin execution from SolarWinds service; Windows Event Log 4688 for new process creation under the service account
STEP 05

Credential harvesting and lateral movement

The SolarWinds Observability database contains stored credentials for every monitored node — SNMP community strings, WMI domain accounts, SSH keys, and database connection strings. The attacker extracts these credentials from the SolarWinds configuration database (typically MSSQL) and uses them to pivot across the entire monitored infrastructure. This is the blast-radius multiplier that elevates this from a single-host compromise to a potential fleet-wide event.
Conditions required:
  • Access to the SolarWinds configuration database
  • Stored credentials not externally vaulted
Where this breaks in practice:
  • Organizations using external credential vaults (CyberArk, HashiCorp Vault) limit stored secrets
  • Network segmentation between the monitoring tier and production tiers
Detection/coverage: Database audit logging on the SolarWinds MSSQL instance; PAM alerting on credential access anomalies
03 · Intelligence Metadata

The supporting signals.

In-the-Wild ExploitationNone observed. Not listed on CISA KEV. No campaigns or threat actor attribution as of 2026-09-24. CISA SSVC marks the companion CVE-2026-28324 as 'automatable' but does not flag CVE-2026-28325 the same way.
Proof-of-ConceptNo public PoC. No exploit code found on GitHub, Exploit-DB, or researcher blogs. The underlying technique (.NET deserialization via ysoserial.net) is well-known, but the protocol-specific payload for WPM passive-player communication has not been published.
EPSS Score0.01518 (1.518%) — 27th percentile. Indicates low predicted exploitation probability in the next 30 days.
KEV StatusNot listed. As of 2026-09-24, CVE-2026-28325 is not on the CISA Known Exploited Vulnerabilities catalog.
CVSS VectorCVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H — Adjacent network vector is the key constraint. Full CIA impact but scope unchanged. The AC:L is debatable given the config prerequisite.
Affected VersionsAll SolarWinds Observability Self-Hosted versions prior to 2026.2.3. End-of-support versions (2024.2 and earlier) will not receive fixes.
Fixed Version2026.2.3 (released 2026-09-22). The patch migrates default passive WPM players to player-initiated (active) communication and generates strong random passwords for remotely installed passive players.
Scanning / ExposureNo GreyNoise or Shodan data specific to port 17781 scanning. The WPM passive-player port is an internal service not typically exposed to the internet. SolarWinds Observability Self-Hosted ranks 2nd of 53 in the infrastructure monitoring category per 6sense/FitGap, with significant enterprise installed base.
Disclosure Date2026-09-22 — coordinated disclosure via SolarWinds security advisory alongside CVE-2026-28324.
ReporterKai Huang of Armadin — reported both CVE-2026-28324 and CVE-2026-28325 through responsible disclosure.

Sources.

  1. GBHackers — SolarWinds Observability Flaws Let Unauthenticated Attackers Execute Remote Code
  2. SecurityOnline — SolarWinds Observability Vulnerabilities Patched
  3. Mallory.ai — SolarWinds Observability Self-Hosted Patches Critical Unauthenticated RCE
  4. OffSeq Threat Radar — CVE-2026-28325 Live Threat Intelligence
  5. Strix.ai — CVE-2026-28325 Detail
  6. SolarWinds Documentation — WPM Player Communication Settings
  7. SolarWinds Documentation — Agent Communication Modes
  8. SolarWinds — Observability Self-Hosted 2026.2 Release Notes
04 · The Call

Final Verdict
= UNCHANGED to HIGH (7.5/10)

Why this verdict

  • Adjacent-network constraint already priced in, but config gate is not. The CVSS vector correctly uses AV:A, but AC:L does not account for the prerequisite that passive WPM player communication mode must be enabled — a specific, non-universal configuration. This shaves ~1 point off the vendor's 8.8.
  • No PoC, no exploitation, low EPSS. At 1.5% EPSS with zero public exploit code and no KEV listing, the near-term weaponization risk is low. An attacker would need to reverse-engineer the WPM passive-player protocol to build a working exploit.
  • Post-initial-access positioning required. AV:A implies the attacker is already inside the network perimeter — this is a second-stage exploit, not an initial-access vector. The attacker needs a prior foothold on the management VLAN.
  • Management VLAN segmentation is common friction. Enterprise SolarWinds deployments are typically isolated on management VLANs with restricted access. The adjacent-network requirement further narrows the reachable population.
  • Role multiplier: SolarWinds Observability is canonically a high-value monitoring platform. ≥80% of installs ARE the production monitoring instance. Compromise yields stored polling credentials (SNMP, WMI, SSH, SQL) for the entire monitored fleet — blast radius is host → fleet. This is analogous to SIEM/detection-plane compromise. The credential-store pivot makes this a domain/fleet-scale outcome when the chain lands. Verdict floor: HIGH. The chain does succeed in the high-value role with fleet-scale blast radius, but AV:A + config gate + no PoC keep it at the floor rather than pushing to CRITICAL.

Why not higher?

CRITICAL would require either internet-reachable attack surface or active exploitation. This CVE has neither — AV:A confines it to adjacent-network attackers, the passive WPM player mode is a non-universal configuration prerequisite, and there is zero evidence of weaponization. The companion CVE-2026-28324 at 9.8 is the more dangerous of the pair and may warrant separate assessment.

Why not lower?

SolarWinds Observability is a canonical high-value target that stores credentials for the entire monitored infrastructure. Compromise of this platform is not a single-host event — it is a fleet-credential-harvesting event analogous to domain controller compromise. The .NET deserialization primitive is commodity-grade even without a public PoC, and the SUNBURST precedent demonstrates that SolarWinds platforms are actively targeted by sophisticated adversaries. Dropping below HIGH would ignore the blast-radius floor.

05 · Compensating Control

1
Switch all WPM players to player-initiated (active) communication immediately — This eliminates the vulnerable passive-player listener on port 17781 entirely. Navigate to Settings > All Settings > WPM Settings > Manage Player Locations and switch each passive player to active mode. This is the single most effective compensating control and should be deployed within the noisgate mitigation SLA of 30 days for HIGH severity — but given the simplicity, do it this week.
2
Block port 17781 at the host firewall and network ACLs — If you cannot immediately switch communication modes, block inbound TCP 17781 on the SolarWinds server's Windows Firewall and on upstream switch/firewall ACLs. This prevents exploitation even if the passive player service remains running. Deploy within 30 days per the noisgate mitigation SLA.
3
Isolate SolarWinds on a dedicated management VLAN with strict ACLs — If not already segmented, move SolarWinds Observability to a management VLAN accessible only from jump hosts and authorized admin workstations. This reduces the adjacent-network attack surface to near-zero. This is a best practice that should already be in place.
4
Upgrade to SolarWinds Observability Self-Hosted 2026.2.3 — Apply the vendor patch which fixes the deserialization flaw and automatically migrates passive WPM players to active communication. Deploy within the noisgate remediation SLA of 180 days for HIGH severity. Prioritize if you have passive WPM players configured.
5
Audit stored credentials in SolarWinds and rotate them — Review all polling credentials stored in the SolarWinds configuration database. Where possible, migrate to external credential vaults (CyberArk, HashiCorp Vault) to limit blast radius if the monitoring platform is ever compromised. Rotate any shared or high-privilege credentials.
6
Enable EDR monitoring on the SolarWinds server — Ensure your EDR agent is active on all SolarWinds servers and APEs with behavioral detection rules for anomalous child processes spawned by the SolarWinds service (e.g., cmd.exe, powershell.exe, certutil.exe spawned by SolarWinds.BusinessLayerHost.exe).
What doesn't work
  • WAF / reverse proxy in front of SolarWinds — this vulnerability is on port 17781 (WPM passive-player protocol), not the web console. A WAF protecting the SolarWinds web UI on port 443 does not intercept traffic to the WPM communication channel.
  • Upgrading WPM players only without upgrading the main server — the deserialization flaw is in the server-side handler that processes incoming data from passive players. Upgrading only the remote WPM player agents does not fix the vulnerable endpoint.
  • Network-level IPS with generic deserialization signatures — .NET BinaryFormatter deserialization payloads are highly polymorphic and protocol-wrapped; generic IPS signatures have poor detection rates for custom serialization protocols like the WPM passive channel.
06 · Verification

Crowdsourced verification payload.

Run this script on each SolarWinds Observability Self-Hosted server and Additional Polling Engine (APE) as a local administrator. Invoke with: powershell -ExecutionPolicy Bypass -File .\Check-CVE-2026-28325.ps1. The script checks the installed product version and whether the vulnerable WPM passive-player listener is active on port 17781.

noisgate-verify.ps1
POWERSHELLREAD-ONLYSAFE
#Requires -RunAsAdministrator
<#
  Check-CVE-2026-28325.ps1
  Checks SolarWinds Observability Self-Hosted for CVE-2026-28325 exposure.
  Outputs: VULNERABLE / PATCHED / UNKNOWN
  Exit codes: 1 = VULNERABLE, 0 = PATCHED, 2 = UNKNOWN
#>

$ErrorActionPreference = 'SilentlyContinue'
$status = 'UNKNOWN'
$reasons = @()

# Step 1: Detect SolarWinds installation and version
$swRegPaths = @(
    'HKLM:\SOFTWARE\SolarWinds\Orion\Core',
    'HKLM:\SOFTWARE\WOW6432Node\SolarWinds\Orion\Core'
)
$installedVersion = $null
foreach ($p in $swRegPaths) {
    $reg = Get-ItemProperty -Path $p -ErrorAction SilentlyContinue
    if ($reg -and $reg.Version) {
        $installedVersion = $reg.Version
        break
    }
}

if (-not $installedVersion) {
    # Fallback: check for SolarWinds services
    $swService = Get-Service -Name 'SolarWinds*' -ErrorAction SilentlyContinue | Select-Object -First 1
    if (-not $swService) {
        Write-Host '[*] SolarWinds Observability Self-Hosted does not appear to be installed.'
        Write-Host 'PATCHED'
        exit 0
    }
    $reasons += 'Could not determine installed version from registry'
}

# Step 2: Check if WPM passive player listener is active on port 17781
$port17781 = Get-NetTCPConnection -LocalPort 17781 -State Listen -ErrorAction SilentlyContinue
$passivePlayerActive = $false
if ($port17781) {
    $passivePlayerActive = $true
    $reasons += 'WPM passive-player listener ACTIVE on port 17781 (vulnerable communication mode)'
} else {
    $reasons += 'Port 17781 not listening (passive WPM player mode not active)'
}

# Step 3: Version comparison
$fixedVersion = '2026.2.3'
if ($installedVersion) {
    $reasons += "Installed version: $installedVersion"
    # Normalize version for comparison (handle YYYY.M.P format)
    try {
        $installed = [version]($installedVersion -replace '^(\d{4})\.(\d+)\.(\d+).*', '$1.$2.$3')
        $fixed = [version]$fixedVersion
        if ($installed -ge $fixed) {
            $status = 'PATCHED'
            $reasons += "Version $installedVersion >= $fixedVersion (patched)"
        } else {
            $status = 'VULNERABLE'
            $reasons += "Version $installedVersion < $fixedVersion (unpatched)"
        }
    } catch {
        $reasons += "Could not parse version string: $installedVersion"
        if ($passivePlayerActive) {
            $status = 'VULNERABLE'
        } else {
            $status = 'UNKNOWN'
        }
    }
} else {
    # No version found but SolarWinds services exist
    if ($passivePlayerActive) {
        $status = 'VULNERABLE'
        $reasons += 'Cannot confirm version but vulnerable communication mode is active'
    } else {
        $status = 'UNKNOWN'
        $reasons += 'Cannot confirm version; passive player mode not active (reduced risk)'
    }
}

# Step 4: Additional context — check if patched behavior is present
if ($status -eq 'PATCHED' -and $passivePlayerActive) {
    $reasons += 'WARNING: Patched version detected but port 17781 still listening — verify WPM player migration completed'
    $status = 'VULNERABLE'
}

Write-Host ''
Write-Host '=== CVE-2026-28325 Check ===' 
Write-Host "Result: $status"
foreach ($r in $reasons) { Write-Host "  - $r" }
Write-Host ''
Write-Host $status

switch ($status) {
    'VULNERABLE' { exit 1 }
    'PATCHED'    { exit 0 }
    default      { exit 2 }
}
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously