bajok
~bajok
Cashmere makes perfect better BTW I USE ARCH

OTW - Bandit

Categories: Misc | Tags: Overthewire


Original description

The Bandit wargame is aimed at absolute beginners. It will teach the basics needed to be able to play other wargames. This game, like most other games, is organised in levels. You start at Level 0 and try to “beat” or “finish” it. Finishing a level results in information on how to start the next level.


Level 0

The goal of this level is for you to log into the game using SSH. The host to which you need to connect is bandit.labs.overthewire.org, on port 2220. The username is bandit0 and the password is bandit0. Once logged in, go to the Level 1 page to find out how to beat Level 1.

Use ssh to connect to the machine.

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

Level 1

The password for the next level is stored in a file called readme located in the home directory. Use this password to log into bandit1 using SSH. Whenever you find a password for a level, use SSH (on port 2220) to log into that level and continue the game.

Use cat command to display the contents of the file.

$ cat readme

Level 2

The password for the next level is stored in a file called - located in the home directory

Use cat command, but specify the file path to avoid reading from the stdin.

$ cat ./-

Level 3

The password for the next level is stored in a file called spaces in this filename located in the home directory

Use cat command, but put the filename in quotation marks to avoid it being treated as more than one file.

$ cat "spaces in this filename"

Alternatively escape whitespace characters in the filename with a backslash.

$ cat spaces\ in\ this\ filename

Level 4

The password for the next level is stored in a hidden file in the inhere directory.

Use ls command to list hidden files in a directory.

$ ls -A inhere/
.hidden

Level 5

The password for the next level is stored in the only human-readable file in the inhere directory. Tip: if your terminal is messed up, try the “reset” command.

Use file command to determine the file type of the files in a directory.

