← All talks

Attempted Research in PHP Class Pollution

BSides Hong Kong · 202519:38145 viewsPublished 2025-07Watch on YouTube ↗
Speakers
Tags
About this talk
Explores prototype pollution and class pollution vulnerabilities across programming languages, focusing on PHP. The speaker demonstrates how object merging functions can be abused to pollute object properties and inject malicious payloads, discusses gadget-based exploitation techniques, and examines whether PHP's type system prevents the escape patterns that make similar vulnerabilities critical in JavaScript and Python.
Show transcript [en]

Oh hello everyone. Uh thank you all for uh attending to my uh town. Uh uh today I will talk about uh my attend research in Php. So first uh let's have a little bit introduction about me. So uh hi my name is more commonly known as CM or SU. Uh I'm a year three information security at PU. I'm also a bounty hunter and a web security researcher and I got uh at least 20 uh CVS. Uh I'm also a very active CT uh play with team L and OSX. So let's first ask ourself what is cast version. Uh but before we uh talk about that we have to understand what is a prototype version. Uh this connectivity class was

first introduced uh by holy bar in uh 2018. The core concept of this uh poly uh class is to uh it's about uh object is dangerous. Let's see. Uh we have a this uh base class and we it has some property called something and a method say something and we create a new base object instance and call method say something to print uh the hello world string into the console. Now how can we update this properties uh value? Well, we can do something like uh simply assign the something property with a uh this syntax. But this is really boring, right? What if we combine or merge two object together? In here we have a recursive merge

function which simply loops all the object u properties and uh uh create a new uh target object to use this uh recursive merge function. We uh we merge the base object with the uh with the user object input. Now we can uh glue or overwrite the other product properties in the object. Now here's a question. Can we escape the object context like uh can we uh pull other project uh objects properties in JavaScript? We have something called uh prototype chain. Let's uh give you a brief example of this property photo chain. Uh let's say we want to access object to property bar but uh object pool doesn't have uh property bar. So what it will do is that uh it

will use the special properties called uh photo to uh access the object a global object photo prototype. and say, "Hey, do you have a property bar?" In this case, uh the global object type does indeed have a post type bar with a value of string bar. After that uh a global object prototype will uh send back to the uh the value to the object and to the uh uh the object the user. Now what if we look the global object prototype uh the uh photo structural property. Let's uh in here we have a JSON object. Um it will first go to the empty object uh prototype because um the base object uh is inherit from the empty object.

Then we will go to the global uh object prototype and add the property payload to the global pro prototype. Then we apply the uh call the recursive merge function to pollute the global uh object prototype. As you can see the merge uh object doesn't have the payload property but it when we try to access it it prints out it return the the spring polluttor after polluting the glo global object line. What if we create a new object? As you can see uh the new empty object doesn't have a property tail but we if you try to access it it return polluted. This is because the it uh since the empty object doesn't have property payloads

up to the uh prototype sh property payload. Now how can we abuse or use this vulnerability? To do so we have to first find a gadget or a dangerous version. In here we have a uh process scripping ss gadget which is inner HTML and it directly embeds HTML code into the uh browser. In here in this situation we can glow property description to achieve uh SSS. Uh this is because the uh product object doesn't have the uh description property so that it will default fall back to the default port object. In short, uh an impactful procion funability requires an useful gadget. So back to the uh beginning of this talk. What is uh cast version?

Well, turns out cast version is just a basic name for prototype version. In uh 2023 a class version in Python was discovered by uh sorry for so here's a meme uh about the for the propos so uh since Python doesn't have the prototype chain uh the uh the researcher decided to relay the vulnerability to a car version. Makes sense, right? So the payload is also similar to prototype version. Then uh in last year 2024 uh class version was discovered by Don and again the payload is very similar to the Python one and the JavaScript one. So here's a simple trivia and yeah it seems like no one asked research question is class question uh possible

