PHP序列化漏洞从入门到实战:原理、魔术方法

免责声明:本文所涉及的技术、工具、代码仅用于网络安全学习、靶场练习及授权渗透测试,所有操作均应在合法合规的前提下进行。未经授权对目标系统进行扫描、测试、入侵、攻击等行为,均为违反《中华人民共和国网络安全法》及相关法律法规,后果由操作者自行承担。请恪守网络安全道德准则,梳理正确安全观念,学习安全技术只为守护网络安全。

前言:序列化漏洞是Web安全领域最经典、最高频、最易理解却最难防御的漏洞类型,尤其在PHP生态中,几乎是CTF竞赛、代码审计、实战渗透的必考点。

一、PHP序列化于反序列化核心原理

1.1 基础定义

  • 序列化:使用serialize()函数,将变量、数组、对象转化为可储存、可传输的字符串。
  • 反序列化:使用unserialize()函数,将序列化字符串还原为原始数据结构。

漏洞本质:用户可控数据直接传入unserialize()函数,攻击者构造恶意序列化字符串,触发代码执行、文件读取、命令执行、权限绕过等危害。

1.2 核心函数

serialize($variable);      //变量/对象---->序列化字符串
unserialize($variable);    //序列化字符串-->还原为原始数据结构

1.3 序列化格式规则

PHP序列化有固定结构格式,是构造Payload的基础

  • 字符串:s:长度:“值”;
  • 整数:i:数值;
  • 对象:o:类名长度:“类名”:属性个数:{属性定义};

举例

<?php
echo serialize('yang');
//输出:s:4:"yang";
?>
  • s:字符串类型
  • 4:字符串长度
  • “yang”:字符串内容

二、无类序列化漏洞(入门)

无类序列化不涉及自定义类,仅对普通字符串、数字进行反序列化后比较,是最基础的漏洞形式。

典型题目代码

<?php
error_reportingg(0);
include "flag.php";
$KEY = "yang";
$str = $_GET['x'];
if(unserialize($str) === $KEY){
    eoch $flag;
}
show_source(_FILE_);
?>

解题思路

  • 对$KEY的值进行序列化
  • 通过GET参数传入序列化字符串
  • 条件成立直接获取flag

最终Payload

http://xxx.xxx.xxx.xxx/1.php?x=S:5:"yang";

经典陷阱:变量赋值顺序陷阱

<?php
//漏洞代码:$KEY在判断后赋值,实际值为空字符串
if (unserialize($cookie)==="$KEY"){
    echo $flag;
}
$KEY = 'ISecer:www.isecer.com';
?>

正确Payload:序列化空字符串

s:0:"";

三、类序列化与魔术方法(漏洞核心)

类序列化是PHP反序列化漏洞的高阶形态,通过自定义类的魔术方法自动触发恶意行为。

3.1 类序列化示例

<?php
class Person{
    public $name = 'yang';
    public $age = 18;
}
$p = new Person();
echo serialize($p);
//输出:0:6:“Percon”:2:{s:4:“name”;s:5:“derry”;s:3:“age”;i:18;}
?>

3.2 必背魔术方法(漏洞触发点)

魔术方法在特定时机自动调用,是反序列化漏洞的核心利用入口:

魔术方法触发时机实战利用价值
__construct()对象创建时初始化执行
__destruct()对象销毁时最高频利用
__wakeup()反序列化开始时需绕过(CVE-2016-7124)
__sleep()序列化时过滤绕过
__toString()对象当字符串输出时XSS、文件读取
__get()访问不可访问属性时代码执行
__set()设置不可访问属性时变量篡改
__call()调用不存在方法时方法劫持

举例:_destruct()触发命令执行

<?php
class Test{
    function _desetruct(){
        system('whoami');
    }
}
//攻击者传入恶意序列化字符串即可执行命令
unserialize($_GET['p']);
?>

四、CVE-2016-7124:_wakeup绕过漏洞

漏洞原理

当序列化字符串中声明的属性个数>真实属性个数时,PHP会跳过_wakeup方法执行。

影响版本

PHP  5<5.6.25;PHP 7<7.0.10

利用方法

原序列化字符串:o : 4 : "name":2:{...}
绕过payload:  o : 4 : "name":3:{...}

仅需将属性数量改大即可跳过_wakeup。

五、原生类反序列化漏洞(无自定义类也能利用)

PHP内置原生类自带魔术方法,无需自定义类即可构建Payload,常见于无源码场景。

常用原生类

  • Exception/Error:自带_toString()→用于XSS
  • SoapClient:可触发SSRF
  • DirectoryIterator:可读取文件

举例:原生类XSS利用

<?php

highlight_file(_FILE_);
$a = unseralize($_GET['k']);
echo $a;
?>

构建Payload

<?php
$e = new Exception("<script>alert(1)</script>");
echo urlencode(serialize($e));
?>

传入Payload即可触发XSS。

六、序列化漏洞实战速查技巧

  1. 漏洞前提:可控数据必须传入unserialize()
  2. 优先寻找:_destruct()、_wakeup、_toString()
  3. 属性格式:private/protected需加%00类名%00
  4. wakeup绕过:直接修改属性个数大于真实属性个数
  5. 无类利用:优先尝试Exception等原生类
  6. 比较绕过:区分===强比较与==弱比较类型

七、总结

PHP反序列化漏洞的核心逻辑是:可控数据进入反序列化点→触发魔术方法→执行恶意代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值