PHP Deserialisation/Object Injection

Article by • February 17, 2020

Explore More

PHP Deserialisation/Object Injection

PHP Deserialisation is something that is rarely seen in black-box/grey-box application assessments but can have devastating effects if exploited. This vulnerability, when exploited, almost always results in Remote Code Execution (RCE), with the possibility of having catastrophic effects on a business’s application and its users. It is also unlikely that it will be identified by a ‘point and click’ automated scanner, and typically requiring the expertise to develop exploit code in order to leverage the weakness. This blog aims to introduce security professionals to the PHP exploit code necessary to exploit these weaknesses.

Some basic knowledge of object orientated PHP programming (Or a similar language such a C or Java) is very useful here.

Consider the following example:

As you can see, the application code shown above has two classes ‘User’ and ‘getSysFile’. This code would allow an application to serve a reminder to the user based on the amount of days since the last password reset. This value is set, then stored as a cookie in the user’s session for the application to use where needed. As this is stored on the client’s machine, it can be modified to jump to other classes in the code path. See the following for an example of the cookie object generated by the application:

So to make this easier to understand lets breakdown this ‘cookie’ object:

  • O:4: – Telling us we have a serialised object with 4 parts (Variable names with values).
  • “User” – Name of the serialised object.
  • :2: – Number of variables in the object.
  • { data } – Denotes this is the data structure of the objects:8: – First parameter name is a string (s) which is eight characters in length (8).
  • “username”; – First parameter is called username.
  • S:9: – The value of the first parameter is a string (s) which is nine characters in length (9).
  • “Mr Tester”; – The value of the first parameter is Mr tester
  • s:12: – Second parameter name is a string (s) which is 12 characters in length (8).
  • “resetMessage”; – Second parameter is resetMessage.
  • b:1; – The value of the second parameter is a boolean (b) which is set to true (1).

So in short, this allows the function to access the object easily for the convenience of both the application and the user. In theory, this is great, however it can be leveraged in order to read files on the host machine. Consider the class above ‘User’, ‘getSysFile’. This is used by the application to read files on the host machine that are temporarily stored to facilitate certain functionality. However, an attacker is able to inject an object into the above object in order to gain access to system files.

Before I explain the development of this exploit, the reason this is possible is known as ‘PHP Magic Methods’. As seen the ‘getSysFile’ class uses the ‘__toString()’ method, which returns whatever the method returns as a string. In our case, this is a file to be used for processing elsewhere. However, unfortunately our developer has included all the classes in the same code path, meaning this method can be invoked by an external threat actor (provided they have enough knowledge of the application code). In our case, this developer has decided to go open source, allowing other users to see the code through a code sharing site. Now consider the following, the above object can be reconstructed in order to invoke this ‘Magic Method’:

So when this file is executed, you should see the following object:

This time with the getSysFile class injected as an object inside the object, which is unserialised by the application. Further down in the code mentioned above, the application runs the following:

With the newly supplied value executing a seemingly valid function, whilst invoking the sensitive method, which should not be accessible to the user. The following would be the result of the new payload:

To summarise, serious considerations as to the methods included in code paths should be undertaken by developers. In addition, considerations as to the need for serialised objects that are user controllable should be deeply scrutinised to ensure an attacker cannot exploit this extremely serious issue.

If you enjoyed Josh’s blog please take a look at his other technical guide:

,

Josh is one of Pentest Peoples Web Application testers, coming from a university background, who's heavily interested in the ethical hacking world.