↓ 跳过正文
  1. Posts/

ISCTF 2025 WP

·456 字·1 分钟·
目录

web
#

Bypass
#

src:

<?php
class FLAG
{
    private $a;
    protected $b;
    public function __construct($a, $b)
        {
            $this->a = $a;
            $this->b = $b;
            $this->check($a,$b);
            eval($a.$b);
        }
    public function __destruct(){
            $a = (string)$this->a;
            $b = (string)$this->b;
            if ($this->check($a,$b)){
                $a("", $b);
            }
            else{
                echo "Try again!";
            }
        }
    private function check($a, $b) {
        $blocked_a = ['eval', 'dl', 'ls', 'p', 'escape', 'er', 'str', 'cat', 'flag', 'file', 'ay', 'or', 'ftp', 'dict', '\.\.', 'h', 'w', 'exec', 's', 'open'];
        $blocked_b = ['find', 'filter', 'c', 'pa', 'proc', 'dir', 'regexp', 'n', 'alter', 'load', 'grep', 'o', 'file', 't', 'w', 'insert', 'sort', 'h', 'sy', '\.\.', 'array', 'sh', 'touch', 'e', 'php', 'f'];

        $pattern_a = '/' . implode('|', array_map('preg_quote', $blocked_a, ['/'])) . '/i';
        $pattern_b = '/' . implode('|', array_map('preg_quote', $blocked_b, ['/'])) . '/i';

        if (preg_match($pattern_a, $a) || preg_match($pattern_b, $b)) {
            return false;
        }
        return true;
    }  
}


if (isset($_GET['exp'])) {
    $p = unserialize($_GET['exp']);
    var_dump($p);
}else{
    highlight_file("index.php");
}

注意 __construct 不可以直接引用 因此 无法让&a = __construct 来调用 此外 $a("", $b); 的形式 无法通过 &a =FLAG 类 来新建对象 触发魔术方法 因此 __construct function 是干扰项 只需专注 __destruct() 由$a("", $b); 想到create_function ()函数

create_function (''.$a);

等价于

eval("function lambda_x() { $b }");

即 创建匿名函数 函数调用时执行$b 注意是调用时 因此直接令$b=system(‘cat /flag’)不可以 因为这样只是创建函数 没有进行调用 令$b= ‘} ’ . $cmd . ’ /*’; 才可以正确执行指令 参考https://blog.csdn.net/smnicdoumeiyou/article/details/155707160有详细解释

接下来便是绕过waf $a 不需要 看$b