网络安全之原型链污染

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

目录:

目录:

一、概念

二、举例

三、 实操了解

总结

四、抛出原题,历年原题复现

第一题:

五、分析与原理

 第二题:

八、分析与原理

九、具体操作,payload与结果

结果: 


一、概念

  JavaScript 规定,所有对象都有自己的原型对象(prototype)。一方面,任何一个对象,都可以充当其他对象的原型;另一方面,由于原型对象也是对象,所以它也有自己的原型。因此,就会形成一个“原型链”(prototype chain):对象到原型,再到原型的原型……

cat.color--->Animal.prototype--->aaa.prototype--->xxx.--->object.protoype--->null

如果一层层地上溯,所有对象的原型最终都可以上溯到`Object.prototype`,即`Object`构造函数的`prototype`属性。也就是说,所有对象都继承了`Object.prototype`的属性。这就是所有对象都有`valueOf`和`toString`方法的原因,因为这是从`Object.prototype`继承的。`Object.prototype`的原型是`null`。`null`没有任何属性和方法,也没有自己的原型。因此,原型链的尽头就是`null`。

二、举例

网络安全之原型链污染,原型模式,javascript,开发语言

三、 实操了解

在我们了解到了具体的“子类继承父类”的关键点后,我们进行实操看一道题

function P() {

}
var p = new P();

console.info(p.constructor === P)

console.info(p.constructor === P.prototype.constructor)

console.info(p.hasOwnProperty('constructor'))

思路:三小问的具体思路:

  1. console.info(p.constructor === P);: 这行代码比较了对象 p 的构造函数是否等于构造函数 P。由于 p 是通过构造函数 P 创建的,所以 p.constructor 应该指向 P,因此这里的比较结果为 true

  2. console.info(p.constructor === P.prototype.constructor);: 这行代码比较了对象 p 的构造函数是否等于构造函数 P.prototype.constructor。在这里,P.prototype.constructor 默认指向 P,因为 P.prototype 是从构造函数 P 继承而来的。因此这里的比较结果也为 true

  3. console.info(p.hasOwnProperty('constructor'));: 这行代码检查对象 p 是否直接拥有自己的属性 'constructor'。然而,'constructor' 实际上是从 P.prototype 继承而来的,因为 p 是通过 new P() 创建的,它的原型是 P.prototype。因此,这里的比较结果为 false

  4. 总结:代码展示了对象 p 与构造函数 P 及其原型之间的关系。对象 p 是通过构造函数 P 创建的,它的原型指向了 P.prototype。这些比较和检查操作说明了原型链在 JavaScript 中的工作方式。

总结

从以上的简单抛出和讲解我们不难看出原型链污染玩的就是两个重要的概念1.原型继承2.属性查找机制,让我们维持着这两个理念看看题型,在题型中理解原型链污染

  1. 原型继承: JavaScript中的对象可以通过原型继承从其他对象继承属性和方法。每个对象都有一个指向其原型的链接,通过这个链接可以访问原型对象的属性和方法。

  2. 属性查找机制: 当访问一个对象的属性或方法时,JavaScript引擎会首先在对象本身查找,如果找不到,它会沿着原型链向上查找,直到找到属性或方法或者到达原型链的末端。

四、抛出原题,历年原题复现

第一题:

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!')
})

五、分析与原理

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

网络安全之原型链污染,原型模式,javascript,开发语言

 结果:

网络安全之原型链污染,原型模式,javascript,开发语言

 第二题:

'use strict';

const express = require('express');
const bodyParser = require('body-parser')
const cookieParser = require('cookie-parser');
const path = require('path');


const isObject = obj => obj && obj.constructor && obj.constructor === Object;

function merge(a, b) {
    for (var attr in b) {
        if (isObject(a[attr]) && isObject(b[attr])) {
            merge(a[attr], b[attr]);
        } else {
            a[attr] = b[attr];
        }
    }
    return a
}

function clone(a) {
    return merge({}, a);
}

// Constants
const PORT = 8080;
const HOST = '0.0.0.0';
const admin = {};

// App
const app = express();
app.use(bodyParser.json())
app.use(cookieParser());

app.use('/', express.static(path.join(__dirname, 'views')));
app.post('/signup', (req, res) => {
    var body = JSON.parse(JSON.stringify(req.body));  {"__proto__": {"admin":1}}
    var copybody = clone(body)
    if (copybody.name) {
        res.cookie('name', copybody.name).json({
            "done": "cookie set"
        });
    } else {
        res.json({
            "error": "cookie not set"
        })
    }
});
app.get('/getFlag', (req, res) => {
    var аdmin = JSON.parse(JSON.stringify(req.cookies))
    if (admin.аdmin == 1) {
        res.send("hackim19{}");
    } else {
        res.send("You are not authorized");
    }
});
app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);

