kavklaw@llm ~ /guides/wireshark

kavklaw@llm $ cat wireshark-guide.md

Wireshark โ€” Network Traffic Analysis

๐ŸŸก Intermediate

โฑ๏ธ 25 min read ยท From your first capture to forensic-level packet analysis and CTF pcap challenges

โ† Back to Guides

โšก Quick Start

Need to analyze a pcap file (a saved recording of network traffic) right now? Here's the 90-second version:

wireshark capture.pcap                          # Open in GUI
tshark -r capture.pcap | head -50               # Quick CLI overview
tshark -r capture.pcap -Y "http"                # Find HTTP traffic
tshark -r capture.pcap --export-objects http,exported_files/    # Extract files
tshark -r capture.pcap -Y "http.request.method == POST" -T fields -e http.file_data   # Credentials
tshark -r capture.pcap -z "follow,tcp,ascii,0"  # Follow a TCP stream

That covers the essentials. Now let's understand how Wireshark works, how to filter like a pro, and how to crack CTF pcap challenges.

๐ŸŒ What Is Wireshark?

Wireshark lets you see packets visible at your capture point. It captures traffic flowing across a network interface and breaks it down into a readable format โ€” you see exactly what's happening, byte by byte.

Started as Ethereal in 1998, renamed Wireshark in 2006. You'll use it for:

  • Penetration testers โ€” analyzing traffic for credentials, sensitive data, and attack vectors
  • CTF players โ€” solving pcap forensics challenges
  • Network engineers โ€” troubleshooting connectivity and performance issues
  • Security analysts โ€” investigating incidents and detecting malicious activity
  • Malware analysts โ€” understanding what malware communicates over the network

Wireshark speaks hundreds of protocols โ€” from Ethernet and IP at the bottom to HTTP, DNS, SMB, TLS at the top. It breaks each packet into its fields, color-codes traffic by type, and lets you filter down to exactly what you're looking for.

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Wireshark Packet Dissection (what you see per packet) โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Layer 7  Application โ”‚  HTTP, DNS, FTP, SMB, TLS     โ”‚
โ”‚ Layer 4  Transport   โ”‚  TCP / UDP  (ports, flags)     โ”‚
โ”‚ Layer 3  Network     โ”‚  IP  (src/dst addresses)       โ”‚
โ”‚ Layer 2  Data Link   โ”‚  Ethernet  (MAC addresses)     โ”‚
โ”‚ Layer 1  Raw         โ”‚  Frame bytes (hex dump)        โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Wireshark expands each layer โ€” click to drill down    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The real power is the display filter engine. The right filter pulls a single login attempt out of millions of packets. Master the filters and you master Wireshark.

Wireshark comes pre-installed on Kali Linux and Parrot OS. For other systems:

# Kali/Debian/Ubuntu
sudo apt update && sudo apt install wireshark tshark
sudo usermod -aG wireshark $USER   # Allow capture without root

# Fedora/RHEL
sudo dnf install wireshark wireshark-cli

# Arch Linux
sudo pacman -S wireshark-qt

# macOS (via Homebrew)
brew install --cask wireshark

# Verify installation
wireshark --version
tshark --version

โš ๏ธ Permissions matter: Raw packet capture requires root privileges or membership in the wireshark group. During installation on Debian/Ubuntu, you'll be asked "Should non-superusers be able to capture packets?" โ€” select YES, then add your user to the wireshark group with the usermod command above. Log out and back in (or run newgrp wireshark) for the group change to take effect. Without this, you can only analyze existing pcap files โ€” live capture won't work.

๐Ÿ’ก Pro Tip: You don't always need the GUI. tshark (the terminal-based Wireshark) is faster for scripting and remote analysis. If you're SSH'd into a machine, tshark is your best friend. Many CTF challenges can be solved entirely from the command line.

Capturing Without Root

Raw packet capture normally requires root privileges. The wireshark group method above avoids running Wireshark as root (which is a security risk). Alternatively, capture with tcpdump as root and analyze the resulting pcap file as a regular user:

sudo tcpdump -i eth0 -w capture.pcap

Then open capture.pcap in Wireshark as non-root.

๐Ÿ“ก Capturing Traffic

When you open Wireshark, the welcome screen shows all available network interfaces with sparkline traffic graphs. Double-click an interface to start capturing.

Choosing the Right Interface

tshark -D                              # List available interfaces

Common interfaces:

  • eth0 โ€” Wired Ethernet
  • wlan0 โ€” Wireless
  • lo โ€” Loopback (localhost traffic)
  • tun0 โ€” VPN tunnel (HTB/THM)
  • any โ€” Capture on ALL interfaces
tshark -i tun0 -w htb_capture.pcap     # HTB/THM โ€” always capture on tun0
tshark -i lo -w localhost_capture.pcap  # Local web app testing โ€” use loopback

Promiscuous vs Monitor Mode

