如何进行原型链污染
我们首先要知道prototype和_proto_有什么关系?我们来以定义构造函数的方式来定义一个类
说白了,就是XiLitter.prototype等价于a.proto。就是一个对象的_proto_属性指向所在的类的prototype属性。
原理
如果我们能够控制改变原型对象的属性。比如对于语句object[a][b]=c 我们可以将a设置为_proto_,然后在原型中设置一个属性b,并赋值于c,那么所有继承该原型对象的实例对象都会在本身不拥有b属性的情况下拥有b属性,且值为c。看个例子
如何利用
只有在以下三种情况才可以进行原型链污染攻击
1.对象递归合并
2.按路径定义属性
3.对象克隆
看代码,只要让secert.ctfshow==='36dboy’就能输出flag。最主要的漏洞代码还是copy的一个递归调用函数
它会for循环遍历object2中的键,如果这个键名在object1和object2中都存在,那么就调用copy函数,否则将object2的key赋值给object1。我们可以控制object2,如果object2中的key设置为_proto_,就可以原型链污染了。我们将object2赋值为{“proto”:{“ctfshow”:“36dboy”}}
因为无论object1还是object2都是有原型的,所以当key为__proto__时,if语句返回true,执行copy函数。又套进去了。。。此时key就为ctfshow了,但是object1中没有ctfshow,所以,if语句返回false,执行赋值语句,则object的原型[ctfshow]就成功赋值为36dboy。
这里有必要多说几句,当__proto__作为键名时,就会进入下一个copy函数,此时就不是object1和object2了,而是object1.__proto__和object2.__proto__了。这就导致了键名__proto__变成了原型了,而ctfshow就成为了原型中的属性,成功污染原型链。