HackBlue

Tools · Network tools · 12 / 24

tshark: cleartext HTTP fields in a lab capture

When the lab service really is HTTP, method, host, path, and status are ordinary fields. A secret in a path or a header is the finding. The fix is to stop putting it there and to move the service to TLS.

15 min read · practice only with authorization

The columns that describe one request

http.request matches request frames. Useful columns are frame.number, ip.src, http.host, http.request.method, http.request.uri, and http.user_agent. Responses use http.response, http.response.code, and http.content_type. These fields populate when the bytes were cleartext HTTP. On TLS they stay empty, which is the previous lesson.

A POST filter is http.request.method == "POST". Quote it so the shell does not eat the double quotes. content_length tells you the size of a body. You rarely need the body itself. If the question is whether a form was posted to an unexpected host, the host, the method, and the length answer it.

What you do when a field contains a secret

A URI that contains token= or a request that carries Authorization is the service exposing a credential on a channel anyone on the lab segment could have recorded. The ticket says which host, which path shape, and which header was present. It does not repeat the secret. The lab rotates the value and the owner moves that hop to TLS.

tshark can summarize cleartext authentication it understands. Treat any such summary as evidence the channel was not confidential. Do not paste the secret into a ticket, a chat, or a command line you will save. Prefer the field list below, which takes method, host, and path and leaves the header value out.

  • http.host is the Host header, not SNI. If both exist, they are different copies of a name.
  • A 401 followed by a 200 on cleartext HTTP basic is still a cleartext credential.
  • User-Agent is a lead. Confirm it with the owner before you treat a rare string as hostile.
  • Exporting every object from the file is a different step, and it belongs in a malware-safe lab VM.

A worked defensive case

The lab status page is intentionally plain HTTP on port 80 so students can see a protocol. The field table shows GET /health from 10.8.0.20 with status 200, and one POST /lab/report?token=redacted from 10.8.0.20 to 10.8.0.40 with a content length of a few dozen bytes. The token query is enough to file the issue. You do not print the matching frame with -x.

The change is small and specific. The report endpoint stops taking the token on the query string, the lab rotates the value that was exposed, and the service moves behind TLS. The health check can stay a path with no secret. You record frame numbers so a reviewer can find the rows in the same pcap.

Where this is documented

The HTTP dissector's fields http.request.method, http.host, http.request.uri, and http.response.code are listed by tshark -G fields. Display-filter strings are quoted as the manual describes for -Y.

Use a host-only lab network, or a capture the owner already handed you. These commands read that file or record a single lab host. They are not a scan of the public internet.

Commands

Cleartext requests: method, host, and path
tshark -r /lab/evidence.pcap -Y 'http.request' -T fields -E header=y -e frame.number -e ip.src -e http.host -e http.request.method -e http.request.uri
Cleartext responses: status and type
tshark -r /lab/evidence.pcap -Y 'http.response' -T fields -E header=y -e frame.number -e ip.dst -e http.response.code -e http.content_type

Diagram

A lab status request with the secret left out of the path

What cleartext HTTP looks like in a case note

Secret on the query stringPath with nothing to rotate

lab status · port 80 · before

GET /lab/report?token=redacted HTTP/1.1
Host: files.lab.internal
User-Agent: lab-health/1.0
HTTP/1.1 200 OK
Content-Type: text/csv
Content-Length: 18

id,name
1,lab-row
  • The token sat in the URI. Anyone who can see the segment can read it.
  • The ticket cites the path shape and the frame number, not a reusable secret.
  • Rotate the lab value. Stop accepting it on the query string.

lab status · port 80 · after

GET /health HTTP/1.1
Host: files.lab.internal
User-Agent: lab-health/1.0
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 2

ok
  • The health check carries no credential.
  • The report download moves to TLS and a header or cookie the lab owner designed.
  • A later capture of port 80 should show /health and nothing else sensitive.

Check yourself

1. Which filter prints cleartext HTTP requests rather than responses?

2. The URI column shows /lab/report?token=redacted. What is the finding?

3. You run the same http.request command on a port 443 file and get no rows. Why is that expected?