Master Key Included: Detecting SolarWinds ARM CVE-2026-28326

Master Key Included: Detecting SolarWinds ARM CVE-2026-28326

Share

TL;DR
Identity governance software decides who may open which file, mailbox, and account across a company, which makes any one of them a shortcut to all of it. This post is about a flaw that hands that position to anyone who can reach the server. 

CVE-2026-28326
is an unauthenticated RCE in SolarWinds Access Rights Manager, fixed in 2026.2.1.7. A client-authentication secret ships with the product, identical on every install, so reaching TCP 55555 is enough to hit a .NET deserialization sink. SolarWinds scored it 8.8 on a vector that assumes adjacent-network reach; check how far your 55555 is exposed. We confirmed execution as NT AUTHORITY\SYSTEM. Our detection tool determines whether an asset is vulnerable with two safe requests.

Summary

On September 17, 2026, SolarWinds released Access Rights Manager (ARM) 2026.2.1 with a fix for CVE-2026-28326. The release notes describe an unauthenticated remote code execution vulnerability whose “issue stems from a hardcoded static key,” rated 8.8 High on CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H. Credit for the original report goes to Kai Huang of Armadin. Bishop Fox staff came at it from the defender’s side, diffing the two builds and validating impact and detection against a lab of two ARM servers, one on each side of the fix.

We traced the root cause to a fallback authentication path on ARM’s gRPC listener, TCP port 55555. TLS does not protect it: the listener requests a client certificate without requiring one, leaving an application-layer check as the only control. The 8.8 severity assumes a network posture that nothing in the software enforces; on a flat network the same bug scores 9.8. The patch also changed a gRPC status code, which lets an anonymous caller read patch state without going near the vulnerability. Our detection tool sends two safe requests to determine whether an asset is vulnerable.

Defender Guidance

  • Patch to 2026.2.1.7 or later. Builds 2026.2.0.42 and earlier are affected. The fix deletes the fallback path rather than hardening it, so patching removes the vulnerability instead of leaving configuration to contain it.
  • Restrict TCP 55555 to ARM’s own components. The listener binds every interface, including IPv6, and SolarWinds’ own prerequisites tell administrators to open the port inbound. Read the rule you actually have rather than assuming the server is out of reach. “Internal” and “reachable only by ARM’s collectors and clients” are different statements; only the second is what the published score assumes. Tightening it bounds the exposure on anything you cannot patch today. See "How Exposed Is 55555?" for more detail.
  • Look for prior use before you patch, not after. The service restart that applies the patch wipes the evidence. Where the GrantMA service is deployed, an ARM administrator can read GET /api/armconfig/network/Connections and look for a record carrying IsAuthenticated: false next to a populated ClientCertThumbPrint, a pairing the vulnerable path produces and an ordinary client login does not. That list is memory-only and drops entries after three days, so a clean result proves little.

Background

Access Rights Manager is SolarWinds’ identity governance product, scanning and managing permissions across Active Directory, file servers, Exchange, and SharePoint, so it holds delegated rights over most of what an organization cares about. It runs as LocalSystem by default, meaning code execution inside it starts at the top of the host and reaches outward through the credentials the product was given on purpose.

The relevant surface is a gRPC listener on TCP 55555, documented by SolarWinds as an inbound requirement. gRPC is a remote procedure call framework running over HTTP/2, used here as the transport between ARM’s own components. On top of gRPC, ARM tunnels .NET Remoting messages whose contents are serialized with BinaryFormatter, two Microsoft technologies that have been obsolete for years.

ARM is the rebranded 8MAN product from protected-networks.com, and the lineage is visible throughout the install tree: older pn.* and lib* assemblies alongside newer SolarWinds.ARM.* code, a literal protected-networks.com\8MAN\ directory, German comments in the configuration files. That older half is where this bug lives. The lineage also explains why a 2026 product still carries Remoting and BinaryFormatter.

BinaryFormatter was obsoleted in .NET 5 and removed from .NET 9, and Microsoft’s own documentation says deserializing untrusted input with it cannot be made safe by any filter placed in front of it. Remoting was declared legacy years earlier and never left Framework. ARM targets Framework 4.8, where both remain supported and no switch turns BinaryFormatter off. Walking away is not simple either: replacing Remoting means rebuilding the transport every ARM component depends on. That constraint shapes the fix we come back to at the end.

We determined the root cause by decompiling both builds and diffing them. Of the 299 files that differ by hash between 2026.2.0.42 and 2026.2.1.7, only 19 first-party assemblies contain real code changes, three of which carry the security fix.

How the Bug Works

The gRPC listener authenticates callers with a client certificate. Unpatched builds also accept a fallback: a caller with no certificate can supply an HMAC token in a request header instead, keyed by a secret the product reads from its own configuration file.

