Animals
There is a prototype pollution vulnerability in /api/tet/list when merging the request data:
app.post('/api/tet/list', function (req, res, next) {
try {
const getList1 = require("./static/list-2010-2016.js")
const getList2 = require("./static/list-2017-2022.js")
let newList = merge(getList1.all(), getList2.all())
let data = req.body.data || "";
newList = merge(newList, data);
res.json(newList)
} catch (error) {
res.send(error)
}
})Furthermore, user input being passed to require() leads to a LFI vulnerability.
app.post('/api/tet/years', function (req, res, next) {
try {
const list = req.body.list.toString();
const getList = require("./static/" + list)
res.json(getList.all())
} catch (error) {
console.log(error);
res.send(error)
}
})If we could find a valid .js file that uses an attribute that we are able to pollute to spawn a new process or execute a command, then we could escalate this to an RCE.
In the Docker container, the most likely place where we could find a suitable candidate would be in the node_modules folder, containing the source code of the installed modules.
Doing a simple search for the child_process string, we could find some interesting scripts:
The changelog.js script indeed has an execSync call with a possible command injection.
Since the require() call would not pass in any arguments, process.argv[2] is undefined. Therefore, we can pollute process.argv[2] with a command injection payload before importing the changelog.js file.
Testing this locally:
To perform this exploit chain on web server, we first perform the prototype pollution:
Then, we exploit the LFI vulnerability to execute the changelog.js script.
This should grant us our reverse shell.
Last updated
Was this helpful?