反序列化漏洞2
一、反序列化漏洞的出现
1. 举例分析反序列化漏洞
1)日志删除类设计
- 类功能:设计了一个Logfile类用于临时记录日志到error.log文件,在类销毁时自动删除该文件
- 关键方法:
- logData()方法使用file_put_contents()写入日志
- __destruct()魔术方法使用unlink()删除文件
- 成员变量:$filename存储要操作的文件名,默认为'error.log'
2)通过GET请求传参反序列化类
- 漏洞触发点:通过$_GET['param']接收参数并直接传递给unserialize()函数
- 包含机制:需要先包含Logfile.php文件,否则反序列化会产生不完整类
- 攻击原理:攻击者可以构造特定的序列化字符串,控制反序列化后的对象属性
3)应用案例
- 例题:反序列化删除文件
- 攻击步骤:
- 创建Logfile对象并将$filename改为'index.php'
- 序列化该对象得到恶意payload
- 通过GET请求将payload传给目标程序
- 效果验证:当对象销毁时,会执行__destruct()删除指定的index.php文件
- 攻击步骤:
- 例题:反序列化读取文件
- 攻击变种:利用__toString()魔术方法中的文件读取操作
- payload构造:修改序列化字符串中的$filename为目标文件路径
- 实际效果:成功读取服务器上的hello.txt文件内容
2. 反序列化漏洞总结
1)unserialize函数参数可控
- 必要条件:unserialize()函数的输入参数必须外部可控
- 典型场景:通过GET/POST请求参数、Cookie、文件内容等传入序列化数据
- 安全建议:避免直接反序列化用户输入,或进行严格过滤
2)脚本定义了Magic方法
- 关键条件:类中必须定义了魔术方法(如__destruct、__toString等)
- 危险操作:魔术方法中包含文件操作(读写/删除)或命令执行等敏感功能
- 常见危险函数:unlink()、file_put_contents()、system()等
3)操作内容需要有对象中的成员变量的值
- 利用基础:敏感操作依赖对象的成员变量值(如$filename)
- 攻击方式:通过反序列化修改这些成员变量的值
- 防御思路:对成员变量的值进行严格校验,或避免将其用于敏感操作
3. 常见利用函数
- 命令执行类:
- exec()、passthru()、popen()、system()
- 文件操作类:
- file_put_contents()、file_get_contents()、unlink()
- 其他危险函数:数据库操作、代码执行等相关函数也可能被利用
二、知识小结
知识点 | 核心内容 | 考试重点/易混淆点 | 难度系数 |
PHP反序列化漏洞原理 | 通过修改反序列化对象的成员变量值,触发魔术方法中的敏感操作(如文件删除、命令执行) | 可控参数与魔术方法的关联性 | ⭐⭐⭐⭐ |
漏洞触发条件 | 1. 反序列化内容可控; 2. 类中存在执行敏感操作的魔术方法; 3. 操作目标通过成员变量动态指定 | 三个条件缺一不可 | ⭐⭐⭐ |
LogFile类漏洞案例 | 析构函数__destruct()中通过unlink()删除filename成员变量指定的文件 | 反序列化时篡改filename可导致任意文件删除 | ⭐⭐⭐⭐ |
ReadFile类漏洞案例 | __toString()魔术方法中读取filename成员变量指定的文件内容 | 篡改filename可实现任意文件读取 | ⭐⭐⭐ |
常见危险魔术方法 | __destruct()、__toString()、__wakeup()等包含文件操作/命令执行逻辑的方法 | system()、eval()等高危函数 | ⭐⭐⭐⭐ |
漏洞利用流程 | 1. 构造恶意序列化字符串; 2. 篡改成员变量值; 3. 触发反序列化操作 | 动态传参(如HTTP GET)是关键 | ⭐⭐⭐⭐ |
防御建议 | 1. 避免反序列化用户输入; 2. 对魔术方法中的操作做严格校验 | 白名单校验文件名/命令 | ⭐⭐⭐ |
一、反序列化漏洞
1. 漏洞分析
1)feed类
- 类定义: feed类定义在Typecho框架中,用于处理RSS和Atom格式的订阅内容。
- toString方法: 该类包含一个toString方法,用于将feed对象转换为字符串表示。
- 漏洞位置: 在toString方法中,访问了对象的属性,若属性不存在,则会触发magic方法。
2)magic函数
- 定义: magic函数是在PHP中定义的一类特殊函数,它们在特定情况下会被自动调用。
- 相关函数:
- __get(): 当访问一个不可访问的属性时触发。
- __call(): 在对象上下文中调用一个不可访问的方法时触发。
- __isset(): 在不可访问的属性上调用isset()或empty()时触发。
- __unset(): 在不可访问的属性上使用unset()时触发。
3)get方法
- 作用: get方法在访问对象属性时被调用,特别是当属性不存在时。
- 利用点: 通过传入不存在的属性,可以触发get方法,进而执行任意代码。
- 执行流程: get方法调用了_applyFilter方法,后者可能包含执行任意代码的逻辑。
4)常见利用函数
- 命令执行函数:
- exec(): 执行外部程序。
- passthru(): 执行外部程序并显示输出。
- popen(): 打开进程文件指针。
- system(): 执行外部程序并显示输出。
- 文件操作函数:
- file_put_contents(): 将内容写入文件。
- file_get_contents(): 从文件读取内容。
- unlink(): 删除文件。
2. 漏洞利用过程
1)漏洞触发
- 反序列化: 通过unserialize函数将可控的序列化数据传入,触发反序列化漏洞。
- magic方法: 访问不存在的对象属性,触发__get方法。
- 代码执行: __get方法调用_applyFilter方法,后者执行任意代码。
2)利用链
- 起点: unserialize函数接收可控输入。
- 中间: __get方法被触发,调用_applyFilter方法。
- 终点: _applyFilter方法执行任意代码,如PHP info命令。
- 完整利用链: 从unserialize到__get,再到_applyFilter,最终执行任意代码。
二、知识小结
知识点 | 核心内容 | 考试重点/易混淆点 | 难度系数 |
CMS系统介绍 | 流行的CMS系统:Typecho | - | 🌟 |
漏洞概述 | Typecho的反削弱化漏洞,CVE编号:CVE-2018-18753 | 漏洞编号及名称 | 🌟🌟 |
复现步骤 | 下载特定版本(1.0.14.10.10),解压并放置到PHPstudy的www目录下 | 版本号及放置目录 | 🌟🌟 |
安装过程 | 访问页面,自动进入安装流程;需提前创建tape co数据库(UTF-8 MB4编码) | 数据库创建及编码 | 🌟🌟🌟 |
漏洞利用 | 使用POC生成payload,通过浏览器访问in store.php并传递finish参数 | POC使用及参数传递 | 🌟🌟🌟🌟 |
验证漏洞 | 执行PHP info命令,查看PHP版本信息 | PHP info命令执行 | 🌟🌟🌟🌟 |
高级利用 | 使用Pation的POC生成一句话木马文件 | 一句话木马生成 | 🌟🌟🌟🌟🌟 |
漏洞分析 | 反序列化漏洞出现在in store.php的第230行 | 反序列化函数位置 | 🌟🌟🌟🌟🌟 |
利用链构建 | 1. 传递反序列化内容 | - | 🌟🌟🌟 |
2. 触发construct方法 | - | 🌟🌟🌟 | |
3. 查找magic函数类(如feed类的to string方法) | magic函数类查找 | 🌟🌟🌟🌟 | |
4. 触发get方法,调用apl if i et执行命令 | get方法触发及命令执行 | 🌟🌟🌟🌟🌟 | |
对比分析 | - | - | - |