Mar 30, 2026·6 min read·4 visits
Sliver versions <= 1.7.3 suffer from a nil pointer dereference in reverse tunnel closure logic, causing goroutine panics and memory leaks when an authenticated session requests a tunnel close.
A Nil Pointer Dereference vulnerability exists in the Sliver adversary emulation framework, specifically within the `tunnelCloseHandler` function. Authenticated operators or active implants can trigger a goroutine panic by attempting to close a reverse tunnel. This results in a localized denial-of-service condition and subsequent resource leakage.
The Sliver adversary emulation framework contains a logic flaw in its server-side reverse tunnel management. Vulnerability GHSA-C279-989M-238F is classified as a Nil Pointer Dereference (CWE-476) within the github.com/bishopfox/sliver package. The flaw affects all versions up to and including 1.7.3. It resides specifically within the server/handlers/sessions.go module, which is responsible for managing multiplexed connections between the management server and active remote implants.
The vulnerability requires an active, authenticated session to trigger. An attacker must possess an active implant session with the Sliver server to initiate the vulnerable tunnel closure sequence. This makes the attack vector authenticated and network-adjacent, as defined by the CVSS 3.1 and 4.0 scoring metrics. The primary impact maps directly to the availability of the framework's management capabilities.
When triggered, the flaw results in a denial-of-service (DoS) condition localized to the specific handler goroutine. Because the Go runtime isolates this failure via a panic recovery mechanism, the main server process does not terminate. However, the failure to cleanly close the reverse tunnel results in persistent state data remaining in memory, constituting a progressive resource leak over the lifetime of the server instance.
The root cause of GHSA-C279-989M-238F stems from an improper variable reference during the evaluation of tunnel ownership. The tunnelCloseHandler function processes incoming MsgTunnelClose messages. Its initial logic attempts to locate a standard forward tunnel using the provided tunnel identifier via the core.Tunnels.Get(tunnelData.TunnelID) method.
When the client requests the closure of a reverse tunnel (rportfwd), the forward tunnel lookup fails and returns nil. The execution flow correctly proceeds to an else branch designed to handle reverse tunnels. Within this branch, the code successfully retrieves the reverse tunnel object using rtunnels.GetRTunnel(tunnelData.TunnelID). The vulnerability materializes in the subsequent authorization check.
The application must verify that the session requesting the closure is the actual owner of the tunnel. To accomplish this, the code evaluates the condition session.ID == tunnel.SessionID. This references the tunnel variable from the outer scope, which is explicitly nil in this execution path. Attempting to access the SessionID field of a nil struct pointer immediately triggers a Go runtime panic.
An examination of server/handlers/sessions.go reveals the exact mechanism of the failure. The vulnerable block resides at lines 172 and 175 of the module. The logic attempts to gracefully handle both standard and reverse tunnels within the same handler function, but incorrectly mixes the namespace of the tunnel objects during the reverse tunnel evaluation phase.
The following snippet demonstrates the flawed logic in the unpatched version of the software. The application correctly validates that rtunnel is not nil, but immediately follows this safe check with an unsafe dereference of the tunnel variable.
} else {
rtunnel := rtunnels.GetRTunnel(tunnelData.TunnelID)
// BUG: 'tunnel' is nil here, but the code accesses 'tunnel.SessionID'
if rtunnel != nil && session.ID == tunnel.SessionID { // LINE 172
rtunnel.Close()
rtunnels.RemoveRTunnel(rtunnel.ID)
} else if rtunnel != nil && session.ID != tunnel.SessionID { // LINE 175
sessionHandlerLog.Warnf("...")
}
}The remediation requires substituting the incorrect tunnel reference with the properly instantiated rtunnel variable. The patch corrects the authorization check to read the SessionID from the active reverse tunnel object. Historical analysis indicates that identical logic in the tunnelDataHandler function was previously patched, but the tunnelCloseHandler function was overlooked during that revision.
- if rtunnel != nil && session.ID == tunnel.SessionID {
+ if rtunnel != nil && session.ID == rtunnel.SessionID {
rtunnel.Close()
rtunnels.RemoveRTunnel(rtunnel.ID)
- } else if rtunnel != nil && session.ID != tunnel.SessionID {
+ } else if rtunnel != nil && session.ID != rtunnel.SessionID {Exploitation of GHSA-C279-989M-238F requires the establishment of a valid reverse tunnel through an active Sliver implant. An operator or an adversary who has compromised the C2 infrastructure sends a MsgTunnelClose protocol message explicitly targeting the reverse tunnel identifier. This action transitions the server state into the vulnerable code path.
Upon receiving the message, the tunnelCloseHandler goroutine executes the flawed authorization check and encounters the invalid memory address. The Go runtime catches this fatal memory violation and triggers a panic. The Sliver framework employs a recoverAndLogPanic() mechanism at the top level of its handler dispatch loop. This prevents the entire server application from crashing completely.
While the primary server process remains operational, the specific goroutine processing the closure request terminates prematurely. The targeted reverse tunnel is never closed, and its metadata is never purged from the internal rtunnels mapping structure. Repeated exploitation of this flaw leads to the silent accumulation of orphaned tunnel objects. This results in memory exhaustion and degraded server performance over time. The functional regression also prevents operators from reclaiming bound network ports.
The vulnerability affects all versions of the Sliver framework up to and including version 1.7.3. Administrators must apply the source code patch directly to the server/handlers/sessions.go file and recompile the server binary, as an official compiled release addressing this specific flaw was not broadly distributed at the time of publication. The patch alters the variable references on lines 172 and 175 to correctly target the rtunnel object.
Organizations utilizing Sliver for internal adversary emulation should prioritize detection of this condition. Security engineers must actively monitor the server execution logs for stack traces and panic events originating from the tunnelCloseHandler. The presence of the string invalid memory address or nil pointer dereference within the context of session handling is a definitive indicator of compromise or operational failure.
Operational mitigation involves strict access control to the Sliver management interface. Limiting the deployment of reverse tunnels (rportfwd) reduces the exposed attack surface until the framework can be properly updated. Operators encountering locked ports due to orphaned reverse tunnels must restart the Sliver server service to flush the leaked metadata and reclaim the operating system resources.
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Sliver BishopFox | <= 1.7.3 | Unpatched as of publication |
| Attribute | Detail |
|---|---|
| Vulnerability Class | Nil Pointer Dereference (CWE-476) |
| Attack Vector | Network (Authenticated Message Passing) |
| CVSS 4.0 Score | 6.9 (Medium) |
| CVSS 3.1 Score | 6.5 (Medium) |
| Impact | Denial of Service (Thread Level), Resource Leak |
| Exploit Status | Unweaponized / Functional Regression |
| KEV Status | Not Listed |
A NULL pointer dereference occurs when the application dereferences a pointer that it expects to be valid, but is NULL, typically causing a crash or exit.