GHSA-2286-HXV5-CMP2

Sliver of Truth: Exposing the C2 Server via Path Traversal

Alon Barad
Alon Barad
Software Engineer

Feb 5, 2026·5 min read·4 visits

Executive Summary (TL;DR)

Authenticated operators on a Sliver C2 server (v1.6.10 and below) can read arbitrary files on the host system by using directory traversal sequences (`../`) in the `WebsiteAddContent` RPC. Fixed in v1.6.11.

Bishop Fox Sliver, a premier command and control framework, suffers from an authenticated path traversal vulnerability in its website management subsystem. By manipulating the logical path of hosted content, an operator can coerce the server into reading arbitrary files from the host filesystem. This turns the hunters into the hunted, allowing low-privileged operators to exfiltrate sensitive server configurations, SSH keys, or system credentials.

The Hook: When the C2 Becomes the Target

Sliver is the darling of the modern red team arsenal. Written in Go, supporting multi-player operations, and packed with features, it's the tool used to manage implants inside compromised networks. We usually think of the C2 server as the fortress—the unassailable base of operations. But what happens when the fortress has a back door unlocked from the inside?

This vulnerability (GHSA-2286-HXV5-CMP2) isn't an exploit against the implants or the victims. It's a fratricidal flaw in the C2 server itself. It allows any authenticated operator—even one with restricted permissions—to read files off the server's disk.

Imagine a scenario where a Blue Team captures a low-level operator's client configuration. Normally, they might just kick the operator or see some logs. With this bug, they can pivot from that stolen config to reading /etc/shadow on your infrastructure. It is a classic case of "trusted input" going rogue.

The Flaw: Trusting the Path

The vulnerability lies in the Website Content Subsystem. Sliver allows operators to host static content (like phishing pages or payload delivery sites) directly from the C2 server. When an operator adds content, they specify a Path (e.g., /index.html) and the raw bytes.

The logic flaw here is a textbook misuse of Golang's path/filepath package. When the server needed to retrieve this content later, it didn't look up a database ID or a hash; it looked up the file on disk using the path provided by the user.

Specifically, the server took the root directory for web content and simply joined it with the user-supplied path using filepath.Join. While filepath.Join cleans up dirty paths, it does not sandbag them against directory traversal if the resulting path is syntactically valid. If you ask for ../../etc/passwd, the server happily resolves the path relative to the web root, realizes it points outside, and—crucially—proceeds to read it anyway.

The Code: A Tale of Two Joins

Let's look at the smoking gun in server/db/models/website.go. In the vulnerable versions, the server reconstructed the file path blindly using the user's input stored in webcontent.Path.

Vulnerable Code:

// The server blindly joins the base directory with the user-controlled Path
contents, _ := os.ReadFile(filepath.Join(webContentDir, webcontent.Path))

If webcontent.Path is ../../../../etc/shadow, the code effectively runs os.ReadFile("/root/.sliver/web/../../../../etc/shadow"). Since the Sliver server often runs with high privileges (sometimes root, though it shouldn't), this reads the system's shadow file.

The Fix (Commit 818127349ccec812876693c4ca74ebf4350ec6b7):

The Bishop Fox team fixed this by decoupling the logical path (the URL) from the physical path (the file on disk). Instead of using the user's string as a filename, they now use the database's internal UUID for the content.

// The server now uses a generated UUID, which cannot contain traversal characters
contents, err := os.ReadFile(filepath.Join(webContentDir, webcontent.ID.String()))

Now, even if the user sets the path to ../../etc/passwd, the server ignores it during file retrieval and looks for a file named 550e8400-e29b-41d4-a716-446655440000 (or similar UUID) inside the web content directory. Simple, elegant, and secure.

The Exploit: Reading /etc/hosts

Exploiting this requires an authenticated mTLS connection to the Sliver server. This means you need a valid operator config file (.cfg). Once connected, we abuse the gRPC interface.

The Attack Chain:

  1. Craft the Payload: We create a WebsiteAddContent request. We set the Name to a dummy website and, critically, we set the Path to a traversal string like ../../../../../../etc/hosts.
  2. Poison the Database: We send this request. The server saves the metadata to its SQL database. It might fail to write the file to disk locally depending on permissions, or it might write it successfully. But the read is what we care about.
  3. Trigger the Read: We call the Website RPC to request details about our site. The server iterates through the content entries. When it hits our malicious entry, it executes the vulnerable os.ReadFile logic.
  4. Exfiltrate: The server reads the actual /etc/hosts from the host OS, packages the bytes into the Protobuf response, and sends it back to our client.

Here is a snippet of how a researcher might construct the traversal path in Go:

// Calculate traversal depth dynamically or just spam ../
targetPath := "/etc/passwd"
webPath := "../../../../../../../../" + strings.TrimPrefix(targetPath, "/")
 
// Send the malicious gRPC call
rpc.WebsiteAddContent(ctx, &clientpb.WebsiteAddContent{
    Name: "exploit-site",
    Contents: map[string]*clientpb.WebContent{
        webPath: {
            Path:        webPath,
            ContentType: "text/plain",
            Content:     []byte("irrelevant"),
        },
    },
})

The Impact: Why This Hurts

You might argue, "If I have an operator config, I already own the C2." Not necessarily. Sliver supports multi-user environments with different roles. This vulnerability collapses those boundaries.

The Real Danger:

  1. Server Compromise: Reading /root/.ssh/id_rsa or /etc/shadow allows the attacker to SSH into the C2 server itself, gaining full root shell access outside the Sliver environment.
  2. Config Theft: The attacker could read the server's main configuration file, potentially recovering database credentials or other sensitive API keys used for integrations (e.g., Discord or Slack webhooks).
  3. Lateral Movement: If the C2 server is inside a protected network segment (e.g., a redirector setup), reading local files helps map the internal network topology via /etc/hosts or network config files.

This is a classic privilege escalation: from "Application User" to "System Administrator".

Fix Analysis (1)

Technical Appendix

CVSS Score
6.5/ 10
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N

Affected Systems

Bishop Fox Sliver Server < 1.6.11

Affected Versions Detail

Product
Affected Versions
Fixed Version
Sliver
Bishop Fox
< 1.6.111.6.11
AttributeDetail
CVE IDN/A (GHSA-2286-HXV5-CMP2)
CVSS v3.16.5 (Medium)
Attack VectorNetwork (Authenticated gRPC)
CWECWE-22 (Path Traversal)
ImpactArbitrary File Read
Privileges RequiredLow (Operator)
CWE-22
Path Traversal

Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')

Vulnerability Timeline

Vulnerability Published & Fixed
2026-02-05

Subscribe to updates

Get the latest CVE analysis reports delivered to your inbox.