Crowdstrike

New Abuse of the ClickOnce Technology: Part 1


Internals of the ClickOnce Deployments

Now that we have an overview of the different ways a ClickOnce application can be deployed, let’s look into how it works under the hood. To focus on the most essential parts of the deployment process, let’s consider one of the most basic scenarios: when users click on a .application file (Scenario 3). 

Rundll32.exe and dfshim.dll: Identifying the required resources

As we’ve highlighted above, the opening of the deployment manifest triggers rundll32.exe to start with the following command line:

Here rundll32.exe uses the library dfshim.dll, a native Windows library defined as the “ClickOnce Application Deployment Support Library,” and the API “ShOpenVerbApplication,” which serves one purpose: identifying the required resources to request the application deployment and redirect the execution flow to them. 

Core functionalities of the deployment are implemented in the “dfdll.dll” library, which, unlike dfshim.dll, does not live in the C:WindowsSystem32. So to load this resource, dfshim.dll first needs to retrieve the location of “dfdll.dll” using the API GetRequestedRuntimeInfo, which returns a path similar to “C:WindowsMicrosoft.NETFramework64v4.0.30319” and then loads dfdll.dll from this directory. Once dfdll.dll is loaded, dfshim.dll dynamically resolves the address of the function dfdll!ActivateDeploymentW(), which is responsible for requesting the deployment and calls it.

As a side note, we could wonder why Microsoft doesn’t rely directly on dfdll.dll instead of using dfshim.dll. After all, why would we need an intermediate instead of calling functionalities from dfdll.dll through rundll32?

We can assume the reason lies in the nature and location of dfdll.dll. As it lives in the .NET folder, it cannot be found with the default dll search order, as most libraries from %System32% directory, and its location may change depending on the version of the .NET. This makes it trickier for Microsoft to standardize the deployment process, and Microsoft likely decided on trusting native resources available from %System32% to act as the intermediate that identifies the correct .NET resources before using them.

dfdll!ActivateDeploymentW(): Launching dfsvc.exe

ActivateDeploymentW() is dedicated to initializing and starting the COM server in charge of the deployment. It first performs sanitary checks on the parameters of the deployment information, such as checking the length of the URL indicating the location of where to download the .application file. It then calls the function dfdll!InvokeServer() alongside the motive for the server creation. In the case of a deployment, this string is “ActivateDeployment,” but this can vary depending on the reason the server is requested. For instance, when the app attempts to fetch updates, we can observe “CheckForDeploymentUpdate.”

InvokeServer() then initializes the COM library using CoInitialize(), and a subfunction called BindToServer() performs a call to CoCreateInstance() with the CLSID {20FD4E26-8E0F-4F73-A0E0-F27B8C57BE6F} to request the creation of the COM server responsible for deploying the ClickOnce application. If the call is unsuccessful, BindToServer() moves on to manually start “dfsvc.exe,” the executable that implements the COM server, using CreateProcessW(). In Part 2 of this blog post, we explore why the call is unsuccessful on updated Windows and what this failure entails.



Source link