Security, Privacy, and Consumer Protection
This guide is for the PKI and Internet Privacy labs. Several students asked to learn how to actually interpret a Wireshark trace rather than just collect one. Use it as a reference while you work.
AI note. You may use an LLM to help interpret a capture (e.g., paste a packet summary and ask what a field means). That is encouraged — but the point of the course is that you can verify the answer against the bytes in front of you. When a model tells you “this is a TLS ClientHello,” confirm it: find the record, the handshake type, the SNI. Don’t submit an explanation you can’t defend.
The bar at the top of Wireshark filters which packets are shown (not which are captured). A few you will use constantly:
| Filter | Shows |
|---|---|
http |
Plaintext HTTP requests/responses |
tls |
TLS records (the encrypted web traffic) |
dns |
DNS queries and responses |
tcp.port == 443 |
All traffic to/from the HTTPS port |
ip.addr == 93.184.216.34 |
Everything to/from one host |
tcp.stream eq 0 |
One specific TCP connection (see §3) |
dns && ip.addr == 1.1.1.1 |
DNS to/from Cloudflare’s resolver |
Combine with && (and), || (or), ! (not). Example:
tls.handshake.type == 1 shows only TLS ClientHello messages.
Every TCP connection (and therefore every HTTP/HTTPS session) opens with three packets. Spotting them tells you where a conversation begins:
Client → Server SYN "let's talk"
Server → Client SYN, ACK "sure, let's talk"
Client → Server ACK "great"
In the packet list, look at the Info column for [SYN], [SYN, ACK], [ACK].
The connection closes with [FIN, ACK] packets (or an abrupt [RST]).
What an eavesdropper learns just from this — even before any data flows, and even if the data is encrypted: the client IP, the server IP, the port (80 vs 443 → HTTP vs HTTPS), and the timing of the connection.
Right-click any HTTP packet → Follow → HTTP Stream (or TCP Stream). Wireshark reassembles the whole conversation and color-codes it (client request in one color, server response in another). With plain HTTP you will see, in the clear:
GET /secret-page.html HTTP/1.1Host:, User-Agent:, Cookie:, Referer:This is the core lesson of the PKI lab: with HTTP, an eavesdropper on the path (your ISP, someone on the same Wi-Fi, a compromised router) sees exactly which resource you requested and its entire contents, including any cookies or credentials sent in the clear.
Useful HTTP filters: http.request.method == "GET", http.host contains "example",
http.cookie.
Switch your capture to the HTTPS version of the site and filter on tls. A TLS 1.2/1.3
session opens with a handshake. The records you should be able to identify:
| Record | tls.handshake.type |
What it carries |
|---|---|---|
| ClientHello | 1 | Cipher suites the client supports, SNI (the hostname!), supported TLS versions |
| ServerHello | 2 | The chosen cipher suite, server’s TLS version |
| Certificate | 11 | The server’s certificate chain (visible in TLS 1.2; encrypted in TLS 1.3) |
| Key exchange / Finished | — | Establishes the shared session key |
| Application Data | — | The actual HTTP request/response — now encrypted |
Try to Follow → TLS Stream on an HTTPS connection. Contrast it with §3: instead of readable HTML you get Application Data records full of ciphertext. The eavesdropper can no longer read the URL path, headers, cookies, or body.
HTTPS encrypts the content, not the fact of the connection. Even with a perfect TLS session, an on-path observer can still see:
www.example.com) in plaintext so the server
knows which certificate to present. Find it with tls.handshake.extensions_server_name.
This is how an ISP can still tell which sites you visit even over HTTPS.
So the honest summary: HTTPS hides what you said, not who you talked to.
Filter on dns. Each lookup is a query (Standard query 0x1a2b A www.example.com)
followed by a response with the answer records. Things to pull out:
dns.qry.name) — the hostname you’re resolving.8.8.8.8, 1.1.1.1, etc.).dns, then File → Export Specified
Packets with “Displayed” selected.dns packets at all — the lookups
ride inside TLS to the resolver (DoH uses tcp.port == 443 to a resolver like
1.1.1.1; DoT uses port 853). The hostname is now hidden from your ISP — but the
resolver operator (e.g., Cloudflare) sees every name you look up. That trust
shift is the heart of the encrypted-DNS tradeoff.http, tls, or dns) to cut the noise.