zoukankan      html  css  js  c++  java
  • 简单了解反序列化

    1. 什么是序列化和反序列化

    ​ 序列化是将对象状态转换为可保持或可传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。

    2. 序列化和反序列化的格式:

    类型:d			->d代表一个整型数字
    O:d	->	对象		->d代表该对象类型的长度,例如上述的azhe类对象长度为4,原生类对象Error长度为5
    a:d	->	数组		->d代表数组内部元素数量,例如array('a'=>'b','x'=>1)有两个元素
    s:d	->	字符串		-dN代表字符串长度,例如abc序列化后为s:3:"abc";
    i:d	->	整型		->d代表整型变量的值,例如300序列化后的值则为i:300;
    
    a - array
    b - boolean
    d - double
    i - integer
    o - common object
    r - reference
    s - string
    C - custom object
    O - class
    N - null
    R - pointer reference
    U - unicode string
    
    class Xlh{
    	public $test=123;
    	protected $test2='123';
    	private $test3=array(1,2,'san');
    }
    
    $xlh= new Xlh();
    $xlh=serialize($xlh);
    echo $xlh."<br>";
    
    $fxlh=unserialize($xlh);
    print_r($fxlh);
    /*
    $aaa=123;
    i:123
    
    $bb="123";
    s:2:"123";
    */
    结果:
    O:3:"Xlh":3:{s:4:"test";i:123;s:8:"%00*%00test2";s:3:"123";s:10:"%00Xlh%00test3";a:3:{i:0;i:1;i:1;i:2;i:2;s:3:"san";}}
    Xlh Object ( [test] => 123 [test2:protected] => 123 [test3:Xlh:private] => Array ( [0] => 1 [1] => 2 [2] => san ) ) 
    

    ​ 序列化的格式:不同的类型序列化之后的表示方式大同小异;

    序列化与json的选择:

    json数据的格式:

    json{
        "key1":"value1",
        "key2":"value2"
    }
    
    • 序列化使用serialize,特别是对象的存储。这是其存在的意义。

    • 与对象无关的数据存储可以使用json,

    • 数据交换时使用JSON,这也是其定义所在。

    • 目前JSON是能用于UTF-8编码的数据。没办法进行对象的存储

    3.session序列化引擎

    php对session的处理有三种引擎分别为php、php_serialize、php_binary.经过这三者处理后的session结构都不相同。

    php_serialize	->与serialize函数序列化后的结果一致
    	a:1:{s:4:"name";s:4:"asdf";}
    php				->key|serialize后的结果
    	name|s:4:"asdf";
    php_binary		->键名的长度对应的ascii字符+键名+serialize()函数序列化的值
    	names:4:"asdf";(前面的电就是asc字符)
    	names:7:"a s d f";
    	
    

    image-20210425170833907image-20210425170845327 image-20210425170902597

    image-20210430085929108

    4.常见函数——魔术方法

    __wakeup() //使用unserialize时触发
    __sleep() //使用serialize时触发
    __destruct() //对象被销毁时触发
    __call() //在对象上下文中调用不可访问的方法时触发——对象调用一个没有声明的方法时,触发
    __callStatic() //在静态上下文中调用不可访问的方法时触发
    __get() //用于从不可访问的属性读取数据
    __set() //用于将数据写入不可访问的属性
    __isset() //在不可访问的属性上调用isset()或empty()触发
    __unset() //在不可访问的属性上使用unset()时触发
    __toString() //把类当作字符串使用时触发			echo 对象; $text=$test+$对象;
    __invoke() //当脚本尝试将对象调用为函数时触发
    
    

    5.常见的漏洞利用

    1. 字符串逃逸:

    反序列化

    原理:类似于SQL注入,都是因为对用户输入过滤严谨造成的封闭,而造成的命令执行:

    反序列化底层实现逻辑:

    反序列化:

    a:4:{i:0;i:123;i:1;s:3:"abc";i:2;s:4:"abcd";i:3;s:5:"abcde";}???asdfe65ff31
    a:4:{i:0;i:123;i:1;s:3:"abc";i:2;s:4:"abcd";i:3;s:5:"abcde";}???
    
    反序列化完成之后,就不在反序列化其它内容了,也就是说,后面的三个问号(任意字符都可以)不会被反序列化。
    反序列化的实现底层是匹配的开始几个字符;只要能够匹配成功,那么就不再管后面的了。
    
    

    反序列化会严格的按照字符串的格式(类型:长度:"变量名"; 类型:长度:"数据(可以是其它类型变量)"; 数字类型:数字; )进行,当正确的读取到 } 时,就不会再读取后面的数据了,因为正确的读取到},就代表着结束。加入在过程中有任何错误,那么反序列化过程就会终止

    **例题: **

    逃逸:ctfshow web入门 web262

    问题:在进行replace时,前后替换的长度有了变换,所以能够进行简单的字符串逃逸

    逃逸:buu安洵杯第一题:

    问题:全部替换

    2. CVE-2016-7124:__wakeup()函数漏洞

    通过修改反序列化字符串的名称,内容的数字来进行错误的唤醒,错误唤醒,但是程序不会终止,而是继续进行,虽然错误了,也会有一个对象被唤醒

    影响版本:PHP5<5.6.25 PHP7<7.0.10

    例题:

    ​ 功放世界第一个反序列化的题,

    ​ bugku安慰奖

    3. 伪协议的利用

    1. 常见文件利用

    例题:buunizhuansiwei

    ​ 考点:php伪协议利用 利用data://伪协议传数据,利用php://filter伪协议读取文件数据

    ​ text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=

    ​ file=php://filter/read=convert.base64-encode/resource=useless.php

    2.PHAR伪协议利用

    作用:phar文件是php的打包文件,在php.ini中可以通过设置phar.readonly来控制phar文件是否为只读,若非只读(phar.readonly=Off)则可以生成phar文件.

    phar文件结构

    四部分,stub、manifest、contents、signature

    1.stub
    phar文件标志,必须包含<?php __HALT_COMPILER(); ?>,PHP结束标志?>可以省略,但语句结束符;与stub的结尾之间不能超过两个空格。在生成phar之前应先添加stub.<?php __HALT_COMPILER(); ?>之前也可添加其他内容伪造成其他文件,比如GIF89a<?php __HALT_COMPILER(); ?>
    
    2.manifest
    存放phar归档信息.Manifest结构如下图
    
    所有未使用的标志保留,供将来使用,并且不得用于存储自定义信息。使用每个文件的元数据功能来存储有关特定文件的自定义信息.
    
    <?php
        class Test{
            public $test="prprpr999888";
    		
    		function __destruct(){
    			echo $this->test."<br>";
    		}
        }
        $phar = new Phar("test.phar"); //后缀名必须为phar
       
        $phar->startBuffering();
        $phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub
        $o = new Test();
        $phar->setMetadata($o); //将自定义的meta-data存入manifest
        $phar->addFromString("test.txt", "test"); 
    	//添加要压缩的文件,将test文件的数据添加到test.php文件中去
    	//由于只是需要构造payload,所以这里的test文件不存在也行
        $phar->stopBuffering();    //签名自动计算
    	
    	file_get_contents('phar://test.phar/test.txt');
    	//这里是上一次运行代码生成的test.phar和test.txt
    	
    	echo"done.<br>";
    ?>
    

    例题:CISCN2019 华北赛区 Day1 Web1 Dropbox

    ​ 考点:phar文件,pop链构造

    pop链:

    ​ 可以简单理解为解题链,一环套一环,从一个文件中,找到下一个文件或者上一个文件是不是对本文件的内容进行了利用;例如例题中的:pop链构造:User(类)->filelsit(类)->file(类)(filename=flag.php)->close()(函数)

    4.session反序列化

    需要知道session_start()这个函数已经这个函数所起的作用:

    当会话自动开始或者通过 session_start() 手动开始的时候, PHP 内部会依据客户端传来的PHPSESSID来获取现有的对应的会话数据(即session文件), PHP 会自动反序列化session文件的内容,并将之填充到 $_SESSION 超级全局变量中。如果不存在对应的会话数据,则创建名为sess_PHPSESSID(客户端传来的)的文件。如果客户端未发送PHPSESSID,则创建一个由32个字母组成的PHPSESSID,并返回set-cookie。

    提示:

    一般如果是session漏洞,源码中一般有session_hanlder='php_serialize'的设置和session_start()的提示

    例题:

    ctfshow web入门反序列化 web 263

    5. 其它类型的组合拳

    [网鼎杯 2020 青龙组]AreUSerialz

    ​ 考点:强弱类型比较,php7.1+对类的属性(公有私有保护)不敏感

    注意:

    1. protected和private的%00截断在复制粘贴之后可能消失,需要手动添加
    2. ``反引号,可以作为系统命令输出给var_dump
    3. 如果不能使用%00就使用0来进行截断
    4. 传递进去的是字符串,在进行pop链的时候,想清楚反序列化的是什么

    类型:

    1. 字符串逃逸
      1. 部分截断(关键字替换的时候两次长度不对等:少变长或者长变少
      2. 全部截断
    2. 伪协议:
      1. 一般的伪协议:data,php://filter等
      2. PHAR伪协议:用伪协议读取的时候自动进行反序列化操作
    3. 本身的漏洞
      1. CVE-2016-7124:wakeup()的绕过
      2. php7.1+ ==>对类型不敏感
    4. session反序列化:自动进行反序列化操作
    5. ssrf+反序列化
    6. 过滤不严谨:
      1. 十六(使用大写的S)进制绕过字符串过滤
      2. 正则表达式不严谨>'[o]:d+' 绕过:在数字前面加上+形成结构>o:+d+
      3. 在PHP中,对类的名字大小写不敏感==>(car类和CAr类是等价的)

    参考:

    深入浅析PHP的session反序列化漏洞问题_php实例_脚本之家 (jb51.net)

    CTF]PHP反序列化总结_Y4tacker的博客-CSDN博客_ctfshow 反序列化

    PHP反序列化漏洞详解 - FreeBuf网络安全行业门户

    https://www.bilibili.com/video/BV1bJ411C7xv?from=search&seid=2459185202854297460

    https://www.bilibili.com/video/BV1JZ4y1c7ro?p=37

    https://www.freebuf.com/news/172507.html

    https://blog.csdn.net/qq_43431158/article/details/99544797

  • 相关阅读:
    贾鹏芳 二胡演奏家
    php 关于下载中文文件实现
    Android 线程。。
    Hadoop命令行接口运行自己编写的类
    ubuntu下jdk环境变量的设置
    navicat导入sql语句文件失败原因-----datetime
    sql server获取当前时间到秒级和毫秒级的语句
    sql关于group by的问题
    java的equal和==的区别
    win8.1 占用80端口问题
  • 原文地址:https://www.cnblogs.com/upstream-yu/p/15191503.html
Copyright © 2011-2022 走看看