High-performance multi-path covert channel over DNS https://endpositive.github.io/slipstream/
Find a file
2025-05-16 16:39:49 +08:00
.github/workflows Update documentation 2025-05-16 16:39:49 +08:00
certs Initial version of slipstream DNS tunnel 2024-12-10 14:40:31 +08:00
docs Update documentation 2025-05-16 16:39:49 +08:00
extern fix stream id duplication 2025-05-05 15:51:17 +08:00
include cli 2025-05-06 15:55:52 +08:00
src cli 2025-05-06 15:55:52 +08:00
.dockerignore cli 2025-05-06 15:55:52 +08:00
.gitignore Update .gitignore 2025-05-09 16:29:33 +08:00
.gitmodules Initial version of slipstream DNS tunnel 2024-12-10 14:40:31 +08:00
CMakeLists.txt cli 2025-05-06 15:55:52 +08:00
Dockerfile Update documentation 2025-05-16 16:39:49 +08:00
LICENSE Create LICENSE 2025-05-11 11:51:11 +08:00
README.md Update documentation 2025-05-16 16:39:49 +08:00

Slipstream

GitHub Release GitHub License

A high-performance covert channel over DNS, powered by QUIC multipath.

Shows a bar chart with benchmark results.

Exfiltrating a 10 MB file over a single DNS resolver.

Highlights

  • Adaptive congestion control for rate-limited resolvers
  • Parallel routing over multiple multiple rate-limited resolvers
  • 60% lower header overhead than DNSTT

Installation

Get the latest binaries GitHub releases or pull the latest version from the GitHub Container Registry.

Usage

Usage: slipstream-server [OPTION...] 
slipstream-server - A high-performance covert channel over DNS (server)

  -a, --target-address=ADDRESS   Target server address (default:
                             127.0.0.1:5201)
  -c, --cert=CERT            Certificate file path (default: certs/cert.pem)
  -d, --domain=DOMAIN        Domain name this server is authoritative for
                             (Required)
  -k, --key=KEY              Private key file path (default: certs/key.pem)
  -l, --dns-listen-port=PORT DNS listen port (default: 53)
Usage: slipstream-client [OPTION...] 
slipstream-client - A high-performance covert channel over DNS (client)

  -c, --congestion-control=ALGO   Congestion control algorithm (bbr, dcubic)
                             (default: dcubic)
  -d, --domain=DOMAIN        Domain name used for the covert channel (Required)
                            
  -g, --gso[=BOOL]           GSO enabled (true/false) (default: false). Use
                             --gso or --gso=true to enable.
  -l, --tcp-listen-port=PORT Listen port (default: 5201)
  -r, --resolver=RESOLVER    Slipstream server resolver address (e.g., 1.1.1.1
                             or 8.8.8.8:53). Can be specified multiple times.
                             (Required)

Quickstart

Server setup

The server listens for DNS messages and attempts to decode QUIC message from them. Any new QUIC streams opened will be forwarded to a specified TCP service. For example, we can start a simple nc listener and configure the slipstream server to connect to it.

$ nc -l -p 5201
$ slipstream-server \
  --dns-listen-port=8853 \
  --cert=certs/cert.pem \
  --key=certs/key.pem \
  --target-address=127.0.0.1:5201 \
  --domain=test.com

Client setup

The client listens on a TCP port for incoming connections. It opens a QUIC connection through the resolver specified. For every TCP connection it accepts, a new QUIC stream will be opened. In this example, we connect to the slipstream server running on port 8853.

$ slipstream-client \
  --tcp-listen-port=7000 \
  --resolver=127.0.0.1:8853 \
  --domain=test.com
Adding 127.0.0.1:8853
Starting connection to 127.0.0.1
Initial connection ID: 54545454
Listening on port 7000...
Connection completed, almost ready.
Connection confirmed.

Usage

You can then connect to the slipstream client on port 7000 as if you were connecting to the nc client on port 5201.

$ base64 /dev/urandom | head -c 5000000 | nc 127.0.0.1 7000

# slipstream client wakes up
[0:9] accept: connection
[0:9] wakeup
[0:9] activate: stream
[0:9] recv->quic_send: empty, disactivate
[0:9] wakeup
[0:9] activate: stream
[0:9] recv->quic_send: empty, disactivate
[0:9] wakeup
[0:9] activate: stream
[0:9] recv->quic_send: empty, disactivate
[0:9] recv: closed stream

# base64 data arrives on the server
S9w3u5up+c39u6vrkBtxKbSxOJA2UElczDgc3x4h3TtZtzvgMX05Ig4whEYDvY5MP8g4dJ1QsXX1
fSDm0y6mOlQ4fQhYchkyKt18fV0tpBkLrPwv6MkW+IaksKe7Qo61s3gxu2jrPBlC1yxML+rYZU93
MYNB7rFC6s3a0eHmfdsfbtBbFIF809X91fqd6gYiKPtWAHc0J5OsEyqMI3QcUGSDJd4Sw+iAC5X7

Real network scenario

You can try this out on a real network (if you have permission). First, you need to have a server outside of the network you want to escape. For a domain name you own, setup the DNS records to point to your nameserver. This ensures that queries for subdomains of test.com will be forwarded to your server.

test.com NS ns.test.com
ns.test.com A 12.23.34.45 

Then run the slipstream server on port 53 (requires elevated privileges) and instruct the client to use a real DNS resolver.

Benchmarks

Comparison of slipstream and other existing DNS tunneling tools can be found in the EndPositive/dns-tunneling-benchmark repository.

Main findings:

  • 42x faster than dnstt for direct connections
  • 23/19 Mbps upload/download speed for direction connections
  • automatically maximizes query rate according to resolver rate-limit

Acknowledgements

David Fifield's DNSTT and Turbo Tunnel concept has been a massive source of inspiration. Although slipstream inherits no code, this work could not have been possible without his ideas.