What would you like to learn?

Try PowerShell, networks, XSS, or Step 138

Browse the full curriculum →

CTF · Wargames

Step 96. Bandit 0–5 — The Wargame Solving Cycle

Step 96Estimated practice · 2.5 hours

Level 2 — Security Introduction and Attack Skill Basics | Difficulty ★★☆☆☆ | Estimated time: 2.5 hours

Prerequisites: Level 1 complete. You’ve connected to a remote server over SSH before, and you know basic Linux commands like ls, cat, and cd.

  • What you need: an SSH client (the built-in ssh in Windows PowerShell is enough), an internet connection, and a notepad or personal wiki for recording passwords.
  • ⚠️ All exercises in this chapter are for your own lab and legal platforms only. Applying them to unauthorized systems is a crime.
  • Legal practice ground notice: today’s stage, OverTheWire Bandit (bandit.labs.overthewire.org), is a legal learning platform officially opened by its operators "for attack practice." Beyond this server and practice folders on your own computer, today’s techniques are not to be used.

This is the start of Level 2. If everything so far was time spent learning tools, from now on it’s time spent breaking problems with tools. The first stage is a wargame — a server deliberately made vulnerable so you can practice attack techniques. Bandit is designed as a ladder where each level’s password becomes the next level’s key, letting you learn Linux commands one rung at a time.

But today’s real goal isn’t six passwords. It’s engraving into your body the solving cycle — the four beats of read, explore, verify, record — that keeps you steady even on a server you’ve never seen. If you consciously repeat this procedure on easy levels, on hard levels the procedure moves your body for you.


1. Learning Objectives

By the end of this chapter, you will be able to:

  • Connect to a remote server over SSH and specify a port
  • Apply the wargame solving cycle (read → explore → verify → record) in order
  • Find hidden files with ls -a, and safely read filenames containing - or spaces
  • Judge a file’s identity by content with file, and do conditional searches with find -size
  • Record each level’s solution as a write-up in a set format

2. Background Knowledge — Today’s Tools and Concepts

Today’s Tools at a Glance

Category Details
Language/environment Linux shell (the Bandit server runs bash) + an SSH client
Today’s commands ssh, ls -a, cat, file, find -size, pwd
Concepts needed Hidden files, characters the shell treats specially, magic numbers, the limits of security by obscurity
Today’s artifacts A Bandit 0→6 password chain + a per-level write-up document

2-1. Bandit’s Structure — The Password Ladder

Bandit’s rules are simple. Connect as bandit0 and find the next level’s password hidden somewhere. With that password you connect as bandit1, then find bandit2‘s password, and so on. Each level’s official page lists hints of "commands you may need this time."

The connection format is always the same.

ssh bandit0@bandit.labs.overthewire.org -p 2220

-p 2220 is the port specification. It’s a mandatory option when attaching to a server on a non-default port (not 22), so memorize the whole format.

2-2. The Solving Cycle — Four Beats

The procedure we’re settling in today.

① Read — read the level page's hints and the guidance files inside the server first
② Explore — sweep the surroundings with ls -a, pwd, file
③ Verify — confirm what you found is the real answer (does it read? is the format right?)
④ Record — immediately write the command, reasoning, and result in your wiki

Beginners skip ① and type commands first. Then attempts become wild spraying. If the hint says "human-readable," it’s a file problem; if it says "hidden," it’s an ls -a problem. Just reading the hint first cuts your attempts in half.

2-3. Hidden Files — The Meaning of .

In Linux, files whose names start with . don’t appear in ls‘s default listing. The original purpose wasn’t security but tidiness — a courtesy to keep configuration files from cluttering folders.

So "it’s hidden, so it must be invisible" doesn’t hold. One ls -a reveals everything. In security, this kind of misconception is called the error of security by obscurity — meaning hiding is not security. It’s why Bandit’s early levels start with hidden-file problems, and on real breached servers too, attackers’ traces are regularly discovered in .-starting files.

2-4. Characters the Shell Treats Specially

