GitHub Advisoryadvisory · Go
GHSA-hx52-cv84-jr5v Sliver is Vulnerable to Authenticated Nil-Pointer Dereference through its Handlers
LOW
Official page ↗
- Aliases
- CVE-2026-29781
- Ecosystem
- Go
- Packages
- github.com/bishopfox/sliver
- Severity
- Low
- CVSS vector
- CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N/E:P
- Weaknesses
- CWE-476
- Reviewed
- 2026-03-05
Affected packages
• Go github.com/bishopfox/sliver: <= 1.7.3 (no fix yet)
Description
1. Executive Summary
A vulnerability exists in the Sliver C2 server's Protobuf unmarshalling logic due to a systemic lack of nil-pointer validation. By extracting valid implant credentials and omitting nested fields in a signed message, an authenticated actor can trigger an unhandled runtime panic. Because the mTLS, WireGuard, and DNS transport layers lack the panic recovery middleware present in the HTTP transport, this results in a global process termination. While requiring post-authentication access (a captured implant), this flaw effectively acts as an infrastructure "kill-switch," instantly severing all active sessions across the entire fleet and requiring a manual server restart to restore operations.
2. Vulnerability Details
2.0 Technical Workflow: From Envelope to Handler
Sliver encapsulates all C2 traffic in a generic `sliverpb.Envelope`, which acts as a routing wrapper. When the server receives an Envelope with `Type = 53` (MsgBeaconRegister), the internal router strips the envelope and passes the raw `Data` bytes directly to the vulnerable `handlers.beaconRegisterHandler(implantConn, data)`. This flow is consistent across all transports, but the error handling of the transport itself determines the final impact.
2.1 BeaconRegister Nil-Pointer Dereference
• Vulnerability Type: Remote Denial of Service via Nil-Pointer Dereference (CWE-476)
• Component: `server/handlers/beacons.go`
• Affected Functions: beaconRegisterHandler.
• Severity: Critical
• Complexity: Low
Root Cause Analysis
The core of the vulnerability lies in the architectural handling of Protobuf messages within the Go runtime. In `proto3`, all fields are optional by design. When a message contains a nested sub-message (like `Register` inside `BeaconRegister`), the Go Protobuf implementation represents this sub-message as a pointer.
In `server/handlers/beacons.go`, the server unmarshals the incoming data without subsequent validation of its nested structures:
```Go
func beaconRegisterHandler(implantConn *core.ImplantConnection, data []byte) *sliverpb.Envelope {
// ...
beaconReg := &sliverpb.BeaconRegister{}
err := proto.Unmarshal(data, beaconReg)
// Successful even if 'Register' sub-message is omitted
// VULNERABILITY: beaconReg.Register is nil if omitted by sender.
// Accessing any property of a nil pointer triggers an immediate runtime panic.
beaconRegUUID, _ := uuid.FromString(beaconReg.Register.Uuid)
// ...
}
```
If an attacker constructs a `BeaconRegister` message and deliberately omits the `Register` field, `proto.Unmarshal` parses the stream without error but leaves the `Register` pointer as `nil`. The subsequent attempt to access `beaconReg.Register.Uuid` triggers a Nil-Pointer Dereference.
2.2 Expanded Inventory: System-Wide Nil-Pointer Vulnerabilities
Beyond the beacon registration, the investigation revealed a systemic pattern of missing nil-checks across various handlers. These vulnerabilities follow the same root cause: immediate dereferencing of nested Protobuf fields post-unmarshalling.
2.2.1 Remote Implant Vectors (Unauthenticated)
These handlers process data from implants. If an implant binary is captured, these can be triggered to crash the server:
• Reverse Tunneling (`server/handlers/sessions.go`): The `createReverseTunnelHandler` panics when `req.Rportfwd` is omitted.
• SOCKS Proxying (`server/handlers/sessions.go`): The `socksDataHandler` fails when the `SocksData` sub-message is absent.
• Pivot/Peer Communication (`server/handlers/pivot.go`): Functions `serverKeyExchange` and `peersToString` dereference `peerEnvelope.Peers` without checking if the peer list is empty or nil.
2.2.2 Authenticated Operator Vectors (gRPC Layer)
The Sliver RPC server (`server/rpc/`) is also susceptible. While these require an authenticated operator, they represent a significant stability risk where a malformed request from a custom client or automated script can bring down the entire C2 infrastructure.
| Function | File | Vulnerable Pattern |
| ------------------- | ------------------------------- | ------------------------------------------------------- |
| getTimeout | server/rpc/rpc.go | `req.GetRequest().Timeout` |
| getError | server/rpc/rpc.go | `resp.GetResponse().Err` |
| Portfwd | server/rpc/rpc-portfwd.go | `req.Request.SessionID` |
| GetSystem | server/rpc/rpc-priv.go | `req.GetRequest().SessionID` |
| GetPrivileges | server/rpc/rpc-priv.go | `req.Request.SessionID` |
| NetConnPivot | server/rpc/rpc-pivot.go | `req.Request.SessionID` |
| PivotListeners | server/rpc/rpc-pivot.go | `req.Request.SessionID` |
| SocksStart | server/rpc/rpc-socks.go | `req.Request.SessionID` |
| SocksStop | server/rpc/rpc-socks.go | `req.Request.SessionID` |
| RPortfwd | server/rpc/rpc-rportfwd.go | `req.Request.SessionID` |
| Shell | server/rpc/rpc-shell.go | `req.Request.SessionID` |
| ShellResize | server/rpc/rpc-shell.go | `req.Request.SessionID` |
| BackdoorImplant | server/rpc/rpc-backdoor.go | `req.Request.SessionID`, `req.Request.Timeout` |
| CrackstationTrigger | server/rpc/rpc-crackstations.go | `statusUpdate.HostUUID` (after unmarshal of `req.Data`) |
| Tasks | server/rpc/rpc-tasks.go | `req.Request.SessionID` |
| ImplantReconfig | server/rpc/rpc-reconfig.go | `req.Request.SessionID` |
| MsfInject | server/rpc/rpc-msf.go | `req.Request.SessionID` |
| Hijack | server/rpc/rpc-hijack.go | `req.Request.SessionID` |
---
3. Proof of Concept & Attack Feasibility
3.1 Attack Feasibility: Credential Extraction
The exploit requires valid implant credentials, which are inherently embedded in Sliver's generated binaries. Since these binaries are often deployed to untrusted or compromised environments, credential recovery is a high-probability event. During testing, it was confirmed that an attacker can obtain the required mTLS certificates and Age Secret Keys through:
• Static Extraction (Trivial): By default, running the `strings` utility on the implant binary or dumping the embedded configuration block is sufficient to recover the private keys.
• Memory Forensics: If an implant is captured during execution, the configuration structures can be carved directly from the process memory, bypassing most disk-level obfuscation.
3.2 Exploit Execution Flow
The provided exploit mtls_poc.go or mtls_poc.go demonstrates how a single captured implant can be weaponized into a "Kill Switch" for the entire C2 infrastructure. The attack follows these steps:
1. Authentication: Establishes a valid mTLS connection using the extracted certificates.
2. Multiplexing: Negotiates a Yamux stream, bypassing standard network-level protections.
3. Payload Construction: Builds a `BeaconRegister` Protobuf message where the `ID` is defined, but the critical `Register…
Related
Alias · CVE (1)
- CVE-2026-29781 Sliver is a command and control framework that uses a custom Wireguard netstack. vulnerability
Weakness · CWE (1)
- CWE-476 NULL Pointer Dereference weakness