Reading cleartext HTTP
Cleartext HTTP is readable in the follow. Host, method, URI, status, and the body are fields, and TLS will hide them later.
A request and a response are separate frames
On a lab server that still speaks HTTP, the dissector marks requests with http.request and responses with http.response. The method is http.request.method, the host is http.host, the path is http.request.uri, and the status is http.response.code. A request and its response do not share a frame. They share a tcp.stream.
The Info column shows the request line when it fits. A body that continues in the next segments is absent from that headline. Follow HTTP Stream, or read http.file_data after reassembly, when the question is the body. Preferences that disable TCP reassembly make a large POST look like a header with no body. Check the preference if the body is mysteriously gone and the snap length was full.
http.request && ip.addr == 10.8.0.20
Headers a defender actually quotes
http.host is the name the client put on the request. It can differ from the address you saw in DNS, and both facts belong in the note. http.user_agent is the client string, useful as a description and weak as a unique identity. http.cookie and http.authorization are credentials in this context. Seeing them in a lab file means the service spoke cleartext. The finding is the missing encryption, and the file now contains secrets that the ticket system may not be allowed to store.
Status codes need the request beside them. A 401 on its own is an authentication challenge. A 401 on a request that already carried Authorization is a rejected credential. A 200 on a POST is success for whatever that POST does. Quote both frames.
Worked case: a GET for the lab status page
10.8.0.40 sends a GET to 10.8.0.20, host lab.example, URI /status, in tcp.stream 3. The next HTTP frame in that stream is status 200, content type text/plain. Follow HTTP Stream shows the request and the body “ok” with nothing else. You record method, host, URI, status, and stream. There is no password in this one, and you say that too, so nobody treats the file as credential material.
A later POST to /login in stream 9 is a different note. The body is present because the capture is full-frame and the server is cleartext. You stop quoting the body in chat. You record that a password crossed the lab network in the clear, which stream, and which host. The fix is to serve that login only over TLS and retire the cleartext listener. Handling of that file is the cleartext-credentials lesson.
Port 80 is not the only place HTTP appears, and 443 usually is not HTTP
http dissects cleartext. A service on port 8080 can be HTTP, and a service on port 80 can be something else. Trust the dissector’s fields, not the port, when you claim it was HTTP. Traffic on 443 that only shows TLS records is not a failure of the HTTP dissector. There is no HTTP to see until the session is decrypted with a key you were given.
Export Objects, HTTP, carves files the dissector reassembled. It works for this cleartext capture. It returns nothing useful from a TLS session you could not open.
Diagram
Read the request and the response as a pair inside one stream
- Request
Filter http.request and note method, host, and URI.
http.request && ip.addr == 10.8.0.20
- Stream
Take the tcp.stream and find the response in that same stream.
- Body
Follow HTTP Stream when the body spans segments.
- Secret
If a cookie or an Authorization header is present, treat the file as sensitive.
A cleartext lab GET, the way the frames split it
tcp.stream 3 · request
GET /status HTTP/1.1 Host: lab.example User-Agent: lab-client
This frame has no response. The status comes later in the stream.
- Method GET, URI /status, host lab.example.
- The client is 10.8.0.40 and the server is 10.8.0.20.
- No cookie and no Authorization header on this one.
tcp.stream 3 · response
The request is the earlier frame. Keep the stream index with the status.
HTTP/1.1 200 OK Content-Type: text/plain ok
- Status 200, body “ok”.
- Same tcp.stream as the GET.
- Nothing here is a credential. Say so in the note.
Check yourself
1. You have an HTTP request in tcp.stream 3. Where is its status code?
2. The Info column shows the POST line and not the form body. The snap length was full. What do you try?
3. Port 443 in the file shows TLS records and no http.host field. What is going on?