Promiscuous mode (default) captures all traffic the NIC (Network Interface Card โ€” your network adapter) can see, not just traffic destined for your MAC address (the hardware address unique to your network adapter). On a switched network, you'll mostly see your own traffic plus broadcasts.

Monitor mode (wireless only) puts your wireless adapter into a raw capture mode that can see all WiFi frames in range, including traffic between other devices. This is essential for wireless pentesting.

sudo airmon-ng start wlan0             # Enable monitor mode โ†’ creates wlan0mon
tshark -i wlan0mon -c 1000 -w wifi_capture.pcap

๐Ÿ” Display Filters vs Capture Filters

This distinction trips up every beginner. Wireshark has two completely different filter systems with different syntax:

Capture Filters (BPF Syntax)

Applied before packets are captured. Uses Berkeley Packet Filter (BPF) syntax, the same language used by the tcpdump command-line tool. These filters limit what's saved to the capture file. Use them when you know exactly what traffic you want and need to keep file sizes manageable.

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  CAPTURE FILTERS (BPF) โ€” set BEFORE capture starts                  โ”‚
โ”‚  Syntax: tcpdump-style         Where: Capture Options dialog        โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  host 10.10.10.100              Traffic to/from a specific host     โ”‚
โ”‚  port 80                        Only port 80 traffic                โ”‚
โ”‚  tcp port 443                   Only TCP port 443                   โ”‚
โ”‚  net 192.168.1.0/24             Traffic on a subnet                 โ”‚
โ”‚  src host 10.10.10.100          Only FROM this host                 โ”‚
โ”‚  dst port 22                    Only TO port 22                     โ”‚
โ”‚  not arp                        Exclude ARP traffic                 โ”‚
โ”‚  tcp and port 80                TCP traffic on port 80              โ”‚
โ”‚  host 10.10.10.1 and port 445   SMB traffic to specific host       โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  DISPLAY FILTERS (Wireshark) โ€” applied AFTER capture                โ”‚
โ”‚  Syntax: Wireshark-native      Where: filter bar (green/red)       โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  ip.addr == 10.10.10.100        Traffic to/from a host             โ”‚
โ”‚  tcp.port == 80                 TCP port 80                        โ”‚
โ”‚  http                           All HTTP traffic                   โ”‚
โ”‚  dns                            All DNS traffic                    โ”‚
โ”‚  tcp.flags.syn == 1             SYN packets only                   โ”‚
โ”‚  http.request.method == "POST"  HTTP POST requests                 โ”‚
โ”‚  frame contains "password"       Packets containing "password"      โ”‚
โ”‚  !(arp or dns)                  Exclude ARP and DNS noise          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Display Filters (Wireshark Syntax)

Applied after capture. Uses Wireshark's own powerful filter language. Filters what's displayed โ€” the full capture is still in memory. This is what you'll use 95% of the time. See the diagram above for a side-by-side comparison.

๐Ÿง  Knowledge Check โ€” Wireshark Fundamentals

What is the difference between capture filters and display filters in Wireshark?
Capture filters use Berkeley Packet Filter (BPF) syntax (same as tcpdump) and are set before you start capturing. They limit what's saved to the file. Display filters use Wireshark's own syntax and filter what's displayed from an already-captured set โ€” the full capture stays in memory. Using the wrong syntax in the wrong box causes errors. The display filter bar turns green when syntax is valid, red when invalid.
Write the display filter to show only HTTP POST requests:
Filter: 
The display filter http.request.method == "POST" shows only HTTP POST requests. This is essential for finding login attempts, form submissions, and file uploads in a capture. Note the Wireshark filter syntax uses == (double equals) and string values in quotes. Combine it with frame contains "password" to find credential submissions.
Write the display filter to remove common protocol noise (ARP, DNS, ICMP):
Filter: 
!(arp || dns || icmp) removes the three most common sources of noise in a capture: ARP broadcasts, DNS queries/responses, and ICMP ping traffic. This is often the first filter to apply when opening any pcap file, as it lets you focus on the interesting traffic like HTTP, FTP, and SMB. Some analysts also add stp (Spanning Tree Protocol) to the exclusion list.
โš ๏ธ Critical Distinction: port 80 is a capture filter. tcp.port == 80 is a display filter. They go in different places and use different syntax. Putting display filter syntax in the capture filter box will give you an error. The display filter bar is the green/red bar at the top of the main Wireshark window โ€” green means valid syntax, red means invalid.

๐Ÿงช Display Filter Recipes

Here are the filters you'll use most often, organized by scenario:

Basic Protocol Filters

http                            # All HTTP traffic
dns                             # All DNS queries/responses  
tcp                             # All TCP traffic
udp                             # All UDP traffic
icmp                            # All ICMP (ping) traffic
arp                             # All ARP traffic
ftp                             # All FTP traffic
ssh                             # All SSH traffic (encrypted payload)
smb || smb2                     # All SMB traffic
tls                             # All TLS/SSL traffic

Address & Port Filters

