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