Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
🐹 Go
Not in CISA KEV

GHSA-97vp-pwqj-46qc — sliver

GHSA-97vp-pwqj-46qc is a CWE-770 vulnerability in github.com/bishopfox/sliver. 1 public exploit reference exists, so weaponization risk is real. No vendor fix is recorded yet; mitigation options are listed below.

Sliver Vulnerable to Authenticated OOM via Memory Exhaustion in mTLS/WireGuard Transports

Also known asCVE-2026-32941GO-2026-4723
Published
Mar 17, 2026
Updated
Mar 30, 2026
Affected
1 pkg
Patched
None yet
Exploits
1 known
Exploitation data as of Sep 21, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

Proof-of-concept exploit code exists

  • CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.

Exploitation and automatability from CISA’s SSVC triage for GHSA-97vp-pwqj-46qc.

EPSS Exploitation Probability

via FIRST.org ↗
0.3%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs23th percentile — riskier than 23% of all scored CVEsHighest risk

EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.

Real-World Exposure

1 pkg affected
🐹github.com/bishopfox/sliver

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects Go packages — download data is not available via public APIs for these ecosystems.

Description

Summary

A Remote OOM (Out-of-Memory) vulnerability exists in the Sliver C2 server's mTLS and WireGuard C2 transport layer. The socketReadEnvelope and socketWGReadEnvelope functions trust an attacker-controlled 4-byte length prefix to allocate memory, with ServerMaxMessageSize allowing single allocations of up to ~2 GiB. A compromised implant or an attacker with valid credentials can exploit this by sending fabricated length prefixes over concurrent yamux streams (up to 128 per connection), forcing the server to attempt allocating ~256 GiB of memory and triggering an OS OOM kill. This crashes the Sliver server, disrupts all active implant sessions, and may degrade or kill other processes sharing the same host. The same pattern also affects all implant-side readers, which have no upper-bound check at all.


Root Cause Analysis

The C2 envelope framing protocol uses a 4-byte little-endian length prefix to delimit protobuf messages on the wire:

[raw_signature (74 bytes)] [uint32 length] [protobuf data]

In socketReadEnvelope, after reading the length prefix, the server immediately allocates a buffer of the attacker-specified size:

// server/c2/mtls.go
const ServerMaxMessageSize = (2 * 1024 * 1024 * 1024) - 1  // ~2 GiB

dataLength := int(binary.LittleEndian.Uint32(dataLengthBuf))
if dataLength <= 0 || ServerMaxMessageSize < dataLength {
    return nil, errors.New("[pivot] invalid data length")
}
dataBuf := make([]byte, dataLength)  // ← Allocates up to ~2 GiB

// ... data is read into buffer ...

// Envelope signature verification happens AFTER allocation and read:
if !ed25519.Verify(pubKey, dataBuf, signature) {
    return nil, errors.New("[mtls] invalid signature")
}

Key issues:

  1. Excessive limit: ServerMaxMessageSize is set to (2 * 1024 * 1024 * 1024) - 1 ≈ 2 GiB, far exceeding any legitimate protobuf envelope (large payloads like screenshots and downloads are chunked at the RPC layer).
  2. Allocation before envelope verification: While the TLS handshake validates the client certificate, the per-envelope ed25519 signature check (ed25519.Verify) occurs after the buffer allocation and io.ReadFull. Once the TLS connection is established, no further cryptographic proof is needed to trigger the allocation.
  3. Yamux amplification: The yamux session allows up to mtlsYamuxMaxConcurrentStreams = 128 concurrent streams. Each stream processes socketReadEnvelope independently, so a single connection can trigger 128 parallel ~2 GiB allocations.
  4. Implant-side exposure: The implant-side readers (ReadEnvelope in mTLS/WireGuard, read() in pivots) have no upper-bound check at all — they accept any dataLength > 0.

The same pattern exists in socketWGReadEnvelope for the WireGuard transport.

Note: The same unbounded allocation pattern is also present in implant-side readers, though it poses no immediate risk to the server 1, 2, 3, 4.


Proof of Concept

PoC Links: mtls_poc.go or Gist Version

  1. Establish mTLS connection: Complete a valid TLS 1.3 handshake presenting a valid implant client certificate.
  2. Negotiate yamux: Send the MUX/1 preface to enter multiplexed stream mode.
  3. Open concurrent streams: Open multiple yamux streams (up to 128).
  4. Send malicious length prefix: On each stream, send a 74-byte raw signature buffer followed by a 4-byte length prefix claiming 0x7FFFFFFF (2,147,483,647 bytes ≈ 2 GiB). No actual data needs to follow.
  5. Result: Each stream triggers a make([]byte, 0x7FFFFFFF) allocation. With 128 concurrent streams, the server process attempts to allocate up to ~256 GiB of memory, causing the OS OOM killer to terminate the process.

Impact

  • Server availability: The Sliver server process is killed. Active implant sessions are disrupted until the operator manually restarts the server.
  • Host degradation: On hosts with swap enabled, the OOM event may cause swap thrashing and degrade other services sharing the same host before the process is killed.

Affected Packages

1 total
EcosystemPackageVulnerable rangeFix
🐹Gogithub.com/bishopfox/sliverall versionsNo fix
Exploits & PoCs
1

Research use only. For defensive security, authorized penetration testing, and academic research only. Never execute exploit code against systems without explicit written authorization.

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for github.com/bishopfox/sliver, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Remediation status

    No patched version of github.com/bishopfox/sliver has shipped for GHSA-97vp-pwqj-46qc yet. Where your build allows, override or pin the dependency away from the vulnerable range, and apply any maintainer-recommended mitigation.

  3. Mitigate without a patch

    If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.

  4. How O3 protects you

    O3 Security's impact-aware SCA analyses which vulnerable code paths your application actually calls, so a match like GHSA-97vp-pwqj-46qc can be triaged on real exposure rather than presence alone.

Tailored to GHSA-97vp-pwqj-46qc. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.

Frequently Asked Questions

# Summary A Remote OOM (Out-of-Memory) vulnerability exists in the Sliver C2 server's mTLS and WireGuard C2 transport layer. The `socketReadEnvelope` and `socketWGReadEnvelope` functions trust an attacker-controlled 4-byte length prefix to allocate memory, with `ServerMaxMessageSize` allowing single allocations of up to **~2 GiB**. A compromised implant or an attacker with valid credentials can exploit this by sending fabricated length prefixes over concurrent yamux streams (up to 128 per connection), forcing the server to attempt allocating **~256 GiB** of memory and triggering an OS OOM kill
O3 Security · Impact-Aware SCA

Is GHSA-97vp-pwqj-46qc in your dependencies?

O3 Security finds GHSA-97vp-pwqj-46qc across Go dependencies, including transitive ones, and its impact-aware SCA ranks findings by whether your code actually calls the vulnerable path.

GHSA-97vp-pwqj-46qc: sliver DoS | O3 Security