Domain Fronting
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.
// Domain Fronting Detection — SNI/Host Header Mismatch and Behavioral Indicators
// Requires network proxy or TLS inspection logs forwarded to Sentinel
// Primary: Look for mismatches between TLS SNI and HTTP Host header in proxy/firewall logs
let KnownCDNDomains = dynamic([
"azureedge.net", "cloudfront.net", "akamaiedge.net", "fastly.net",
"cloudflare.com", "msecnd.net", "trafficmanager.net",
"azurefd.net", "amazonaws.com", "googleusercontent.com"
]);
// Query 1: CommonSecurityLog (proxy/firewall with TLS inspection)
CommonSecurityLog
| where TimeGenerated > ago(24h)
| where DeviceAction !in ("deny", "block")
| where RequestURL has "https://"
| extend DestinationDomain = tolower(DestinationHostName)
| extend RequestHostHeader = extract(@"Host:\s*([^\r\n]+)", 1, AdditionalExtensions)
| where isnotempty(RequestHostHeader)
| where DestinationDomain != tolower(RequestHostHeader)
| where DestinationDomain has_any (KnownCDNDomains) or RequestHostHeader has_any (KnownCDNDomains)
| extend SNIHost = DestinationDomain
| extend HTTPHost = tolower(RequestHostHeader)
| extend IsSNIBlank = (isempty(DestinationDomain) or DestinationDomain == "-")
| extend MismatchType = iff(IsSNIBlank, "Domainless_Fronting", "SNI_Host_Mismatch")
| project TimeGenerated, DeviceName, SourceIP, DestinationIP, SNIHost, HTTPHost,
MismatchType, RequestURL, SourceUserName, BytesSent, BytesReceived,
ApplicationProtocol, DeviceVendor
| sort by TimeGenerated desc Data Sources
Required Tables
False Positives
- Legitimate CDN-hosted applications that use different front-end domains for load balancing or A/B testing where SNI and Host headers intentionally differ
- Corporate split-tunneling VPN configurations where internal proxy rewrites Host headers for SSL inspection purposes
- Web application frameworks or reverse proxies (nginx, HAProxy) that modify Host headers for internal routing, appearing as mismatches in proxy logs
- Content delivery architectures using shared CDN certificates where the certificate domain differs from the requested content domain by design
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.