OverTheWire Bandit Levels 19-34 Hints and Notes
Tags: ctf, overthewire, hacking, security
Published: 2022-03-24 16:39:12

# Table of Contents
[Level 19 - setuid](#level-19)
[Level 20 - nc](#level-20)
[Level 21 - cron](#level-21)
[Level 22 - Script](#level-22)
[Level 23 - Script](#level-23)
[Level 24 - for loop](#level-24)
[Level 25 - more](#level-25)
[Level 26 - shell](#level-26)
[Level 27 - git clone](#level-27)
[Level 28 - git log](#level-28)
[Level 29 - git branch](#level-29)
[Level 30 - git tag](#level-30)
[Level 31 - gitignore](#level-31)
[Level 32 - bash](#level-32)
[Level 33](#level-33)
___

## Level 19

_Use the setuid binary in the homedirectory to access /etc/bandit_pass/bandit20_

`ls -l` on the homedirectory file you will see letter `s` in the permissions in place of the user execution.

> Setuid, which stands for set user ID on execution, is a special type of file permission in Unix and Unix-like operating systems such as Linux and BSD. It is a security tool that permits users to run certain programs with escalated privileges.

> When an executable file's setuid permission is set, users may execute that program with a level of access that matches the user who owns the file. For instance, when a user wants to change their password, they run the passwd command. The passwd program is owned by the root account and marked as setuid, so the user is temporarily granted root access for that limited purpose.

Here, the homedirectory bandit20-do has the setuid permission set, and /etc/bandit_pass/bandit20 can only be read by the owner bandit20. We can open /etc/bandit_pass/bandit20 at the runtime of bandit20-do binary:
```
./bandit20-do cat /etc/bandit_pass/bandit20
```

___
## Level 20
_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)_

1.Check which ports are in use
```
nmap localhost
```
2.Open a connection on an unused port and send current password
```
echo password | nc -l -p 60000 &
```
The `&` at the end allows you to listen to port in the background, so you can run the next command in the same terminal.
3.Run the setuid binary on the port
```
./suconnect 600000
```

___
## Level 21
_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_

Let's look at what is inside the crontab file for bandit22. A crontab file is a simple text file containing a list of commands meant to be run at specified times.
```
cat cronjob_bandit22
```

> Typical format for a cron job is:
> Minute(0-59) Hour(0-24) Day_of_month(1-31) Month(1-12) Day_of_week(0-6) Command_to_execute

Cron offers some special strings, which can be used in place of the five time-and-date fields:

- `@reboot`, run once at startup
- `@yearly`, run once a year, "0 0 1 1 *"
- `@annually`, same as `@yearly`
- `@monthly`, run once a month, "0 0 1 * *"
- `@weekly`, run once a week, "0 0 * * 0"
- `@daily`, run once a day, "0 0 * * *"
- `@midnight`, same as `@daily`
- `@hourly`, run once an hour, "0 * * * *"

`program &> /dev/null`, which will redirect both stderr and stdout to /dev/null, so nothing will be printed on screen. `/dev/null` is a special file (i.e. a virtual device, known as the null device) that’s present in every single Linux system and purely used to write.  Everything you write to `/dev/null` will be discarded.

Now let's see the bash script that is been executed
```
cat /usr/bin/cronjob_bandit22.sh
```
- `#!/bin/bash` is called a shebang line, this script runs in the bash environment
- `chmod 644 /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv` chmod 644 means only the owner are allowed to write/modify, read-only for others (group) included
- `cat /etc/bandit_pass/bandit22 > /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv` gets password from `bandit22` and redirects stdout to `/tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv`

To view the password for next level:
```
cat /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv
```

___
## 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_

Output from `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 first line is shebang as usual, defining the bash environment in which the script is run. 

The second line assigns output from command `whoami` to variable myname.

The next line uses a new command `md5sum`.

> When downloading files, particularly installing files from websites, it is good to verify that the download is valid. A website will often display a hash value for each file to make sure the download is completed correctly. `md5sum` is one of the tools you can use to validate file transfer.

If a file has changed, the checksum will throw a warning. Here we're simply displaying the hash for text `I am user $(whoami)`, clean the output with `cut` and assign the hash to variable mytarget.

Output from `echo I am user $myname | md5sum `:
```
8169b67bd894ddbb4412f91573b38db3  -
```
There's an extra dash after the hash. `cut -d cut -d ' ' -f 1` specifies the delimiter (`-d`) as space (`' '`), and select the first field with `-f`. `-d ' '` separates the hash and dash since there's a space between them, returns the hash only.

When this script is being run, it will write the currently logged-on user’s password into a file.

We can see the password is redirected to /tmp/hash. There is a caveat here, the currently logged-on user is bandit22, but we want the password for bandit23:
``` 
echo I am user bandit23 | md5sum | cut -d ' ' -f 1
```
This gives us the file name in tmp directory that stores bandit23 password. Now we just need to view it using `cat /tmp/hash`.

___
## Level 23
Follow the same procedure as the previous level, the shell script running in /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
```

First the shebang is declared, then myname saves user who is currently logged on the system. Goes inside the directory /var/spool/$myname, prints the task it is about to carry out on screen with echo. 

The for loop `for i in * .*` matches all files in the currently directory, including hidden files starting with a dot. `for i in *` returns all regular files in the working directory, `for i in .*` returns all hidden files (starting with a dot).

`if [ "$i" != "." -a "$i" != ".." ]` skips the special files `.` and `..` in the for loop.

The `stat` command displays file status. Try `stat -x file` to see the output from stat. `--format` option allows you to design the desired output from stat. `%U` format specifier returns the owner of the file/file system. There are many versions of stat, on Mac, the equivalent command is `stat -f %Su file`.

The `timeout` allows the user to execute a command and then terminate it after a set time has passed. The `timeout` command uses the “SIGTERM” to stop a process, but many processes ignore the “SIGTERM” signal. To forcefully terminate a process using the “SIGKILL” signal `-s 9`, cannot be ignored by any process.

Here, it checks if the owner of file is bandit23. If so, execute the file, and terminate after 60 seconds.

At the end of the for loop, it removes each file/folder.

1. Find where the password is stored
From previous levels, we know that all passwords are in /etc/bandit_pass. Password for bandit24 will be in /etc/bandit_pass/bandit24. However, we get a permission denied when we directly `cat /etc/bandit_pass/bandit24`.

2. Make the bash script
We do have permissions to create, read and write files in /tmp, make a new folder in tmp with mybandit23.sh that contains the following bash script (/tmp/dir23/mybandit23.sh):
    ```
    #!/bin/bash                                             
    cat /etc/bandit_pass/bandit24 > /tmp/dir23/bandit24pass       
    ```
    Make the file executable by changing the mode to have all permissions:
    ```
    chmod 777 mybandit23.sh
    ```
    You might want to change the permissions of the entire `dir23` folder to make it writable by others.

3. Copy the bash script to be run by bandit24

    We know that if we make an executable script in /var/spool/bandit24, it will be run with a timeout of 60 seconds.

    ```
    cp mybandit23.sh /var/spool/bandit24/mybandit23.sh
    ```

    Check our bash script is there:
    ```
    cat /var/spool/bandit24/mybandit23.sh
    ```

Wait until the shell script file in the folder is deleted, and check the /tmp/dir23 directory, a bandit24pass file should appear. `cat bandit24pass` to get the password.

___
## Level 24
_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._

`nc localhost 30002` asks for the password and a 4 digit pin code on a single line. The steps we need to take are get all combinations of the password and pins, pass each one to port 30002.

Navigate to /tmp where we are granted write permissions, and make a new folder called mydir24. Inside /tmp/mydir24, create a shell script bruteforce.sh that would loop through 4 digit numbers and append each one to pins.txt
```
#!/bin/bash
for i in {0000..9999}
do 
    echo "password $i" >> pins.txt
done
```
Make the bash script executable by user:
```
chmod 700 bruteforce.sh
```

Now run the script to create pins.txt, and give the output to port 30002:
```
nc localhost 30002 < pins.txt
```
or
```
cat pins.txt | nc localhost 30002
```

___
## Level 25
_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._

In the home directory of bandit25, there is a bandit26.sshkey private key file, 
```
ssh -i bandit26.sshkey bandit26@localhost
```
the connection closes immediately. Let's take the hint from the task and checkout what shell bandit26 is using.

> The /etc/passwd file is a text file with one record per line, each describing a user account. It consists of 7 fields, the last field is the program that is started every time the user logs into the system, i.e. the shell for an interactive user.
 

```
cat /pwd/passwd | grep bandit26
```
Instead of /bin/bash, bandit26 uses /usr/bin/showtext. A quick `cat /usr/bin.showtext` gives

```
#!/bin/sh

export TERM=linux

more ß/text.txt
exit 0
```
The code that terminates the shell is `exit 0`, and the only command that runs before is `more ~/text.txt`.

`more` command is used to view the text files in the command prompt, displaying one screen at a time in case the file is large. 

**Minimise your terminal before ssh into bandit26 to trigger `more`**. The large “bandit26” ASCII art banner will force a “more” message to prompt you to continue. **Press `v` to enter the default vim text editor, and type ":e /etc/bandit_pass/bandit26"** to open bandit26 password file within vim.

___
## Level 26
The shell still immediately terminates after ssh login. Do the same trick again, minimise the terminal window and then ssh login. Press "**v**" to enter vim and change shell type "**:set shell=/bin/bash**". Now type "**:shell**" should take you back to the bash shell. Do "ls -l" to see all files in the home directory. 

The file "bandit27-do" has the special permission for the user access level, which means we can directly "cat" the password in /etc/bandit_pass/bandit27 (only bandit27 has the read permission) while we execute bandit27-do. A file with SUID always executes as the user who owns the file, regardless of the user passing the command.

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

___
## Level 27
_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. Clone the repository and find the password for the next level._

ssh login to bandit27 as usual, make a new directory within /tmp/ where we have the write permission. 
```
mkdir -p /tmp/dir27
```
cd into the directory, then
```
git clone ssh://bandit27-git@localhost/home/bandit27-git/repo
```
Enter the password when you're prompted on the command line. There is only one file contained in the repository, `cat` the file to see bandit28 password.

___
## Level 28
_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 and find the password for the next level._

Same procedure as the previous level, `mkdir -p /tmp/dir28`, then `git clone ssh://bandit28-git@localhost/home/bandit28-git/repo`. This time when you cat the README.md, it doesn't show the password. Let's have look at the commit history to see if there's any clue. Type following command within the repository:
```
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
> commit de2ebe2d5fd1598cd547f4d56247e053be3fdc38
> Author: Ben Dover <noone@overthewire.org>
> Date:   Thu May 7 20:14:49 2020 +0200
>     initial commit of README.md

There are actually 3 commit pushes for the repository. From the commit messages, it looks like the second commit probably contains the password. To see the actual changes made in each commit, do `git log -p`; Alternatively, to display changes in the second commit only, do `git show` followed by the commit hash:
```
git show c086d11a00c0648d095d04c089786efef5e01264
```

___
## Level 29
_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 find the password for the next level._

Same procedure as the previous level, `mkdir -p /tmp/dir28`, then `git clone ssh://bandit28-git@localhost/home/bandit28-git/repo`. This time when you cat the README.md, in place of password it shows _no passwords in production!_. It implies this is the production branch, there is probably a development branch. To see all existing branches:
```
git branch -a
```
switch to the dev branch:
```
git checkout dev
```
see the README.md file on this branch:
```
cat README.md
```

___
## Level 30
_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 find the password for the next level._

Same procedure as previous levels, but this time there is nothing useful contained in README.md...neither `git branch` or `git log` has anything interesting. Do `ls -al` to see the hidden files, `cd .git` and search for anything that looks like a clue. The _packed-refs_ file contains reference to the master branch, as well as a tag called _secret_. Let's check existing tags:
```
git tag
```
Double check the tag reference:
```
git show-ref --tags
```
 
> Tags are ref's that point to specific points in Git history. Tagging is generally used to capture a point in history that is used for a marked version release (i.e. v1. 0.1). A tag is like a branch that doesn't change. Unlike branches, tags, after being created, have no further history of commits.

Reveal the content of the tag using `git show`:
```
git show secret
```

___
## Level 31
_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 find the password for the next level._

Same procedure as previous levels, the actual instructions are in README.md of the repository. The task for this level is to push a text file to the remote repository. Inside of the repository, make the key.txt file with the required text. 

Now the file exists locally, to push to remote, first step is to add the file to stage:
```
git add .
```

Double check the file has been added:
```
git status
```
and it hasn't! Let's see everything inside the repository:
```
ls -al
```
There is a .gitignore file which tells git not to track the changes in certain types of files. Remove the line from .gitignore, now try add to stage again, then git commit:
```
git commit -m "adding my key file"
```
and push the changes:
```
git push
```

___
## Level 32
After you ssh login, you will enter UPPERCASE SHELL where non of the terminal commands work anymore. To escape out of the shell and spawn a new shell, use the special parameter:
```
$0
```
display password as usual:
```
cat /etc/bandit_pass/bandit33
```

> $0 Expands to the name of the shell or shell script. This is set at shell initialization.

> If Bash is invoked with a file of commands, $0 is set to the name of that file.

> If Bash is started with the -c option, then $0 is set to the first argument after the string to be executed, if one is present. Otherwise, it is set to the filename used to invoke Bash, as given by argument zero.

[What is the meaning of $0 in the Bash shell](https://unix.stackexchange.com/questions/280454/what-is-the-meaning-of-0-in-the-bash-shell)

___
## Level 33
```
ssh bandit33@bandit.labs.overthewire.org -p 2220
```
password: c9c3199ddf4121b10cf581a98d51caee

bandit33@bandit:~$ cat README.txt
Congratulations on solving the last level of this game!

At this moment, there are no more levels to play in this game. However, we are constantly working on new levels and will most likely expand this game with more levels soon.

Keep an eye out for an announcement on our usual communication channels!

In the meantime, you could play some of our other wargames.

If you have an idea for an awesome new level, please let us know!