OverTheWire Bandit: Levels 12 to 17 — Day 3 of the Wargame
Series: Daily Bandit — N levels a day until I finish all 34.
OverTheWire Bandit: Levels 12 to 17 — Day 3 of the Wargame
Series: Daily Bandit — N levels a day until I finish all 34.
Day 2 was about finding things. Day 3 was about unraveling them.
The challenge description for Level 12 says the file has been “repeatedly compressed.” I didn’t realize that meant eight layers deep. By the end, I was hex-dumping, gzip-ping, bzip2-ing, tar-ing, and doing it all again. This is the level where the training wheels come off.
And then came TLS 1.3, a KEYUPDATE bug, and an SSH key that almost got eaten by my terminal.
Let’s go.
Level 11 → Level 12: The Compression Chain
Log in as bandit12.
bandit12@bandit:~$ ls
data.txt
One file. But cat data.txt shows a hex dump. The challenge says this is a hex dump of a file that's been repeatedly compressed using multiple formats.
First, create a working directory in /tmp:
bandit12@bandit:~$ mktemp -d
/tmp/tmp.7ZkXYPjZcu
bandit12@bandit:~$ cp data.txt /tmp/tmp.7ZkXYPjZcu/
bandit12@bandit:~$ cd /tmp/tmp.7ZkXYPjZcu/
Now reverse the hex dump back into binary:
bandit12@bandit:/tmp/tmp.7ZkXYPjZcu$ xxd -r data.txt output.bin
xxd -r takes the hex dump and writes the actual binary. Now I have a binary file. Let's see what it is:
bandit12@bandit:/tmp/tmp.7ZkXYPjZcu$ file output.bin
output.bin: gzip compressed data, was "data2.bin"
Gzip. Rename and decompress:
bandit12@bandit:/tmp/tmp.7ZkXYPjZcu$ cp output.bin data2.gz
bandit12@bandit:/tmp/tmp.7ZkXYPjZcu$ gzip -d data2.gz
bandit12@bandit:/tmp/tmp.7ZkXYPjZcu$ ls
data.txt data2 output.bin
bandit12@bandit:/tmp/tmp.7ZkXYPjZcu$ file data2
data2: bzip2 compressed data, block size = 900k
Bzip2. Rename and decompress:
bandit12@bandit:/tmp/tmp.7ZkXYPjZcu$ cp data2 data3.bz2
bandit12@bandit:/tmp/tmp.7ZkXYPjZcu$ bzip2 -d data3.bz2
bandit12@bandit:/tmp/tmp.7ZkXYPjZcu$ file data3
data3: gzip compressed data, was "data4.bin"
Gzip again. This pattern of file → rename → decompress repeated. Here's the full chain:
xxd -rhex dump → gzip- gzip → bzip2
- bzip2 → gzip
- gzip → tar archive
- tar → another tar archive
- tar → gzip
- gzip → ASCII text
At each step, I ran file on the output, renamed it with the right extension, and decompressed. The file command is indispensable here — without it, you'd be guessing formats blind.
bandit12@bandit:/tmp/tmp.7ZkXYPjZcu$ cat data8
The password is FO5dwFsc0cbaIiH0h8J2eUks2vdTDwAn
Forty minutes for one password. But I’ll never forget the compression toolchain.
Lesson learned: file tells you the format. xxd -r reverses hex dumps. And when a file says "repeatedly compressed," it means it. Keep a mental tree of gzip → bzip2 → gzip → tar patterns.
Password: FO5dwFsc0cbaIiH0h8J2eUks2vdTDwAn
Level 12 → Level 13: SSH Keys
bandit13@bandit:~$ ls
sshkey.private
No password to find here. Instead, there’s a private SSH key. The password is stored in /etc/bandit_pass/bandit14 and can only be read by user bandit14. I need to use this key to log in as bandit14.
Copy the key to my local machine:
# On my machine:
$ chmod 600 id_rsa
$ ssh -p 2220 -i id_rsa bandit14@bandit.labs.overthewire.org
The chmod 600 is essential — SSH refuses to use a key with loose permissions. Once logged in as bandit14:
bandit14@bandit:~$ find / -user $(whoami) 2>/dev/null
/etc/bandit_pass/bandit14
bandit14@bandit:~$ cat /etc/bandit_pass/bandit14
MU4VWeTyJk8ROof1qqmcBPaLh7lDCPvS
$(whoami) evaluates to bandit14, so this finds all files owned by me. The password file is owned by bandit14 and readable only by bandit14 — exactly as described.
Lesson learned: SSH keys need chmod 600 to work. find / -user $(whoami) is a quick way to find files owned by your user across the filesystem.
Password: MU4VWeTyJk8ROof1qqmcBPaLh7lDCPvS
Level 13 → Level 14: Telnet Submission
bandit14@bandit:~$ telnet localhost 30000
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
I pasted the current password and got back the next one:
MU4VWeTyJk8ROof1qqmcBPaLh7lDCPvS
Correct!
8xCjnmgoKbGLhHFAZlGE5Tmu4M2tKJQo
telnet is raw TCP. Send text, get text back. Simple.
Lesson learned: telnet works as a primitive TCP client for plain-text protocols.
Password: 8xCjnmgoKbGLhHFAZlGE5Tmu4M2tKJQo
Level 14 → Level 15: OpenSSL s_client
bandit15@bandit:~$ openssl s_client -connect localhost:30001
This connects to a TLS-protected service. The server uses a self-signed certificate (CN = SnakeOil), but that’s fine — we’re not verifying, just submitting.
The terminal fills up with certificate details, session tickets, and TLS handshake information. After all that, I pasted the password:
8xCjnmgoKbGLhHFAZlGE5Tmu4M2tKJQo
Correct!
kSkvUpMQ7lBYyCM4GBPvCvT1BfWRy0Dx
Lesson learned: openssl s_client is the TLS equivalent of telnet. It handles SSL/TLS handshakes so you can interact with encrypted services from the command line.
Password: kSkvUpMQ7lBYyCM4GBPvCvT1BfWRy0Dx
Level 15 → Level 16: Port Scanning and the KEYUPDATE Bug
bandit16@bandit:~$ nmap -p 31000-32000 localhost
PORT STATE SERVICE
31046/tcp open unknown
31518/tcp open unknown
31691/tcp open unknown
31790/tcp open unknown
31960/tcp open unknown
Five ports. I need to find which one speaks SSL/TLS and gives the next credentials. Let’s dig deeper:
bandit16@bandit:~$ nmap -sV -p 31046,31518,31691,31790,31960 localhost
PORT STATE SERVICE VERSION
31046/tcp open echo
31518/tcp open ssl/echo
31691/tcp open echo
31790/tcp open ssl/unknown
31960/tcp open echo
Two SSL ports. 31518 is ssl/echo — it just sends back whatever you send. 31790 is ssl/unknown — that's the one.
I tried openssl s_client -connect localhost:31790 and pasted the password. Nothing happened. The connection stayed open, and typing the password just returned KEYUPDATE repeatedly.
After some research, I found the issue. TLS 1.3 has a post-handshake mechanism called KEYUPDATE that refreshes encryption keys mid-session. OpenSSL interprets any line starting with certain characters as a command. My password starts with k — which matches KEYUPDATE.
The fix is the -nocommands flag:
bandit16@bandit:~$ openssl s_client -connect localhost:31790 -nocommands
This disables OpenSSL’s command interpretation. I pasted the password:
kSkvUpMQ7lBYyCM4GBPvCvT1BfWRy0Dx
Correct!
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAvmOkuifmMg6HL2YPIOjon6iWfbp7c3jx34YkYWqUH57SUdyJ
...
-----END RSA PRIVATE KEY-----
A private SSH key for bandit17. Copied it, saved it, chmod 600, and logged in.
Lesson learned: TLS 1.3’s KEYUPDATE renegotiation can interfere with OpenSSL’s command parsing. -nocommands disables it. When debugging network tools, pay attention to protocol versions and their quirks.
Password for next level: Private SSH key (save to file, chmod 600, ssh -i key bandit17@host)
Wrapping Up Day 3
Five levels. Here’s the map:
- Level 11→12 — Hex dump reversal and compression chain:
xxd -r,gzip -d,bzip2 -d,tar -xf,file - Level 12→13 — SSH key authentication:
chmod 600,ssh -i,find / -user $(whoami) - Level 13→14 — Raw TCP submission:
telnet - Level 14→15 — TLS submission:
openssl s_client -connect - Level 15→16 — Port scanning and KEYUPDATE workaround:
nmap -sV,openssl s_client -nocommands
The standouts today were the compression chain (eight layers of decompression that took forty minutes) and the KEYUPDATE bug (where TLS 1.3 ate my password because it started with ‘k’). The terminal equivalent of a type mismatch.
Next: Levels 17 → 22. More SSH keys, process monitoring, and the diff command.
Cheatsheet
# Level 11 → 12
xxd -r data.txt output.bin
cp output.bin data2.gz && gzip -d data2.gz
# Repeat: file → rename → decompress until ASCII
# Level 12 → 13
chmod 600 id_rsa
ssh -p 2220 -i id_rsa bandit14@bandit.labs.overthewire.org
find / -user $(whoami) 2>/dev/null
# Level 13 → 14
telnet localhost 30000
# Level 14 → 15
openssl s_client -connect localhost:30001
# Level 15 → 16
nmap -p 31000-32000 localhost
openssl s_client -connect localhost:31790 -nocommands 메타데이터
- post_id
- 33cdf78bd671
- slug
- overthewire-bandit-levels-12-to-17-day-3-of-the-wargame-33cdf78bd671
- url
- https://medium.com/@alph4r1us/overthewire-bandit-levels-12-to-17-day-3-of-the-wargame-33cdf78bd671
- canonical_url
- https://medium.com/@alph4r1us/overthewire-bandit-levels-12-to-17-day-3-of-the-wargame-33cdf78bd671
- author_url
- https://medium.com/@alph4r1us
- status
- ok
- fetched_at
- 2026-06-13 12:55:53