HTB — RenderQuest

RenderQuest is one the web challenges Hackthebox provides to practice analyzing source code and finding vulnerabilities. The vulnerability this challenge presents is called SSTI — Server Side Template Injection.
Server-side template injection is when an attacker is able to use native template syntax to inject a malicious payload into a template, which is then executed server-side.
Source code analysis
Once you download the source code of the challenge, you will have the following files :

The core functionality of the application is locates in the main.go
file. Opening the main.go
file we notice that there are two end points (/render
and /static
) identified in the main()
:
....
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", getIndex)
mux.HandleFunc("/render", getTpl)
mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
fmt.Println("Server started at port " + WEB_PORT)
http.ListenAndServe(":"+WEB_PORT, mux)
}
From themain()
function we see that the function responsible for handling requests to the endpoint /render
is called : getTpl()
starting from line 124.
The/render
endpoint takes several parameter:
use_remote
page

Function getTpl() to handle /render
The interesting section of the code is from line 164 which allows the application to fetch a remote resource using the function readRemoteFile

Looking at the function readRemoteFile
:

readRemoteFile
Notice how this function does not do any sort of sanitization and simply fetches returns the contents of the remote page
Back to line 165 , we see that the variable tmplFile
is set to the return value of the readRemoteFile
:


On line 180 a new template is generated and displayed using the contents of tmplFile
, which we control through the page
query parameter. This essentially exposes the application to SSTI because we could host a harmful file for the application to fetch and render.
Exploitation
POCs used from :
To validate that we have indeed found an SSTI we need to setup an environment in which we host a malicious template that the application will fetch. For this I used Ngrok which allows you to expose local services to the internet. You could also use other webhooks for this purpose but I found that ngrok work best and was quick for POCs.
The malicious file we will be hosting: index.tpl
{{ .FetchServerInfo "ls -al " }}
Setting up a python web server python -m http.server 4433
Expose this local server using ngrok : ngrok http http://localhost:4433
Finally we provide the link to our hosted file to the application:

Okay so now you are probably asking yourself where does malicious template have :
{{ .FetchServerInfo "ls -al " }}
The template engine used in this application is html/template and with some research I landed on this blog that explains how we can get get remote code execution in GO applications using this template engine insecurely. To sum it up, this template engine allows us to access objects that are defined with the application, this includes variables, functions etc.
Naturally the next step was to find a function in this application I could abuse to get remote code execution.
This function was FetchServerInfo
:

FetchServerInfo
This function takes one parameter command
.
To call this function, we use the following payload:
{{ .FetchServerInfo "ls -al " }}
Thank you for reading this far !!