Hey! Not your first time visiting our CTF Recaps? Go ahead and jump on down to the insights! If it is your first time, allow us to give a quick rundown of what these are. Wizer CTFs were launched to challenge developers to learn to think like a hacker in order to learn to code more securely. It's part of our new security awareness training we're designing focused on the dev team!
Once a challenge is retired the Wizer Wizard behind these creations - our very own CTO Itzik Spitzen - creates takeaways that provide clues into the challenge from the perspective of defending your script. Want to testdrive a CTF before reading the notes? Go ahead at wizer-ctf.com - it's free and there's something for all levels.
In this challenge, we identifiy an Insecure Deserialization vulnerability which results in an RCE (Remote Code Execution) capability and take advantage of it to read a secret file from the project. Check out this CTF for yourself here.
Our code uses the node-serialize package. This package allows for the serialization and deserialization of javascript objects. These objects can contain functions. In order to properly serialize and deserialize these, eval must be used.
This makes the library inherently vulnerable to a remote code execution IF an attacker is able to control the string to be deserialized. The maintainer of this project is well-aware of this and has included this section in the README, warning developers.
However, clearly this developer did not take that warning to heart and that has left this code vulnerable to an RCE:
A combination of an unsolvable vulnerability in the `node-serialize` library with the ability to return any message using the custom `No items found` message, allows the user to run pretty much any RCE and get the response directly.
With the goal of reading the secret.js file, the first step is to identify the RCE within the `message` value of the sent JSON, and use the format: `_$$ND_FUNC$$_function (){}()` to run any code. Adding `()` at the end of the function code will ensure that it's executed upon deserialization. Once that's done, some code to read the file should be incorporated in the RCE, however, leaving one last hump to cross, which is to find where the `secret.js` file is actually located. Looking at the URL, an attacker can identify that the challenge is deployed on Vercel, which is a Serverless Function deployment. This means that the files might be reorganized by the service. Running `process.cwd()` and a few shell commands (such as `ls` etc) to identify the file and parent folder, is required to finally discover the full path for `secret.js` and execute the attack.
RCE is one of the worst types of attacks, since it enables an attacker to potentially take over the server, read any data and perform almost any action freely. Needless to say that having access to various keys and a server, could even result in taking over an entire system.
Wanna join us on our next challenge? Sign up for our mailing list at wizer-ctf.com.