In this blog, let’s dive deep into PHP Deserialization Vulnerability on how to identify the serialization and exploit the vulnerability in PHP applications. The deserialization vulnerability in PHP is also known as PHP Object Injection.
As stated earlier, the PHP application uses serialize() and unserialize() methods for serialization and deserialization, respectively. The code to serialize the object in PHP looks like the below code:
In the code, the object that is serialized is an array that contains three distinguished values. The serialized data has to use a structured format to properly deserialize the stream of data back into the object.
As seen in the above output, the JSON format is used to structure the serialized data along with some identification on how the data should be interpreted. There are certain annotations used, which are mentioned below:
Due to this unique nature of serializing data in PHP, it became trivial to identify if the application uses serialization or not while doing Blackbox testing.
For example, if data has JSON format along with data structure as object-type: object- size:object-definition, then it is safe to assume the data is serialized.
The unserialize() takes a single serialized variable and converts it back to the PHP value. The deserialized data, often supplied to dangerous functions, such as exec(), eval(), and shell_exec(), if malicious data is directly provided to process, it will cause intended behaviour in program workflow.
For the demo purpose, let’s use Xtremely Vulnerable Web Application, which has a PHP Object Injection lab for practice.
To solve the PHP Object Injection lab, navigate to the PHP Objection Injection, then click on the Click Here button to see changes on the web page.
As seen in the above image, the XVWA – Xtreme Vulnerable Web Application is displayed on the page, however, on close observation, some data is also reflected in address bars, which looks similar to what is shown in the previous PHP serialized data structure.
Here the serialized object is an array, as it starts with a, with two string values s in it, with index denoted as i.
The above-shown PHP code is responsible for the deserialization of data supplied through the parameter r. Before diving into analyzing the code, one thing which one should know for exploiting the insecure deserialization, the thing called Magic Methods in PHP.
At the moment, let’s look into wakeup() as it is mentioned in the above vulnerable PHP code. So what’s magical about this method?
According to the PHP document regarding wakeup() method, the unserialize() method will first look for wakeup() method. If present, then this function will reconstruct any resources that the object have.
Simply put, if PHP code is supplied as a serialized object then wakeup() will make a replica of code at the time of deserialization hence overwriting the original PHP code causing unintended behaviour.
To understand this clearly, look at the below code used to exploit the PHP Object injection. The code implements the same class as present in the above vulnerable PHP code, which is PHPObjectInjection, also it’s variable $inject but this time with values to execute arbitrary command either OS command id by leveraging the system()function.
The serialized output of the above code will look like the data as mentioned below:
So as per the document, the wakeup() method will reconstruct the class, and its Variable, at runtime with provided serialized data as shown in the below image. Note: Below modification is done for visualization purpose of how wakeup() method will modify the code as per my understanding.
Now everything putting into perspective, the last thing is to execute the supplied input, which will be done by eval() in this case. Whenever the $inject variable has value, it is directly supplied to eval(), causing remote code execution as shown in the below image.
It may seem hard and overwhelming to exploit the PHP Object Injection at first glance, but once the methodology is known and been familiar with vulnerable functions and methods in PHP, it becomes trivial to spot and exploit such vulnerabilities.
More vulnerable code examples on PHP Object Injection can be found at OWASP site. To go deeper into PHP Object Injection, search and study publicly available exploits of the same vulnerability by simply googling, “PHP object injection cve exploitdb”. As for the mitigation of PHP Object Injection, it is as simple as not to supply user-supplied input to unserialize() method.