Site Logo
Niklas Heringer - Cybersecurity & Math
Cover Image

What I Learned from Bandit Wargames - Level 0-12 (And Why You Should Try It)

Maybe you’ve already come across the Bandit Wargames from OverTheWire, an awesome, game-style approach to teaching linux and problem-solving thinking basics.

I’d greatly recommend that you try them out for yourself. Use Google but not ChatGPT, only if you already have an idea but are not making progress on how to execute it.

All war games are divided into levels, with Bandit being the “basics” to all other wargames. It consists of 34 levels, where you hop from container to container with ssh.

I won’t spoiler solutions, just go over what i’ve learned, how to approach problems of similar styles and the essence of what they’ll teach you too!

If you’re not familiar with SSH and how to use it, a quick read will greatly help.


Starting Tips: referencing files

Let’s say you want to use cat FILE to read out the next password. What if the filename’s a bit special? Containing whitespaces, . or starting with - special?

Dealing with Tricky Filenames in Linux

1. Current Directory Executables

If the file isn’t in $PATH, run it with:

./filename

2. Filenames with Spaces

cat "file with spaces.txt"
# or
cat file\ with\ spaces.txt

Tab completion works: Type first few chars, hit Tab, shell autocompletes and escapes it:

cat file\ [Tab]

3. Filenames with Dashes (-)

Leading dashes are interpreted as options:

cat -- -filename
# or
./--script.sh

(-- tells the command: no more options)

4. Filenames with Dots (.)

No special handling needed:

cat file.name.txt
./script.sh

5. Quoting vs Escaping

6. Tab Completion

Use Tab to autocomplete weird names:

Pro Tip: Use ls -b to show escape sequences (\ ) for non-printable or special characters.


Bash Basics - Always Worth a Revisit

No extended magic needed here, something as simple as

for file in *; do
  echo "Looking into $file"
  cat "$file"
done

can save you quite some time.

If you use such on foreign systems such as wargames, make sure to delete them after you finish!


Understanding Directory Content

Understanding ls and it’s Options

ls -la: How often have you used that command without exactly knowing what it does?

You’ll most likely know that ls serves to display directory content, but the options?

Read all about them if you want, for now let’s use

Understanding the Output of ls -la

Run ls -la somewhere and you’ll see something along the lines of

drwxr-x--- 2 root bandit5 4096 Jul 28 19:03 maybehere01

Now what does that all mean?


Linux File Permissions

This great RedHat article is really worth a read, i greatly recommend it.

Applying What We’ve Learned

With all that, we can tell what drwxr-x--- 2 root bandit5 4096 Jul 28 19:03 maybehere01 means:

We’re dealing with the directory maybehere01, owned by bandit5 who has rwx permissions on the file, r-x writes for the user group of bandit5 and then no rights for all others (---). It is 4096 bytes and was last modified Jul 28 at 19:03.


Using find for Systematic File Searches in Linux

Sometimes you’re looking for files with specific properties: size, readability, executability, or content type. Here’s how to build powerful find one-liners to help you zero in.

Core Logic Pattern

find [STARTING-DIR] -type f [SIZE-FLAGS] [PERM-FLAGS] -exec file {} + | grep [CONTENT-TYPE]
Component Purpose
find . Start search in current directory
-type f Only include files
-size 33c File is exactly 33 bytes (use +33c or -33c for greater/less)
! -executable File is not executable
-exec file {} + Describe file contents (file command)
grep 'ASCII text' Narrow to human-readable text

️ Practical One-Liners

1. Find all files of exactly 1033 bytes and not executable:

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

2. Find human-readable (ASCII) files under 200 bytes:

find . -type f -size -200c -exec file {} + | grep 'ASCII text'

3. Find non-executable text files of any size:

find . -type f ! -executable -exec file {} + | grep 'ASCII text'

4. Find scripts (shell script) in current dir:

find . -type f -exec file {} + | grep 'shell script'

5. Combine with grep content search (e.g., contains “password”):

find . -type f -exec grep -l 'password' {} +

Tips

find . -type f -iname "*.txt"

Use -perm /111 to find files with any executable bit set (useful in CTFs):

find . -type f -perm /111

At some point, a command like find / -type f -user [USER] -group [GROUP] -size [SIZE]c 2>/dev/null will come in handy - but what about this 2>/dev/null fun?

File Descriptors in Linux

In Unix-like systems, every process has three default file descriptors:

FD Name Purpose Symbol
0 stdin Standard input (e.g. keyboard) <
1 stdout Standard output (e.g. screen) >
2 stderr Standard error (error messages) 2>

How to Use Them in Shell

Goal Command Example
Redirect output to a file echo hello > out.txt
Append output to a file echo again >> out.txt
Redirect only errors somecmd 2> errors.txt
Redirect both output and errors somecmd > all.txt 2>&1
Suppress error messages somecmd 2>/dev/null
Provide input from a file somecmd < input.txt

Tip: 2>&1 means “redirect stderr (2) to wherever stdout (1) is going.”


Searching a File with Regex

Basic Syntax

grep 'PATTERN' data.txt 

Extended Regex

Use -E to enable extended regex (e.g., +, |, ?, ()):