ip.addr == 10.10.10.100                  # To or from this IP
ip.src == 10.10.10.100                   # FROM this IP only
ip.dst == 10.10.10.100                   # TO this IP only
eth.addr == aa:bb:cc:dd:ee:ff            # MAC address filter
tcp.port == 80                           # TCP port 80 (either direction)
tcp.dstport == 443                       # Destination port 443
tcp.srcport == 8080                      # Source port 8080
udp.port == 53                           # UDP port 53 (DNS)
ip.addr == 10.10.10.0/24                 # Entire subnet
tcp.port in {80, 443, 8080, 8443}        # Multiple ports

HTTP-Specific Filters

http.request                             # HTTP requests only
http.response                            # HTTP responses only
http.request.method == "GET"             # GET requests
http.request.method == "POST"            # POST requests
http.request.uri contains "login"        # URIs containing "login"
http.host == "target.htb"                # Specific Host header
http.response.code == 200                # 200 OK responses
http.response.code >= 400                # Error responses (4xx, 5xx)
http.content_type contains "json"        # JSON responses
http.cookie contains "session"           # Cookie inspection
http.set_cookie                          # Set-Cookie headers
http.authorization                       # Authorization headers
http.request.uri contains "api"          # API endpoint traffic

Content Search Filters

frame contains "password"                # Search raw bytes for string
frame contains "flag{"                   # CTF flag hunting!
http.file_data contains "admin"          # Search HTTP body content
tcp contains "login"                     # TCP payload search
data.data contains "secret"              # Data field search
frame matches "flag\{[a-zA-Z0-9]+\}"    # Regex match (slower)

TCP Analysis Filters

tcp.flags.syn == 1 && tcp.flags.ack == 0   # SYN packets (new connections)
tcp.flags.reset == 1                        # RST packets (rejected connections)
tcp.flags.fin == 1                          # FIN packets (closing connections)
tcp.analysis.retransmission                 # Retransmitted packets
tcp.analysis.zero_window                    # Zero window (flow control)
tcp.analysis.duplicate_ack                  # Duplicate ACKs
tcp.stream eq 5                             # Specific TCP stream number

Combining Filters

Use && (AND), || (OR), ! (NOT), and parentheses to build complex filters:

http.request.method == "POST" && ip.dst == 10.10.10.100     # AND โ€” both conditions
dns || http                                                   # OR โ€” either condition
!arp && !dns && !icmp                                         # NOT โ€” remove noise

(http.request.method == "POST" || http.request.method == "PUT") && 
  ip.src == 192.168.1.50                                      # Complex combination

(tcp.port == 80 || tcp.port == 443) && ip.addr == 10.10.10.100  # Parentheses for grouping
๐Ÿ’ก Pro Tip: Learn to type !(arp || dns || icmp || stp) as your first filter when opening any pcap. This removes protocol noise and lets you focus on interesting traffic. You can save this as a filter button in Wireshark for one-click access.

๐Ÿ”— Following TCP/UDP/HTTP Streams

This is one of Wireshark's most powerful features, and it's very beginner-friendly. "Following a stream" reconstructs the full conversation between two endpoints, showing you exactly what was sent and received in order. Think of it like reading a chat transcript between two computers. Instead of looking at individual packets, you see the whole conversation at once.

How to Follow a Stream

In the GUI: Right-click any packet โ†’ Follow โ†’ TCP Stream (or UDP/HTTP/TLS). A new window shows the full reconstructed conversation. Client data appears in red, server data in blue.

tshark -r capture.pcap -z "follow,tcp,ascii,0"    # Stream 0 โ€” change number for others
tshark -r capture.pcap -z "follow,http,ascii,0"   # Follow HTTP stream
tshark -r capture.pcap -z "conv,tcp"               # List all TCP streams & endpoints
tshark -r capture.pcap -Y "tcp.stream eq 5" -T fields -e data.data  # Specific stream

What to Look For in Streams

  • Login credentials โ€” usernames and passwords in HTTP POST forms, FTP commands, SMTP AUTH
  • API tokens โ€” Bearer tokens, API keys, session cookies
  • Command output โ€” if someone ran commands via a web shell, you'll see the full I/O
  • File transfers โ€” files sent over FTP, HTTP uploads, or raw TCP
  • Encoded data โ€” Base64 encoded payloads, URL-encoded commands
๐Ÿ’ก Pro Tip: In the Follow Stream window, use the "Stream" dropdown at the bottom to cycle through all streams. In many CTF challenges, the flag is in one specific stream โ€” systematically check each one. The stream number also appears in the display filter bar, so you can easily jump back and forth.

๐ŸŒ HTTP Analysis

HTTP is cleartext, which means Wireshark can dissect every request and response in full detail. This is where you'll find credentials, API keys, uploaded files, and exploitation attempts.

Analyzing HTTP Requests

Filter for all HTTP requests with http.request, then expand the packet in Wireshark to see full details:

