//nefariousplan

CVE-2024-12356: Treasury Was the Proof of Concept

patterns

cve

proof of concept

BeyondTrust ships a product called Privileged Remote Access. CVE-2024-12356 lets an unauthenticated remote attacker get privileged remote access to it. The product description and the attack description are the same four words. By the time the public proof-of-concept landed as a thirteen-line nuclei template in February 2025, the weaponized version had already run, in December 2024, against the U.S. Treasury Department, and BeyondTrust had discovered the bug by watching it run against their own cloud.

The public PoC is a presence check

The artifact in projectdiscovery/nuclei-templates/code/cves/2024/CVE-2024-12356.yaml is forty-three lines of YAML, of which thirteen are the actual exploit payload:

code:
  - engine:
      - sh
      - bash
    source: |
      # brew install websocat
      company=`curl -k -s "$Scheme://$Host/get_portal_info" | cut -d '=' -f2 | tail -n 1 | cut -d';' -f1`
      echo -ne "1\n\n0\n\xC0';select 1 -- -\n" | websocat -k wss://$Host/nw --protocol "ingredi support desk customer thin" -H "X-Ns-Company: $company" --binary -n --max-messages-rev 2

    matchers:
      - type: word
        part: response
        words:
          - "0 success"
          - "1 try again later"

Two interactions. The first is an unauthenticated GET to /get_portal_info. The endpoint returns a key=value; text blob, and the template parses out the company id by reading the last key= line and taking the value before the next ;. That endpoint is the per-tenant identifier service: every BeyondTrust appliance answers it without authentication, because the customer-thin-client needs to know which tenant it is talking to before it can connect.

The second is a WebSocket upgrade to wss://<host>/nw, with the harvested company id sent as the X-Ns-Company header and the WebSocket subprotocol set to ingredi support desk customer thin. The subprotocol name is a five-token routing string. The last two tokens, customer thin, identify a customer-facing thin client. The framework on the other end believes an end user is connecting to ask for support.

The binary frame after the upgrade is four lines:

1

0
\xC0';select 1 -- -

The first three are an action-code header (1, empty, 0). The fourth is the field that exercises the bug. \xC0 is a UTF-8 lead byte for a two-byte sequence; the byte that follows it is ' (0x27), which is not a valid UTF-8 continuation byte. The pair is malformed by design. A sanitizer that decodes UTF-8 will either consume \xC0' as one mangled grapheme or reject it; an executor that operates on raw bytes will see \xC0 and ' separately and process the quote as a quote. The ';select 1 -- - after the lead byte is a SQL-injection probe.

Now read the matcher. It fires on 0 success or 1 try again later. Both are server protocol replies: the message-class status codes the framework sends back when a client message has been processed. The matcher does not check whether select 1 actually executed. It does not check whether a command ran. It checks whether the server reached the point where it returns a status code at all.

What the public PoC proves is reachability. There is a service on the other end of /nw that accepts a thin-client subprotocol string, parses a \xC0-led binary frame, and returns a status. CVE-2024-12356 is classified as command injection (CWE-77), and the probe payload is SQL syntax, because the field that ends up as a command argument is the same field a SQL-shaped sanitizer was supposed to clean. That is the bug class. The nuclei template does not write the rest of it. By the time the template was published in February 2025, the rest had been written elsewhere.

The advisory says every version

BeyondTrust's BT24-10 advisory, dated 2024-12-16, lists affected versions as PRA ≤ 24.3.1 and RS ≤ 24.3.1. The advisory body is more candid than the table:

All BeyondTrust Privileged Remote Access (PRA) and Remote Support (RS) versions contain a command injection vulnerability which can be exploited through a malicious client request.

The fix is split across two patches, BT24-10-ONPREM1 and BT24-10-ONPREM2, "dependent on PRA version" and "dependent on RS version." The advisory then adds, in the section that explains how to apply the fix:

If customers are on a version older than 22.1, they will need to upgrade in order to apply this patch.

The minimum version is older than the supported window. The bug in the customer-thin-client /nw handler has been present continuously since at least the 22.1 line, and the advisory does not name a release where the bug was introduced. The reading the advisory permits is the simple one: the bug was always there.

The patch reached the cloud first

BeyondTrust patched their cloud customers on December 16, 2024, the same day BT24-10 was published. That ordering is the tell. The vendor did not patch their cloud after disclosure. They disclosed after the patch had already been applied to the fleets they operated themselves, in response to incident response work they had been doing on those fleets.

