Wizer CTF #6: Invite Card Creator

Link to challenge: CTF #6

Goal

In this challenge, we identify an SSTI (Server-Side Template Injection) vulnerability which results in exposing a secret environment variable.

Description of code

Our code is an invite card creator that allows users to generate cards to invite others. It does it by using the EJS (Embedded Javascript) template engine. A user can provide a first-name, last-name and role, which will then result in a lovely invite card for that person. The code is intended to strictly limit the use of the following arguments <%=firstName%>, <%=lastName%> and <%=role%>, which it does pretty well. The code then uses the `ejs.render()` method to generate the card which is sent back to the API caller as a string.


What’s wrong with that approach?

The main flaw of the code is that it's passing through extended options as the 3rd argument to the `ejs.render()`, and by that, allowing the settings to be fully controlled through user input. If we read the manual, we can see that one could provide certain options which change the behavior of the library.

By reading the manual of that intended functionality here:


We can quickly spot an interesting setting which could be altered in order to potentially inject malicious code to run within the context of the app.

What would a successful SSTI attack look like in this case?

Once the attacker realizes that it's possible to alter the delimiters, the code which is restricting the arguments to specific ones is no longer relevant, an attacker could change the delimiter and then provide a new argument, one or more, which will be interpreted in the context of the app.
For example providing the following delimiters:

    "delimiter": ".",
    "openDelimiter": "[",
    "closeDelimiter": "]"

Then, providing a `[.<malicious code goes here>.]` argument, won't be restricted by the app code and will indeed run in the app. To achieve the goal of the game, a malicious code should read the `champ_key` and then, once known, the next API invocation could include the champ key and capture the flag.

So what?

Needless to point out that an SSTI is a remarkably capable attack, which allows an attacker to practically run malicious code within the context of a currently running app. Since it's a server side attack, an SSTI is a powerful entry point which could result in gaining unauthorized access to data from various sources (such as environment variables, database, other APIs which are accessible in that code etc.) and even executing shell commands remotely and potentially taking over the server.

Main Takeaways:


Code Wizer!