T1001 Splunk · SPL

Detect Data Obfuscation in Splunk

Adversaries may obfuscate command and control traffic to make it more difficult to detect. C2 communications are hidden—though not necessarily encrypted—in an attempt to make content more difficult to discover or decipher and to reduce conspicuousness. Observed techniques include adding junk data to protocol traffic to frustrate pattern matching (T1001.001), embedding payloads in image or media files via steganography (T1001.002), and impersonating legitimate protocols to blend with normal traffic (T1001.003). Real-world examples include Okrum hiding C2 commands in HTTP Cookie and Set-Cookie headers, RDAT encoding AES ciphertext in DNS subdomain labels, FunnyDream sending zlib-compressed obfuscated packets, StrelaStealer XOR-encrypting HTTP POST payloads, Ninja modifying HTTP headers and URL paths to masquerade as legitimate services, and TrailBlazer disguising C2 traffic as Google Notifications HTTP requests.

MITRE ATT&CK

Tactic
Command and Control
Technique
T1001 Data Obfuscation
Canonical reference
https://attack.mitre.org/techniques/T1001/

SPL Detection Query

Splunk (SPL)
spl
| multisearch
  [search index=network sourcetype="stream:http"
  | eval detection_vector="HTTP_Obfuscation"
  | eval url_path=coalesce(uri_path, uri, "-")
  | eval user_agent_lower=lower(coalesce(http_user_agent, "-"))
  // Flag 1: Non-standard User-Agent strings not matching known browser/runtime patterns
  | eval flag_suspicious_ua=if(
      NOT match(user_agent_lower, "(mozilla|chrome|safari|firefox|edge|curl|python-requests|go-http-client|wget|java|okhttp|axios)"),
      1, 0
    )
  // Flag 2: Base64 or high-entropy encoded blob in URL path (40+ contiguous Base64 chars)
  | eval flag_encoded_url=if(match(url_path, "[A-Za-z0-9+/]{40,}={0,2}"), 1, 0)
  // Flag 3: Encoded data in Cookie header (Okrum pattern — C2 commands hidden in Cookie values)
  | eval flag_encoded_cookie=if(
      match(coalesce(cookie, "-"), "[A-Za-z0-9+/=]{50,}"),
      1, 0
    )
  // Flag 4: Response body size divisible by cipher block size (16 bytes) — AES block alignment
  // Common indicator of encrypted/padded C2 response with predictable structure
  | eval resp_len=tonumber(coalesce(bytes_out, response_body_len, "0"))
  | eval flag_block_aligned=if(resp_len > 0 AND resp_len < 4096 AND (resp_len % 16)==0, 1, 0)
  // Flag 5: HTTP POST directly to an IP address (no domain) — raw C2 without domain fronting
  | eval flag_post_to_ip=if(
      method=="POST" AND match(coalesce(dest_ip, dest, "-"), "^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$"),
      1, 0
    )
  | eval suspicion_score=flag_suspicious_ua + flag_encoded_url + flag_encoded_cookie + flag_block_aligned + flag_post_to_ip
  | where suspicion_score > 0
  | table _time, src_ip, dest_ip, site, url_path, method, status,
          http_user_agent, cookie, bytes_out,
          flag_suspicious_ua, flag_encoded_url, flag_encoded_cookie,
          flag_block_aligned, flag_post_to_ip, suspicion_score, detection_vector]

  [search index=network (sourcetype="bro:dns" OR sourcetype="zeek:dns")
  | eval detection_vector="DNS_Obfuscation"
  | eval query_name=coalesce(query, "-")
  | eval labels=split(query_name, ".")
  | eval first_label=mvindex(labels, 0)
  | eval label_len=len(first_label)
  // High-entropy subdomain: 30+ chars of Base64/hex alphabet (RDAT/DNS-tunnel pattern)
  | eval flag_encoded_url=if(label_len >= 30 AND match(first_label, "^[A-Za-z0-9+/=_\\-]+$"), 1, 0)
  | eval flag_suspicious_ua=0
  | eval flag_encoded_cookie=0
  | eval flag_block_aligned=0
  | eval flag_post_to_ip=0
  | eval suspicion_score=flag_encoded_url
  | where suspicion_score > 0
  | table _time, src_ip, query_name, first_label, label_len,
          flag_encoded_url, suspicion_score, detection_vector]

  [search index=wineventlog sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=22
  | eval detection_vector="Sysmon_DNS_Obfuscation"
  | eval query_name=coalesce(QueryName, "-")
  | eval labels=split(query_name, ".")
  | eval first_label=mvindex(labels, 0)
  | eval label_len=len(first_label)
  | eval flag_encoded_url=if(label_len >= 30 AND match(first_label, "^[A-Za-z0-9+/=_\\-]+$"), 1, 0)
  | eval flag_suspicious_ua=0
  | eval flag_encoded_cookie=0
  | eval flag_block_aligned=0
  | eval flag_post_to_ip=0
  | eval suspicion_score=flag_encoded_url
  | where suspicion_score > 0
  | table _time, host, Image, User, query_name, first_label, label_len,
          flag_encoded_url, suspicion_score, detection_vector]

