Prototype Pollution to RCE
Vulnerable Code
const { execSync, fork } = require('child_process');
function isObject(obj) {
console.log(typeof obj);
return typeof obj === 'function' || typeof obj === 'object';
}
// Function vulnerable to prototype pollution
function merge(target, source) {
for (let key in source) {
if (isObject(target[key]) && isObject(source[key])) {
merge(target[key], source[key]);
} else {
target[key] = source[key];
}
}
return target;
}
function clone(target) {
return merge({}, target);
}
// Run prototype pollution with user input
// Check in the next sections what payload put here to execute arbitrary code
clone(USERINPUT);
// Spawn process, this will call the gadget that poputales env variables
// Create an a_file.js file in the current dir: `echo a=2 > a_file.js`
var proc = fork('a_file.js');PP2RCE via env vars
Poisoning __proto__
__proto__Poisoning constructor.prototype
constructor.prototypePP2RCE via env vars + cmdline
DNS Interaction
PP2RCE vuln child_process functions
Forcing Spawn
Controlling a require file path
Setting require file path via prototype pollution
Absolute require
Relative require - 1
Relative require - 2
Relative require - 3
VM Gadgets
Fixes & Unexpected protections
Other Gadgets
References
Last updated

