Linux FundamentalsTHREAT/LOW2025-12-13

OverTheWire: Bandit Levels 0–15

Progression through OverTheWire's Bandit CTF. Mastered core Linux CLI utilities, raw TCP socket interactions (Netcat), ROT13 encoding, and SSH key exfiltration techniques.

#OverTheWire#Linux#Netcat#SSH

Overview

Bandit is OverTheWire's introductory wargame designed to teach Linux command-line fundamentals through practical challenges. Each level stores the password for the next level in an increasingly obscure location. Levels 0 through 15 cover file system navigation, search and filtering, encoding, compression, and basic network socket interaction.

Levels 0 to 5: The Basics

Level 0 to 1

Objective: Read a file named readme in the home directory.

Password: ZjLjTmM6FvvyRnrb2rfNWOZOTa6ip5If

code
cat readme

Level 1 to 2

Objective: Read a file whose name is a literal dash character.

A bare dash is interpreted by most Unix programs as stdin rather than a filename. You must prefix it with an explicit path to tell the shell it refers to a file.

Password: 263JGJPfgU6LtdEvgfWU1XP5yac29mFx

code
cat ./-

Level 2 to 3

Objective: Read a file with spaces in its name.

Use tab completion: type cat space and press Tab. The shell will escape the spaces automatically. Alternatively, wrap the filename in quotes or escape each space manually.

Password: MNk8KNH3Usiio41PRUEoDFPqfxLPlSmx

code
cat "./spaces in this filename"
cat ./spaces\ in\ this\ filename

Level 3 to 4

Objective: Read a hidden file inside the inhere directory.

Files whose names begin with a dot are hidden by default in Linux. The ls -la flag combination lists all files including hidden ones with full metadata.

Password: 2WmrDFRmJIq3IPxneAaMGhap0pFhF3NJ

code
cd inhere
ls -la
cat .hidden

Level 4 to 5

Objective: Find the only human-readable file among several in the inhere directory.

The file command identifies the type of each file based on its content rather than its extension. Look for the entry labeled ASCII text in the output.

Password: 4oQYVPkxZOOEOO5pTW81FB8j8lxXGUQw