Hypertext Transfer Protocol
  Request Method: POST
  Request URI: /login.php
  Host: target.htb
  User-Agent: Mozilla/5.0 ...
  Content-Type: application/x-www-form-urlencoded
  Cookie: PHPSESSID=abc123def456

HTML Form URL Encoded: application/x-www-form-urlencoded
  Form item: "username" = "admin"
  Form item: "password" = "P@ssw0rd123"     โ† CREDENTIALS IN CLEARTEXT!

Extracting Form Data with tshark

tshark -r capture.pcap -Y "http.request.method == POST" \
  -T fields -e http.host -e http.request.uri -e http.file_data     # POST form data

tshark -r capture.pcap -Y "http.request" \
  -T fields -e http.host -e http.request.full_uri                   # All requested URLs

tshark -r capture.pcap -Y "http.cookie" \
  -T fields -e ip.src -e http.cookie                                # Cookies

tshark -r capture.pcap -Y "http.user_agent" \
  -T fields -e ip.src -e http.user_agent | sort -u                  # User-Agents (ID tools)

Identifying Suspicious HTTP Activity

Directory brute forcing (many 404s from one source):

tshark -r capture.pcap -Y "http.response.code == 404" \
  -T fields -e ip.dst -e http.request.uri | head -20

Web shell traffic detection:

http.request.uri contains "cmd="
http.request.uri contains "exec="
http.request.uri contains "shell"
frame contains "

SQL injection attempts:

http.request.uri contains "UNION"
http.request.uri contains "' OR "
frame contains "sqlmap"

๐Ÿ”‘ Finding Credentials in Cleartext

Here's why unencrypted traffic is a critical security risk: when data travels across a network without encryption, anyone on the same network segment can read it. Think of it like sending a postcard instead of a sealed letter โ€” every mail carrier along the way can read your message. On a shared network (coffee shop WiFi, corporate LAN, compromised router), an attacker running Wireshark or tcpdump can capture login credentials, session tokens, personal data, and API keys in real time. This is why HTTPS and encrypted protocols exist โ€” they turn that postcard into a sealed, tamper-proof envelope.

One of the most common pentest findings (and CTF challenges) involves extracting credentials from unencrypted traffic. Many protocols transmit credentials in cleartext or with weak encoding.

Protocols That Leak Credentials

