Under Nextruction - Web (24 solves)
I started learning Next.js recently, and I’ve begun developing a small website. It’s still under development, so I’m not exposing sensitive features using key Next.js APIs. I should be safe, right?
- Attachment:
under-nextruction.tar.xz
- URL:
https://under-nextruction.fcsc.fr:2213/
TODO
Happy Face - Speedrun/Web (4 solves)
Let’s put a smile on your face.
- Attachment:
happy-face.tar.xz
- URL:
https://happy-face.fcsc.fr/
During the FCSC, there was a category called Speedrun
where participants had to solve various challenges (reverse, pwn, crypto, web, etc.) within 9 hours. The goal of this category was to measure the speed and versatility of each player.
Introduction
Happy Face was a web challenge, it had a single feature: transforming sad text đĸ into happy text đ.
The source code was simple, there was a single page that accepted an optional parameter called text
.
If the text
parameter contained:
<
,>
,\
: The request was aborted.emojis
and(
: These characters were replaced with other emojis or)
.
Afterward, the text
variable (our input) and the output
variable (filtered input) were rendered inside a Freemarker template. The template engine was up to date, version 2.3.34
.
|
|
Source:
com/speedrun/demo/DemoApplication.kt
When a simple payload is executed, it runs twice (text
and output
variables)!
When an RCE payload is attempted, an error occurs because the filtered input contains syntax errors and is executed before the valid input.
|
|
My strategy was to find a way to prevent the page from crashing with the filtered
variable and achieve RCE with the second variable.
Attempt / Recover
To achieve this, I first searched for try/catch
features within the Freemarker template documentation. I found one called attempt, recover.
|
|
However, the characters <>
are completely blocked, making it impossible to use for the challenge.
FTL directive
The ftl directive allows a user to switch the <tag>
syntax to [tag]
syntax (which is not filtered).
This directive also determines if the template uses angle bracket syntax (e.g. <#include ‘foo.ftl’>) or square bracket syntax (e.g. [#include ‘foo.ftl’]). Simply, the syntax used for this directive will be the syntax used for the whole template, regardless of the FreeMarker configuration settings.
However, the directive must be on the first line of the template, which cannot be controlled.
This directive, if present, must be the very first thing in the template.
Playing with quotes
I had an idea that made me think of a dangling markup payload. The goal was to place the non-valid code inside a string, preventing its execution. Then, the second payload would close the string to execute the code.
However, I encountered an <EOF>
error when trying to run this code.
|
|
I resolved this issue by simplifying the payload and using a raw
string.
To indicate that a string literal is a raw string literal, you have to put an
r
directly before the opening quotation mark or apostrophe-quote. Freemarker - Expressions
To obtain the flag, simply execute the binary /app/get_flag
.
|
|