grep -E 'your-regex-pattern' data.txt

Example Patterns

Goal Command Example
Lines starting with “pass” grep '^pass' data.txt
Lines ending in “.txt” grep '\.txt$' data.txt
Lines containing digits grep '[0-9]' data.txt
Match “abc”, “def”, or “ghi” grep -E 'abc | def | ghi' data.txt
Word with exactly 5 letters grep -E '\b[a-zA-Z]{5}\b' data.txt
Lines that are only numbers grep -E '^[0-9]+$' data.txt

Other Tips


Introducing awk

awk is a powerful text-processing language built right into most Unix systems. It’s made for scanning files line by line, breaking them into fields (columns), and acting on patterns.

Whether you’re parsing logs, extracting passwords, or slicing structured data, awk is your lightweight weapon.

You can read more about it here .

Basic Syntax

awk options 'selection _criteria {action }' input-file > output-file

Field Structure

By default, awk splits each line into fields based on whitespace:

Variable Meaning
$0 The entire line
$1 First word (field)
$2 Second word
... And so on
NF Number of fields

Common Examples

awk '{ print }' data.txt
awk '{ print $1 }' data.txt
awk '/admin/ { print $3 }' data.txt
awk 'NF > 5' data.txt

Use Case: Find the Word After “millionth”

awk '{for (i=1;i<NF;i++) if ($i=="millionth") print $(i+1)}' data.txt

Loops through all fields; if a field is millionth, it prints the word after it.

Tips and Tricks

Trick Explanation
-F":" Change field delimiter to :
BEGIN {} Code to run before processing input
END {} Code to run after all input is read
awk '{ print $NF }' Print the last word in each line
awk '{print $(NF-1)}' Print second to last word
awk 'length($0) > 50' Print lines longer than 50 characters
awk '{count++} END {print count}' Count lines in a file

When to Use awk vs grep, cut, sed

Tool Best For
grep Matching simple patterns
cut Extracting fixed columns (by delimiter)
sed Stream edits, substitution
awk Pattern-based logic, field parsing, conditions, inline scripting

Think of awk as a lightweight scripting language for text. It’s one of the best tools to learn early, especially when you find yourself needing conditional parsing or data extraction without writing a full script.


Encoding and Decoding with base64

Sometimes you’ll find that a file looks like gibberish — a long string of letters, numbers, and slashes. That’s often base64 encoding, used to hide or safely transmit data.

What Is It?

Base64 is not encryption — just a way to encode binary data into readable text. It’s easily reversible.

How to Use It

Decode base64 from a file:

base64 -d encoded.txt

Encode a file to base64:

base64 original.txt > encoded.txt

Decode a base64 string inline:

echo 'c2VjcmV0' | base64 -d
# Output: secret

Encode inline:

echo 'password123' | base64

Tip: Always double-check if a weird-looking string is base64: Use file, grep -E '^[A-Za-z0-9+/=]{10,}$', or just try decoding and see.


Translating and Cleaning Text with tr

The tr command is a small but powerful tool to translate, squeeze, or delete characters. Great for quick text cleanup, lowercasing, or working with encoded messages.

🔧 Basic Syntax

tr [OPTIONS] SET1 [SET2]
Option Meaning
-d Delete characters in SET1
-s Squeeze repeated characters
-c Complement: use all except SET1

Useful Examples

1. Convert UPPERCASE to lowercase

echo "HELLO" | tr 'A-Z' 'a-z'

2. Lowercase to UPPERCASE

echo "bandit" | tr 'a-z' 'A-Z'

3. Remove all digits

echo "pass123word" | tr -d '0-9'

4. Replace spaces with underscores

echo "some file name" | tr ' ' '_'

5. Squeeze repeating characters

echo "aaaabbbcccc" | tr -s 'a-c'
# Output: abc

6. Keep only alphanumerics

cat file.txt | tr -cd '[:alnum:]\n'

This deletes everything except letters, numbers, and line breaks.

Pro Tips

When to Use tr

Use Case Why tr Works Well
Cleanup of encoded strings Strip padding, unwanted characters
Format transformations Spaces → underscores, case changes
Lightweight replacements No need for sed or scripting

ROT Ciphers with tr (e.g., ROT13)

ROT ciphers are simple substitution ciphers where each letter is rotated by n positions in the alphabet. ROT13 is the most common.

🔒 ROT13 example: an, bo, …, na

Apply ROT13 using tr

echo "uryyb jbeyq" | tr 'a-zA-Z' 'n-za-mN-ZA-M'
# Output: hello world

tr maps a-z to n-z followed by a-m → neat and fast.

Test ROT13 interactively

echo "hello world" | tr 'a-z' 'n-za-m'

Repeating tr 'a-z' 'n-za-m' twice returns the original!

DIY ROT with other shifts

To ROT5 digits:

echo 12345 | tr '0-9' '5-90-4'
# Output: 67890

ROTX ≈ shift-X on the alphabet. But tr is static, so ROT7 etc. needs scripting or tools like python -c.


The Bandit war games are teaching me a lot about commands i didn’t know before. I’m excited to see what part 2 will bring about in learnings! See you soon. Drink enough water and be kind.