HomeThe Stash

Lab 03 — Bandit 5 to 10: finding things you cannot see

LabSeptember 13, 2026

BeginnerTime ~45 minTarget OverTheWire BanditLevels 5 → 10Needs Lab 02

0 / 5 steps

The goal

The first six levels were about opening files you already knew the name of. These five are the opposite problem: the file is somewhere in a haystack and all you have is a description of it. By the end you will be able to search a filesystem by size, owner and type, and pull one line out of a file with a million of them.

No passwords here either. OverTheWire ask content creators not to publish game credentials, and their passwords rotate regardless. You get the reasoning and the commands; the answers are yours to find. Bandit is free and community-run — start at overthewire.org.

Where this picks up. You should be logged in as bandit5, which means you have finished Lab 02. Same host, same port 2220, same notes file open beside you.

Steps

01Search by what a file is, not what it is called

This level hides the file somewhere beneath inhere and describes it three ways: human-readable, exactly 1033 bytes, and not executable. You are not given a name, because the name is not the point.

$ find inhere -type f -size 1033c ! -executable
then read whatever single path comes back

$ cat inhere/maybehere07/.file2

Each word is a filter, and they stack. -type f means a regular file, not a directory. -size 1033c is exactly 1033 bytes — the c matters enormously, because a bare -size 1033 means 1033 512-byte blocks, which is a completely different question. ! negates the test that follows it.

Notice what find is doing that ls cannot. It walks the whole tree beneath the path you gave it, so subdirectories are searched without you asking. From here on, “I do not know where it is” stops being an obstacle.

02Search the whole machine by ownership

Now the file is somewhere on the server — anywhere — and the description is that it is owned by user bandit7, owned by group bandit6, and 33 bytes. Read that pairing twice. The user and the group are different numbers, and transposing them is the most common way to fail this level.

$ find / -type f -user bandit7 -group bandit6 -size 33c 2>/dev/null

What 2>/dev/null is for. Searching from / as an unprivileged user means find will hit hundreds of directories it is not allowed to read, and complain about every one. Those complaints go to standard error, stream number 2. Redirecting stream 2 into /dev/null throws them away and leaves only the result you wanted on screen.

This is your first real encounter with the three streams — stdin (0), stdout (1) and stderr (2) — and they are the foundation of everything in the next three steps. The reason errors get their own stream is exactly this: so you can discard the noise without discarding the answer.

Ownership as a search key is not a puzzle-game trick. On a compromised host, “which files does this service account own that it should not” is a real question, and this is how you ask it.

03One line out of a million

A file called data.txt, and the thing you want sits next to the word millionth. This is the simplest command in the whole lab and the one you will type most often for the rest of your career.

$ grep millionth data.txt

grep prints the lines that match. That is all it does, and it is enough. Three flags turn it from useful into indispensable: -i ignores case, -r searches a whole directory tree, and -v inverts the match so you see everything that does not contain the pattern. That last one is how you strip known-good noise out of a log.

04The line that appears exactly once

Same filename, harder question: every line in it is repeated except one. Find the one. There is no pattern to grep for, so you need two commands and a pipe.

$ sort data.txt | uniq -u

Why the sort is not optional. This is the single most valuable thing in this lab. uniq only ever compares a line to the one directly above it — it has no memory beyond that. Run uniq -u data.txt on its own and you get nonsense, because identical lines scattered through the file never end up adjacent. Sorting first is what puts the duplicates next to each other so uniq can see them.

And the pipe. | takes the standard output of the command on the left and makes it the standard input of the command on the right. Nothing is written to disk. This is the idea Unix is built on: small tools that read a stream and write a stream, chained into something none of them could do alone. Once that clicks, -u is a footnote — it just means “only the lines that were never repeated”, where -d would mean the opposite and -c would count them.

05Text hiding inside a binary

The last one in this run: data.txt again, but this time it is mostly not text. What you want is one of the few readable runs in it, and it has several = characters in front of it.

$ strings data.txt | grep ===
run  strings data.txt  on its own first to see what it pulls out

strings walks a file byte by byte and prints any run of printable characters long enough to look deliberate — four or more by default, adjustable with -n. Everything else it discards. That is why you can point it at a binary and get back URLs, error messages, file paths and the occasional hard-coded password.

This is genuine malware-triage technique, not a game mechanic. Running strings over an unknown executable is frequently the first thing an analyst does, because authors leave a surprising amount of plain text lying around in compiled code. You have just done, in one line, what that job starts with.

On the grep ===: you are filtering the readable output down to the run with the equals signs. Three is enough to be distinctive without assuming exactly how many there are.

Lab complete

You can now find a file by its properties rather than its name, search a whole filesystem without drowning in permission errors, and chain small tools together to pull one line out of noise. That is most of what day-to-day Linux work actually consists of.

Before you leave — prove it

Without looking: one, what is the difference between -size 33c and -size 33? Two, why does uniq need sort in front of it? Three, what does 2>/dev/null throw away, and what does it deliberately keep?

If the second one gives you any hesitation, go back to step 04. It is the idea that carries furthest.

What you learned

  • find -type -size -user -group — describing a file you cannot name
  • The c suffix on -size — bytes, not 512-byte blocks
  • 2>/dev/null — discarding stderr while keeping stdout
  • grep, and -i -r -v — matching, and inverting the match to remove noise
  • sort | uniq -u — and why uniq is blind without the sort
  • strings — readable text pulled out of binary, the first move in triage

NextBandit 10 to 15: encodings, and your first SSH key

Go deeper

Original walkthrough. The wargame belongs to the OverTheWire community; this page reproduces none of their level text and none of their passwords, in line with their rules for content creators. If a command here no longer does what the page says, tell me and I will fix it.