OverTheWire Bandit: Level 16 to Level 17
The Goal
Find which port in the range 31000-32000 on localhost is running an SSL/TLS service that will return the next credentials when given the current password. The other ports either don’t speak TLS or just echo back whatever you send them.
What I Did
Step 1 — Port Scan
First I needed to find which ports in the range were even open. Used nmap:
1
bandit16@bandit:~$ nmap -p 31000-32000 localhost
Five ports came back open:
1
2
3
4
5
31046/tcp open
31518/tcp open
31691/tcp open
31790/tcp open
31960/tcp open
Step 2 — Test Each Port for TLS
Tested each port with openssl s_client. Three of them (31046, 31691, 31960) failed immediately with:
1
2
error:0A0000F4:SSL routines:ossl_statem_client_read_transition:unexpected message
New, (NONE), Cipher is (NONE)
No certificate, no cipher — these ports don’t speak TLS at all.
Two ports (31518 and 31790) completed a full TLS handshake, showing the SnakeOil self-signed certificate and negotiating TLS_AES_256_GCM_SHA384.
Step 3 — Find the Right Port
Tried submitting the password to port 31518 — it echoed the password back and closed. Echo server.
Tried port 31790 interactively — kept getting Wrong! Please enter the correct current password even with the correct password. After debugging, the issue was that openssl s_client in interactive mode was sending extra characters — specifically pressing the up arrow key accidentally sent ^[[A to the server alongside the password.
Fixed it by piping the password directly:
1
echo "kS0Hf0u5HiXFwKMKFqXvPdOTNGGa0X8V" | openssl s_client -connect localhost:31790 -quiet
The server accepted it and returned a private SSH key for bandit17.
Step 4 — Save the Key and Connect
Copied the private key to my local machine, set correct permissions, and connected as bandit17:
1
2
chmod 600 bandit17.key
ssh -i bandit17.key bandit17@bandit.labs.overthewire.org -p 2220
What KEYUPDATE Is
KEYUPDATE appeared in the output and caused confusion. It’s a TLS 1.3 feature where the server rotates the session encryption keys mid-connection for additional security. It has nothing to do with whether your password was correct — it just means the server refreshed its encryption state. You can’t control it and it doesn’t require any action.
Why Piping Fixed the Interactive Issue
In interactive mode, openssl s_client processes everything you type including control characters. Pressing the up arrow sends the escape sequence ^[[A which gets transmitted to the server as part of your input. The server sees kS0Hf0u5HiXFwKMKFqXvPdOTNGGa0X8V^[[A instead of just the password.
Piping with echo sends exactly the string you specify plus a newline — nothing else. Cleaner, safer, and scriptable.
How I Identified Echo Servers vs the Real Server
- Echo servers — send back whatever you type. Port 31518 returned the password straight back.
- Real server — validates the input and responds differently. Port 31790 said
Wrong!when the password was malformed, and returned the private key when it was correct.
The Wrong! message was actually useful — it confirmed port 31790 was the checking server, not an echo server. Echo servers don’t have logic to validate input.
Difference From Previous Levels
This level introduced two new concepts on top of what Level 15 taught:
Port scanning — instead of being told exactly which port to connect to, you have to discover it yourself. nmap scans a range and reports which ports have services listening.
Echo servers as distractors — not every open port is the answer. Identifying which services do what requires testing each one, not just connecting to the first open port.
Commands Used
| Command | What it did |
|---|---|
nmap -p 31000-32000 localhost | Found 5 open ports in the range |
openssl s_client -connect localhost:PORT | Tested each port for TLS support |
echo "password" \| openssl s_client -connect localhost:31790 -quiet | Sent password cleanly without extra characters |
chmod 600 bandit17.key | Set correct permissions on the private key |
ssh -i bandit17.key bandit17@... | Logged into bandit17 using the key |