Home  >  Article  >  Backend Development  >  PHP brief analysis of deserialization structure knowledge points

PHP brief analysis of deserialization structure knowledge points

WBOY
WBOYforward
2022-07-29 15:18:582020browse

This article mainly introduces you to the relevant knowledge about PHP. Serialization is actually converting data into a reversible data structure. Naturally, the reverse process is called deserialization. PHP uses two functions to serialize and deserialize data: serialize formats the object into an ordered string, and unserialize restores the string to the original object. I hope it will be helpful to everyone.

PHP brief analysis of deserialization structure knowledge points

(Recommended tutorial: PHP video tutorial)

Introduction

The purpose of serialization is to facilitate data Transmission and storage. In PHP, serialization and deserialization are generally used for caching, such as session caching, cookies, etc.

Common magic methods in deserialization

  • __wakeup() //When executing unserialize(), this function will be called first

  • __sleep() //When executing serialize(), this function will be called first

  • __destruct() //Triggered when the object is destroyed

  • __call() //Triggered when an inaccessible method is called in an object context

  • __callStatic() //Triggered when an inaccessible method is called in a static context

  • __get() //This method will be called when reading data from inaccessible attributes or if the key does not exist

  • __set() / /Used to write data to inaccessible properties

  • ##__isset() //Triggered by calling isset() or empty() on inaccessible properties

  • __unset() //Triggered when unset() is used on an inaccessible property

  • __toString() //Triggered when the class is used as a string

  • __invoke() //Triggered when trying to call an object as a function

Deserialization bypasses little trick

php7 .1 Deserialization is not sensitive to class attributes

We said earlier that if the variable is protected, the serialization result will be preceded by

\x00*\x00

But in specific versions 7.1 and above, it is not sensitive to class attributes. For example, the following example will still output

abc

<?php
class test{
    protected $a;
    public function __construct(){
        $this->a = &#39;abc&#39;;
    }
    public function  __destruct(){
        echo $this->a;
    }
}
unserialize(&#39;O:4:"test":1:{s:1:"a";s:3:"abc";}&#39;);
even if there is no \x00*\x00

Bypass_wakeup(CVE-2016-7124)

Version:

PHP5 < 5.6.25

PHP7 < 7.0.10

Exploit Method: When the value representing the number of object attributes in the serialized string is greater than the actual number of attributes, the execution of __wakeup will be skipped

For a custom class like the following

<?php
class test{
    public $a;
    public function __construct(){
        $this->a = &#39;abc&#39;;
    }
    public function __wakeup(){
        $this->a=&#39;666&#39;;
    }
    public function  __destruct(){
        echo $this->a;
    }
}

If executed

unserialize('O:4:"test":1:{s:1:"a";s:3:"abc";}');The output result is 666

Increase the value of the object attribute number and execute

unserialize('O:4:"test":2:{s:1:"a";s:3:"abc"; }');The output result isabc

Bypassing some regular expressions

preg_match('/^O:\d /')Match whether the serialized string starts with an object string. This has been a similar test point in the previous CTF.

Use the plus sign to bypass (note that when passing parameters in the URL, it must be encoded as +)

serialize(array(a ) ) ; / / a));//a));//a is the object to be deserialized (the serialization result starts with a, not Affects the destruction of $a as an array element)

<?php
class test{
    public $a;
    public function __construct(){
        $this->a = &#39;abc&#39;;
    }
    public function  __destruct(){
        echo $this->a.PHP_EOL;
    }
}
function match($data){
    if (preg_match(&#39;/^O:\d+/&#39;,$data)){
        die(&#39;you lose!&#39;);
    }else{
        return $data;
    }
}
$a = &#39;O:4:"test":1:{s:1:"a";s:3:"abc";}&#39;;
// +号绕过
$b = str_replace(&#39;O:4&#39;,&#39;O:+4&#39;, $a);
unserialize(match($b));
// serialize(array($a));
unserialize(&#39;a:1:{i:0;O:4:"test":1:{s:1:"a";s:3:"abc";}}&#39;);

Using the reference

<?php
class test{
    public $a;
    public $b;
    public function __construct(){
        $this->a = &#39;abc&#39;;
        $this->b= &$this->a;
    }
    public function  __destruct(){

        if($this->a===$this->b){
            echo 666;
        }
    }
}
$a = serialize(new test());

The above example sets

$b to the reference of $a, You can make $a always equal to $b

Hexadecimal bypass character filtering

O:4:"test":2:{ s:4:“

The above is the detailed content of PHP brief analysis of deserialization structure knowledge points. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:jb51.net. If there is any infringement, please contact admin@php.cn delete