Skip to main content

Command Palette

Search for a command to run...

Complete Walkthrough for Overthewire Bandit

Easy-to-follow explanations for every Overthewire Bandit wargame level

Updated
•10 min read
Complete Walkthrough for Overthewire Bandit

Level 0:

  • SSH into the lab as bandit0 user
ssh bandit0@bandit.labs.overthewire.org -p 2220
🔒 bandit0

Level 0 -> Level 1:

  • The home folder for the user bandit0 has a readme file.

  • Reading the file contents with cat command gives the password.

cat readme
🔒 NH2SXQwcBdpmTEzi3bvBHMM9H66vVXjL

Level 1 -> Level 2:

  • The user has file named - but when tried to read with cat - it shows nothing.

  • This is because - has a special meaning in Linux

  • So reading it giving a path from the current location.

cat ./-
🔒 rRGizSaX8Mk1RTb1CNQoXTcYZWU6lgzi

Level 2 -> Level 3:

  • The file name in this case contains spaces.

  • Reading the file normally will result in error because Linux will treat them as separate files when spaces is present so need to escape them.

cat spaces\ in\ this\ filename
🔒  aBZ0W5EmUfAf7kHTQeOwd8bauFJ2lAiG

Level 3 -> Level 4:

  • The file is inside inhere folder and the file is hidden.

  • The file name can be viewed by running ls -al inhere command.

  • Now view the file.

cat inhere/.hidden
🔒 2EW7BBsr6aMMoJ2HjW067dm8EgX26xNe

Level 4 -> Level 5:

  • The inhere has many file but the password is in the human readable file

  • Using file command can give us the type of file and its information