Four design decisions compound here, each independently avoidable:

  1. A shipped shared secret is used as an authenticator. The key ships in the installer, identical on every deployment of that build and recoverable by anyone who can download the product. Nothing regenerates it at install time.
  2. The token authenticates only values the caller already controls. The HMAC covers a string built from two request fields, with no challenge, nonce, or binding to the channel or the request body. Anyone holding the key can mint a valid token offline.
  3. Nothing requires the caller to be local. ARM spawns short-lived local child processes with no certificate of their own, so they need a way to reach the local server. That was built with a shared secret and no locality check, on a listener bound to every interface. ARM’s one code path for rejecting remote callers does nothing on the server role, the only role that accepts them.
  4. Success grants a borrowed identity. Rather than minting a narrowly scoped “local task” principal, the path loads a registered client’s certificate from the server’s own store and adopts its thumbprint. Downstream authorization treats the caller as that client.

That last step has a precondition that is already satisfied. The code looks for a certificate file matching a pattern in ARM’s certificate directory; on a default install, with no client enrolled, one is already there. We verified this on a clean lab build, so an attacker has nothing to arrange in advance.

Past the gate, the connection reaches a duplex stream of .NET Remoting messages, deserialized by BinaryFormatter behind a filter that rejects type names matching 27 regular expressions covering publicly known gadget types. That is a denylist over an unbounded type space, applied to a sink that executes what it is given.

Why TLS Doesn’t Stop It

The listener runs over TLS and asks callers for a client certificate. Whether that amounts to a control depends on which of two gRPC options the code selects.

ARM configures the port to request a client certificate and verify it if one is presented. A caller that presents none still completes the handshake; requiring a certificate is a different option, one the code does not use here. So an attacker finishes TLS anonymously, the connection is marked unauthenticated, and the application layer interceptor becomes the only control standing. That interceptor is what the shipped key defeats.

The lesson generalizes past ARM — a service described as protected by mutual TLS may only be requesting client certificates rather than requiring them. The difference is one enum value in a configuration call, so check which of the two any such service actually passes.

How Exposed Is 55555?

How much this bug costs you depends on whether an attacker can reach the port at all, which is a firewall question rather than a software one. It is the assumption inside the published CVSS vector, so resolve it before triaging by the score.

ARM does not open the port itself. The Windows Firewall rule it creates for 55555 and the other component ports starts life disabled, set to block, and scoped to 127.0.0.1, becoming an allow rule only when an administrator configures one through the Configuration Wizard. The intended posture is an allowlist of known ARM components, close to what AV:A describes and a reasonable basis for the vendor’s 8.8.

Nothing in the software enforces that posture. The listener binds every interface, including IPv6; no part of the authentication path is subnet-aware, the third design defect above. Deciding who can reach the deserialization sink is left entirely to the firewall rule, whose contents are whatever an administrator put there, possibly years ago, possibly widened in a troubleshooting session nobody narrowed again. SolarWinds’ documented prerequisites instruct administrators to open 55555 inbound. ARM cannot reach remote collectors otherwise, so on any working multi-host deployment the port is open. The remaining variable is how widely.

Where the rule genuinely restricts 55555 to registered ARM components, an attacker needs a foothold inside that zone first, and 8.8 is the right number. That zone is not only servers. The wizard registers collector hosts alongside the machines running the ARM client console, which are ordinary administrator workstations, so a phished console operator is inside the allowlist without any server being touched. AV:A describes reachability, not difficulty.

A rule that admits any internal host, or a network flat enough that the distinction is academic, collapses adjacent reach into general reach, so the same bug scores 9.8 on AV:N. CVSS offers Modified Attack Vector for precisely this adjustment; make it deliberately rather than inheriting a base score built on an unverified firewall posture. On unpatched hosts, treat a permissive rule as an exposure finding in its own right.

Detecting It Safely

The fix changed something an anonymous caller can observe, giving a detection method that reads patch state from the server’s behavior rather than a version string.

Before the patch, every rejection path in the authentication gate returned gRPC 14, UNAVAILABLE. The replacement gate rejects with gRPC 16, UNAUTHENTICATED, and the message Client certificate not found. Please register your application first. Nothing else on that path returns 16, so two anonymous calls separate the builds:

Remoting/Send

GetCertificate

Build

Verdict

14 UNAVAILABLE

0 OK

2026.2.0.42 and earlier

VULNERABLE

16 UNAUTHENTICATED

any

2026.2.1.7 and later

PATCHED

14 UNAVAILABLE

14 UNAVAILABLE

either

INCONCLUSIVE

