Detect Domain Fronting in IBM QRadar
Adversaries may take advantage of routing schemes in Content Delivery Networks (CDNs) and other services which host multiple domains to obfuscate the intended destination of HTTPS traffic or traffic tunneled through HTTPS. Domain fronting involves using different domain names in the SNI field of the TLS header and the Host field of the HTTP header. If both domains are served from the same CDN, the CDN may route to the address specified in the HTTP header after unwrapping the TLS header. A variation, 'domainless' fronting, utilizes a blank SNI field. Real-world actors including APT29 and tools like Cobalt Strike, Mythic, and SMOKEDHAM have leveraged domain fronting to hide C2 traffic behind legitimate CDN infrastructure.
MITRE ATT&CK
- Tactic
- Command and Control
- Technique
- T1090 Proxy
- Sub-technique
- T1090.004 Domain Fronting
- Canonical reference
- https://attack.mitre.org/techniques/T1090/004/
QRadar Detection Query
/* Domain Fronting Detection — T1090.004
Requires custom event properties defined in QRadar:
'TLS SNI' — the TLS Server Name Indication extension value from proxy/firewall logs
'HTTP Host Header' — the HTTP Host header value from proxy logs
Configure via: Admin > Custom Event Properties > Add Property (Regex extraction from raw log)
Tested log source types: Blue Coat ProxySG (186), Squid (191), Zscaler (232), Forcepoint Web (261)
*/
SELECT
DATEFORMAT(starttime, 'YYYY-MM-dd HH:mm:ss') AS event_time,
sourceip AS src_ip,
destinationip AS dest_ip,
destinationport AS dest_port,
username,
LOGSOURCETYPENAME(devicetype) AS log_source_type,
QIDNAME(qid) AS event_name,
"TLS SNI" AS tls_sni,
"HTTP Host Header" AS http_host_header,
CASE
WHEN ("TLS SNI" IS NULL OR "TLS SNI" = '' OR "TLS SNI" = '-')
AND "HTTP Host Header" IS NOT NULL
THEN 'Domainless_Fronting'
ELSE 'SNI_Host_Mismatch'
END AS mismatch_type
FROM events
WHERE
destinationport = 443
AND "TLS SNI" IS NOT NULL
AND "HTTP Host Header" IS NOT NULL
AND LOWER("TLS SNI") != LOWER("HTTP Host Header")
AND (
LOWER("TLS SNI") LIKE '%azureedge.net%'
OR LOWER("TLS SNI") LIKE '%cloudfront.net%'
OR LOWER("TLS SNI") LIKE '%akamaiedge.net%'
OR LOWER("TLS SNI") LIKE '%fastly.net%'
OR LOWER("TLS SNI") LIKE '%cloudflare.com%'
OR LOWER("TLS SNI") LIKE '%msecnd.net%'
OR LOWER("TLS SNI") LIKE '%azurefd.net%'
OR LOWER("TLS SNI") LIKE '%amazonaws.com%'
OR LOWER("TLS SNI") LIKE '%googleusercontent.com%'
OR LOWER("HTTP Host Header") LIKE '%azureedge.net%'
OR LOWER("HTTP Host Header") LIKE '%cloudfront.net%'
OR LOWER("HTTP Host Header") LIKE '%akamaiedge.net%'
OR LOWER("HTTP Host Header") LIKE '%fastly.net%'
OR LOWER("HTTP Host Header") LIKE '%cloudflare.com%'
OR LOWER("HTTP Host Header") LIKE '%msecnd.net%'
OR LOWER("HTTP Host Header") LIKE '%azurefd.net%'
OR LOWER("HTTP Host Header") LIKE '%amazonaws.com%'
OR LOWER("HTTP Host Header") LIKE '%googleusercontent.com%'
)
START '2000-01-01 00:00' STOP NOW
ORDER BY starttime DESC QRadar AQL detection for domain fronting (T1090.004) correlating TLS SNI and HTTP Host header values parsed from proxy and next-gen firewall log sources. Identifies both classic domain fronting (SNI points to a CDN domain, Host header points to a different domain served by the same CDN) and domainless fronting (blank SNI with a populated Host header). Requires two custom event properties — 'TLS SNI' and 'HTTP Host Header' — to be defined in QRadar via Admin > Custom Event Properties with regex extraction patterns matching your proxy log format (e.g., for Bluecoat: `cs_host` for HTTP Host, `tls_sni` field for SNI).
Data Sources
Required Tables
False Positives & Tuning
- Azure Front Door and Azure CDN services serving enterprise SaaS tenants routinely use a shared TLS certificate with an azurefd.net or azureedge.net SNI while routing requests to customer-specific Origin Host headers — this is documented CDN behaviour for multi-tenant ingress, not an attack
- Content delivery architectures for streaming media (video CDNs, game update distribution) frequently negotiate TLS at a CDN edge PoP with one SNI while the HTTP-layer Host header identifies the origin backend, producing systematic false positives for specific destination IP ranges
- Load balancer health checks and synthetic monitoring agents (Pingdom, Datadog Synthetics, AWS Route53 health checks) may probe HTTPS endpoints with mismatched SNI and Host values as a side-effect of monitoring CDN-fronted applications
Other platforms for T1090.004
Testing Methodology
Validate this detection against 4 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1Simulate Domain Fronting HTTP Request with curl
Expected signal: Sysmon Event ID 3 (Network Connection): connection to azureedge.net IP. Network proxy logs (if TLS inspection enabled): SNI=legitimate-front.azureedge.net, Host header=different-domain.azureedge.net — mismatch detected. DNS query for legitimate-front.azureedge.net logged in Sysmon Event ID 22.
- Test 2Install and Run meek-client (Tor Domain Fronting Plugin)
Expected signal: Sysmon Event ID 1: meek-client.exe process creation with -WindowStyle Hidden equivalent arguments including --front=ajax.aspnetcdn.com and --url=https://meek.azureedge.net/. Sysmon Event ID 3: meek-client.exe connecting to azureedge.net on port 443. Sysmon Event ID 22: DNS queries for ajax.aspnetcdn.com and meek.azureedge.net. PowerShell Event ID 4104 from the Invoke-WebRequest download cradle.
- Test 3Cobalt Strike-style Domain Fronting HTTP Request via PowerShell
Expected signal: Sysmon Event ID 3: powershell.exe network connection to ajax.aspnetcdn.com (IP of CDN). Sysmon Event ID 22: DNS query for ajax.aspnetcdn.com. Process Event ID 1 for PowerShell with above CommandLine. Proxy logs (with TLS inspection): Host header value 'c2.attacker-domain.example.com' visible separately from SNI 'ajax.aspnetcdn.com' — mismatch triggers alert.
- Test 4Detect Domainless Fronting via Blank SNI Field
Expected signal: Network logs: TLS ClientHello packet with no SNI extension (empty server_name field in TLS handshake). Proxy logs: destination hostname blank or '-' in the SNI field, while HTTP Host header contains 'target-domain.cloudfront.net'. Sysmon Event ID 3: connection to cloudfront.net IP without associated hostname from DNS.
References (10)
- https://attack.mitre.org/techniques/T1090/004/
- http://www.icir.org/vern/papers/meek-PETS-2015.pdf
- https://www.mandiant.com/resources/blog/no-easy-breach-dhs-and-apt29
- https://www.cobaltstrike.com/blog/cobalt-strike-and-malleaable-c2-profiles/
- https://posts.specterops.io/a-guide-to-attacking-domain-trusts-971e52cb2944
- https://digi.ninja/blog/domain_fronting.php
- https://thedfirreport.com/2021/08/29/cobalt-strike-a-defenders-guide/
- https://github.com/api0cradle/LOLBAS
- https://unit42.paloaltonetworks.com/domain-fronting/
- https://skylightcyber.com/2019/07/18/cobalt-strike-for-the-win/
Unlock Pro Content
Get the full detection package for T1090.004 including response playbook, investigation guide, and atomic red team tests.