file ./*

cat ./-file07
🔒 lrIWWI6bB37kxfiCQZqUdOIYfr6eEeqR

Level 5 -> Level 6:

  • There are many folders and inside them many file where finding manually is not a viable option

  • So using the find command to find the file described in the specification.

find -type f -size 1033c

cat maybehere07/.file2
🔒 P4L4vucdmLnm8I7Vl7jG1ApGSfjYKqJU

Level 6 -> Level 7:

  • This time the file can be anywhere in the system

  • Using find command to get the specific file and using 2>/dev/null will not print the error in the terminal.

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

🔒 z7WtoNQU2XfjmMtWA8u5rN4vzqu4v99S

Level 7 -> Level 8:

  • The password is in the very large file next to the word millionth

  • Using grep to get the line with the matching word.

cat data.txt | grep millionth

🔒 TESKZC0XvTetK0S9xNwm25STk5iWrBvP

Level 8 -> Level 9:

  • The password is the unique text in a large file.

  • We can use sort tool to sort the entire file in combination with uniq tool which removes the consecutive duplicate line

cat data.txt | sort | uniq -c
cat data.txt | sort | uniq -c | grep "1 "

🔒 EN632PlfYiZbn3PhVK3XOGSlNInNE00t

Level 9 -> Level 10:

  • The human readable strings can be extracted from a non-text file using the strings command.

  • We can then use grep to find the line with ==== characters.

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

🔒 G7w8LIi6J3kTb8A7j9LgrywtEUlyyp6s

Level 10 -> Level 11:

  • The password is in the data.txt file but is encoded with Base64 encoding.
cat data.txt | base64 -d

🔒 6zPeziLdR2RKNdNYFNb6nVCKzphlXHBM

Level 11 -> Level 12:

  • The password is in the data.txt file but the password is rotated by 13 position known as ROT13

🔒 JVNBBFSmZwKKOP0XbFXOoW8chDz5yVRv

Level 12 -> Level 13:

  • Since it is the hexdump of a compressed file
xxd -r data.txt > data
file data

  • Renaming the file to .gz and extracting with gzip gives the result as data .
mv data data.gz
gzip -d data.gz
file dataNow renaming and using the bzip2 tool.
mv data data.bz2
bzip2 -d data.bz2

mv data.bz2.out data.gz
gzip -d data.gz
file data

  • Same process

🔒 wbWdlBxEir4CaE8LaPhauuOo6pwRmrDw

Level 13 -> Level 14:

  • We get ssh private key instead of password.

  • The password is stored in /etc/bandit_pass/bandit14 and is only readable by bandit14 user.

  • First ssh as bandit14 user and read the password file

ssh bandit14@localhost -i sshkey.private -p 2220
cat /etc/bandit_pass/bandit14
🔒 fGrHPx402xGC7U7rXKDaxiWFTOiF0ENq

Level 14 -> Level 15:

  • To connect to the localhost at port 30000 we can use netcat
nc localhost 30000

🔒 jN2kgmIXJ6fShzhT2avhotn4Zcka6tnt

Level 15 -> Level 16:

  • For connection using the SSL we can use openssl or ncat
openssl s_client -connect localhost:30001
ncat --ssl localhost 30001

🔒 JQttfApK4SeyHwDlI9SXGR50qclOAil1

Level 16 -> Level 17:

  • For checking the ports in range listening for connection nmap can be used
nmap -sC -sV -p 31000-32000 localhost

  • The service for port 31790 is not echo so it is the valid one.

  • Sending the request and password to the service gives the ssh private key instead of password.

ncat --ssl localhost 31790

  • Save the private key to a file /tmp/sd/private

  • change the permission to 600

chmod 600 private
ssh bandit17@localhost -i private -p 2220

Level 17 -> Level 18:

  • There are two files password.new and password.old and the password is the only line changed between the two files.

  • Here, we can use the diff tool which is used to see differences between two files.

diff password.new password.old

🔒 hga5tuuCLF6fFzUpnagiMN8ssu9LFrdg

Level 18 -> Level 19:

  • We get logged out as soon as we logged in due to some commands in .bashrc

  • We can send commands to run after ssh to read the readme file before the session exit.

  • The auto logout is due to exit 0 command at the end of .bashrc file .

🔒 awhqfNnAbc1naukrpqDYcF95h7HoMTrC

Level 19 -> Level 20:

  • There is a executable file named bandit20-do which is a setuid binary.

  • This means the binary can be run with the privilege of the other user bandit20

  • We can use this to read the contents of the password file for the bandit20 user.

./bandit20-do cat /etc/bandit_pass/bandit20
🔒 VxCazJaVykI6W36BkBU0mJTCM8rR95XT

Level 20 -> Level 21:

  • The suconnect binary connects to localhost at the specified port given as argument

  • We log in with two session, listen to localhost at 2023

  • run suconnect binary with 2023 as port

  • provide the previous password from the listening session which sends it to suconect, which checks the password and returns the password for next level if correct.

nc -lvp 2023
🔒 NvEJF7oVjkddltPSrdKEFOllh9V1IBcq

Level 21 -> Level 22:

  • The /etc/cron.d directory has a Cronjobfile for the bandit22 user.

  • Looking at the contents it is running the /usr/bin/cronjob_bandit22.sh script continuously.

  • The scripts is echoing the password of the bandit22 user into a file in /tmp directory.

  • Reading the file gives us the password.

🔒 WdDozAdTM2z9DiFEQ2mGlwngMfj4EZff

Level 22 -> Level 23:

  • looking at the cron job

  • Looking at the script it is copying the password to the file named MD5 sum of the string I am user $myname
#!/bin/bash

myname=$(whoami)
mytarget=$(echo I am user $myname | md5sum | cut -d ' ' -f 1)

echo "Copying passwordfile /etc/bandit_pass/$myname to /tmp/$mytarget"

cat /etc/bandit_pass/$myname > /tmp/$mytarget
  • Since the user we want the password for is bandit23.

  • Now reading the file with name as the md5 hash

🔒 QYw0Y2aiA672PsMmh9puTQuhoz8SyR2G

Level 23 -> Level 24:

  • Looking at the cron job script of bandit24 user we see it executes and deletes the scripts present in the /var/spool/bandit24/foo directory
#!/bin/bash

myname=$(whoami)

cd /var/spool/$myname/foo
echo "Executing and deleting all scripts in /var/spool/$myname/foo:"
for i in * .*;
do
    if [ "$i" != "." -a "$i" != ".." ];
    then
        echo "Handling $i"
        owner="$(stat --format "%U" ./$i)"
        if [ "${owner}" = "bandit23" ]; then
            timeout -s 9 60 ./$i
        fi
        rm -f ./$i
    fi
done
  • We need to create a script at the location and make it executable to all users.

  • the script will be executed with the privilege of the bandit24 user and we can read the password stored in /etc/bandit_pass/bandit24

#!/bin/bash

cat /etc/bandit_pass/bandit24 > /tmp/pwned
cat /tmp/pwned

🔒 VAfGXJ1PBSsPSnvsjI8p759leLZ9GGar

Level 24 -> Level 25:

  • For this we need to call daemon at localhost at port 30002 with password of previous level and secret 4 digit pin

  • First we generate the password and pin combination and brute force it to the service

#!/bin/bash

for i in {0..9}
do
  for j in {0..9}
  do
    for k in {0..9}
        do
             for l in {0..9}
             do
                echo  "VAfGXJ1PBSsPSnvsjI8p759leLZ9GGar $i$j$k$l" >> pin.txt
             done
        done
    done
done
for i in {0000..9999};do echo$i >> pin.txt ; done
  • We then pipe the combination to the service and store response in a text file
cat pin.txt | nc localhost 30002 > response
  • Now grep the password

🔒 p7TaowMYrmu23Ol8hiZh9UvD0O9hpx8d

Level 25 -> Level 26:

  • when logged in we get the private RSA key of user 26

  • but the default shell is not bash or anything

  • it is /usr/bin/showtext

#!/bin/sh

export TERM=linux

exec more ~/text.txt
exit 0
  • The exec command shows the following result. The content is after "Enjoy you stay!".

  • Looking at the man page of the more command we figure we can go into vim while reading in more mode by pressing the V key .

  • We then make our terminal so small that it automatically goes to more when showing the text in *text.txt* file.

  • we then read file in vim by going to normal mode and entering the following command.

:r /etc/bandit_pass/bandit26
  • We can also run shell commands or get shell from vim

  • But for that we have to set the shell to bash as it has a different shell by default

:set shell=/bin/bash
:! cat /etc/bandit_pass/bandit26
:! /bin/bash
🔒 c7GvcKlw9mC7aUQaPx7nwFstuAIBw1o1

Level 26 -> Level 27:

  • We have a SUID binary by bandit27 user which takes command as argument.
./bandit27-do cat /etc/bandit_pass/bandit27
🔒 YnQpBuifNMas1hcUFk70ZmqkhUU2EuaS

Level 27 -> Level 28:

  • We first clone the repository in /tmp directory

  • note that the port should be 2220

git clone ssh://bandit27-git@localhost:2220/home/bandit27-git/repo
  • Reading the README file in the repository which has the password.

🔒 AVanL161y9rsbcJIsFHuw35rjaOM19nR

Level 28 -> Level 29:

  • Cloning the git repository we see the password is hidden

  • Since it is a git repository the changes are saved. Viewing git log

  • the latest commit message indicates some credentials leak so we checkout to the previous commit.

  • Read the Readme file again

🔒 tQKvmcwNYcFS6vmPHIUSI3ShmsrQZK8S

Level 29 -> Level 30:

  • The readme file shows no password

  • The log also do not have any information

  • But if we look at the branch in remote location we see some more branches

  • If we observe the password field at the readme, it gives hint as not in the production
git checkout dev
  • Then read the file again

🔒 xbhV3HpNGlTIdnjUrdAlPzc2L6y9EOnS

Level 30 -> Level 31:

  • We do not find anything repeating the previous challenges

  • But when we view tags it shows a file named secret

git tag
git show secret

🔒 OoffzGDlzhAlerFJ2cAiz1D41JW1Mhmt

Level 31 -> Level 32:

  • Reading the README file we know the task to be performed

  • creating the file with the content

  • removing the file from the .gitignore and push them to remote repository we get the flag.

🔒 rmCBvG56y58BXzv98yZGdO7ATVL5dW8y

Level 32 -> Level 33:

  • Upon ssh we get a shell where every command is converted to upper shell and then executed

  • However environment variables like SHELL are accessible as they are in upper case.

  • we execute $0 which represent the command which runs the program or binary.

  • Eg. /bin/bash uppershell $0 represents /bin/bash and $1 represent uppershell which is the argument.

  • We get the shell of bandit33

  • on inspection we can see that uppershell is a binary with suid set to bandit33 and group bandit32 has the executable permission.

  • From this we might guess, upon login through ssh /bin/bash uppershell command was executed.

Thank You !!!