$ file inhere/* 
inhere/-file00: data 
inhere/-file01: data 
inhere/-file02: data 
inhere/-file03: data 
inhere/-file04: data 
inhere/-file05: data 
inhere/-file06: data 
inhere/-file07: ASCII text 
inhere/-file08: data 
inhere/-file09: data 

Level 6

The password for the next level is stored in a file somewhere under the inhere directory and has all of the following properties:

Use find command to search for files that meet the abovementioned requirements. The find command can’t determine whether a file is human-readable or not, however the -exec flag can be utilized to run the file command on the selected files.

$ find inhere/ -size 1033c ! -perm /111 -size 1033c -exec file '{}' \;
inhere/maybehere07/.file2: ASCII text, with very long lines

Level 7

The password for the next level is stored somewhere on the server and has all of the following properties:

Use find command to search for files that meet the abovementioned requirements. In addition, redirect stderr to /dev/null to avoid permission errors being printed along with the valid data.

$ find / -user bandit7 -group bandit6 -size 33c 2>/dev/null
/var/lib/dpkg/info/bandit7.password

Level 8

The password for the next level is stored in the file data.txt next to the word millionth

Use grep command to search for a string in the file.

$ grep "millionth" data.txt

Level 9

The password for the next level is stored in the file data.txt and is the only line of text that occurs only once

Use sort command to reorder the strings, pipe the output to uniq command to count the repetitions and use grep command to filter out all strings that occurred in the file more than once.

$ sort data.txt | uniq -c | grep "\ 1\ "

Level 10

The password for the next level is stored in the file data.txt in one of the few human-readable strings, preceded by several ‘=’ characters.

Use strings command to print all human-readable strings from the file and pipe it to grep command to select only lines that contain more than one occurrence of the ‘=’ character.

$ strings data.txt | grep -E '={2,}'

Level 11

The password for the next level is stored in the file data.txt, which contains base64 encoded data

Use base64 command to decode the file.

$ base64 -d data.txt

Level 12

The password for the next level is stored in the file data.txt, where all lowercase (a-z) and uppercase (A-Z) letters have been rotated by 13 positions

Use tr command to shift the letters in the file by 13 positions.

$ cat data.txt | tr 'a-zA-Z' 'n-za-mN-ZA-M' 

Level 13

The password for the next level is stored in the file data.txt, which is a hexdump of a file that has been repeatedly compressed. For this level it may be useful to create a directory under /tmp in which you can work using mkdir. For example: mkdir /tmp/myname123. Then copy the datafile using cp, and rename it using mv (read the manpages!)

Use xxd command to recreate source file from the hexdump.

$ xxd -r data.txt data

Then use file command to determine the file type of the source.

$ file data
data: gzip compressed data, was "data2.bin", last modified: Thu May 7 18:14:30 2020

Extract contents of the gzip compressed archive using gunzip.

$ gunzip -c data > data2

Repeat the process of detecting archive types and extracting data until the flag shows up. Use below commands for extracting bzip and tar archives.

$ tar -xvf data
$ bunzip2 -c data

Level 14

The password for the next level is stored in /etc/bandit_pass/bandit14 and can only be read by user bandit14. For this level, you don’t get the next password, but you get a private SSH key that can be used to log into the next level. Note: localhost is a hostname that refers to the machine you are working on

Use ssh to connect to the machine using the private key.

$ ssh bandit14@localhost -i sshkey.private

Level 15

The password for the next level can be retrieved by submitting the password of the current level to port 30000 on localhost.

Print the password to the stdout and pipe it to netcat command to send it to the specified port.

$ cat /etc/bandit_pass/bandit14 | nc localhost 30000

Level 16

The password for the next level can be retrieved by submitting the password of the current level to port 30001 on localhost using SSL encryption.

Print the flag to the stdout and pipe it to openssl s_client command to send it over the encrypted channel.

$ cat /etc/bandit_pass/bandit15 | openssl s_client -connect localhost:30001 -ign_eof

Level 17

The credentials for the next level can be retrieved by submitting the password of the current level to a port on localhost in the range 31000 to 32000. First find out which of these ports have a server listening on them. Then find out which of those speak SSL and which don’t. There is only 1 server that will give the next credentials, the others will simply send back to you whatever you send to it.

Use nmap to enumerate ports that are listening for incoming connections.

$ nmap -sT localhost -p 31000-32000
Starting Nmap 7.40 ( https://nmap.org ) at 2021-08-23 19:52 CEST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00027s latency).
Not shown: 996 closed ports
PORT      STATE SERVICE
31046/tcp open  unknown
31518/tcp open  unknown
31691/tcp open  unknown
31790/tcp open  unknown
31960/tcp open  unknown

Nmap done: 1 IP address (1 host up) scanned in 0.10 seconds

To automate the task, parse the previous command so that only port numbers are returned and save the output to the variable.

$ ports=$(nmap localhost -p 31000-32000 | grep -E "^[0-9]" | cut -d/ -f 1)

Use the xargs command to run openssl s_client command on each port. The timeout command is used to terminate connections since this does not happen automatically.

$ echo "$ports" | xargs -I{} sh -c "cat /etc/bandit_pass/bandit15' | \
    timeout 0.1 openssl s_client -connect localhost:{} -ign_eof"

Level 18

There are 2 files in the homedirectory: passwords.old and passwords.new. The password for the next level is in passwords.new and is the only line that has been changed between passwords.old and passwords.new

Use diff command to compare the files.

$ diff passwords.old passwords.new

Level 19

The password for the next level is stored in a file readme in the homedirectory. Unfortunately, someone has modified .bashrc to log you out when you log in with SSH.

Use ssh to execute cat command on the remote host.

$ ssh bandit18@bandit.labs.overthewire.org -p 2220 cat readme

Level 20

To gain access to the next level, you should use the setuid binary in the homedirectory. Execute it without arguments to find out how to use it. The password for this level can be found in the usual place (/etc/bandit_pass), after you have used the setuid binary.

Execute the binary to find out how to use it.

$ ./bandit20-do
Run a command as another user.
  Example: ./bandit20-do id

Run the id command to see which user the binary runs as.

$ ./bandit20-do id
uid=11019(bandit19) gid=11019(bandit19) euid=11020(bandit20) groups=11019(bandit19)

Use the binary to display the password for the next user.

$ ./bandit20-do cat /etc/bandit_pass/bandit20

Level 21

There is a setuid binary in the homedirectory that does the following: it makes a connection to localhost on the port you specify as a commandline argument. It then reads a line of text from the connection and compares it to the password in the previous level (bandit20). If the password is correct, it will transmit the password for the next level (bandit21).

Display bandit20’s password and pipe it to the netcat listener started on a high port with netcat and move it to background.

$ cat /etc/bandit_pass/bandit20 | nc -l -p 45454 &

Execute the binary to connect to the listener.

$ ./suconnect 45454

Level 22

A program is running automatically at regular intervals from cron, the time-based job scheduler. Look in /etc/cron.d/ for the configuration and see what command is being executed.

Use cat command to view the user’s crontab.

$ cat /etc/cron.d/cronjob_bandit22
@reboot bandit22 /usr/bin/cronjob_bandit22.sh &> /dev/null
* * * * * bandit22 /usr/bin/cronjob_bandit22.sh &> /dev/null 

The script /usr/bin/cronjob_bandit22.sh is run every minute with privileges of user bandit22. Read the script using cat command.

$ cat /usr/bin/cronjob_bandit22.sh

#!/bin/bash
chmod 644 /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv
cat /etc/bandit_pass/bandit22 > /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv

The script sets permissions of the file /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv, so anyone can read it and stores in it the password for the next user.


Level 23

A program is running automatically at regular intervals from cron, the time-based job scheduler. Look in /etc/cron.d/ for the configuration and see what command is being executed.

Use cat command to view the user’s crontab.

$ cat /etc/cron.d/cronjob_bandit23
@reboot bandit23 /usr/bin/cronjob_bandit23.sh &> /dev/null
* * * * * bandit23 /usr/bin/cronjob_bandit23.sh &> /dev/null 

The script /usr/bin/cronjob_bandit23.sh is run every minute with privileges of user bandit23. Read the script using cat command.

$ cat /usr/bin/cronjob_bandit23.sh

#!/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

The script writes the password for the next user to the file /tmp/$mytarget where $mytarget is equal to the md5 hash of the string “I am user bandit23”. Use md5sum command to get the absolute path to the file.

$ echo "/tmp/$(echo I am user bandit23 | md5sum | cut -d' ' -f 1)"
/tmp/8ca319486bfbbc3663ea0fbe81326349

Level 24

A program is running automatically at regular intervals from cron, the time-based job scheduler. Look in /etc/cron.d/ for the configuration and see what command is being executed.

Use cat command to view the user’s crontab.

$ cat /etc/cron.d/cronjob_bandit24
@reboot bandit24 /usr/bin/cronjob_bandit24.sh &> /dev/null
* * * * * bandit24 /usr/bin/cronjob_bandit24.sh &> /dev/null

The script /usr/bin/cronjob_bandit24.sh is run every minute with privileges of user bandit24. Read the script using cat command.

$ cat /usr/bin/cronjob_bandit24.sh

#!/bin/bash
myname=$(whoami)

cd /var/spool/$myname
echo "Executing and deleting all scripts in /var/spool/$myname:"
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

The script executes all files in the /var/spool/bandit24 directory that are owned by the user bandit23. Create a script which will read the password for the next user and write it to the accessible location. Then make the file executable and copy it to the /var/spool/bandit24 directory. In addition, add write permissions for everyone to the accessible location because the script will run as the bandit24.

$ mkdir /tmp/knownlocation
$ echo "cat /etc/bandit_pass/bandit24 > /tmp/knownlocation/password" > /tmp/knownlocation/script
$ chmod +x /tmp/knownlocation/script
$ chmod o+w /tmp/knownlocation
$ cp /tmp/knownlocation/script /var/spool/bandit24/script

After a minute the password file should appear in the /tmp/knownlocation directory.


Level 25

A daemon is listening on port 30002 and will give you the password for bandit25 if given the password for bandit24 and a secret numeric 4-digit pincode. There is no way to retrieve the pincode except by going through all of the 10000 combinations, called brute-forcing.

Use for loop to iterate over all possible 4-digit pincodes and send the combinations to the specified port with netcat. Use grep command to return only the lines containing “Correct” string and one below it.

for i in {0000..9999}; do echo "$(cat /etc/bandit_pass/bandit24) $i"; done | \
    nc localhost 30002 | grep -A 1 "Correct"

Level 26

Logging in to bandit26 from bandit25 should be fairly easy… The shell for user bandit26 is not /bin/bash, but something else. Find out what it is, how it works and how to break out of it.

Use ssh to connect to the machine using private key of a user bandit26.

$ ssh bandit26@localhost -i bandit26.sshkey

The connection was closed after the successful login. Read the /etc/passwd file to find out what login shell is bandit26 using.

$ cat /etc/passwd | grep bandit26
bandit26:x:11026:11026:bandit level 26:/home/bandit26:/usr/bin/showtext

Bandit26 is using /usr/bin/showtext as the login shell. Check its file type with file command.

$ file /usr/bin/showtext
/usr/bin/showtext: POSIX shell script, ASCII text executable

Since it’s a shell script and not a binary use cat command to display its contents.

$ cat /usr/bin/showtext

#!/bin/sh
export TERM=linux

more ~/text.txt
exit 0

The login shell is a script which sets the TERM variable to “linux” and runs the more command on a file ~/text.txt. When the program exits the login session is terminated. The more pager is closed when the last line of the file has been printed. To avoid termination of the connection the contents of the file must not fit into the terminal window. There is no option to edit the file text.txt due to the lack of permissions, but it is possible to change the size of the terminal window. Resize the terminal window so that it fits only one line of text at once and use ssh to connect to the machine.

$ ssh bandit26@localhost -i bandit26.sshkey

The more pager can execute system commands, but for some reason this functionality doesn’t work as intended in this environment. Another thing that can be done from the more page is to open the currently viewed file in vi editor by pressing character ‘v’. Vi commands can be used to set the shell variable to /bin/bash and spawn a shell.

$ :set shell=/bin/bash
$ :shell

Level 27

Good job getting a shell! Now hurry and grab the password for bandit27!

Execute the binary from the bandit26’s home directory to run the cat command as user bandit27 and read the bandit27’s password file.

$ ./bandit27-do cat /etc/bandit_pass/bandit27 

Level 28

There is a git repository at ssh://bandit27-git@localhost/home/bandit27-git/repo. The password for the user bandit27-git is the same as for the user bandit27.

Use git to clone the repository to the accessible location.

$ git clone ssh://bandit27-git@localhost/home/bandit27-git/repo /tmp/accessible

List the contents of the repository.

$ ls /tmp/accessible
README

Cat the README file.

$ cat /tmp/accessible/README

Level 29

There is a git repository at ssh://bandit28-git@localhost/home/bandit28-git/repo. The password for the user bandit28-git is the same as for the user bandit28.

Clone the repository the same way as in the previous task and read the README.md file.

$ cat README.md

$ Bandit Notes
Some notes for level29 of bandit.

### credentials

- username: bandit29
- password: xxxxxxxxxx

Check the git log for any significant changes.

$ git log
commit edd935d60906b33f0619605abd1689808ccdd5ee
Author: Morla Porla <morla@overthewire.org>
Date:   Thu May 7 20:14:49 2020 +0200

    fix info leak

commit c086d11a00c0648d095d04c089786efef5e01264
Author: Morla Porla <morla@overthewire.org>
Date:   Thu May 7 20:14:49 2020 +0200

    add missing data

Use git checkout command to bring back the previous version of the file from before the “fix info leak” commit.

$ git checkout c086d11a00c0648d095d04c089786efef5e01264 README.md

Level 30

There is a git repository at ssh://bandit29-git@localhost/home/bandit29-git/repo. The password for the user bandit29-git is the same as for the user bandit29.

Clone the repository and read the README.md file.

$ cat README.md

$ Bandit Notes
Some notes for bandit30 of bandit.

### credentials

- username: bandit30
- password: <no passwords in production!>

“No passwords in production” indicates, that the repository may contain more branches. Use git branch command to list all branches.

$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/dev
  remotes/origin/master
  remotes/origin/sploits-dev

Use git checkout command to switch to the development branch.

$ git checkout dev

Level 31

There is a git repository at ssh://bandit30-git@localhost/home/bandit30-git/repo. The password for the user bandit30-git is the same as for the user bandit30.

Clone the repository and read the README.md file.

$ cat README.md
just an epmty file... muahaha

The git log shows only one commit and there are no other branches. Use git tag command to check if the repository was tagged at some point.

$ git tag
secret

Use git show command to read the tag message.

$ git show secret

Level 32

There is a git repository at ssh://bandit31-git@localhost/home/bandit31-git/repo. The password for the user bandit31-git is the same as for the user bandit31.

Clone the repository and read the README.md file.

$ cat README.md
This time your task is to push a file to the remote repository.

Details:
    File name: key.txt
    Content: 'May I come in?'
    Branch: master

Check which branch is active.

$ git branch
* master

Create the requested file.

$ echo "May I come in?" > key.txt

Add it to the index. Use the -f flag to omit the .gitignore exclusion rules.

$ git add key.txt -f

Commit the changes.

$ git commit -m 'useful commit message'

Push changes to the remote repository.

$ git push

Level 33

After all this git stuff its time for another escape. Good luck!

Connecting to the machine results in obtaining a specific shell which converts all alphabetical characters to uppercase. Output of a few example commands is shown below.

>> whoami
sh: 1: WHOAMI: not found
>> bunzip2
sh: 1: BUNZIP2: not found
>> 123:"
sh: 2: Syntax error: Unterminated quoted string
>> "123"
sh: 1: 123: not found

This output shows that the program executed as the login shell takes the user’s input, converts all letters to uppercase and then does something like sh -c ‘INPUT’.

Since digits and special characters are interpreted as usual they can be used to escape the shell. Assuming that the program works the way it was described above, the “sh” may be referenced in the stdin by using a special shell parameter $0. In sh, the $0 refers to the executed program’s name, so the sh -c ‘$0’ will result in the program executing sh -c ‘sh’.
Use the $0 special parameter as a payload.

>> $0

Level 34

At this moment, level 34 does not exist yet.