Friday, November 5, 2021

A unique adventure of detection and exploitation in unsafe .NET object deserialization

On a recent pentest I came across a fun vulnerability that took me down a rabbit hole and I am dragging you with me! As always, I was using Firefox, burp pro, and a slim docker image of kali. While doing stuff burp pointed out that it saw base64 encoded data in a post request. Then it started giving false positives on java deserialization issues in a __VSX post var.









First its Apache commons collections, beanutils, then java 8. I knew none of this could be true as it’s not a java project, but just to be on the safe side I loaded up ysoserial and ran a few tests, with nothing to show. I was however seeing error messages in the responses that was telling me .NET deserialization was happening.

Error: System.ArgumentException: The serialized data is invalid.

So I got, what was thought to be valid serialized data, and attempted to decode it. Doing a base64 decode gave me gzip data, so I unzipped the data and was left with something that indeed looked like a .NET object.






Then I looked at YSoSerial.NET to help build payloads and I still needed to know what type of payload to use as it had many to choose from. Rather than brute force I wanted to verify what type of vuln I was looking at. So the framework seems to use secure viewstate functionality, because the burp extensions I was using for viewstate decoding was telling me that the view state data is secure, but this data was easily decoded and looked like page state type information. Also, the parameters name seemed to be  custom and the viewstate burp decoders would not be look for it. So, I had to find a way to ensure the __VSX param data was in fact valid viewstate data. I had to find a viewstate validator that takes individual input to verify I had viewstate data, luckily there are a number to choose from so that was easy. One thing most have in common is that they do not take gziped data, this was a little annoying. Doing all this allowed me to determine I need to use the TypeConfuseDelegate gadget chain and ObjectStateFormatter formatter to make payloads with YSoSerial.NET.







I took the above and, debase64 encoded it, gzipped it, rebase64 encoded it, url encoded special chars, stuffed all that in the __VSX post param and submitted. Checked burp collaborator client window a few seconds later and had a connection from the applications systems that gave me the username being used on the system by the application. 

 W00t! 

Well almost, next steps would have been to get a full functional shell and priv esc. I didn’t have time to get that far, and I have already been detected at this point. I don’t know for sure if it was my playing around or the exploit itself, so given more time to hack with I might be able to get RCE undetected, we will never know.

I think this vuln exists because the devs needed special data pushed to the app that was not available in the cookie cute viewstate data functions, so they created their own with no regard to current viewstate protections. I don’t know if I will ever see anything like this again and it was beautiful!  

I have never come across anything like this, it was a challenge and pleasure for me to explore. Some of the tools and techniques used were new for me and this all took a few days to work out despite the condensed version above. I hope you enjoyed my blundering with this vulnerability, and I hope it helps you in some way. Happy hacking.