Beaconing and data exfiltration in a PCAP
Finding regular C2 beacons and a DNS tunnel in a packet capture, then writing a detection for the pattern.
Scenario
A one-hour packet capture from a user VLAN was handed over with a note: "something talks to the internet at odd times." I had to find the host, show what it was doing, and give the SOC something they could detect.
Which host is beaconing, and is data leaving through DNS?
Evidence and tools
vlan20.pcap, one hour, about 600 MB- Zeek to turn the capture into searchable logs
- Wireshark to look at individual packets
- A short Sigma rule for the final detection
Analysis
Find the beacon
Zeek's connection log lists every flow. Sorting by destination and counting connections shows which hosts are contacted on a timer.
$ zeek -r vlan20.pcap
$ cat conn.log | zeek-cut id.orig_h id.resp_h id.resp_p | sort | uniq -c | sort -rn | headOne internal host contacted the same external address every 60 seconds, with a small random delay of a few seconds. The payload sizes were nearly identical each time, which is typical for a check-in.
Look at DNS
The same host also sent many DNS queries with very long, random-looking subdomains of one domain.
dns && dns.qry.name.len > 50Decoding the first label of several queries showed pieces of a file name and then base64-like data. That is a DNS tunnel used to move data out in small chunks.
Timeline
- 10:02First beacon60-second check-ins to the external address begin.
- 10:19Tunnel startsLong DNS queries to one domain appear.
- 10:41Largest burstAbout 900 queries in five minutes.
- 10:58Capture endsBeaconing still running.
Findings and IOCs
| Type | Value | Note |
|---|---|---|
| Host | 10.20.1.57 |
Source of the beacons and DNS queries |
| IP | 192.0.2[.]77 |
Beacon destination (sample value) |
| Domain | cdn-sync[.]example |
Used for DNS tunnelling |
| Pattern | 60 s interval, small jitter | Regular check-in |
Detection
A rule for the DNS pattern, written in Sigma form for a DNS log source:
title: Very Long DNS Query Names
status: experimental
logsource:
category: dns
detection:
selection:
query|re: '^[a-z0-9+/=_-]{40,}\.'
condition: selection
falsepositives:
- Some CDNs and anti-virus products use long names
level: mediumConclusion and recommendations
One workstation was acting as a beacon and sending data out over DNS. I would isolate it, collect its memory and disk, and check whether other hosts query the same domain.
- Block the domain and address at the resolver and the firewall
- Alert on long query names and on very regular outbound connections
- Collect DNS logs centrally so the pattern can be searched across hosts
What I would do differently
I would test the rule against a week of normal DNS logs first to measure how many false positives it creates.