Welcome to another TryHackMe write-up. Today we will be going through a medium-difficulty room called “Wonderland” that is based around Linux privilege escalation techniques.
Let’s get into it!
Link to the Wonderland room: https://tryhackme.com/room/wonderland
Let’s begin by scanning the machine with nmap and see what we can find.
22/SSH - OpenSSH 7.6p1 80/HTTP - Golang net
Excellent! Let’s check out the website!
We are greeted with a very simple home page which follows the “Alice in Wonderland” theme of the box.
There’s nothing interesting in the source code either so let’s use
gobuster to do some directory brute-forcing.
gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u http://TARGET_IP/
gobuster shows us some interesting directories. The
/img directory is standard for websites. It’s where a website’s images are typically stored. The
/r directories certainly pique my interest. The
poem directory just contains a very long poem (who would’ve guessed!) called “Jabberwocky” which is basically nonesense. Let’s take a look at what’s in the
gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u http://TARGET_IP/r/
Oh… Let’s keep going…
gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u http://TARGET_IP/r/a/
Down the rabbit hole we go…
gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u http://TARGET_IP/r/a/b/
If we carry on, eventually we’ll find that the word it spells out is
Let’s head over to the
And we have a page with nothing all that interesting. If we take a look at the source code of the page, we’ll find some credentials.
Another way of getting these credentials is by using the
curl command like so:
curl -v http://TARGET_IP/r/a/b/b/i/t/
This may be easier to read.
Excellent! Now that we have what seems to be
Alice‘s password, let’s see if we can SSH into the machine as the
And we’re in! Here comes the fun part!
Let’s begin by taking a look at what’s in
Alice‘s home directory.
So we have
root.txt here and a python script… If
root.txt is here, what’s in the
/root folder? That may be a clue regarding the location of the
user.txt flag 😉
Ok, let’s now take a look at the python script.
It imports the
random module, and uses it to select ten random lines from a poem.
Checking what the
Alice user can run as sudo may clue us as to who we’re going to be escalating our privileges to first.
That’s interesting! We can run that python script in our home directory as the
rabbit user. But all the script does is select ten random lines from a poem. There’s no way for us to execute any code as the rabbit user… Or is there??
So it uses the
random module to select random lines in the poem string.
A module is just a python file with functions that can be referenced. So when the
import random line is executed, the script goes and looks for that
random.py file. We can find out where it’s looking for this
python3.6 -c 'import sys; print(sys.path)'
Oh dear… It’s looking in our current directory first ([”])
So if we were to make a
random.py file in this directory, the python script would reference that file since it’s the first place it checks…
Let’s make a
random.py file in this directory with the following code to spawn a shell:
import pty pty.spawn("/bin/bash")
And now we run the python script as
sudo -u rabbit python3.6 /home/alice/walrus_and_the_carpenter.py
And we get a shell as the
Let’s start off by taking a look at what’s in the
rabbit user’s home directory.
We have a binary in here called
teaParty. If we want to take a look at it in depth, we’ll have to use a debugging tool (in this case, I’ll be using
radare2). Let’s move this binary to our local host.
First, let’s set up a temporary http server on this machine.
python3.6 -m http.server
This will serve the current directory on the default port of 8000.
And we can use
wget to retrieve the binary.
We can double-check that it’s on our local host.
But it’s not an executable now so let’s change that.
chmod +x teaParty
There we go! Now we’re ready to look under the hood of this binary!
Rabbit: Reverse Engineering
Let’s open up this binary in
radare2 in debugger mode.
r2 -d ./teaParty
radare2 to analyse it.
Now let’s print out the list of the binary’s functions.
Let’s take a look at the
And we get this monstrosity… It’s called assembly code :’)
As we look through the assembly code, we can see that
setgid are set to 1003. This could be an indication as to who we are going to escalate our privileges to next.
Let’s take a look at
/etc/passwd and see who has an id of 1003.
cat /etc/passwd | grep 1003
It’s the Mad Hatter!
Going back to the assembly code, we see some comments which show the code being executed.
Note how the
echo command has an absolute path whereas the
date command does not. This is an insecure reference to a file and can be exploited.
If a program is being referenced without an absolute path, it has to check the
PATH environment variable in order to find the location of the binary. However, we can change that variable.
Let’s prepend the current directory to the
PATH environment variable.
And now we’ll create a file called
date in our current directory. This will be the file that is referenced when the
date command is executed.
date is executed, it will spawn a shell. Since the uid and gid are set to that of the
hatter user, when the
date program is executed in the
teaParty binary, it will spawn a shell as the
Let’s make our newly-created file executable.
chmod +x date
And now let’s execute the
And where the
date program should have been executed, we get a command prompt for the
hatter user. Awesome!!
hatter user’s directory, we see a text file containing a password.
Using that password to view
sudo -l doesn’t work.
Let’s see what files belong to the
find / -xdev -user hatter 2>/dev/null
-xdev flag shows mounted directories but doesn’t list what’s in them.
Nothing that we haven’t seen in their home directory.
Let’s see what the
hatter‘s group owns.
Hold up! Why on earth do they own
It doesn’t have an SUID bit or anything obvious…
But we can check its capabilities with the
File capabilities aim to provide more control over root permissions. It’s sort of an improvement on SUID binaries since they can usually be exploited (of course that depends on the program with the SUID bit).
The main idea is that file capabilities are just individual fragments of root privileges (I believe there are about 40 file capabilities). They prevent or at least reduce the need to switch to the root user when executing a program.
Going back to our example, we see that we can run
perl with the
cap_setuid+ep capability. This means we can run it with a uid of 0 (which is root). This is essentially the same thing as running the program as root…
Let’s check GTFO bins for a payload.
This is exactly what we’re looking for!
Let’s copy and paste it in.
perl -e 'use POSIX qw(setuid); POSIX::setuid(0); exec "/bin/sh";'
Permission denied… Let’s check our id and verify we are who we think we are.
We have the uid of the
hatter user which is correct but our gid is still that of the
OH! That reminds me of the credentials from earlier (
password.txt in the
hatter user’s home directory)! Maybe we can use them to SSH in as the
And it works!!
Let’s just double-check our id again.
And now we paste in that payload from GTFO bins… And get a root shell!
And just a gentle reminder that now you can grab the
root.txt file from the very start in Alice’s home directory. 🙂
I had so much fun doing this room! I learnt so much and got some hands-on practice too which was awesome. I need to do CTFs more regularly. I learn so much from them, especially when they are just above my skill level as it will expand my comfort zone.
Anyways, I hope this was of some help and an enjoyable read. Until next time! 🙂