Welcome back to my OverTheWire Bandit wargame walkthrough series - the last post in the series! We only have three more levels: 30, 31 and 32. You’ll remember that in the previous post, we began understanding the basics of git
, namely the commands “clone”, “log”, “switch” and “checkout”. Now, we’ll continue where we left off by using git
to find our password for level 31, and again for level 32, before hitting the finale - level 33. Level 33 will be a fun break-out challenge, so it’s definitely worth persevering through to the end. We’re nearly there now - let’s get to the finish line!
Level 30 - Level 31
In this level, we have another git
repository at ssh://bandit30-git@localhost/home/bandit30-git/repo via port 2220. Our task is to, again, clone the repository and find the password for the next level.
First, let’s create a temporary directory like last time.
$ cd $(mktemp -d)
Now, let’s clone the repository:
$ git clone ssh://bandit30-git@localhost:2220/home/bandit30-git/repo
Cloning into 'repo'...
The authenticity of host '[localhost]:2220 ([127.0.0.1]:2220)' can't be established.
ED25519 key fingerprint is SHA256:C2ihUBV7ihnV1wUXRb4RrEcLfXC5CXlhmAAM/urerLY.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Could not create directory '/home/bandit30/.ssh' (Permission denied).
Failed to add the host to the list of known hosts (/home/bandit30/.ssh/known_hosts).
_ _ _ _
| |__ __ _ _ __ __| (_) |_
| '_ \ / _` | '_ \ / _` | | __|
| |_) | (_| | | | | (_| | | |_
|_.__/ \__,_|_| |_|\__,_|_|\__|
This is an OverTheWire game server.
More information on http://www.overthewire.org/wargames
bandit30-git@localhost's password:
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (4/4), done.
Now that we’ve cloned the repo, let’s navigate to it and see what’s inside:
$ cd repo
$ ls -l
total 4
-rw-rw-r-- 1 bandit30 bandit30 30 Jul 1 17:22 README.md
Let’s see what README.md contains this time:
$ cat README.md
just an epmty file... muahaha
Okay, let’s see if there are any hints in the commit history:
$ git log
commit 49ebc0513539a56d3626f3121ff4e72585064047 (HEAD -> master, origin/master, origin/HEAD)
Author: Ben Dover [email protected]>
Date: Thu Jun 20 04:07:17 2024 +0000
initial commit of README.md
There is only one commit here. Since we’re already on the only commit, there are no answers here. Running git branch -a
also tells us that there are no other branches for us to investigate.
Let’s have a look to see if there are any tags. Tags in git
are used to mark specific points in history as being important. Typically, they are used to mark release points (for example, v1.0, v2.0). Tags are very similar to branches, but unlike branches, they are designed to be immutable. To operate on tags, we use the git tag
command:
$ git tag -l
secret
Here, we’ve found a tag named “secret”. Let’s try switching to it:
$ git switch secret
fatal: reference is not a tree: secret
Unfortunately, we get an error when trying to switch to it. Let’s do some investigation to determine why this error could be happening. To help us, we can use git
’s “plumbing commands”. git
plumbing commands are low-level commands that provide more detailed control over git
’s internal structure. We can use these commands to investigate what the secret tag is referencing.
First, let’s find out what object hash the secret tag is pointing to:
$ git show-ref --tags secret
84368f3a7ee06ac993ed579e34b8bd144afad351 refs/tags/secret
Now that we have the object’s hash (its identifier), we can determine what type of object it is:
$ git cat-file -t 84368f3a7ee06ac993ed579e34b8bd144afad351
blob
A blob (binary large object) stores the files’ contents in git
. This explains why we couldn’t switch to it earlier; it’s not a tree (directory) or commit.
Finally, let’s print the contents of the blob. This is akin to using cat
on a normal file (hence the name of the command):
$ git cat-file -p 84368f3a7ee06ac993ed579e34b8bd144afad351
<password>
Level 31 - Level 32
In this level, we have another git
repository at ssh://bandit31-git@localhost/home/bandit31-git/repo via port 2220. Our task is to, again, clone the repository and find the password for the next level.
First, let’s create a temporary directory again.
$ cd $(mktemp -d)
Now, let’s clone the repository:
$ git clone ssh://bandit31-git@localhost:2220/home/bandit31-git/repo
Cloning into 'repo'...
The authenticity of host '[localhost]:2220 ([127.0.0.1]:2220)' can't be established.
ED25519 key fingerprint is SHA256:C2ihUBV7ihnV1wUXRb4RrEcLfXC5CXlhmAAM/urerLY.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Could not create directory '/home/bandit31/.ssh' (Permission denied).
Failed to add the host to the list of known hosts (/home/bandit31/.ssh/known_hosts).
_ _ _ _
| |__ __ _ _ __ __| (_) |_
| '_ \ / _` | '_ \ / _` | | __|
| |_) | (_| | | | | (_| | | |_
|_.__/ \__,_|_| |_|\__,_|_|\__|
This is an OverTheWire game server.
More information on http://www.overthewire.org/wargames
bandit31-git@localhost's password:
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (4/4), done.
Let’s navigate to the repo and see what’s inside:
$ cd repo
$ ls -l
total 4
-rw-rw-r-- 1 bandit31 bandit31 147 Jul 1 19:09 README.md
Let’s see what README.md contains:
$ 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
We need to create a file named “key.txt” with the content “May I come in?”. We can do that with echo
, redirecting the output to a file:
$ echo 'May I come in?' > key.txt
The next step is to add the file to the staging area. The git add
command adds changes to the staging area before committing them to the repository. It tells git
to include updates to a file in the next commit, which we’ll create shortly.
$ git add key.txt
The following paths are ignored by one of your .gitignore files:
key.txt
hint: Use -f if you really want to add them.
hint: Turn this message off by running
hint: "git config advice.addIgnoredFile false"
You’ll notice that we’ve received a warning - the file is ignored by our .gitignore file. The .gitignore file tells git
which files (or patterns) it should ignore. This is useful for excluding temporary files, build artifacts and other files you do not want to track in your repository.
As recommended by the hints from git
, we can tell git
to add the ignored file anyway using the -f (force) option:
$ git add -f key.txt
Now that the file is staged, the next step is to commit it. A commit in git
is a snapshot of your changes, which we have seen examples of in the previous levels. Each commit requires a message that describes the changes, which we must provide when we create the commit. This helps keep track of the project’s history and makes it easier to understand the reasoning behind the changes made.
To create a commit, we use the git commit
command, specifying the -m option to provide a message:
$ git commit -m "added key.txt"
[master 58256f0] adding key.txt
1 file changed, 1 insertion(+)
create mode 100644 key.txt
The final step is to push the commit to the remote repository. The git push
command uploads your local repository content to a remote repository. Pushing (and pulling) is what enables multiple developers to use a git
repository to collaborate on a project.
$ git push
The authenticity of host '[localhost]:2220 ([127.0.0.1]:2220)' can't be established.
ED25519 key fingerprint is SHA256:C2ihUBV7ihnV1wUXRb4RrEcLfXC5CXlhmAAM/urerLY.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Could not create directory '/home/bandit31/.ssh' (Permission denied).
Failed to add the host to the list of known hosts (/home/bandit31/.ssh/known_hosts).
_ _ _ _
| |__ __ _ _ __ __| (_) |_
| '_ \ / _` | '_ \ / _` | | __|
| |_) | (_| | | | | (_| | | |_
|_.__/ \__,_|_| |_|\__,_|_|\__|
This is an OverTheWire game server.
More information on http://www.overthewire.org/wargames
bandit31-git@localhost's password:
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 2 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 326 bytes | 326.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
remote: ### Attempting to validate files... ####
remote:
remote: .oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.
remote:
remote: Well done! Here is the password for the next level:
remote: 3O9RfhqyAlVBEZpVb6LYStshZoqoSx5K
remote:
remote: .oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.
remote:
To ssh://localhost:2220/home/bandit31-git/repo
! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'ssh://localhost:2220/home/bandit31-git/repo'
git
attempts to connect to the remote repository (requiring us to enter our password again) and uploads the commit. You’ll notice that the remote repository rejected our commit as this is just a wargame, but, in reality, our commit would have been added to the remote repository.
You’ll find the password in the message from the remote repository in the git push
output.
Level 32 - Level 33
Congratulations on making it to the final level of the Bandit wargame! You’ve come a long way, solving challenging problems and honing your skills. Let’s tackle this last level together.
When you log in, you will see the usual welcome message, but this time, it is followed by “WELCOME TO THE UPPERCASE SHELL”.
You’ll notice that when you run a command, it gets automatically converted to uppercase, which means our regular commands don’t work due to Linux being case-sensitive. For example, trying to list the directory contents with ls
:
>> ls -l
sh: 1: LS: Permission denied
We need to find something useful to us that is already in uppercase or has no concept of case (such as symbols and numbers). Let’s confirm this by checking if the $PATH variable is expanded correctly:
>> $PATH
sh: 1: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin: not found
The output shows that $PATH
was expanded, so variables could be helpful to us. Let’s consider what other variables might be beneficial. Argument variables like $1
, $2
, and so on refer to positional parameters passed to a script. The special variable $0
represents the name of the program (or script) being executed. Given the error messages we’ve seen, our commands are clearly being executed in the sh
shell. Thus, $0
should refer to sh
.
Using this, we can simply enter $0
, which cannot be converted to uppercase and will be expanded to sh
. sh
is then executed, giving us a shell:
>> $0
$
Now we have a shell, we can execute commands without them being converted to uppercase. Now, let’s read the password for the final level:
$ cat /etc/bandit_pass/bandit33
<password>
Congratulations! You have successfully completed the Bandit wargame. You have demonstrated perseverance and problem-solving skills by tackling a variety of challenges, from basic Linux commands to more advanced topics like git
and scripting. This journey has equipped you with valuable skills that will be beneficial in many areas of cybersecurity and system administration.
Feel proud of what you have accomplished. Some of these levels have been challenging, but your hard work has paid off. Well done!