code
file ./*
cat ./-file07

Levels 5 to 10: Filtering and Finding

Level 5 to 6

Objective: Find a file that is human-readable, exactly 1033 bytes in size, and not executable.

The -size 1033c flag specifies size in bytes. The ! operator negates the following condition.

Password: HWasnPhtq9AVKe0dmk45nxy20cvUa6EG

code
find . -type f ! -executable -size 1033c

# To additionally confirm human-readable content
find . -type f ! -executable -size 1033c -exec file {} + | grep "text"

Level 6 to 7

Objective: Find a file owned by user bandit7, group bandit6, and exactly 33 bytes in size, located somewhere on the entire filesystem.

Searching from the root generates many permission denied errors. Redirecting stderr to /dev/null silences them so only valid results appear.

Password: morbNTDkSW6jIlUc0ymOdMaLnOlFVAaj

code
find / -user bandit7 -group bandit6 -size 33c 2>/dev/null

Level 7 to 8

Objective: Find the password stored next to the word millionth in data.txt.

Password: dfwvzFQi4mU0wfNbFOe9RoWskMLg7eEc

code
grep "millionth" data.txt

Level 8 to 9

Objective: Find the one line in data.txt that appears exactly once.

uniq only detects adjacent duplicates, so the file must be sorted first before piping into it.

Password: 4CKMh1JI91bUIZZPXDqGanal4xvAg0JM

code
sort data.txt | uniq -u

Level 9 to 10

Objective: Find the password hidden among human-readable strings in a binary file, preceded by several equals signs.

data.txt is a binary file. The strings command extracts all printable character sequences from it, making the relevant line visible.

Password: FGUW5ilLVJrxX9kMYMmlN4MgbpfMiqey

code
strings data.txt | grep "===="

Levels 10 to 13: Encoding and Compression

Level 10 to 11

Objective: Decode a Base64-encoded file.

Password: dtR173fZKb0RRsDFSGsg2RWnpNVj3qRr

code
base64 -d data.txt

Level 11 to 12 (ROT13)

Objective: Decode a ROT13-encoded file.

ROT13 rotates each letter in the alphabet by 13 positions. The tr command maps each character in the input range to its rotated equivalent.

Password: 7x16WNeHIi5YkIhWsfFIqoognUTyj9Q4

code
cat data.txt | tr 'A-Za-z' 'N-ZA-Mn-za-m'

Level 12 to 13 (Nested Compression)

Objective: Reconstruct a binary from a hexdump, then iteratively decompress it through multiple layers of compression.

data.txt is a hexdump of a file that has been compressed repeatedly. The process requires identifying the current compression format with file, renaming the file with the correct extension, decompressing it, and repeating until a plaintext file is reached.

Password: FO5dwFsc0cbaIiH0h8J2eUks2vdTDwAn

code
# Step 1: Reconstruct the binary from the hexdump
xxd -r data.txt > data.bin

# Step 2: Identify the format
file data.bin

# Step 3: Rename and decompress based on the format
# Gzip
mv data.bin data.gz && gzip -d data.gz

# Bzip2
mv data data.bz2 && bzip2 -d data.bz2

# Tar
mv data data.tar && tar -xf data.tar

Repeat steps 2 and 3 until file reports the result as ASCII text.

Level 13 to 14 (SSH Key Exfiltration)

Objective: Use an SSH private key found in the home directory to authenticate as bandit14 on the same host.

The home directory contains sshkey.private, a private key for bandit14. Because direct localhost connections are blocked by the server configuration, the key must be exfiltrated to your local machine first, then used to connect from outside.

Password: MU4VWeTyJk8ROof1qqmcBPaLh7lDCPvS (authentication via SSH key)

code
# Copy the key to your local machine
scp -P 2220 [email protected]:sshkey.private .

# Restrict permissions (required by the SSH client)
chmod 600 sshkey.private

# Connect as bandit14 using the key
ssh -i sshkey.private [email protected] -p 2220

Security policies in sshd_config such as DenyUsers or AllowGroups can block connections originating from localhost. Moving the credential to a trusted external machine bypasses the restriction by connecting from an allowed source. This is a common lateral movement pattern in real-world environments.

Level 14 to 15 (Raw TCP Socket Interaction)

Objective: Submit the current level password to a service listening on port 30000 on localhost using a raw TCP connection.

The service accepts plaintext input without any protocol handshake. Any tool capable of opening a raw TCP connection works here.

Current password location: /etc/bandit_pass/bandit14

Password: 8xCjnmgoKbGLhHFAZlGE5Tmu4M2tKJQo

code
# Retrieve the current password
cat /etc/bandit_pass/bandit14

# Method A: Netcat
nc localhost 30000

# Method B: Telnet
telnet localhost 30000

# Method C: Ncat
ncat localhost 30000

# One-liner: pipe directly without copy-pasting
cat /etc/bandit_pass/bandit14 | nc localhost 30000

Not all network services require a dedicated client. Many internal tools and custom applications listen on raw TCP ports and accept plaintext input. Netcat is the standard tool for interacting with them manually, whether for debugging or exploitation.

Key Takeaways

  • The find command with -user, -group, -size, and -perm flags is foundational for privilege escalation enumeration on Linux systems.
  • Always redirect stderr to /dev/null with 2>/dev/null when running filesystem-wide searches to suppress permission noise.
  • The file command identifies true file types from magic bytes regardless of extension, which is essential during the nested compression challenge and in forensics work generally.
  • Netcat is the most versatile tool for raw TCP interaction. Mastering it early pays dividends across CTFs and real engagements.
  • SSH key exfiltration via scp combined with chmod 600 is a practical lateral movement technique that appears in real-world scenarios, not just CTFs.
  • ROT13 and Base64 are not encryption. They are encoding schemes that provide zero confidentiality and appear frequently in CTF challenges and real-world obfuscation attempts.