Chapter 2.4 Quiz - Encrypted Traffic Analysis & TLS Inspection
Quiz Mode - All answers are hidden under collapsible sections. Attempt each question before revealing the answer.
Question 1
A threat hunter notices regular outbound TLS connections from 192.168.5.44 to a cloud IP every 60 seconds. The byte volume per session is approximately 1-2 KB. The jitter ratio across 120 sessions is 0.025. What is the most likely explanation, and what Zeek log field would you first examine to confirm?
Reveal Answer
Answer: C2 beaconing
Explanation: The combination of regular interval (60s), low byte volume (check-in with no tasking), and extremely low jitter ratio (0.025 - essentially machine-precise timing) is the textbook signature of a C2 beacon. Human-driven traffic has jitter ratios above 0.5; malware beacons are often below 0.1.
First Zeek log to examine: conn.log - specifically the ts (timestamp), id.orig_h, id.resp_h, duration, orig_bytes, and resp_bytes fields. Sort by timestamp for the source/destination pair and compute inter-arrival deltas.
cat conn.log | zeek-cut ts id.orig_h id.resp_h orig_bytes resp_bytes | \
awk '$2 == "192.168.5.44"' | sort -k1 | \
awk 'prev != "" { print $1 - prev, $0 } { prev=$1 }'
Follow-up: Check ssl.log for the JA3 hash of these sessions and look it up against known-bad JA3 databases (ET JA3 feed, abuse.ch). Also check dns.log for the resolution of the destination IP - DGA-generated domains or recently registered domains are strong C2 indicators.
MITRE ATT&CK: T1071.001 (Application Layer Protocol: Web Protocols), T1573.002 (Encrypted Channel)
Question 2
You are performing TLS inspection on a corporate proxy. A workstation sends a ClientHello with SNI=allowed-cdn.cloudflare.com, but after decryption you observe the HTTP Host header reads c2.malware-domain.ru. What attack technique is this, and what is the most reliable network-layer control to prevent it?
Reveal Answer
Answer: Domain Fronting (MITRE ATT&CK T1090.004)
Explanation: Domain fronting abuses the architectural split between TLS routing (SNI) and HTTP routing (Host header) on CDN infrastructure. The CDN accepts the TLS connection based on SNI (pointing to a legitimate domain it hosts), then routes the HTTP request based on the Host header (pointing to the attacker's origin). From the firewall's perspective, the destination IP belongs to Cloudflare and SNI looks legitimate.
Most reliable controls:
- TLS inspection - only effective control that exposes the Host header mismatch. Without decryption, you see only the SNI.
- SNI/Host correlation rule (post-decryption): Alert when SNI does not match HTTP Host header. Implement in mitmproxy addon or Suricata rule.
- CDN-level mitigation - Cloudflare, Fastly, and AWS CloudFront have disabled domain fronting for most plans, but it remains possible on some CDNs.
# mitmproxy detection addon
def request(self, flow):
sni = flow.client_conn.tls_extensions.get("server_name","")
host = flow.request.headers.get("host","")
if sni and host and sni.lower() not in host.lower():
# Block or alert
flow.response = mitmproxy.http.Response.make(
403, b"Domain fronting blocked", {"Content-Type": "text/plain"})
Defensive note: DNS-layer filtering can partially mitigate this by blocking the HTTPS DNS record type, which prevents ECH key retrieval - but does not prevent basic domain fronting.
Question 3
You have a PCAP of a TLS 1.2 session where the server used ECDHE-RSA-AES256-GCM-SHA384 cipher. You have the server's RSA private key. Can you decrypt the session? Explain why or why not, and what artifact you would need instead.
Reveal Answer
Answer: No - because ECDHE provides Perfect Forward Secrecy.
Explanation:
In cipher suites beginning with ECDHE (Elliptic Curve Diffie-Hellman Ephemeral), the session key is derived from ephemeral DH key material generated fresh for each session. The server's RSA private key is only used to authenticate the DH key exchange (sign the server's ephemeral DH public key), not to encrypt the pre-master secret. As a result:
- Possessing the server's RSA private key tells you nothing about the session key
- Even if you captured the handshake, the pre-master secret was never transmitted encrypted under the RSA key - it was computed independently by both sides from the DH exchange
- Compromising the RSA key after the session doesn't help; the ephemeral DH keys were discarded after the handshake
What you need instead:
- SSLKEYLOGFILE output from the client or server at the time of the session - this records the session-specific master secret
- Endpoint memory forensics - extracting the session key from the process's memory space during the session
# Confirm cipher suite in capture
tshark -r capture.pcap \
-Y 'tls.handshake.type == 2' \
-T fields -e tls.handshake.ciphersuite
# 0xC030 = TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 -> PFS -> private key useless
# If you had SSLKEYLOGFILE:
tshark -r capture.pcap \
-o "tls.keylog_file:/tmp/session_keys.log" \
-Y http -T fields -e http.request.uri
MITRE ATT&CK context: Perfect Forward Secrecy (T1573.002) is explicitly favored by sophisticated actors precisely because it prevents retrospective decryption even if the server is later compromised.
Question 4
A Suricata rule fires on a JA3 hash matching a known Cobalt Strike default profile. The SOC analyst dismisses it as a false positive because the destination domain has a valid Let's Encrypt certificate and resolves to a major CDN. Why might the analyst be wrong, and what three additional data points should be collected before closing the alert?
Reveal Answer
Answer: The analyst is conflating certificate legitimacy with traffic legitimacy.
Explanation: A valid Let's Encrypt certificate proves only that the domain owner completed a DNS or HTTP challenge at the time of issuance - it says nothing about the purpose of the server. Let's Encrypt is free, automated, and issues certificates to malicious infrastructure constantly. CDN hosting is equally neutral - attackers routinely use AWS CloudFront, Azure CDN, and Cloudflare to host C2 infrastructure, gaining reputation cover and geographic distribution.
The JA3 match is evidence of the client's TLS library configuration matching a known-bad profile. This is independent of what the server is.
Three additional data points to collect:
-
Beaconing pattern - Query
conn.logfor the source IP's connection history to this destination. Regular interval + low jitter + small byte volume = beacon.cat conn.log | zeek-cut ts id.orig_h id.resp_h orig_bytes | \
awk '$2 == "ALERT_SRC_IP" && $3 == "ALERT_DST_IP"' | sort -k1 -
Process responsible for the connection - Correlate the alert timestamp with EDR/endpoint telemetry. Which process opened the TLS connection?
cmd.exe,powershell.exe, orsvchost.exemaking TLS connections is highly suspicious. -
JARM fingerprint of the server - Actively scan the destination server's TLS stack fingerprint and compare against known Cobalt Strike Team Server JARM hashes. A CDN serving legitimate content will not have a CS Team Server JARM.
python3 jarm.py destination-domain.com -p 443
# Compare output to: 2ad2ad0002ad2ad00042d42d000000ad9bf51cc3f5a1e29eecb81d0c7b06eb
MITRE ATT&CK: T1071.001, T1090.004, T1583.004 (Acquire Infrastructure: Server)
End of Quiz 2.4 - Encrypted Traffic Analysis & TLS Inspection