If a filename is -, cat interprets it not as a file but as standard input. If a filename contains spaces, cat spaces in this filename gets interpreted as a command trying to read four files. The filename is colliding with the command’s grammar.

There are only two fixes. Attach a path to say "it’s a file, not an option" (./-), or wrap it in quotes to bind it into one ("spaces in this filename"). This principle applies as-is to other special characters like *, ?, $.


3. Follow Along

3-1. Level 0 — Connecting Is the Whole Problem

Level 0’s assignment is entirely "connect via SSH."

Input

ssh bandit0@bandit.labs.overthewire.org -p 2220

When asked for a password, enter bandit0. Screen on successful connection (output example — the server connection is yours to do):

bandit0@bandit:~$

How to read it: the prompt’s bandit0@bandit means "you’ve entered server bandit as user bandit0." Here’s cycle beat ①, read — reading the readme placed in the home folder reveals Level 1’s password (cat readme).

Why: the procedure for opening a remote server’s door is the first scene of every penetration and analysis task going forward. When the four pieces — address, user, port, password — come together, the door opens.

3-2. Level 1 → 2 — A File Named -

This time the home folder has a file whose name is just -.

Input (inside the server, output example)

ls
cat -

Run cat - and it looks like nothing happens — the shell interpreted - as "standard input" and is waiting for your typing. Escape with Ctrl+C.

The correct command

cat ./-

How to read it: attaching ./ makes it a path meaning "the file named - in the current folder," dodging the option interpretation. This one-character difference is all of Level 1.

3-3. Level 2 → 3 — A Filename with Spaces

This time the filename is spaces in this filename.

Input (inside the server, output example)

cat "spaces in this filename"

Or tab autocompletion (type up to cat sp and press Tab) inserts the escapes for you. Both are correct.

How to read it: quotes are a declaration that "inside here is one chunk." Since the shell uses spaces as separators, a name containing spaces must be bound together without fail.

3-4. Level 3 → 4 — Hidden Files

There’s a hidden file inside the inhere folder.

Input (inside the server, output example)

cd inhere
ls
ls -a

How to read it: ls looks empty, but ls -a shows the real listing. . and .. are the special "self · parent folder" entries present in every folder, so skip them — the dot-starting file below them is the target.

Why: memorize that the first command of exploration is always not ls but ls -a. Seeing what’s hidden must be the default.

3-5. Level 4 → 5 — Judging Identity with file

Inside inhere are ten files from -file00 to -file09, and only one of them is a "human-readable" file.

Input (inside the server, output example)

cd inhere
file ./-*

Output example

./-file00: data
./-file01: data
...
./-file07: ASCII text
...

How to read it: file judges identity not by the file’s name but by its content’s first bytes (magic numbers). The one judged ASCII text is the answer. In ./-*, the * is a wildcard meaning "any characters that follow," so we judged all ten at once.

This experiment reproduces identically on your own computer too (measured 2026-09-09 on WSL, Ubuntu 24.04):

