菜单

Detailed analysis of PHP object injection detail

2017年11月23日 - PHPer

Prerequisite knowledge

In the PHP class there may be some called magic function (magic function), these functions will be automatically triggered when certain events in the class, for example (__construct) will be created in an object called __destruct () will be called in the destruction of an object when the object is __toString, as a string called. The common magic functions are __construct (), __destruct (), __toString (), __sleep (), __wakeup ().

Examples are as follows:

Code is as follows

<? 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 (‘varr1′,’varr2’);

}

Public function (__wakeup) {

Echo “__wakeup< br>”;

}

}

$obj = new (test); / instantiate objects, invoke the __construct (__construct) method, output

$obj-> (echoP); (echoP) / / call method, output “abc”

Echo $obj; //obj object is a string output, call __toString () method, output __toString

$s =serialize ($obj); //obj object to be serialized, call __sleep () method, output __sleep

Echo unserialize ($s); //$s will be the first to be deserialized, will call the __wake () method, the object to be deserialized out but also as a string, it will call the _toString () method.

/ / the script ends in turn calls the __destruct () method, output __destruct

&gt?;

principle

Why do you use sequential words like this? The main thing is to facilitate the transmission of data, and after data recovery, the data properties will not change. For example, after serializing an object, it still saves all the information about this object. At the same time, you can save the serialized values in the file so that you can read the data directly from the file when you need to use it, and then you can serialize it. Use Serialize () and unserialize () to serialize and de serialize in PHP.

The harm of serialization is that if the serialized content is controllable by the user, the user can inject carefully constructed payload. When serializing, it is possible to start some magic methods in the object, resulting in unexpected harm.

Object injection

In essence, serialize () and unserialize () do not have any holes in the implementation of PHP. The main reason for the vulnerability is that the application results in dealing with objects, magic functions, and serialization related issues.

If a class is used to temporarily store a log into a file in a program, the log file is deleted when the __destruct () method is called. The code is roughly as follows:

Logfile.php

Code is as follows

<? PHP

Class LogClass {

Public = $logfilename””;

Public function logdata ($text) {

“Echo log data”.$text. “< br/>”;

File_put_contents ($this-> logfilename, $text, FILE_APPEBD);

}

Public function (__destruct) {

Echo’deletes’.$this-> logfilename;

Unlink (dirname (__FILE__).’/’.$this-> logfilename);

}

}

&gt?;

Use LogClass in other classes

LogLogin.php

Code is as follows

<? Phpinclude “index.php””;

$obj = new LogClass ();

$obj-> logfilename = “login.log””;

$obj-> logdata (record log ‘);

&gt?;

The code above is a normal use of the LogClass class to complete the logging function.

The following is an example of the use of an object injection vulnerability.

News.php

Code is as follows

<? PHP

Include “logfile.php””;

Codes the use the LogClass / / some

Class User {

Public $age = 0;

Public $name = ”;

Public function (print_data) {

Echo “User”.$this-> name. “is”.$this-&gt “years old.< br/> age;”;

}

}

Accept input / / as an User object from the user

$usr = unserialize ($_GET[“user”);

&gt?;

The code shown above uses the LogClass object and accepts input from the user to serialize it into a User object.

When we submit the following data

News.php? User=O:4: “User”: 2:{s:3: “age”; i:20; s:4: “name”; s:4: “John”;}

Such statements can be used normally, but also programmers hope to use the method.

But if the submitted data is:

News.php? User=O:8: “LogClass”: 1:{s:11: “logfilename”; s:9: “.Htaccess”;}

So you end up with delete.Htaccess.

You can see that the constructed data lead to the execution of the __destruct () method in LogClass and then delete the important configuration files in the web site.

It can also be seen from the above example that if the user’s input is not strictly controlled and the user’s input is serialized, it is possible to implement code execution vulnerabilities.

Injection point

PHP object injection is usually on the logic of program. For example, a User class defines __toString () used for formatting output, but also has the File class defines __toString () method to read and display the contents of the file, then the attacker may have configuration files to read site by the class User deserialization to construct a File class.

User.php

Code is as follows

<? PHP

Class FileClass {

Public $filename = “error.log”;

Public function (__toString) {

Echo filename changed ==&gt. $this-> filename; “;

Return @file_get_contents ($this-> filename);

}

}

Class UserClass {

Public $age = 0;

Public $name = ”;

Public function (__toString) {

Return’User’.$this-> name. “is”.$this-&gt age.’years old.; < br/>’;

}

}

$obj = unserialize ($_GET[‘usr’]);

Echo $obj; call obj (__toString) / / method

&gt?;

Normally, we should import UserClass serialized strings, such as user.php, usr=O:9:, “UserClass”: 2:{s:3: “age”; i:18; s:4: “name”; s:3: “Tom”;}, the page will finally output User Tom is 18 years old. This is also an ideal way to use it.

But if we import data into user.php, usr=O:9: “FileClass”: 1:{s:8: “filename”; s:10: “config.php”;}, the last output of the page is that the filename has changed; ==> config.php, executed the __toString () method in FileClass.

So you can read the source code in config.php.

Vulnerability mining

These holes are generally difficult to mining, although the show looks very simple, but in fact the conditions is still quite demanding, and find the object injection vulnerability is generally through the audit source code to find, see unserialize () the parameter is controllable, the other parameter object deserialization there may be.

defense

To test the various boundary conditions in the program

To avoid the user’s controllability of the unserialize () parameter, the json_decode method can be used to transfer the parameter.

Serialize – Generates a storable representation of a value

Serialize – a representation of producing a stored value

Unserialize – Creates a PHP value from a stored representation

Unserialize – creates the value of PHP from stored representations

<? PHP

/ / declare a class

Class dog {

Var $name;

Var $age;

Var $owner;

Function dog (“unnamed $in_name=”, “$in_age= 0 $in_owner=”, “unknown”) {

$this-> name = $in_name;

$this-> age = $in_age;

$this-> owner = $in_owner;

}

Function (getage) {

Return ($this-> age * 365);

}

   

Function (getowner) {

Return ($this-> owner);

}

   

Function (getname) {

Return ($this-> name);

}

}

/ / instantiate the class

$ourfirstdog = new dog (“Rover”, “12”, “Lisa and Graham”);

/ / serialize function will be converted into a serialized string instance of the

$dogdisc = Serialize ($ourfirstdog);

Print $dogdisc; //$ourfirstdog has serialized to string O:3: “dog”: 3:{s:4: “name”; s:5: “Rover”; s:3: “age”; i:12; s:5: “owner”; s:15: “Lisa and Graham”;}

Print'< BR>’;

*

—————————————————————————————–

Where you can store the string $dogdisc to any place such as session, cookie, database, PHP file

—————————————————————————————–

* /

/ / we in the cancellation of this class

Unset ($ourfirstdog);

/ * reduction operation * /

*

—————————————————————————————–

Here will string out of $dogdisc such as session, from your storage place to read cookie, database, PHP file

—————————————————————————————–

* /

Here we use unserialize / / () reduction object has been serialized

$pet = unserialize ($dogdisc); / / $pet at this time is already in front of the $ourfirstdog object.

Get / / age and name attribute

$old = $pet-> getage ();

$name = $pet-> getname ();

This class at / / uninstantiable can continue to use, but also the attributes and values are maintained in the serialized state before

Print “Our first dog is called $name and is $old days old< br&gt”;”;

Print'< BR>’;

&gt?;

发表评论

电子邮件地址不会被公开。