This website uses cookies

To provide the highest level of service we use cookies on this site.
Your continued use of the site means that you agree to their use in accordance with our terms and conditions.

Insights

Trust Me, I’m a Plugin: Chaining WebDAV and Unsigned Code to Remote Code Execution

Mateusz Lewczak

September 19, 2025

Today’s story is about how two seemingly unrelated things came together to create a global Remote Code Execution vulnerability (at least from the application’s perspective).

But let’s start at the beginning. During a pentest of a desktop application, I noticed that it was using resources shared over WebDAV. This is where it stored documents, configuration files, and so on. And here’s the kicker: from the application’s point of view, the most critical detail was that everyone had full access to this WebDAV share – without any authentication. You could read files, delete them, or even upload your own. That last bit actually opened the door to RCE in the web application – but that’s a story for another day.

The application was also designed to be extensible. In other words, its developers had built in support for plugins, which could then be loaded directly into the application. It was the classic setup: dynamically loading DLL files with specific exported functions. Unfortunately, the application didn’t perform any cryptographic verification of plugin signatures. In practice, that meant it had no way of knowing whether a plugin actually came from a trusted vendor or not.

So, what do these two points have in common? The distribution model. Plugins, updates, and other resources were all being distributed via WebDAV. In other words, the same place where anyone could freely read, delete, or upload files – without authentication – was also the trusted source for feeding the application new components.

On the server, there was also a manifest file that described which plugins existed, their versions, their sizes, and exactly what the application was supposed to load. Based on this manifest, the app would check whether it already had all the latest components – or if it needed to download something new.

Put those two facts together, and you’ve got a dangerous mix:
• An application happily loading DLL plugins without verifying their origin or signature.
• A distribution channel that anyone could tamper with.

That meant a malicious plugin could be dropped into WebDAV and then pulled in by the application as if it were a legitimate update. Phase #001 – creating a malicious plugin Here’s an example of a malicious plugin. Its sole purpose is to launch the system calculator process when an instance of the PluginExtension class is created: This code should be compiled in Visual Studio targeting .NET Framework 4.0 for the x64 architecture. In order for the plugin to pass all the checks in PluginLoader, a StrongName object also needs to be created:

1. Generate a key pair for StrongName using the Visual Studio Developer Command Prompt with the following command: 2. Next, specify this key pair for signing in the Visual Studio project settings: After this preparation, the project needs to be compiled as a DLL library. Phase #002 – packing a malicious plugin Plugins in the application are packaged as a ZIP archive together with a .qpkg manifest file. This manifest must be created right after building the malicious plugin. To do this, the following steps are required:

1. Create the following directory structure: 2. Move the compiled DLL file to the plugins/APP.exploit directory.
3. Create a plugin-config.xml file and place it in the plugins/APP.exploit directory: 4. Pack the entire plugins directory into a data.zip archive: 5. Obtain information about the size of files data.zip, plugin-config.xml and APP.Exploit.dll.
6. Obtain the SHA1 hash for files data.zip, plugin-config.xml and APP.Exploit.dll using the following commands in PowerShell: 7. Create a manifset.qpkg file, and insert previously obtained information in the marked places: With everything prepared, the final step was delivering the malicious plugin. And for that, I could simply take advantage of the WebDAV property I mentioned earlier – the complete lack of authentication.

For context, WebDAV (Web Distributed Authoring and Versioning) is an extension of HTTP that adds methods for remote content management. Beyond the standard GET and POST, it supports operations like:
• PUT – upload a file to the server.
• DELETE – remove a file.
• MKCOL – create a new collection (folder).
• PROPFIND – query properties and list directory contents.
• MOVE / COPY – relocate or duplicate resources.

In practice, this makes WebDAV behave a lot like a network filesystem – except, in this case, one that required no authentication at all. Phase #003 – providing a malicious plugin To deliver a malicious plugin, follow the steps below:

1. First, create a directory where the malicious plugin will be stored: 2. Upload the created manifest.qpkg file to the newly created directory: 3. Upload the data.zip archive containing the malicious plugin to the newly created directory: 4. Now it’s needed to download the global plugin manifest, which can be found at the following URL: 5. In order for the plugin to be recognized by the application, modify the existing global manifest by adding the following XML tag at the end: 6. All that remains is to upload the new global manifest using the following command: Everything was ready – it was time to launch the application. Phase #004 – application update When users launch the application the next time, they will be greeted with the following message, suggesting that the APP application has been updated: When the user goes through with the update, the malicious plugin gets downloaded and loaded into the process (as I observed in Procmon). At that point, the malicious code embedded in the DLL is executed: Conclusion: When Architecture Choices Turn into RCE This vulnerability didn’t stem from a single bug or coding oversight. Instead, it was the result of several independent design decisions that, when combined, created a straight path to Remote Code Execution.
• Plugins were loaded dynamically, but no cryptographic verification was performed to ensure their origin.
• WebDAV was used as the distribution channel, yet it had no authentication or access control.
• The update mechanism fully trusted the manifest provided from this channel.

On their own, each of these choices might have seemed harmless or “just good enough.” Together, they became a perfect recipe for compromise: attackers could upload a malicious DLL, modify the manifest, and watch as the application happily pulled in and executed the malicious plugin. Key Takeaways – What Not to Do • Don’t trust client-side extensibility without strong validation. Every plugin or extension should be cryptographically signed and verified before loading.
• Don’t use unauthenticated distribution channels. WebDAV, FTP, or HTTP shares without access control are not safe ways to push updates.
• Don’t rely solely on manifest files. Update manifests must be integrity-protected (e.g., signed) so they can’t be tampered with.
• Don’t combine insecure components. Each weak link amplifies the risk when chained with others.

In the end, this story shows how seemingly unrelated features – an open WebDAV share and unsigned plugins – came together to create a global RCE vulnerability. Security is not only about fixing individual bugs. It’s about making thoughtful architectural choices that don’t leave the door wide open for attackers.










Next Pentest Chronicles

When Usernames Become Passwords: A Real-World Case Study of Weak Password Practices

Michał WNękowicz

9 June 2023

In today's world, ensuring the security of our accounts is more crucial than ever. Just as keys protect the doors to our homes, passwords serve as the first line of defense for our data and assets. It's easy to assume that technical individuals, such as developers and IT professionals, always use strong, unique passwords to keep ...

SOCMINT – or rather OSINT of social media

Tomasz Turba

October 15 2022

SOCMINT is the process of gathering and analyzing the information collected from various social networks, channels and communication groups in order to track down an object, gather as much partial data as possible, and potentially to understand its operation. All this in order to analyze the collected information and to achieve that goal by making …

PyScript – or rather Python in your browser + what can be done with it?

michał bentkowski

10 september 2022

PyScript – or rather Python in your browser + what can be done with it? A few days ago, the Anaconda project announced the PyScript framework, which allows Python code to be executed directly in the browser. Additionally, it also covers its integration with HTML and JS code. An execution of the Python code in …

Any questions?

Happy to get a call or email
and help!