FTP โ€” credentials sent in plaintext (you'll see USER admin โ†’ PASS secretpassword):

ftp.request.command == "USER" || ftp.request.command == "PASS"

HTTP Basic Auth โ€” Base64 encoded (trivially decoded with echo "YWRtaW46cGFzc3dvcmQ=" | base64 -d โ†’ admin:password):

http.authorization

HTTP Form Login โ€” POST body in cleartext:

http.request.method == "POST" && frame contains "password"

Other cleartext protocols โ€” use these display filters:

telnet                          # Everything in cleartext, character by character
smtp.req.command == "AUTH"      # SMTP Auth โ€” Base64 encoded
pop.request.command == "USER" || pop.request.command == "PASS"   # POP3
imap.request contains "LOGIN"   # IMAP
ldap.bindRequest && !(ldap.bindRequest_element.authentication == 3)  # LDAP Simple Bind
snmp.community                  # SNMP community strings

Automated Credential Extraction

tshark -r capture.pcap -Y "ftp.request.command == USER || ftp.request.command == PASS" \
  -T fields -e ftp.request.command -e ftp.request.arg               # FTP credentials

tshark -r capture.pcap -Y "http.authorization" \
  -T fields -e ip.src -e http.authorization                         # HTTP Basic Auth

tshark -r capture.pcap -Y "snmp" \
  -T fields -e ip.src -e ip.dst -e snmp.community                  # SNMP community strings

tshark -r capture.pcap -Y "http.request.method == POST && http.request.uri contains login" \
  -T fields -e frame.time -e http.file_data | head -30              # Brute force detector

๐Ÿง  Knowledge Check โ€” Analysis & Extraction

๐Ÿ“‹ Scenario
$ tshark -r capture.pcap -z "io,phs" -q
Protocol Hierarchy Statistics:
  eth
    ip
      tcp
        http    45.2%
        tls     30.1%
      udp
        dns     20.5%
        data     4.2%
Based on the protocol hierarchy, what should you analyze first and why?
HTTP traffic (45%) should be analyzed first because: (1) it's cleartext โ€” you can see everything, (2) it's the largest portion of traffic, and (3) HTTP contains form submissions, API calls, file transfers, and often credentials. Start by exporting HTTP objects (File โ†’ Export Objects โ†’ HTTP) and searching for credentials in POST requests. TLS is encrypted and harder to analyze without keys. DNS should be checked next for exfiltration patterns.
Which protocol transmits credentials in cleartext (or trivially decoded Base64)?
FTP sends USER and PASS commands in plaintext. HTTP Basic Auth uses Base64 encoding (trivially decoded). Telnet sends everything character-by-character in cleartext. SMTP AUTH uses Base64. POP3, IMAP, and SNMP community strings are also cleartext. SSH, HTTPS, LDAPS, and similar encrypted protocols protect credentials in transit. Always check for these cleartext protocols when analyzing a pcap.
In CTF pcap challenges, what should you always check for flag hunting? (Select the best approach)
The systematic approach is: (1) Check protocol hierarchy to see what's in the capture, (2) Export HTTP/SMB objects for files, (3) Search for flag format strings across all packets, (4) Follow every TCP stream to see full conversations, (5) Check DNS for tunneling/hidden data in subdomains or TXT records, (6) Check ICMP payloads for embedded data, (7) Extract and analyze any found files with 'file' and 'strings'. Flags can be hidden anywhere โ€” systematic checking beats random searching.
What nmap scan type must you use through a SOCKS proxy (proxychains)?
You must use -sT (TCP connect scan) through SOCKS proxies. SYN scans (-sS) require raw sockets which don't work through SOCKS. ICMP (ping) doesn't work either, so always add -Pn to skip ping. UDP scans (-sU) also won't work. The full command through proxychains is: proxychains nmap -sT -Pn target.
You're given a pcap file and a .pem private key file. What does this strongly suggest?
When a CTF gives you both a pcap and a private key, the intended solution is almost always to decrypt TLS traffic. Load the key in Wireshark: Edit โ†’ Preferences โ†’ Protocols โ†’ TLS โ†’ RSA keys list (add IP, port, protocol, key file). The encrypted "Application Data" packets will become readable HTTP/other protocol data. Note this only works with RSA key exchange (not forward secrecy); for PFS, you'd need the SSLKEYLOGFILE.
๐Ÿ’ก Pro Tip: Use Edit โ†’ Find Packet (Ctrl+F) in Wireshark, set it to "String" and search for common credential keywords: password, passwd, pass, login, user, token, secret, key, auth. This brute-force approach catches credentials across all protocols.

๐Ÿ”’ TLS/SSL Inspection

TLS (Transport Layer Security, the encryption behind HTTPS) makes traffic unreadable in Wireshark. All you see is "Application Data" with no visible content. But there are several ways to decrypt it if you have the right keys:

Extracting Information Without Decryption

Even without decryption keys, the TLS handshake reveals useful metadata:

tls.handshake                    # All handshake messages
tls.handshake.type == 1          # Client Hello
tls.handshake.type == 2          # Server Hello
tls.handshake.type == 11         # Certificate
tls.handshake.extensions_server_name  # SNI (Server Name Indication) โ€” which hostname was requested

Extract SNI hostnames, TLS versions, and JA3 fingerprints (JA3 is a method of fingerprinting TLS clients by hashing their handshake parameters โ€” useful for identifying specific tools or malware):

tshark -r capture.pcap -Y "tls.handshake.type == 1" \
  -T fields -e ip.dst -e tls.handshake.extensions_server_name | sort -u   # SNI hostnames

tshark -r capture.pcap -Y "tls.handshake.type == 2" \
  -T fields -e tls.handshake.version | sort | uniq -c                     # TLS versions

tshark -r capture.pcap -Y "tls.handshake.type == 1" \
  -T fields -e tls.handshake.ja3                                          # JA3 fingerprint

Decrypting TLS Traffic

If you have the server's private key (RSA key exchange only) or the SSLKEYLOGFILE (pre-master secrets), you can decrypt TLS traffic:

Method 1: SSLKEYLOGFILE (works with modern TLS including PFS โ€” Perfect Forward Secrecy, where each session uses a unique key so compromising one session doesn't compromise others). Set this environment variable before starting the browser:

export SSLKEYLOGFILE=/tmp/tls_keys.log

Then in Wireshark: Edit โ†’ Preferences โ†’ Protocols โ†’ TLS โ†’ (Pre)-Master-Secret log filename โ†’ set to /tmp/tls_keys.log. Wireshark will now decrypt TLS traffic.

Method 2: RSA private key (only works with RSA key exchange, no PFS). In Wireshark: Edit โ†’ Preferences โ†’ Protocols โ†’ TLS โ†’ RSA keys list โ†’ add IP, Port, Protocol, Key file.

Decrypt with tshark:

tshark -r capture.pcap -o "tls.keylog_file:/tmp/tls_keys.log" -Y http
๐Ÿ’ก Pro Tip: In CTF challenges, if you're given both a pcap and a private key file (.pem/.key), the challenge almost certainly wants you to decrypt TLS traffic. Load the key in Wireshark's TLS settings and the encrypted traffic will magically become readable HTTP.

๐Ÿ“ก DNS Analysis

DNS traffic is a goldmine. It reveals what hosts were contacted, can expose data exfiltration, and in CTFs often hides flags in DNS queries or TXT records.

Basic DNS filters:

dns                              # All DNS traffic
dns.flags.response == 0          # DNS queries only
dns.flags.response == 1          # DNS responses only
dns.qry.name contains "target.htb"  # Queries for specific domain
dns.flags.rcode == 3             # NXDOMAIN (domain not found)

DNS query types:

dns.qry.type == 1               # A records
dns.qry.type == 28              # AAAA records
dns.qry.type == 5               # CNAME (Canonical Name โ€” alias pointing to another domain)
dns.qry.type == 16              # TXT records (often hide data!)
dns.qry.type == 15              # MX records (mail servers)
dns.qry.type == 33              # SRV records (service discovery)
dns.qry.type == 252             # AXFR (zone transfer โ€” downloads the ENTIRE DNS zone!)

Extract and analyze DNS data with tshark:

tshark -r capture.pcap -Y "dns.flags.response == 0" \
  -T fields -e dns.qry.name | sort -u                 # All queried domains

tshark -r capture.pcap -Y "dns.qry.name" \
  -T fields -e dns.qry.name | awk 'length > 50'       # DNS tunneling (long labels)

tshark -r capture.pcap -Y "dns.txt" \
  -T fields -e dns.txt                                 # TXT record answers

DNS Exfiltration Detection

DNS tunneling/exfiltration encodes data in DNS queries (usually as long subdomain labels). Watch for:

  • Unusually long domain names (normal DNS labels are short)
  • High volume of DNS queries to the same domain
  • Base64 or hex-encoded subdomain labels
  • TXT record queries with large responses
tshark -r capture.pcap -Y "dns.qry.name" \
  -T fields -e dns.qry.name | \
  awk -F. '{for(i=1;i<NF;i++) if(length($i)>20) print}' | sort -u    # Long labels

tshark -r capture.pcap -Y "dns.qry.name contains exfil.evil.com" \
  -T fields -e dns.qry.name | \
  sed 's/.exfil.evil.com//' | base64 -d                               # Decode exfil data

๐Ÿ“Š Statistics & Conversations

Wireshark's statistics features give you a high-level overview before diving into individual packets. Always check statistics first when analyzing an unfamiliar pcap.

Key Statistics Views

In the GUI: Statistics menu โ†’ various options. With tshark:

tshark -r capture.pcap -z "io,phs"       # Protocol hierarchy (% per protocol)
tshark -r capture.pcap -z "conv,ip"       # Conversations โ€” who's talking to whom?
tshark -r capture.pcap -z "conv,tcp"      # TCP conversations (src, dst, packets, bytes)
tshark -r capture.pcap -z "endpoints,ip"  # List all IP addresses
tshark -r capture.pcap -z "http,tree"     # All HTTP requests
tshark -r capture.pcap -z "dns,tree"      # DNS query statistics
tshark -r capture.pcap -z "io,stat,1"     # IO graph (1-second intervals)
๐Ÿ’ก Pro Tip: When you first open a CTF pcap, go to Statistics โ†’ Protocol Hierarchy. This immediately tells you what protocols are present. If you see FTP โ†’ look for credentials. HTTP โ†’ look for web traffic. DNS โ†’ check for tunneling. This 5-second check sets your analysis direction.

๐Ÿ“ฆ Exporting Objects

Wireshark can reconstruct and export files transferred over HTTP, SMB, TFTP, and other protocols. This is critical for CTF challenges where files are hidden in pcaps.

GUI Export

File โ†’ Export Objects โ†’ HTTP/SMB/TFTP/DICOM

This shows all files transferred over the selected protocol. You can save individual files or export all at once.

CLI Export with tshark

mkdir http_objects
tshark -r capture.pcap --export-objects http,http_objects/

mkdir smb_objects
tshark -r capture.pcap --export-objects smb,smb_objects/

mkdir tftp_objects
tshark -r capture.pcap --export-objects tftp,tftp_objects/

After exporting, always check file types โ€” some files might be renamed or disguised:

file http_objects/*
xxd http_objects/suspicious_file | head   # Check magic bytes

Manual File Extraction

When automatic export doesn't work, you can manually extract files:

  1. Find the file transfer in a TCP stream
  2. Right-click โ†’ Follow โ†’ TCP Stream
  3. Change "Show data as" to Raw
  4. Click Save As to save the raw bytes

For binary files in HTTP: follow the HTTP stream, show as Raw, save โ€” but remove the HTTP headers manually. Alternatively, use Export Packet Bytes (Ctrl+Shift+X) on just the data portion.

๐Ÿ’ก Pro Tip: After exporting HTTP objects, run file * and strings on everything. CTF flags are often hidden in images (steganography), PDFs, or disguised files. An exported "image.png" might actually be a ZIP file โ€” check the magic bytes!

โŒจ๏ธ tshark CLI Automation

tshark is the command-line version of Wireshark. It has the same dissection capabilities but is perfect for scripting, automation, and working on remote servers without a GUI.

Essential tshark Commands

tshark -r capture.pcap                    # Basic read โ€” like tcpdump
tshark -r capture.pcap -Y "http.request"  # Apply display filter

tshark -r capture.pcap -Y "http.request" \
  -T fields -e frame.number -e ip.src -e http.request.method -e http.request.uri   # Custom fields

tshark -r capture.pcap -Y "http.request" \
  -T fields -E separator=, -e ip.src -e http.host -e http.request.uri              # CSV output

tshark -r capture.pcap -Y "http.request" -T json | python3 -m json.tool            # JSON output
tshark -r capture.pcap -Y "http.response.code == 404" | wc -l                      # Count packets
tshark -r capture.pcap -Y "frame.number == 42" -V                                  # Packet details

Live capture and ring buffer:

sudo tshark -i tun0 -Y "http.request" -T fields -e http.host -e http.request.uri
sudo tshark -i eth0 -b filesize:10000 -b files:5 -w capture.pcap  # Rotate files

tshark Scripting Examples

tshark -r capture.pcap -T fields -e ip.src -e ip.dst | \
  tr '\t' '\n' | sort -u                                          # All unique IPs

tshark -r capture.pcap -Y "http.request" \
  -T fields -e frame.time -e ip.src -e http.request.method \
  -e http.request.full_uri                                        # HTTP timeline

tshark -r capture.pcap -Y "tcp.flags.syn == 1 && tcp.flags.ack == 0" \
  -T fields -e ip.src -e tcp.dstport | \
  sort | uniq -c | sort -rn | head -20                            # Detect port scanning

tshark -r capture.pcap -T fields -e frame.protocols -e data.data 2>/dev/null | \
  grep -oP '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}'     # Extract emails

tshark -r capture.pcap -z "endpoints,ip" -q                       # Bandwidth per IP

๐Ÿ† CTF Patterns & Techniques

Network forensics is a staple CTF category. Here are the most common patterns and how to solve them:

Pattern 1: Hidden Flag in HTTP Traffic

tshark -r challenge.pcap --export-objects http,exported/              # Step 1: Export objects
tshark -r challenge.pcap -Y 'frame contains "flag{"'                  # Step 2: Search for flag
tshark -r challenge.pcap -Y 'frame contains "CTF{"'
tshark -r challenge.pcap -Y "http.response" \
  -T fields -e http.file_data | strings | grep -i flag                # Step 3: Response bodies

Pattern 2: Credentials in FTP/Telnet

tshark -r challenge.pcap -Y "ftp.request.command == USER || ftp.request.command == PASS" \
  -T fields -e ftp.request.command -e ftp.request.arg               # FTP credentials

tshark -r challenge.pcap -Y "ftp-data" -z "follow,tcp,ascii,0"     # FTP transferred files
tshark -r challenge.pcap -z "follow,tcp,ascii,0" | grep -A 500 "Telnet"  # Telnet session

Pattern 3: File Carved from TCP Stream

Identify file transfers by looking for magic bytes:

tshark -r challenge.pcap -Y "tcp" -T fields -e data.data | \
  grep -i "504b0304"    # ZIP magic bytes (PK..)

tshark -r challenge.pcap -Y "tcp" -T fields -e data.data | \
  grep -i "89504e47"    # PNG magic bytes

To export: in Wireshark, Follow TCP Stream โ†’ Show as Raw โ†’ Save As.

Pattern 4: DNS Exfiltration / Hidden Data

Look for encoded subdomains (e.g., dGhlIGZsYWcgaXM.evil.com โ†’ base64 of flag data):

tshark -r challenge.pcap -Y "dns.qry.name" \
  -T fields -e dns.qry.name | sort -u                     # All DNS queries

tshark -r challenge.pcap -Y "dns.qry.name contains evil.com" \
  -T fields -e dns.qry.name | \
  sed 's/.evil.com//g' | tr -d '\n' | base64 -d           # Decode exfil subdomains

tshark -r challenge.pcap -Y "dns.txt" -T fields -e dns.txt  # Hidden TXT records

Pattern 5: Wireless (802.11) Challenges

WiFi management frame filters:

wlan.fc.type == 0              # Management frames
wlan.fc.type_subtype == 0x08   # Beacon frames (network names)
wlan.fc.type_subtype == 0x04   # Probe requests
wlan.fc.type_subtype == 0x0b   # Authentication frames
eapol                          # EAPOL (Extensible Authentication Protocol over LAN)
                               # โ€” captures the WPA 4-way handshake needed for WiFi password cracking
tshark -r wifi.pcap -Y "wlan.fc.type_subtype == 0x08" \
  -T fields -e wlan.ssid | sort -u   # Extract SSIDs (network names)

Export EAPOL frames and crack with aircrack-ng or hashcat.

Pattern 6: ICMP Tunneling

Data hidden in ICMP echo request/reply payloads:

tshark -r challenge.pcap -Y "icmp" -T fields -e data.data             # Raw hex
tshark -r challenge.pcap -Y "icmp.type == 8" -T fields -e data.data | xxd -r -p  # Hex โ†’ ASCII
๐Ÿ’ก Pro Tip: For CTF pcap challenges, always follow this checklist: (1) Protocol hierarchy โ€” what's in the capture? (2) Export HTTP/SMB objects. (3) Search for flag format strings. (4) Follow every TCP stream. (5) Check DNS for hidden data. (6) Look for encoded payloads (Base64, hex). (7) Check ICMP payloads. (8) Extract and analyze any files found.

๐ŸŽฏ Real-World Methodology

When analyzing a pcap file, whether for a CTF, incident response, or pentest, follow this systematic approach:

Phase 1: Overview (2 minutes)

capinfos capture.pcap                          # Capture file info
tshark -r capture.pcap -z "io,phs" -q          # Protocol hierarchy
tshark -r capture.pcap -z "conv,ip" -q         # Conversations
tshark -r capture.pcap -z "endpoints,ip" -q    # Endpoints
tshark -r capture.pcap -T fields -e frame.time | head -1   # First packet time
tshark -r capture.pcap -T fields -e frame.time | tail -1   # Last packet time

Phase 2: Quick Wins (5 minutes)

mkdir exported && tshark -r capture.pcap --export-objects http,exported/   # Export HTTP objects

# Search for common flag formats
for pattern in "flag{" "CTF{" "FLAG{" "ctf{" "key{"; do
  echo "=== Searching: $pattern ==="
  tshark -r capture.pcap -Y "frame contains \"$pattern\"" 2>/dev/null
done

tshark -r capture.pcap -Y "ftp.request.command == USER || ftp.request.command == PASS" \
  -T fields -e ftp.request.arg 2>/dev/null                                # FTP creds

tshark -r capture.pcap -Y "http.authorization" \
  -T fields -e http.authorization 2>/dev/null                             # HTTP auth

Phase 3: Deep Dive (as needed)

tshark -r capture.pcap -Y "http.request" \
  -T fields -e frame.time -e ip.src -e http.request.method -e http.request.full_uri  # HTTP detail

tshark -r capture.pcap -z "follow,tcp,ascii,0"              # Follow streams

tshark -r capture.pcap -Y "dns.flags.response == 0" \
  -T fields -e dns.qry.name | sort -u                       # DNS queries

tshark -r capture.pcap -z "expert" -q                        # Expert info (anomalies)

Phase 4: Reconstruction

For complex file extraction, use the Wireshark GUI, NetworkMiner for automated carving, or foremost/binwalk on raw stream data for hidden files.

Timeline reconstruction:

tshark -r capture.pcap -Y "http.request || ftp.request || dns.flags.response==0" \
  -T fields -e frame.time_relative -e ip.src -e ip.dst \
  -e _ws.col.Protocol -e _ws.col.Info | head -50

โš ๏ธ Common Mistakes

โŒ Mistake #1: Confusing display filters with capture filters.
port 80 is BPF syntax (capture filter). tcp.port == 80 is Wireshark syntax (display filter). Using the wrong syntax in the wrong box gives you errors or no results. The display filter bar turns green when the syntax is valid, red when it's wrong.
โŒ Mistake #2: Not checking Statistics โ†’ Protocol Hierarchy first.
Before searching for anything specific, understand what's in the capture. A 5-second protocol hierarchy check tells you whether to focus on HTTP, FTP, DNS, or something else entirely.
โŒ Mistake #3: Ignoring DNS traffic.
DNS queries reveal every hostname contacted. DNS tunneling hides data in subdomain labels. DNS TXT records can contain flags, tokens, or configuration data. Always check DNS.
โŒ Mistake #4: Only using the GUI.
The GUI is great for exploration, but tshark is essential for automation, large pcap files, and scripted analysis. Learn both. Many CTF challenges are faster to solve with a one-liner than clicking through the GUI.
โŒ Mistake #5: Not exporting HTTP objects.
File โ†’ Export Objects โ†’ HTTP extracts all transferred files with one click. Many challenges hide flags in images, documents, or other files embedded in HTTP traffic. Always export and examine every object.
โŒ Mistake #6: Forgetting to check ICMP payloads.
ICMP echo (ping) packets can carry data in their payload. This is commonly used for ICMP tunneling and data exfiltration. In CTFs, flags are frequently hidden in ICMP payloads.

๐Ÿ”„ Tool Comparison: Wireshark vs tcpdump vs tshark

๐Ÿฆˆ Wireshark

GUI
10/10
Filtering
10/10
Performance
5/10
Scripting
6/10
Use Cases
9/10

Best for: Interactive analysis, protocol deep-dives, following streams, CTF pcap challenges. The go-to for visual packet inspection.

๐Ÿ“Ÿ tcpdump

GUI
0/10
Filtering
6/10
Performance
10/10
Scripting
7/10
Use Cases
7/10

Best for: Remote capture on headless servers, quick traffic checks over SSH, lightweight packet capture with BPF filters. Pre-installed on most Linux systems.

๐Ÿ”ง tshark

GUI
0/10
Filtering
10/10
Performance
9/10
Scripting
10/10
Use Cases
9/10

Best for: Automated pcap analysis, scripted field extraction, piping output to other tools. Wireshark's power without the GUI overhead.

๐Ÿ“š Further Reading