八、分析与原理

分析:小例题:obj[a][b] = value。如果攻击者可以控制avalue,则可以将a的值设置为__proto__,并且将使用值value为应用程序的所有现有对象定义属性b

分析整个代码:首先定义一个函数merge,关于合并两个对象的设计是非常不安全的。由于执行merge()的库的最新版本已经打了补丁,这道题目使用了旧方法合并对象,从而易受到攻击。
在上面的代码中,我们可以快速注意到的一点是将2 个“admins”定义为const adminvar admin。理想情况下,js中不允许将const变量再次定义为var,所以在题目中有一个需要我们搞懂的点便是,其中一个是正常的a,而另一个是其他的a(同形异义字)。

原理:对象递归合并、按路径定义属性、对象克隆

九、具体操作,payload与结果

从源代码入手:
  Merge()函数是以一种可能发生原型污染的方式编写的。这是问题分析的关键。
    易受攻击的函数是在通过clone(body)访问/signup时被调用的,因此我们可以在注册时发送JSON有效负载,这样就可以添加admin属性并立即调用/getFlag来获取Flag。
   如前所述,我们可以使用__proto__(points to constructor.prototype)来创建值为1的admin属性。
执行相同操作的最简单的payload:

{"__proto__": {"admin": 1}}

结果: 

网络安全之原型链污染,原型模式,javascript,开发语言

 网络安全之原型链污染,原型模式,javascript,开发语言文章来源地址https://www.toymoban.com/news/detail-637208.html

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

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

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

相关文章

  • 安全开发-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)
  • 安全基础 --- 原型链污染

    大部分面向对象的编程语言,都是通过“类”(class)实现对象的继承。传统上,JavaScript 语言的继承不通过 class,而是通过“原型对象”(prototype)实现 JavaScript 规定,每个函数都有一个 prototype 属性,指向一个对象 js中类的建立 js 中,定义一个类,需以 定义“构造函数”

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

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

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

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

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

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

    2024年02月11日
    浏览(29)
  • 网络安全入口设计模式

    网络安全入口涵盖了几种设计模式,包括全局路由模式、全局卸载模式和健康终端监控模式。网络安全入口侧重于: 全局路由 、 低延迟故障切换 和 在边缘处减轻攻击 。 上图包含了3个需求。 •网络安全入口模式封装了全局路由模式。因此,实现可以将请求路由到不同区域

    2024年02月09日
    浏览(32)
  • 26岁转行网络安全,成功上岸安全开发!

    前言 我是去年 9 月 22 日才正式学习网络安全的,之前在国营单位工作了 4 年,在长沙一个月工资只有 5000 块,而且看不到任何晋升的希望,如果想要往上走,那背后就一定要有关系才行。 而且国营单位的气氛是你干的多了,领导觉得你有野心,你干的不多,领导却觉得你这

    2024年02月11日
    浏览(86)
  • 发现网络安全的基本实践:安全代码开发

    本文的目标是对安全代码开发在网络安全中的重要性提供清晰、全面的看法。然后,我们将探讨数字世界中迫在眉睫的威胁、安全开发的指导原则以及可用的工具和技术。 我们还将分析如何将安全性整合到开发周期和培训中,作为确保这一基本实践成功的关键要素。通过对安

    2024年02月04日
    浏览(29)
  • JavaScript设计模式(一)——构造器模式、原型模式、类模式

    个人简介 👀 个人主页: 前端杂货铺 🙋‍♂️ 学习方向: 主攻前端方向,正逐渐往全干发展 📃 个人状态: 研发工程师,现效力于中国工业软件事业 🚀 人生格言: 积跬步至千里,积小流成江海 🥇 推荐学习:🍍前端面试宝典 🍉Vue2 🍋Vue3 🍓Vue2/3项目实战 🥝Node.js🍒

    2024年02月11日
    浏览(32)
  • 【前端知识】JavaScript——设计模式(工厂模式、构造函数模式、原型模式)

    工厂模式是一种众所周知的设计模式,广泛应用于软件工程领域,用于抽象创建特定对象的过程。 优点:可以解决创建多个类似对象的问题 缺点:没有解决对象标识问题(即新创建的对象是什么类型) 示例: 构造函数模式与工厂模式相比,没有显式地创建对象,其属性和方

    2024年02月15日
    浏览(37)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包