Wireshark
Wireshark packet analysis — display filters, protocol dissection, and traffic investigation.
Wireshark — Security-Focused Analysis
Capture and Display Filters
Capture filters (BPF syntax) limit what gets written to disk. Display filters (Wireshark syntax) limit what you see. Use capture filters for targeted collection; display filters for analysis.
Capture filters — applied during capture (BPF syntax)
# Capture only RADIUS traffic
udp port 1812 or udp port 1813
# Capture traffic to/from a specific host
host 10.50.1.20
# Capture only TCP SYN packets (connection attempts)
tcp[tcpflags] & (tcp-syn) != 0 and tcp[tcpflags] & (tcp-ack) == 0
# Capture DNS traffic
udp port 53 or tcp port 53
# Capture everything except SSH (reduce noise during remote capture)
not port 22
CLI capture with tshark — headless Wireshark
# Capture 1000 packets of RADIUS traffic to file
sudo tshark -i eth0 -c 1000 -f "udp port 1812 or udp port 1813" -w /tmp/radius.pcap
# Capture with ring buffer — 10 files of 100MB each (prevents disk fill)
sudo tshark -i eth0 -b filesize:102400 -b files:10 -w /tmp/capture.pcap
# Read a pcap and apply a display filter
tshark -r capture.pcap -Y "eap" -T fields -e frame.time -e eth.src -e eap.type
RADIUS and EAP-TLS Analysis
Display filter — isolate RADIUS authentication exchanges
radius
Display filter — show only RADIUS Access-Reject (failed auth)
radius.code == 3
Display filter — show only RADIUS Access-Accept (successful auth)
radius.code == 2
Display filter — isolate EAP messages within RADIUS
eap
Display filter — EAP-TLS specifically
eap.type == 13
Display filter — show EAP failures only
eap.code == 4
RADIUS/EAP-TLS exchange — what a successful 802.1X auth looks like
1. RADIUS Access-Request (EAP-Response/Identity) 2. RADIUS Access-Challenge (EAP-Request/EAP-TLS: Server Hello, Certificate) 3. RADIUS Access-Request (EAP-Response/EAP-TLS: Client Certificate, Key Exchange) 4. RADIUS Access-Challenge (EAP-Request/EAP-TLS: Change Cipher Spec) 5. RADIUS Access-Request (EAP-Response/EAP-TLS: Finished) 6. RADIUS Access-Accept (EAP-Success, VLAN attributes) Key fields to inspect: - radius.User-Name — who is authenticating - radius.Calling-Station-Id — client MAC address - radius.NAS-IP-Address — switch/AP sending the request - radius.Tunnel-Private-Group-Id — assigned VLAN - eap.tls.handshake.certificate — client/server certificates
Extract RADIUS username and result with tshark
tshark -r radius.pcap -Y "radius" \
-T fields -e frame.time -e radius.code -e radius.User_Name \
-e radius.Calling_Station_Id -e radius.NAS_IP_Address \
| awk -F'\t' '{
code = "Unknown"
if ($2 == 1) code = "Access-Request"
if ($2 == 2) code = "Access-Accept"
if ($2 == 3) code = "Access-Reject"
if ($2 == 11) code = "Access-Challenge"
printf "%-25s %-18s %-20s %-18s %s\n", $1, code, $3, $4, $5
}'
TLS Handshake Inspection
Display filter — TLS handshake messages only
tls.handshake
Display filter — TLS Client Hello (see what the client supports)
tls.handshake.type == 1
Display filter — TLS Server Hello (see what the server chose)
tls.handshake.type == 2
Display filter — TLS certificate messages
tls.handshake.type == 11
Display filter — TLS alerts (errors, version mismatches)
tls.alert_message
Extract TLS versions and cipher suites with tshark
tshark -r capture.pcap -Y "tls.handshake.type == 2" \
-T fields -e ip.src -e ip.dst -e tls.handshake.version \
-e tls.handshake.ciphersuite \
| sort | uniq -c | sort -rn
Detect weak TLS — SSLv3 or TLS 1.0 (should be disabled)
tls.handshake.version <= 0x0301
Detect self-signed or expired certificates
# Export certificates from pcap, then inspect
tshark -r capture.pcap -Y "tls.handshake.type == 11" \
-T fields -e tls.handshake.certificate \
| head -1 | xxd -r -p | openssl x509 -inform DER -text -noout
JA3 fingerprinting — identify TLS clients by their Client Hello pattern
# JA3 hash is in tshark with the ja3 plugin
tshark -r capture.pcap -Y "tls.handshake.type == 1" \
-T fields -e ip.src -e ja3.hash -e tls.handshake.extensions_server_name \
| sort | uniq -c | sort -rn | head -20
DNS Tunneling Detection
DNS tunneling hides data in DNS queries — long subdomain labels, high query volume, TXT record abuse.
Display filter — DNS queries only (not responses)
dns.flags.response == 0
Display filter — DNS TXT record queries (common tunneling vector)
dns.qry.type == 16
Display filter — DNS queries with long domain names (tunneling indicator)
dns.qry.name.len > 50
Detect DNS tunneling patterns with tshark
# Find domains with unusually long queries — data encoded in subdomain
tshark -r capture.pcap -Y "dns.flags.response == 0" \
-T fields -e ip.src -e dns.qry.name \
| awk -F'\t' 'length($2) > 50 {print $1, length($2), $2}' \
| sort -k2 -rn | head -20
Count DNS queries per source IP — high volume = suspicious
tshark -r capture.pcap -Y "dns.flags.response == 0" \
-T fields -e ip.src \
| sort | uniq -c | sort -rn | head -10
Find queries to non-standard DNS servers — possible exfiltration
tshark -r capture.pcap -Y "dns.flags.response == 0 && !(ip.dst == 10.50.1.1)" \
-T fields -e ip.src -e ip.dst -e dns.qry.name \
| head -20
ARP Spoofing Detection
Display filter — ARP requests and replies
arp
Display filter — duplicate IP detection (ARP announcements)
arp.duplicate-address-detected
Detect ARP spoofing — multiple MAC addresses claiming the same IP
tshark -r capture.pcap -Y "arp.opcode == 2" \
-T fields -e arp.src.hw_mac -e arp.src.proto_ipv4 \
| sort -t$'\t' -k2 | uniq | awk -F'\t' '{
if (prev_ip == $2 && prev_mac != $1) {
print "SPOOF DETECTED: IP " $2 " claimed by " prev_mac " AND " $1
}
prev_ip = $2; prev_mac = $1
}'
Gratuitous ARP — unsolicited announcements (spoofing technique)
arp.isgratuitous == 1
Credential and Cleartext Detection
These filters help identify defensive gaps — cleartext protocols that should be encrypted.
HTTP Basic Auth — base64 credentials in the clear
http.authorization
Extract HTTP Basic Auth credentials (for defense validation)
tshark -r capture.pcap -Y "http.authorization" \
-T fields -e ip.src -e ip.dst -e http.host -e http.authorization \
| awk -F'\t' '{
split($4, a, " ")
if (a[1] == "Basic") {
cmd = "echo " a[2] " | base64 -d 2>/dev/null"
cmd | getline decoded
close(cmd)
print "Src:", $1, "Dst:", $2, "Host:", $3, "Creds:", decoded
}
}'
FTP cleartext credentials
ftp.request.command == "USER" || ftp.request.command == "PASS"
Telnet traffic — should not exist on your network
telnet
SMTP cleartext auth
smtp.auth.username || smtp.auth.password
HTTP POST bodies — form submissions with possible credentials
http.request.method == "POST" && http.content_type contains "form"
Malicious Traffic Patterns
Detect port scanning — many SYN packets to different ports, no established connections
tshark -r capture.pcap -Y "tcp.flags.syn == 1 && tcp.flags.ack == 0" \
-T fields -e ip.src -e ip.dst -e tcp.dstport \
| awk '{print $1, $2}' | sort | uniq -c | sort -rn | head -10
# High count from single source to single dest = port scan
Detect beaconing — regular interval callbacks to C2
tshark -r capture.pcap -Y "ip.dst == 203.0.113.50" \
-T fields -e frame.time_epoch \
| awk 'NR>1 {printf "%.1f\n", $1-prev} {prev=$1}' \
| sort | uniq -c | sort -rn | head -5
# Consistent intervals (e.g., every 60.0 seconds) = beaconing
Detect large data transfers — possible exfiltration
tcp.len > 10000
Extract all unique external IPs contacted — threat intel fodder
tshark -r capture.pcap -T fields -e ip.dst \
| sort -u \
| awk '!/^10\./ && !/^172\.(1[6-9]|2[0-9]|3[01])\./ && !/^192\.168\./' \
| sort -u > /tmp/external_ips.txt
wc -l /tmp/external_ips.txt
Useful Wireshark Features
Follow TCP Stream: Right-click packet → Follow → TCP Stream
Reconstructs the full conversation in order
Expert Info: Analyze → Expert Information
Shows warnings, errors, retransmissions, resets
Statistics:
Conversations: Statistics → Conversations → sort by bytes
Protocol Hierarchy: Statistics → Protocol Hierarchy — what's on the wire
IO Graphs: Statistics → IO Graphs — traffic volume over time
DNS: Statistics → DNS — query types, response codes
Coloring rules: View → Coloring Rules
Red = errors/resets, green = normal, etc.
Time display: View → Time Display Format → UTC Date and Time
Always use UTC for incident investigation