HackBlue

Tools · Wireshark · 27 / 30

Case: a password left in the lab file

A cleartext login is readable because the service sent it that way. The finding is the listener. The file is now a secret.

13 min read · practice only with authorization

Where a password sits when HTTP is clear

On a lab service that still accepts logins over HTTP, the password is in the TCP payload. A form post puts it in the body, often as a parameter of an application/x-www-form-urlencoded request. HTTP Basic puts it in the Authorization header. Wireshark decodes Basic because Base64 is an encoding, not a cipher: the details tree shows the user and the password in the clear. Anyone with the file can read what the tree shows.

Find the request first. http.request.method == "POST" && ip.addr == 10.8.0.20 narrows the list to posts aimed at the lab server. http.authorization finds the header when Basic was used. Follow HTTP Stream if the body is split across segments. The password is not in the SYN, and it is not in DNS. It is in the HTTP message.

Snippet
http.request.method == "POST" && ip.addr == 10.8.0.20

Worked case: the lab wiki still listened on port 80

The lab wiki on 10.8.0.20 was supposed to redirect everything to TLS. A capture on the client 10.8.0.40 shows a POST /login in tcp.stream 9, host lab.example, and a body that contains the account name ada and a password. The value in this write-up is a placeholder, lab-only-example. In a real lab file the value is the password that was typed, and you do not copy it into a ticket, a chat, or a lesson.

The same stream’s response is HTTP 302 with a session cookie, still on port 80. Two secrets are in the file: the password that was sent, and the cookie that came back. The service accepted a login without TLS. That is the finding. The control is to close the cleartext listener, require TLS, and rotate the lab password because it has been stored in a capture.

  • Stream 9, client 10.8.0.40, server 10.8.0.20 port 80.
  • POST /login, host lab.example, form body present.
  • Response sets a session cookie in cleartext.
  • Placeholder password in class notes. The real one stays in the case folder.

Handle the file as if it were the password

Store the pcapng with the engagement notes, not in a paste. If a reviewer needs the frames, export tcp.stream 9 to a small file and share it through the channel the agreement allows. Redact screenshots. A follow-stream window cropped badly still leaks the body in the corner.

Search the rest of the file before you call this the only hit. http.authorization and http.cookie on the same server tell you whether other requests repeated the mistake. One login is enough to justify closing the listener. A dozen logins are the same finding with a longer list of accounts to rotate.

Snippet
(http.authorization || http.cookie || http.set_cookie) && ip.addr == 10.8.0.20

What you change, and what you do not do next

The owner disables the port 80 listener or makes it redirect without accepting the POST. New captures of a login should show a TLS handshake and opaque application data, with no http.request.method field. That retest belongs on the lab service, with a throwaway account.

You do not replay the POST, and you do not try the password anywhere else to “see if it is reused.” The capture already proved the service took a secret in the clear. Further use of the secret is outside the lab exercise.

Diagram

The login is one stream: a form went out, a cookie came back

  1. Find

    Filter posts to the lab server, or frames that carry Authorization.

    Posts to the lab server
    http.request.method == "POST" && ip.addr == 10.8.0.20
  2. Follow

    Follow HTTP Stream and confirm the body or the Basic header is present.

  3. Stop

    Do not copy the secret into the ticket. Record the stream, the host, and the port.

  4. Retest

    After the listener is closed, a new lab login should show TLS and no HTTP fields.

What the cleartext stream contains, with the secret replaced

RequestResponse

tcp.stream 9 · port 80

POST /login HTTP/1.1
Host: lab.example
Content-Type: application/x-www-form-urlencoded

username=ada&password=<lab secret>
The response is a later frame
in the same stream.
  • The body is readable because the service spoke HTTP.
  • The placeholder stands in for a real password. Do not type the real one here.
  • Stream 9, 10.8.0.40 to 10.8.0.20.

tcp.stream 9 · response

The POST is the earlier frame.
Keep them together by stream index.
HTTP/1.1 302 Found
Set-Cookie: session=<lab cookie>
Location: /home
  • The cookie is a second secret in the same file.
  • The finding is the cleartext listener, not the user’s choice of password.
  • Rotate the lab password. Store the pcapng with the case notes.

Check yourself

1. A lab capture of an HTTP login contains a password. Where do you look for it?

2. Wireshark shows a username and password under an Authorization: Basic header. Why is that possible?

3. What do you change after this file?