The public chronology, from BeyondTrust's incident communications and Treasury's subsequent statements:

Date Event
2024-12-02 BeyondTrust observes anomalous activity in their Remote Support SaaS environment
2024-12-05 BeyondTrust isolates compromised customer instances
2024-12-08 BeyondTrust notifies the U.S. Treasury Department that an attacker has compromised their RS SaaS instance
2024-12-16 BT24-10 published; cloud customers receive the patch the same day
2024-12-18 BT24-11 / CVE-2024-12686 published, a second command injection in the same product line
2024-12-19 CISA adds CVE-2024-12356 to the Known Exploited Vulnerabilities catalog
2024-12-30 Treasury publicly discloses the breach
2025-02-21 Ritik Chaddha publishes the nuclei detection template

The vendor learned about the bug because attackers were already using it. The customers learned about the bug because attackers were already through it. The defenders' detection content arrived as a thirteen-line YAML file sixty-seven days after the advisory and eighty-one days after BeyondTrust's IR began. None of these dates are anomalies. They are how this category of product produces CVEs. Ivanti runs the same subscription; CrushFTP filed the documenting wiki page on the day they admitted the bug existed. Disclosure-after-exploitation is the pattern's name. The defender's first signal is a breach.

The product is the attack surface

BeyondTrust Privileged Remote Access is a privileged-access broker. It accepts inbound connections from the internet so that vendors, contractors, and remote staff can reach internal resources without a VPN. It holds long-lived credentials for the destination systems it brokers. It is sold to enterprises that classify their privileged-access broker as part of their security stack.

This is trust inversion at the architectural layer. The product's job is to authorize privileged access to internal resources. The exploit authorizes privileged access to internal resources. The validation that should have stopped the inversion was never built, because the architecture treated the customer-thin-client as a distrusted-but-known caller and the /nw code path was never modeled as hostile. CVE-2024-12356 is what happens when the distrusted caller can reach a code path that the design assumed only well-formed thin clients would reach. Once the attacker holds the X-Ns-Company tenant identifier (returned by the unauthenticated lookup endpoint) and can speak the four-line binary protocol, the validation downstream never fires. The system has decided this caller is, in its view, an in-product caller.

Security-tool-as-primitive is the more specific shape. The defender's hands become the attacker's hands. PRA's job is to grant privileged remote access; the bug grants privileged remote access. The blast radius scales with the product's deployment footprint, which for an enterprise privileged-access broker is: every privileged destination it brokers. The Treasury Department was not a customer of an obscure desktop utility. They were a customer of the thing they bought to broker privileged access on their behalf, and the thing they bought brokered it on someone else's behalf.

The advisory's other tell is the December 2024 pair: BT24-10 (CVE-2024-12356) on December 16, BT24-11 (CVE-2024-12686) on December 18. Two command injection CVEs in the same product line in the same week, after the same incident. One vulnerability uncovered by IR and one neighbor uncovered by the audit somebody decided to run when the first one was found. The bug class lives in the codebase. The audit triggered by the breach found the next instance two days later. The advisory's claim that "all versions" of PRA and RS are affected, and that customers running anything below 22.1 need to upgrade before they can patch, names the same shape: the substrate has been carrying this primitive since before the supported window began.

CVSS 9.8. AV:N. PR:N. EPSS 0.93857. The numbers describe an unauthenticated network-reachable RCE in a product whose entire purpose is to grant unauthenticated network-reachable access to other systems on a controlled basis. The control was the part that broke.

What the PoC documents

What the public artifact documents is what was already known to the actor who held it: the /get_portal_info endpoint is unauthenticated, the /nw WebSocket accepts the customer-thin-client subprotocol from any TLS peer who knows the company id, the \xC0-prefixed binary frame survives whatever sanitization the framework applies, and the SQL-shaped field reaches a context where the framework treats it as a command argument. None of those facts are the exploit. They are the preconditions an exploit needs.

The exploit was the four-line frame extended to write something useful into the command argument, run for the first time on a Treasury workstation in late November or early December 2024, observed by BeyondTrust's cloud telemetry on December 2, traced to the customer-thin-client handler over the next two weeks, and patched on December 16 in the cloud and on December 16 in the public advisory. The thirteen-line YAML you can run against your own appliance today is what the rest of the world received in February 2025 in lieu of the missing two weeks.

PoC: projectdiscovery/nuclei-templates

The product is named Privileged Remote Access. So is the attack.