in every single programming languages maybe in PHP. So I decided to uh research in this uh PHP class but ultimately um it is similar to other class version but um I just couldn't escape the object context. Uh before we dive into the uh how PHP class works we have to understand how uh developers to do object mergers in PHP. There are some uh built-in away function like uh away merge, away merge recursively, a way replace recursive. But there are some caveats like the first one is is that object must be converted into associative way by ten in here. Let's give you a an example. In here we have a base class which is similar to the JavaScript one but in PHP

syntax and we have a coil page that accept a user in input. And here we use the uh built-in function away merge to merge the base object with the user input object and in the and we did uh polluted the property something. However, it's it's an object uh away. Well, the second caveat is that uh PHP away function return an away. So maybe we can use a type casting again to convert the away into an object again. Well, if you do that, it just return standard class object. So what is that object? Uh if you look at the PHP documentation, uh standard cast is basically means um it's a generic empty cast. It means that uh so

that uh the original object instance will lose all its uh methods. If we try to uh uh call method say something uh PHP will throw a an exception. So are there any uh other merging function used in the wild? Well, yes, because the developers want the original object. But how? Well, simply just look through every single U properties and the original object still here. We can also use the QR code tone to uh tone the original object. And then uh we do the mering again and it is the same result. Now uh can we put uh other the objects methods? Well, unfortunately no. Uh this is because the uh for each loop uh we can

only get the properties and value key. As you can see, it has no uh method C. But what if we can uh escape the object context? Unfortunately, I cannot know because PP doesn't have a special property like the one in JavaScript like portal. Maybe we could do uh object property. In here, we have a uh I'll give you an example. Uh we have a object a class called B and it have has a uh remote code execution get called function hell check. It will simply look through every single H command and execute them through the uh by the PHP function passed through. We can also define a merge function which is the accessing uh the the one in

previous version. And here is a post snippet that accept a uh user input. In the first line we get the user JSON object. Then we create a new uh full object instance and call method health. Then we pass the uh user input uh user JSON object into a PHP object. Then we merge the base object with the past uh PHP object. And finally call method PH. If we spin up a PHP server and send a post request to uh the endpoint, we can see that uh we uh we put the property health check commands with the value of uh id before mer uh command is the p command which executed expectedly. However, if we uh after version, we can

see that the command is H ID. We successfully overwrite or polluted the original uh command. Another uh gadget example is that uh an authentic authentication bypass gadget. It call function is admin. It will check the property admin. uh the property username is strictly equals to the string admin by default the value is guest. So it will print out the is not admin message. Now before merging we can see that the username property uh value but is guess which prints out is not admin. After merging the uh the username is admin and in print out is admin. So uh object property version is possible. But how about associative away key position? Again uh we we have a uh associative way

called conflict and it has key health check command and we have the exact same uh remote code execution g called health track but this time it takes uh a comp argument. uh it will look through every every single uh capture commands and again execute them uh by the pass through fish function. In here we uh get the uh user JSON object and then uh print out the config and call function health check. Then we uh pass the user JSON object and then but this time we use uh set the uh associative back to true which means uh we pass the user JSON object into a a associative away instead of a standard standard class object.

Then we use the uh away merge build use pp building function to merge the config away with our uh user input object. Finally we call uh the health check function. Now if we try to pull health check commands using this obser request we can see that we still uh we can override the healthare command. So with that said uh associative away key position is indeed again possible. So how about any real world cases? Well, no. I couldn't find any cases. This is uh simply just too many gadgets to find and most of them are not impactful. So in conclusion, uh PHP class version is well possible. So on uh object property and associative away key version is useful if and only if uh

an imple is found in the future. Maybe uh we could uh escape uh find a way to escape the object contest and maybe other classes or maybe uh try to collude the objects methods or find an exploit that can lead to a Google remote code execution. uh but most importantly uh you want to research this politic vulnerability task in other programming languages like in uh let's say golang z plus uh per and more so that's it thank you for

Would you consider cast to be a language design problem like application development problem? I would say it's more like a it's like a design problem. Yeah. So, so is like uh developers have to like uh do something extra to mitigate the issue of the language. I would say yes. Uh if you take a look at the JavaScript prototype example, the developer usually have to see the object and uh to prep. Yeah. Any more questions? No. Okay. Thank you very much. Hey. All right. And uh