Detect Command and Control over QUIC/HTTP-3 Evading TLS-Inspecting Proxies in Sumo Logic CSE
QUIC (RFC 9000) and the HTTP/3 application mapping built on it (RFC 9114) run entirely over UDP, encrypt the transport-layer handshake itself, and never expose a classic TCP three-way handshake or a plaintext TLS record layer for a legacy SSL-decrypting proxy to intercept. Most enterprise TLS-inspection appliances and secure web gateways were built around TCP/443 and either cannot terminate QUIC's own handshake or are configured to fall back to 'passthrough' when they encounter UDP/443 traffic they cannot decrypt — which means anything an adversary tunnels inside a QUIC/HTTP-3 session sails past controls that would otherwise fingerprint, block, or log the equivalent HTTPS request. Because Chrome, Edge, and a large and growing fraction of CDN-fronted web traffic (Google, Cloudflare, Fastly, Facebook) now negotiate HTTP/3 by default, a C2 implant that speaks QUIC gets both an inspection blind spot and enormous statistical cover: 'UDP/443 to a CDN IP' is now an unremarkable line in most environments' network logs. This detection is deliberately host- and process-centric rather than payload-centric, because the QUIC handshake itself is encrypted and cannot be content-inspected without terminating it: it flags UDP/443 sessions to non-private destinations that are NOT initiated by a known browser or OS-update process, and further requires either a sustained volume of connections or a session duration long enough to rule out a single incidental probe. It differs from the T1071.001 base record — which describes HTTPS/HTTP C2 generically across the classic TCP/443 path — by encoding the specific field-level signal (protocol=UDP, port=443, non-browser initiating process) that identifies the QUIC transport variant, and by explicitly calling out that this traffic is invisible to any control that only decrypts and inspects TCP/443.
MITRE ATT&CK
- Tactic
- Command and Control
Sumo Detection Query
_sourceCategory=network/paloalto
| parse "src=*," as src_ip nodrop
| parse "dst=*," as dst_ip nodrop
| parse "dport=*," as dest_port nodrop
| parse "proto=*," as proto nodrop
| parse "action=*," as fw_action nodrop
| parse "bytes_sent=*," as bytes_sent nodrop
| parse "bytes_received=*," as bytes_received nodrop
| where fw_action = "allow"
| where proto = "udp"
| where dest_port = "443"
| where !isPrivateIP(dst_ip)
| eval total_bytes = toLong(bytes_sent) + toLong(bytes_received)
| count as SessionCount, sum(total_bytes) as TotalBytes, count_distinct(dst_ip) as DistinctRemoteIPs by src_ip
| where SessionCount >= 10
| sort by SessionCount desc Sumo Logic query over Palo Alto Networks TRAFFIC logs, parsing the standard PAN-OS CSV syslog fields for allowed UDP sessions to a non-private destination on port 443, then aggregating per internal source host. Private-address exclusion uses the built-in isPrivateIP operator rather than a string comparison. Firewall telemetry cannot see the initiating process, so this is the network-layer arm only and should be correlated against endpoint process telemetry (the KQL or SPL rule) before a result is treated as confirmed C2 rather than legitimate QUIC-capable software.
Data Sources
Required Tables
False Positives & Tuning
- Legitimate QUIC-capable third-party applications not distinguishable from firewall flow data alone
- Corporate VPN or SD-WAN clients deliberately tunnelling over UDP/443
- CDN-fronted SaaS integrations generating genuine sustained UDP/443 volume from a shared egress point
- DNS-over-QUIC resolver traffic to a small, stable set of public resolver IPs
Other platforms for THREAT-C2-QUICHTTP3TLSInspectionBypass
Testing Methodology
Validate this detection against 3 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 1Non-Browser HTTP/3 Beacon Simulation via curl (Linux)
Expected signal: Endpoint network telemetry (Sysmon Event ID 3, MDE DeviceNetworkEvents, or auditd network records) showing repeated UDP destination port 443 sessions from the curl process to a non-private remote IP, spaced at roughly one-minute intervals over a 12-minute window.
- Test 2Raw UDP/443 Beacon via PowerShell UdpClient (Windows, Process Arm Only)
Expected signal: Sysmon Event ID 3 and MDE DeviceNetworkEvents: repeated UDP connection records with DestinationPort 443 and InitiatingProcessFileName powershell.exe, spaced roughly 60 seconds apart over a 12-minute window. Because no real QUIC handshake occurs, the destination will not respond meaningfully, which is expected and does not affect the network-layer telemetry this test validates.
- Test 3Non-Browser HTTP/3 Beacon Simulation via curl (macOS)
Expected signal: EDR network-connection telemetry for macOS (for example, MDE for Mac DeviceNetworkEvents or the equivalent EDR network event) showing repeated UDP destination port 443 sessions from the curl process to a non-private remote IP at roughly one-minute intervals.
References (9)
- https://attack.mitre.org/techniques/T1071/001/
- https://attack.mitre.org/tactics/TA0011/
- https://datatracker.ietf.org/doc/html/rfc9000
- https://datatracker.ietf.org/doc/html/rfc9114
- https://github.com/redcanaryco/atomic-red-team/tree/master/atomics/T1071.001
- https://learn.microsoft.com/en-us/defender-xdr/advanced-hunting-devicenetworkevents-table
- https://learn.microsoft.com/en-us/sysinternals/downloads/sysmon
- https://blog.cloudflare.com/http3-the-past-present-and-future/
- https://docs.zeek.org/en/current/scripts/base/protocols/quic/main.zeek.html
Response Playbook
Triage
- Confirm the initiating process is genuinely not QUIC-capable browser or OS-update software under a different install path or renamed binary — check the digital signature and publisher, not just the file name, since a masquerading implant may simply drop a file named chrome.exe outside the real browser install directory.
- Pull the process's parent chain and command line. A QUIC-speaking process launched from an interactive shell, a scheduled task, an Office application, or an unsigned parent is far more consistent with an implant than with legitimate software.
- Check whether the destination IPs resolve to a small, well-known CDN or cloud-fronting range (Cloudflare, Fastly, Google, Akamai) versus a narrow, low-reputation ASN. Legitimate QUIC-capable third-party tools tend to talk to large CDN ranges; a bespoke C2 front is more likely to sit behind a single provider with few other tenants.
- Look at connection regularity. A fixed or near-fixed interval between sessions (beaconing) from the same process to the same one or two destinations is a stronger indicator than steady but organically-varying traffic to many distinct CDN edges, which is what a browser or updater typically produces.
- Check whether the organisation's TLS-inspecting proxy or NGFW actually decrypts and logs this UDP/443 session, or only shows it as a passthrough/unknown-protocol flow — the absence of any corresponding proxy-layer visibility for high-volume UDP/443 traffic is itself a strong signal the control has a blind spot being exploited.
- Search the host for other indicators of compromise in the same window — new scheduled tasks, registry Run key persistence, credential access, or lateral movement tooling — since a QUIC-based C2 channel is typically paired with conventional post-exploitation activity once command execution is established.
Containment
- Isolate the endpoint via EDR network isolation rather than only blocking the destination IP or ASN, since QUIC-based implants commonly rotate through many CDN-fronted IPs and an IP block alone will not reliably sever the channel.
- Terminate the offending process and capture its memory first if the investigation may need in-memory configuration, keys, or staged commands, since QUIC's encrypted transport means the wire traffic itself will not yield that information after the fact.
- Where the organisation has no legitimate business need for the specific application, block it by hash, publisher, or path with the EDR or application-control policy rather than relying on a network-layer rule.
- As an interim network control, configure the perimeter to block outbound UDP/443 for hosts or segments that have no legitimate QUIC use case, forcing any remaining C2 traffic to fall back to TCP/443 where existing TLS-inspection and SNI-based controls regain visibility.
- Escalate to the team owning TLS-inspection policy to confirm whether QUIC passthrough is an intentional exception or an unreviewed gap, since this detection's entire premise is that many proxies silently do not decrypt UDP/443.
Evidence Collection
- Full Sysmon Event ID 3 (or MDE DeviceNetworkEvents) history for the host across the whole activity window, not only the alerting window, since QUIC-based beacons often start at low volume before ramping up.
- Process memory of the flagged process, captured before termination, since the QUIC handshake and any application-layer payload inside it are encrypted end-to-end and unrecoverable from wire captures alone.
- Any available NGFW or TLS-inspecting-proxy logs for the same host and time window, specifically checking whether the UDP/443 flow was logged as passthrough, blocked, or not logged at all — this establishes the actual inspection gap being exploited.
- Prefetch, ShimCache, Amcache, and the parent process's own artifacts, to establish how the flagged binary arrived on the host and whether it was dropped by another process or user-installed.
- A packet capture (pcap) of a live or reproduced session for QUIC version and ALPN negotiation fields — while the payload is encrypted, the initial handshake still reveals whether HTTP/3 was actually negotiated versus a raw UDP protocol merely using port 443 for cover.
Escalation Criteria
- !The flagged process is unsigned, is not a known application, or is running from a user-writable or temp directory rather than a standard install path.
- !Connection regularity shows a fixed-interval beacon pattern to one or two low-reputation destinations rather than organic traffic to a broad CDN range.
- !The organisation's TLS-inspection or SSL-decryption policy confirms it does not decrypt or log UDP/443 traffic, meaning this channel has been fully blind to existing controls.
- !The same process or destination pattern appears on multiple hosts in a short window, indicating deployed tooling rather than one-off software choice.
- !The host also shows credential access, persistence establishment, or lateral-movement tooling in the same window, indicating the QUIC channel is live C2 rather than incidental application traffic.
- !The activity originates from a server, domain controller, jump host, or other privileged management system rather than a general user workstation.
Investigation Guide
Related Techniques
Forensic Artifacts
- >
Sysmon Event ID 3 / MDE DeviceNetworkEvents records showing UDP destination port 443 sessions from a non-browser initiating process — the primary artifact this detection depends on. - >
NGFW or TLS-inspecting-proxy logs (or their absence) for the same UDP/443 flow, which establish whether the traffic was decrypted, passed through, or never logged at all. - >
Process memory of the flagged binary, since QUIC's encrypted handshake and application data leave no recoverable plaintext on the wire. - >
Prefetch, ShimCache, and Amcache entries for the flagged binary, establishing first-execution time and install path. - >
A packet capture showing the QUIC Initial packet's ALPN extension (revealing h3 negotiation) even though later packets are fully encrypted, useful for confirming genuine HTTP/3 use versus a raw-UDP protocol merely reusing port 443.
Tuning Guidance
Build the QUIC-capable-application allowlist before enabling this in alerting mode: run the fleet-wide non-browser UDP/443 hunt over 30 days and add every legitimate third-party application (VoIP clients, game launchers, VPN/SD-WAN software, DNS-over-QUIC resolvers) to the exclusion list by process name and, where available, publisher signature rather than by name alone, since a masquerading implant can trivially reuse a common file name. Do not lower the connection-count and duration thresholds without first confirming what legitimate QUIC-capable software is already present, because these two thresholds are what separates a beaconing implant from a single incidental QUIC negotiation by an otherwise benign library. Treat any host that reaches a destination exclusively over UDP/443 with no corresponding TCP/443 session as higher priority than one that mixes both, since real browsers typically retain TCP as a fallback and a QUIC-only relationship is the strongest available signal from network metadata alone. If the organisation's TLS-inspecting proxy can be configured to block rather than passthrough undecryptable QUIC — forcing all clients to negotiate TCP/443 instead — that policy change is a more durable control than this detection and should be pursued in parallel; where it is not feasible (for example, because it breaks a business-critical QUIC-dependent SaaS integration), this detection becomes the primary compensating control and its false-positive list should be reviewed on a monthly cadence as new QUIC-capable software is adopted.
Hunting Queries
Fleet-wide 30-day hunt for every non-browser process observed making a UDP/443 connection, independent of the volume and duration thresholds used in the alerting rule. Because this will surface every legitimate QUIC-capable third-party application in the environment (VoIP clients, game launchers, VPN software), the output is the correct starting point for building the process-name and publisher allowlist the alerting rule's exclusion list depends on, and for spotting outliers — a process seen on only one or two hosts fleet-wide, with no obvious business purpose, is the pattern worth escalating first.
// Hunt: fleet-wide inventory of every non-browser process making any UDP/443 connection, regardless of volume, to build the QUIC-capable-application allowlist
DeviceNetworkEvents
| where Timestamp > ago(30d)
| where ActionType == "ConnectionSuccess"
| where Protocol =~ "Udp"
| where RemotePort == 443
| where ipv4_is_private(RemoteIP) == false
| where InitiatingProcessFileName !in~ ("chrome.exe", "msedge.exe", "firefox.exe", "brave.exe", "opera.exe", "GoogleUpdate.exe", "MicrosoftEdgeUpdate.exe")
| summarize ConnectionCount = count(), DistinctRemoteIPs = dcount(RemoteIP), Devices = dcount(DeviceId), FirstSeen = min(Timestamp), LastSeen = max(Timestamp) by InitiatingProcessFileName, InitiatingProcessFolderPath
| sort by Devices desc index=windows sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=3
| eval ImageLower=lower(coalesce(Image, "unknown"))
| eval ProtocolLower=lower(coalesce(Protocol, ""))
| eval DestPort=tonumber(coalesce(DestinationPort, "-1"))
| where ProtocolLower="udp" AND DestPort=443
| where NOT (like(ImageLower, "%\\chrome.exe") OR like(ImageLower, "%\\msedge.exe") OR like(ImageLower, "%\\firefox.exe") OR like(ImageLower, "%\\brave.exe") OR like(ImageLower, "%\\opera.exe"))
| stats count as ConnectionCount, dc(DestinationIp) as DistinctRemoteIPs, dc(ComputerName) as Devices, min(_time) as FirstSeen, max(_time) as LastSeen by ImageLower
| eval FirstSeen=strftime(FirstSeen, "%Y-%m-%d %H:%M:%S"), LastSeen=strftime(LastSeen, "%Y-%m-%d %H:%M:%S")
| sort - Devices Hunts for destination IPs that a host reaches exclusively over UDP/443 with no accompanying TCP/443 session over the same window. Ordinary QUIC-capable browsers almost always retain a TCP/443 fallback path and mix both protocols to the same CDN edge over time; a destination reached only ever via UDP/443 from a given host is a stronger indicator of a purpose-built QUIC channel (browser or otherwise) than raw connection volume alone, and is specifically the pattern that defeats a TCP-only SNI allowlist.
// Hunt: UDP/443 sessions with no corresponding TCP/443 TLS session to the same remote IP from the same host, indicating QUIC-only communication that a TCP-based SNI allowlist would never see
let UdpTargets = DeviceNetworkEvents | where Timestamp > ago(7d) | where Protocol =~ "Udp" and RemotePort == 443 | distinct DeviceId, RemoteIP;
let TcpTargets = DeviceNetworkEvents | where Timestamp > ago(7d) | where Protocol =~ "Tcp" and RemotePort == 443 | distinct DeviceId, RemoteIP;
UdpTargets
| join kind=leftanti TcpTargets on DeviceId, RemoteIP
| summarize QuicOnlyDestinations = make_set(RemoteIP, 20) by DeviceId index=windows sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=3
| eval ProtocolLower=lower(coalesce(Protocol, ""))
| eval DestPort=tonumber(coalesce(DestinationPort, "-1"))
| where DestPort=443
| eval PairKey=ComputerName.":".DestinationIp
| stats values(ProtocolLower) as ProtocolsSeen by PairKey, ComputerName, DestinationIp
| where mvcount(ProtocolsSeen)=1 AND ProtocolsSeen="udp"
| table ComputerName, DestinationIp Atomic Red Team Tests
Uses a curl build with HTTP/3 support to repeatedly negotiate a genuine QUIC/HTTP-3 session to a public HTTP/3-enabled endpoint from a non-browser process at a fixed interval, simulating the beacon shape this detection targets. Run only on an authorised lab host with permission to generate this outbound traffic.
Command
for i in $(seq 1 12); do
curl --http3-only --max-time 10 -s -o /dev/null https://cloudflare-quic.com/ || curl --http3 --max-time 10 -s -o /dev/null https://cloudflare-quic.com/
sleep 60
done
echo 'HTTP/3 non-browser beacon simulation complete' Cleanup
true Expected Telemetry
Endpoint network telemetry (Sysmon Event ID 3, MDE DeviceNetworkEvents, or auditd network records) showing repeated UDP destination port 443 sessions from the curl process to a non-private remote IP, spaced at roughly one-minute intervals over a 12-minute window.
Expected Detection
The rule should flag the host and the curl process once ConnectionCount reaches 10 and DurationMinutes reaches at least 11, since curl is not on the known-browser exclusion list. If the local curl build lacks HTTP/3 support, both curl invocations will fail silently per iteration and no QUIC traffic will be generated — confirm with 'curl --version' that HTTP/3 is listed before relying on this test.
Sends UDP datagrams to a remote host on port 443 from PowerShell at a fixed interval without performing a real QUIC handshake. This exercises only the network-arm signal (non-browser process, UDP, port 443, repeated over time) and is a safe, lightweight way to validate the detection's field logic on a corporate endpoint without depending on HTTP/3 protocol support anywhere in the path.
Command
$targetIp = "1.1.1.1"
$udpClient = New-Object System.Net.Sockets.UdpClient
$bytes = [System.Text.Encoding]::ASCII.GetBytes("atomic-test-quic-beacon")
for ($i = 0; $i -lt 12; $i++) {
$udpClient.Send($bytes, $bytes.Length, $targetIp, 443) | Out-Null
Start-Sleep -Seconds 60
}
$udpClient.Close()
Write-Host 'Raw UDP/443 beacon simulation complete' Cleanup
Get-Process -Name powershell -ErrorAction SilentlyContinue | Where-Object { $_.Id -eq $PID } | Out-Null Expected Telemetry
Sysmon Event ID 3 and MDE DeviceNetworkEvents: repeated UDP connection records with DestinationPort 443 and InitiatingProcessFileName powershell.exe, spaced roughly 60 seconds apart over a 12-minute window. Because no real QUIC handshake occurs, the destination will not respond meaningfully, which is expected and does not affect the network-layer telemetry this test validates.
Expected Detection
The rule should flag DeviceName/ComputerName with InitiatingProcessFileName powershell.exe once ConnectionCount reaches 10 and DurationMinutes reaches at least 11. This test validates the field-matching and thresholding logic independent of whether the destination actually speaks QUIC, and should be paired with the curl-based test to also validate genuine HTTP/3 negotiation end to end.
Uses curl's HTTP/3 support on macOS to repeatedly negotiate a genuine QUIC session to a public HTTP/3 endpoint from a non-browser process, validating the same beacon pattern on a Unix-like endpoint with a different EDR/telemetry stack than Windows Sysmon.
Command
for i in $(seq 1 12); do
curl --http3-only --max-time 10 -s -o /dev/null https://cloudflare-quic.com/ || curl --http3 --max-time 10 -s -o /dev/null https://cloudflare-quic.com/
sleep 60
done
echo 'HTTP/3 non-browser beacon simulation complete (macOS)' Cleanup
true Expected Telemetry
EDR network-connection telemetry for macOS (for example, MDE for Mac DeviceNetworkEvents or the equivalent EDR network event) showing repeated UDP destination port 443 sessions from the curl process to a non-private remote IP at roughly one-minute intervals.
Expected Detection
The rule should flag the host and the curl process once ConnectionCount reaches 10 and DurationMinutes reaches at least 11, since curl is not on the known-browser exclusion list. macOS system curl builds do not always ship with HTTP/3 support; verify with 'curl --version' and install a Homebrew curl build with HTTP/3 enabled if the bundled version lacks it.
Related Detections
Tactic Hub
Detection Variants (1)
Different telemetry and tradecraft for the same technique — pick the one that matches the data you collect.