Pug
Syntax
The content below is based on OffSec's WEB-200 course.
Pug is specially-designed to generate HTML files and that is why it has syntax for specifying an HTML tag and tag attributes. Some things to note:
Pug requires the first word to be the HTML tag that will wrap the following data (e.g.
h1).It allows us to pass tag attributes within parantheses after the tag declaration (
input(type='hidden' name='admin' value='true').Keywords like
ifandelseare not treated as HTML tags.Puge can execute JavaScript code directly.
With the dash character (
-) the code will be executed by the JavaScript engine and the output won't be displayed (unbuffered code) (- secret = ['β€οΈ','π', 'π€']).With the equal sign (
=) the code will be execute and the output will be displayed (buffered code) (= secret = ['β€οΈ','π', 'π€']).
h1 Hello, #{name}
input(type='hidden' name='admin' value='true')
if showSecret
- secret = ['β€οΈ','π', 'π€']
p The secrets are:
each val in secret
p #{val}
else
p No secret for you!SSTI
The example below is based on OffSec's WEB-200 course.
Pug requires each line to start with an HTML tag and it uses JavaScript which handles in a non-strict way. Thus, we can use a simple payload such as #{7*'7'} and it is executed to 49 and wrapped around <>, we can infer that Pug is used (Figure 1).

Pug is typically rendering on the server-side and since we know that it uses NodeJS, we can use the child_process.spawnSync command to execute system commands. The child_process module is not available by default, but we can import it via the requirefunction, if the latter exists (Figure 2).

require function is available.It seems that we don't have direct access to require but we can still access it through global.process.mainModule (Figure 3).

require via the global object.Next, we can use require to import child_process, and use the latter for execute system commands (Figure 4).

To read the flag we need to pass the file as a command argument.
Last updated
Was this helpful?