I find deserialization vulnerabilities somewhat special and beautiful. The fact you can execute your own code (sometimes remotely) in an application written in a managed language and it doesn’t even take memory corruption or stack overflow is mind blowing. Because of that I’m very interested in this kind of vulnerabilities, especially in .NET based applications. No wonder a blog post by Soroush Dalili about deserialization of .NET resources caught my attention.
The researcher noticed, that .NET resource file formats - both compiled (.resources) and not (.resx) store serialized objects inside of them. So if an attacker can tamper the file, he can execute arbitrary code during deserialization when the files are opened. Users don’t think resource files can be malicious. Usually files with these extensions are opened in code editors, but I immediately thought about .NET decompilers. Unfortunately or thankfully :) I didn’t notice that Soroush already found these vulnerabilities in .NET Reflector and ILSpy.
First I needed an executable for testing. So I’ve created an empty C# project in Visual Studio and added a string resource. It is available on GitHub. For PoC payload generation I’ve used ysoserial.net by Alvaro Muñoz.
After the compilation I’ve got the EvilResx.exe for testing. There are differences in resource handling between decompilers. ILSpy for example doesn’t deserialize resources:
Telerik JustDecompile gives a warning before opening a resource file instead:
When I opened dnSpy and expanded resources it didn’t warn me, but a calculator popped up:
The developer of dnSpy pointed out there is a setting I wasn’t aware of in options dialog with a note that it is unsafe:
But for some reason the setting was ON by default. He decided to remove the setting completely and immediately released a new version with the fix 5.0.11.
After that I tried to find what else potentially vulnerable resource editors are out there. One application I found was Resource.NET. It allows editing .resx and .resources files. I used EvilResx.ClickMe.resources from intermediate build folder and ClickMe.resx from sources of my PoC project. However after contacting the owner he claimed it is a vulnerability in Microsoft .NET Framework ResourceReader class :). I’ve sent him multiple ideas how it could be fixed:
- See if the file contains a serialized object and show a warning.
- Check if the file has the Mark of the Web that indicates it was downloaded and show a warning (as Visual Studio does).
- Implement custom .resources parser as ILSpy did.
But as far as I know nothing was done.
2018.12.17 - Reported the issue to the author of dnSpy.
2018.12.18 - Six(!) hours later a new release v5.0.11 with a fix was made.
2018.12.18 - Reported the vulnerabilty to the author of Resource.NET.
2018.12.18 - Resource.NET replied it is a vulnerability in Microsoft framework.
2019.05.27 - Resource.NET vulnerability publicly disclosed.