The second call confirms both that the endpoint is ARM and that it is in the server role, the only role that accepts external requests. A collector answers both probes identically on both builds, so it is reported as unknown rather than as patched. We validated both branches on the same machine, before and after an in-place upgrade.

Neither probe forges a token or touches the hardcoded key. Both carry a zero length gRPC message, so no serialized object enters the exchange.

A refused probe writes an informational line naming the peer and the reason, so expect your own scan in ARM’s log. An attack that succeeds is quieter than the scan that finds the hole: the gate returns early once it accepts the forged token, and ARM’s one warning for a remote connection is suppressed on the server role. Finding nothing in the log is weak evidence; the connection list in the guidance above is the better place to look.

The listener also resets any TLS connection that does not negotiate ALPN h2, the TLS extension where client and server agree on the protocol inside the tunnel (h2 is HTTP/2). A scanner that speaks TLS without it gets zero bytes back and reports the port as dead rather than as a gRPC service.

We built a working exploit chain and fired it against an unpatched lab server. It gave command execution as NT AUTHORITY\SYSTEM, confirmed out of band with an HTTP callback and a file dropped on the target. From an unauthenticated network position, reaching 55555 is enough.

The Patch

To address this vulnerability, the vendor fixed three assemblies. The gate is now rewritten rather than patched around.

The entire fallback authentication branch is deleted. In its place, a caller with no client certificate is accepted only when two conditions hold: the peer is localhost, and it presents a token matching one the server generated. That token is a fresh GUID created on every server start, never written to disk, and passed on the command line to the child processes the server launches itself.

Either condition would close the path on its own: localhost keeps a remote caller off it entirely, and a per-process random value leaves nothing to extract from an installer. Dropping the HMAC for a direct comparison is sound now that the token is a bearer credential scoped to localhost rather than a signature over data the caller chose.

The rejection also changed from a silent UNAVAILABLE to UNAUTHENTICATED with an actionable message, a small usability fix that happens to make remote patch-state detection possible.

Alongside the gate, the deserialization filter was hardened from denylist-only to an allowlist checked before a widened denylist. The client side code that computed the old HMAC was removed. One caveat belongs with that: the allowlist still admits everything under System., where most public gadgets live, so for that prefix the denylist is still the control doing the work.

The compromise is reasonable in context. Removing BinaryFormatter is not an option on .NET Framework, and rebuilding the remoting transport underneath every ARM component is a far larger project than a security release can carry. Faced with a sink they could not remove, SolarWinds shut the door in front of it. The gate rewrite ends this vulnerability quite effectively.

Conclusion

CVE-2026-28326 is an unauthenticated remote code execution vulnerability over a single TCP port, with no user interaction, against a product that runs as LocalSystem and holds delegated rights across most of the estate. Upgrade to 2026.2.1.7 or later and restrict TCP 55555 to the components that need it.

Impact does not vary with configuration. On an affected server build, anyone who can reach 55555 is past authentication and at the deserialization sink. Triage is therefore two separate questions. The first, whether the build is vulnerable, is answerable from outside in two safe requests; the second, how far 55555 is exposed, only by reading the firewall rule that governs it. An inconclusive result is not a clean one: a host your scan cannot reach may still be unpatched, and reachable from somewhere your scanner is not.

The more durable lesson is upstream of both. A local convenience became a remote authentication bypass because nothing in the code enforced the word “local,” and a mutual TLS configuration that requested certificates without requiring them left an application layer check as the only thing between an anonymous caller and a deserialization sink. Every step that got there was locally reasonable, which is why this combination is easy to build by accident.

Cosmos customers were notified about this vulnerability research shortly after the vendor advisory published. If you are interested in learning more about managed services delivered through our Cosmos platform, visit https://bishopfox.com/services/continuous-threat-exposure-management.

Our detection tool is available on GitHub: github.com/BishopFox/CVE-2026-28326-check.

For more vulnerability intelligence insights, visit the Bishop Fox Blog.


Jon Williams

By Jon Williams

Staff Security Engineer

As a researcher for the Bishop Fox Threat Enablement & Analysis team, Jon spends his time hunting for vulnerabilities and writing exploits for software on our customers' attack surface. Jon has written and presented research on various topics including enterprise wireless network attacks, bypassing network access controls, and reverse-engineering edge security device firmware.


Banksy Fox exploder1

By Threat Enablement & Analysis Team

The Bishop Fox Threat Enablement & Analysis team researches emerging vulnerabilities, exploits, and attacker techniques to understand how new threats translate into real-world risk. The team combines vulnerability research, exploit development, threat intelligence, and offensive security expertise to analyze new disclosures, validate exploitability, and develop methods for identifying affected systems at scale.

Subscribe to our blog

Be first to learn about latest tools, advisories, and findings.