Skip to content

The preprocessor

To make writing challenges easier, we also have a custom preprocessor based on Tera. This allows you to use variables, loops, conditionals, and more in your challenge files.

To use the preprocessor, simply create a file with the .plftera extension. This file will be processed by the preprocessor before being used in the challenge. This works for the docker-compose.yml and also for anything in the data dir, which will be loaded into the challenge as a volume.

There is a built-in is_export variable that is false if the challenge is being deployed as an instance and true if the challenge is being exported as a handout.

There is also a built-in actor variable that defines the owner of the challenge instance (team name for team CTFs or user name for individual CTFs).

JS Extensions

The preprocessor can be extended by declaring JS functions in the _ctfgarden directory. In the _ctfgarden subdirectory if your challenge, you can create arbitrary JS files that will be loaded by the preprocessor.

The JS files can call registerTeraHandler(name: string, handler: (args: Record<string, string>) => string) to register a new Tera handler. The handler will be exposed as a function in the Tera preprocessor.

Everything supported by Boa.js 0.21.0 is supported, as well as the crypto.getRandomValues and crypto.randomUUID functions from the Web Crypto API.

Imprint