mkdir file-lab && cd file-lab
echo 'readable file' > file-a
printf 'x00x01x02' > file-b
file ./*
./file-a: ASCII text
./file-b: data

3-6. Level 5 → 6 — A Taste of Conditional Search with find

The goal is a file somewhere in inhere that is "1033 bytes and not executable."

Input (inside the server, output example)

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

How to read it: conditions narrow as they stack (AND). The c in -size 1033c is the "bytes" unit marker — drop it and it gets interpreted in 512-byte block units, changing the result. ! is negation, "not."

Here’s the identical reproduction on my own computer (measured 2026-09-09 on WSL):

dd if=/dev/zero of=target bs=1 count=1033 2>/dev/null
find . -type f -size 1033c
./target

The same command works on the server and on my computer — proof that these techniques aren’t game-specific but general-purpose tools. dd is a command that makes a file of an exact size; bs=1 count=1033 means "1033 blocks of 1 byte each."

3-7. Hidden Files Deep Dive — Make, Hide, and Find

On your own computer (Linux/WSL), not the server, confirm obscurity’s limits yourself.

Input (measured 2026-09-09 on WSL)

mkdir hide-lab && cd hide-lab
echo 'secret memo' > .secret
echo 'normal file' > normal.txt
ls
ls -a

Output (measured 2026-09-09)

--- ls ---
normal.txt
--- ls -a ---
.
..
.secret
normal.txt

One step further — try making a three-dot folder. After mkdir ..., run ls -a (measured 2026-09-09):

.
..
...
.secret
normal.txt

How to read it: mixed in between . and .., ... passes a scanning eye. It’s a classic trick real malware uses, and defenders look for exactly this shape.

Why: experience a concealment technique once from the "making side," and the eye on the "finding side" changes. After today, your ls -a will look one layer more carefully.

3-8. Writing a Write-up — Your First Official Solution Record

The cycle’s last beat: recording. Make bandit-0to5.md in your notepad or wiki and fill each level in this format.

# Bandit Level N → N+1
- **Hint**: (one line of what's written on the official page)
- **What I saw while exploring**: (what stood out in the ls results)
- **Command**: (what I actually typed)
- **Reasoning**: (why this command)
- **Newly learned**: (if none, write "none — procedure review")

The "reasoning" slot is the core. The moment you write the reason you typed a command, memorization turns into understanding. As for the passwords themselves, not uploading them to a public repository is wargame etiquette — record only the commands and the thinking process.


4. Missions & Exercises

Mission — Completing the Bandit 0→6 Ladder and Proving the Cycle

  1. Connect as bandit0 and complete the chain leading up to Level 6’s password
  2. At each level, leave one line each of the four beats — read → explore → verify → record — in your notes
  3. On your own computer (or WSL), make 1 hidden file + 1 filename with spaces + 1 file of 1033 bytes, and find them all again with ls -a, file, and find -size 1033c
  4. Complete a write-up document in the 3-8 format

Exercises

Exercise 1. Explain why cat - can’t read the file, and by what principle each of the two fixes (./- and quotes) works.

Exercise 2. What are the . and .. that always appear in ls -a results, and why must they not be counted as hidden files?

Exercise 3. What does the file command look at to judge identity? If you feed an executable file named photo.jpg to file, how will it be judged?

Exercise 4. In find . -size 1033c, why does dropping the c change the result?


Answers & completion criteria · expand/collapse

5. Model Answers & Completion Criteria

Mission Model Answer

The chain’s skeleton (server-side commands as output examples, key commands only):

ssh bandit0@bandit.labs.overthewire.org -p 2220   # password bandit0
cat readme                                         # L0→1
cat ./-                                            # L1→2
cat "spaces in this filename"                      # L2→3
cd inhere && ls -a && cat ./.hidden                # L3→4 (confirm the actual hidden filename)
file ./-* && cat ./-file07                         # L4→5 (the number depends on the judgment result)
find . -type f -size 1033c ! -executable           # L5→6

The local reproduction part is exactly the measured commands from 3-5~3-7. How to verify: ① is each stage’s password an alphanumeric string of around 32 characters? ② does connecting to the next level with that password actually work — this is the substance of the "verify" beat. ③ is the write-up’s "reasoning" slot filled for every level?

Exercise Answers

Answer 1. Because in the shell, - conventionally means standard input (stdin), cat - waits for keyboard input instead of reading a file. ./- is the method of attaching a path to make explicit that "it’s a file," and quotes like cat "./-" are the method of binding the string into one argument. Both are different means to the same end: "avoiding the shell’s special interpretation."

Answer 2. . points to the current folder and .. to the parent folder — special entries present in every folder. Since they’re guidepost links, not files, they mustn’t be counted in the hidden-file count. The objects of interest are the actual dot-starting files listed below them.

Answer 3. It looks at the content’s first bytes (magic numbers) and character composition. It doesn’t look at the name. So an executable file named photo.jpg gets judged as ELF ... executable — content, not name, tells the identity (see the 2026-09-09 measurement in section 3-5, where a file containing the three bytes x00x01x02 was judged data).

Answer 4. Without c, the size unit becomes 512-byte blocks, so it looks for a file of "1033 blocks (about 520 thousand bytes)." A 1033-byte file doesn’t match the condition and the result comes out empty-handed (measured 2026-09-09 on WSL: the search without c found nothing).

Completion Criteria Checklist

  • [ ] I can connect in the ssh user@address -p port format
  • [ ] I can recite the solving cycle’s four beats (read → explore → verify → record) in order
  • [ ] I can find hidden files with ls -a and explain the meaning of ./..
  • [ ] I can read - and space-containing filenames via path-attaching and quotes
  • [ ] I can explain that file judges by content, not name
  • [ ] I know the meaning of c in find -size 1033c
  • [ ] Mission: I completed the Bandit 0→6 chain and the write-up

6. Common Pitfalls & Fixes

Wall 1. The ssh connection drops right away or a port error appears

Symptom (measured-family message):

ssh: connect to host bandit.labs.overthewire.org port 22: Connection refused

Cause: you dropped -p 2220 and went to the default port 22. Bandit listens on 2220.
Fix: ssh bandit0@bandit.labs.overthewire.org -p 2220 — visually compare the three pieces: user, address, port. If outbound 2220 is blocked on a company or school network, you’ll need to try from a different network.

Wall 2. I ran cat – and there’s no response

Symptom: the cursor just blinks and the prompt doesn’t come back.
Cause: - got interpreted as standard input and it’s waiting for your typing.
Fix: escape with Ctrl+C and retype cat ./-. No response is itself the hint — "right now the shell isn’t seeing this as a file."

Wall 3. Reading a space-containing filename shows "No such file or directory" repeatedly

Symptom (output example):

cat: spaces: No such file or directory
cat: in: No such file or directory

Cause: typed without quotes, the name got split at the spaces. The shell looked for four files.
Fix: wrap the whole thing like cat "spaces in this filename", or use Tab autocompletion after cat sp.

Wall 4. The find result is completely empty

Symptom: it should definitely be there, but nothing comes out.
Cause: if even one condition is wrong, the AND makes the whole thing empty-handed. Dropping the c in -size 1033c is the most frequent cause.
Fix: peel off conditions one by one and narrow down which condition makes it 0 results. The standard of find debugging is "subtracting conditions."

Wall 5. I don’t know where I wrote down the password I found yesterday

Symptom: the level chain is broken and you have to solve from the beginning again.
Cause: an absent recording habit — beat ④ of the cycle was missing.
Fix: solve again, but this time write immediately upon finding. Commands you just typed inside the server can be salvaged with history | tail -10. One chain-breaking accident is enough for a lifetime.


7. Summary

Today’s Concepts

Concept One-line explanation
Wargame A legal server deliberately made vulnerable for attack practice
Solving cycle The four beats: read → explore → verify → record
Hidden file A file starting with . that drops out of ls‘s default listing
Security by obscurity The misconception "it’s hidden, so it’s safe" — not security
Magic number Marker bytes at a file’s front — the identity evidence file looks at
Special character avoidance Attaching a path (./-) and binding with quotes

Today’s Commands

Command What it does
ssh user@address -p port Connect to a remote server (port specified)
ls -a Full listing including hidden files
cat ./- Read a file named -
cat "a b" Read a filename containing spaces
file ./-* Judge identity by content
find . -size 1033c Search by size condition (c = bytes)

An Instinct More Important Than Commands

Fix your first 30 seconds upon entering an unfamiliar server. Confirm your position with pwd, sweep everything with ls -a, and read the guidance files first. This 30-second rhythm is the same on a wargame or a real-world server. And the habit of writing immediately upon finding — an unrecorded discovery is a discovery that never happened. One last sentence to remember: "nothing is hidden; there’s only what you haven’t looked at." Today’s ls -a is the start of that eye.


Once every box is checked, Step 96 is complete.

ONE STEP FURTHER

Finished this lesson?

Check the completion criteria, then mark your progress.

Something wrong with this page or a link? Let us know.
Next