| sort - suspicion_score, - _time
high severity medium confidence

Multi-source SPL detection for T1001 Data Obfuscation using multisearch across three data sources: (1) stream:http — analyzes HTTP traffic for five obfuscation indicators: non-standard User-Agent strings, Base64-encoded URL path segments (40+ chars), encoded Cookie header values (Okrum C2 pattern), AES block-aligned response sizes indicating padded/encrypted payloads, and raw HTTP POST to IP addresses. A cumulative suspicion score (1–5) enables priority triage. (2) bro:dns / zeek:dns — detects high-entropy subdomain labels (30+ chars of Base64/hex alphabet) consistent with DNS-tunneled C2 (RDAT pattern). (3) Sysmon Event ID 22 (DNS Query) — catches the same DNS entropy pattern from endpoint telemetry when network Zeek/Bro is unavailable. Results are unioned and sorted by suspicion score descending.

Data Sources

Network Traffic: Network Traffic Content (stream:http)Network Traffic: Network Traffic Flow (bro:dns / zeek:dns)Process: Process Creation (Sysmon Event ID 22 DNS queries)

Required Sourcetypes

stream:httpbro:dnszeek:dnsXmlWinEventLog:Microsoft-Windows-Sysmon/Operational

False Positives & Tuning

  • CDN and object storage services (S3, Azure Blob, CloudFront) that embed long object hashes or signed tokens directly in URL paths — add their domains to an exclusion lookup
  • OAuth2 redirect URIs and SAML assertion URLs carrying base64-encoded tokens — these are expected patterns from identity providers (Google, Azure AD, Okta)
  • Automated monitoring scripts and health-check agents using custom User-Agent strings — build an allowlist of internal scan IPs to suppress flag_suspicious_ua
  • DNS-based service mesh frameworks (Consul, Kubernetes CoreDNS) generating long service-discovery hostnames — exclude internal resolver IPs for DNS obfuscation vectors
  • Enterprise proxy solutions that re-sign or transform URLs during content inspection may produce Base64-looking path segments — validate source IP against known proxy infrastructure before escalating
Download portable Sigma rule (.yml)

Other platforms for T1001


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.

  1. Test 1Encoded C2 Data in DNS Subdomain Queries (RDAT Pattern)

    Expected signal: Sysmon Event ID 22 (DNS Query): Three DNS queries where QueryName contains 30+ character Base64-alphabet subdomains prepended to test-canary.example.com. DNS server query logs (if forwarded to SIEM): same queries with NXDOMAIN responses. Windows DNS Client cache: ipconfig /displaydns will show the queried names.

  2. Test 2Obfuscated Cookie-Based C2 Simulation (Okrum Pattern)

    Expected signal: Sysmon Event ID 3 (Network Connection): outbound connection from powershell.exe to 127.0.0.1:8888. stream:http (if full packet capture enabled): HTTP GET request with Cookie header containing 50+ character Base64 string and a non-standard User-Agent. Sysmon Event ID 1: powershell.exe process creation with the above command line.

  3. Test 3Block-Aligned HTTP POST Payload (AES-Padded C2 Response Pattern)

    Expected signal: Sysmon Event ID 3: Four outbound connections from powershell.exe to 127.0.0.1:9090 with 3-second intervals. stream:http: POST requests to /update with content-type application/octet-stream; User-Agent 'Windows-Update-Agent/10.0' does not match standard Windows Update agent strings. Network bytes_out should reflect block-aligned sizes.

  4. Test 4Junk Data Padding in DNS TXT Record Queries (FunnyDream/Compression Pattern)

    Expected signal: Sysmon Event ID 22: DNS TXT query for a 32-char random-prefix subdomain of junk-obfuscation-test.example.com. Sysmon Event ID 3: outbound HTTP connection from powershell.exe to 127.0.0.1:7777. stream:http: POST with Content-Type application/x-compress and base64-encoded deflate-compressed body — unusual content-type for browser-originated traffic.

Unlock Pro Content

Get the full detection package for T1001 including response playbook, investigation guide, and atomic red team tests.

Response PlaybookInvestigation GuideHunting QueriesAtomic Red Team TestsTuning Guidance

Related Detections