# 1337 - Web challenge
In this challenge we can easily see its source code at:
[Source code](http://1337.chal.imaginaryctf.org/source)
At the same time, it is easy to see the [Dockerfile](http://1337.chal.imaginaryctf.org/docker), based on the Dockerfile we can realize that the name of the flag file has been changed.
Looking at the main thread of execution, at the `/` endpoint, the server receives 2 main params, `text` and `dir`

then these 2 parameters are passed through a function called `leetify` for processing and then rendered by the web server

The `leetify` function has a fairly simple function of filtering out blacklisted characters and replacing the corresponding alphanumeric characters in the preset dictionary,

and can be converted back.

The server uses the [mojojs template](https://github.com/mojolicious/template.js) library, so here comes the `SSTI` vulnerability.
To bypass we just need to pass the param `dir=from` to not be converted from characters to numbers and use the `text` param to insert the template there.

then I tried exploitable cases leading to RCE like using `require`, `child_process`,... but everything seems not available in the current context. And throw with error:
```
ReferenceError: require is not defined
```
but it looks like we omitted an important variable `ctx`, then we focused on this more, hoping to get a lot of things needed to be able to escape the sandbox.
First we need to dump all the properties and methods from the variable `ctx`
Payload: `?text=<%= console.log(ctx) %>&dir=from`

As we can see that there are many properties and methods in the variable `ctx`. We've tried accessing each property, but there doesn't seem to be anything special here.
We then began to dig deeper into the library's source code, and realized that the variable `ctx` also had an attribute `home`

Payload: `?text=<%= console.log(ctx.home) %>&dir=from`

the result returned is the instance of the `Path module`,
and luckily this is exactly what we were looking for

Based on the Path module, we can read any file and can also list existing files on a given path.
Because `ctx.home` returns an instance with the path being the current path, here we only need to list the files that are present and which contain the flag file.

Payload: `?text=<%= a=ctx.home %><% for await (const file of a.list({recursive: true})) { =%><%= file.toString() %><% } =%>&dir=from`

Flag stored at: `/app/app/Dockerfile/app/FL46_7BVY31.7X7`
To read the file we need to use `ctx.home` to create a new `Path` instance with the path being the filename to read through the file scheme.

But besides that, we cannot use quotes to create strings, because in the scheme file there are special characters that will cause syntax errors. One way to fix it is to use `regex` to get the string,
Example: `/abc/.source === "abc"`
and the path to the flag is obtained via the URL param.
Payload: `?text=<%= a=ctx.home.constructor.fromFileURL(ctx.req._query.get(/file/.source)).createReadStream() %><%= ctx.res.send(a) %>&dir=from&file=file:///app/FL46_7BVY31.7X7&dir=from`

> Flag: ictf{M0J0_15N7_0N_P4YL04D54LL7H37H1N65}