惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Cyberwarzone
Cyberwarzone
Google DeepMind News
Google DeepMind News
宝玉的分享
宝玉的分享
博客园_首页
量子位
博客园 - 司徒正美
罗磊的独立博客
腾讯CDC
IT之家
IT之家
S
Schneier on Security
Hugging Face - Blog
Hugging Face - Blog
L
Lohrmann on Cybersecurity
H
Hacker News: Front Page
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
J
Java Code Geeks
Know Your Adversary
Know Your Adversary
人人都是产品经理
人人都是产品经理
有赞技术团队
有赞技术团队
大猫的无限游戏
大猫的无限游戏
D
Darknet – Hacking Tools, Hacker News & Cyber Security
AWS News Blog
AWS News Blog
Spread Privacy
Spread Privacy
I
InfoQ
T
Threatpost
Simon Willison's Weblog
Simon Willison's Weblog
云风的 BLOG
云风的 BLOG
L
LINUX DO - 热门话题
A
About on SuperTechFans
Blog — PlanetScale
Blog — PlanetScale
Latest news
Latest news
Forbes - Security
Forbes - Security
Security Latest
Security Latest
NISL@THU
NISL@THU
The GitHub Blog
The GitHub Blog
P
Proofpoint News Feed
The Hacker News
The Hacker News
M
MIT News - Artificial intelligence
S
SegmentFault 最新的问题
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
B
Blog
A
Arctic Wolf
C
Check Point Blog
G
Google Developers Blog
S
Security @ Cisco Blogs
Google DeepMind News
Google DeepMind News
The Cloudflare Blog
L
LINUX DO - 最新话题
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
P
Privacy International News Feed
小众软件
小众软件

Blog

CrowdStrike CrowdStrike CrowdStrike CrowdStrike CrowdStrike CrowdStrike CrowdStrike CrowdStrike CrowdStrike CrowdStrike CrowdStrike CrowdStrike CrowdStrike CrowdStrike Why AI Projects Stall and How CIOs Can Respond | CrowdStrike CrowdStrike Leads 2026 Frost Radar for Cloud Runtime Security CrowdStrike Expands Identity Leadership with OpenID and IDPro CrowdStrike 2026 Report: China Fuels Attacks on Tech June 2026 Patch Tuesday: Updates and Analysis | CrowdStrike CrowdStrike and Zscaler Bring Continuous Identity Security to Zero Trust Access 3 Principles to Safely Scale Agentic AI | CrowdStrike ISO 42001:2023 and the New Reality of Cloud AI Data Risk How to Stop AI-Driven Data Loss | CrowdStrike CrowdStrike and NVIDIA Bring Enterprise-Grade Security to AI Factory CrowdStrike and NVIDIA Collaboration Scales AI-Native Agents Secure Shadow AI at the Control Plane with Falcon for IT CrowdStrike Named Leader in 2026 Gartner Magic Quadrant for Endpoint Protection Shadow AI: The Hidden Risk Expanding Across the Enterprise CrowdStrike Named a Leader in Identity Threat Detection and Response Inside CrowdStrike’s Takedown of a Developer-Targeting Botnet Measuring AI-Enabled Success: 3 Trackable KPIs New Claude Integration Brings Audit Data to Falcon Platform How to Protect Identities and Sessions from Infostealers Now Live: CrowdStrike 2026 Financial Services Threat Landscape Report Falcon AIDR Detects Threats at Prompt Layer in Kubernetes AI Apps May 2026 Patch Tuesday: Updates and Analysis | CrowdStrike AI Threat Detection with Automated Leads | CrowdStrike CrowdStrike Named a Leader in Gartner Magic Quadrant for Cyberthreat Intelligence CrowdStrike Launches Falcon OverWatch for Defender CrowdStrike Technical Risk Assessments Reveal Common Exposure Patterns Tune In: The Future of AI-Powered Vulnerability Discovery Defending Against CORDIAL SPIDER and SNARKY SPIDER CrowdStrike Expands ChatGPT Enterprise Integration CrowdStrike Named a Leader in 2026 Frost & Sullivan Radar for CNAPP CrowdStrike Expands Real-Time CDR to Google Cloud CrowdStrike Falcon Cloud Security Delivers 264% ROI CrowdStrike Falcon Platform Achieves 441% ROI in Three Years CrowdStrike Introduces Shadow AI Visibility Service How Defenders Must Respond to Frontier AI | CrowdStrike Frontier AI for Defenders: CrowdStrike and OpenAI TAC April 2026 Patch Tuesday: Updates and Analysis | CrowdStrike How CrowdStrike Accelerates Exposure Evaluation Against Threats | Blog STARDUST CHOLLIMA Likely Compromises Axios npm Package Falcon for IT Supports Windows Secure Boot Certificate Lifecycle Management Detecting CVE-2026-20929: Kerberos Relay Attack via DNS CNAME Abuse How Charlotte AI Agentworks Fuels Security's Agentic Ecosystem CrowdStrike Flex for Services Expands Access to Elite Security Expertise Falcon Data Security Secures Data Wherever It Lives and Moves CrowdStrike Advances CNAPP with Adversary-Informed Risk Prioritization CrowdStrike Services and Agentic MDR Put Agentic SOC in Reach
CrowdStrike
Mathilde Venault · 2026-06-18 · via Blog

Sharing applications with the world is no easy task. Developers struggle to ensure compatibility across different platforms, vendors continually search for new channels to showcase and distribute their software, and users often encounter hurdles when installing and updating the applications. To help solve this challenge, Microsoft offers multiple solutions including its Microsoft Store, the native Windows Installer component (.msi packages), and a lesser-known but powerful option: ClickOnce technology. 

ClickOnce is a deployment technology that enables developers to package and distribute applications that users can run, install, and automatically update with minimal interaction and without requiring administrative privileges. However, ClickOnce's user-friendly deployment process is a double-edged sword — while it simplifies software deployment for legitimate developers, it also provides threat actors with an easy way of spreading malware.

In this two-part series, we document  — for the first time, to our knowledge — the internals of this little-documented technology and discuss its security implications. Part 1 examines how the technology works under the hood, from the publication of the app to its installation on the user endpoint. In Part 2, we focus on how threat actors can take advantage of ClickOnce apps. We summarize known weaponization methods, disclose what we believe to be a previously unknown abuse our research uncovered, discuss detection strategies, and demonstrate how the CrowdStrike Falcon® platform provides protection against these attacks in real-world environments.

Want to hear more? Come catch our talk at REcon 2026 in Montreal on June 19, where we'll walk through it all live.

Background on the ClickOnce Technology 

ClickOnce is a “deployment technology,” which refers to the process of getting an application published with the ClickOnce technology to run and optionally install on a remote system. Its scope is therefore twofold: It provides developers with a streamlined way to distribute applications across different environments, and it offers users a standardized mechanism to execute (and optionally install) software. 

The concept is pretty straightforward: Developers can share one of the ClickOnce deployment files, on which the user would only have to “click once” to deploy the application. These deployment files can be hosted on the vendor's website, where they introduce their app alongside an “Install” button. When clicked, the button triggers the download of the ClickOnce deployment file, and after some prerequisites are met, directly initiates the deployment. First, the OS asks for the user’s confirmation if the publisher’s signature cannot be verified, and upon confirmation, uses a standardized procedure to deploy the app alongside a dedicated wizard to  keep the user informed of every step.

Figure 1. ClickOnce’s wizard

Figure 1. ClickOnce’s wizard

Microsoft engineered this technology to provide a user-friendly solution to install and update applications, with greater flexibility than traditional installation methods like MSI packages that require, among other things, elevated privileges. 

Key features of ClickOnce include: 

  • Minimal user interaction to deploy an application, hence the name “ClickOnce,” highlighting that the deployment can be as simple as clicking a webpage “Install” button in certain deployment scenarios
  • No elevated privileges required to perform the deployment
  • Self-contained packaging that eliminates the need for external dependencies
  • Self-updating functionality allowing applications to automatically fetch and install updates from the deployment server

Before diving into how it works under the hood, let's clarify key terminology:

  • A "ClickOnce application" refers to software that was published using the ClickOnce technology.
  • Publishing describes the process of packaging and exporting software into ClickOnce-compatible resources. This can be seen as a type of compilation that, from the source code of an application, produces the ClickOnce resources required to deploy it.
  • The "deployment" refers to the execution of a ClickOnce application and its potential installation onto the system afterward
  • A "deployment scenario" represents a complete sequence of events and processes that occur from the user’s deployment request to the end of the deployment. 

ClickOnce’s Deployment Journey

Publishing a ClickOnce Application

Let’s walk through the publishing process of a basic ClickOnce application to understand where the ClickOnce technology comes into play. 

In Visual Studio, when a C# or a Visual Basic application is ready to be distributed, we can choose to "publish" our application instead of compiling it into an executable. A dedicated wizard then pops up to guide us in the configuration of the deployment parameters, where we can specify:

  • The medium from where the application will be installed (website, network file share, or offline medium) 
  • The location from which the application can fetch updates, should any be available
  • Whether or not the application should be available offline, which determines if the application should only be executed, or also installed into the system

Figure 2. Visual Studio’s publish wizard

Figure 2. Visual Studio’s publish wizard

Upon successful publishing, we would see the following output generated:

Figure 3. Part of the files generated from the publishing of a ClickOnce app

Figure 3. Part of the files generated from the publishing of a ClickOnce app

This directory houses key files that drive different aspects of the ClickOnce deployment process. First listed is the .application file is known as the "ClickOnce deployment manifest." This is an XML-based file that holds various information about the application, the publisher, and the signature. It points to the resources required to start the deployment of the application it defines. When a user interacts with this file, it triggers the application’s deployment and sets the ClickOnce mechanisms in motion.

Alternatively, the deployment can be initiated by the second binary from the folder, "setup.exe," which acts as a standalone installer. This method differs from the one using the .application file through the components and mechanisms involved during the deployment. They represent two different options to start the deployment, which we'll detail in further sections.

Then, we have the "publish.htm," which is a default webpage allowing users to deploy a ClickOnce app from a browser. It contains basic information about the ClickOnce application, but more importantly, an "Install" button that links to the location of either the "setup.exe" installer or the ".application" file. This introduces an additional option to deploy an application: triggered when a user is requesting it from the browser instead of relying on local files.

Figure 5. publish.htm rendered in the Chrome browser

Figure 5. publish.htm rendered in the Chrome browser

These three files belong to distinct deployment scenarios, which represent different ways an application can be deployed. While they differ in some ways, they can intertwine and it can be tricky to identify what happens under which deployment scenario. So let's examine the different scenarios and observe what happens within each of them. 

Deployment Scenarios

As previously mentioned, clicking on a webpage’s button can trigger the download of either the .application manifest or the setup.exe binary to initiate the deployment. This path represents the first category of deployment scenarios: when ClickOnce apps are deployed from web browsers. Within this category, we distinguish two paths: when the deployment is initiated from Microsoft Edge (Scenario 1), or when the deployment is being requested from any other browser, such as Chrome (Scenario 2). 

Scenario 1: .application deployment using MSEdge

When the user clicks the "Install" button of a MSEdge’s webpage referencing a .application file, the browser downloads the deployment manifest and offers to "open" it to initiate the deployment. 

Figure 6. Screenshot of an install from Edge

Figure 6. Screenshot of an install from Edge

Upon confirmation, the browser launches a rundll32.exe process that acts as a COM client designed to request the deployment to a COM server. In such cases, rundll32.exe starts with the following command line:

Using the deployment manifest alongside dedicated libraries, rundll32.exe retrieves the resources required for the next steps and starts the "dfsvc.exe" binary. This process initializes the COM server responsible for receiving the deployment requests and ensures the deployment, eventually executing the ClickOnce application from a predefined location.

Figure 7. Deployment Scenario 1

Figure 7. Deployment Scenario 1

The Aftermath:  .appref-ms Files

If the ClickOnce application has been configured to be available "offline," the application is not only run but also installed on the system. This includes an additional step, where dfsvc.exe drops an application reference file, determined by a ".appref-ms" extension. This file contains a single line referencing the name of the application, and the location where it can be deployed from, alongside various metadata. For instance, the content of "MyApp.appref-ms" is:

This .appref-ms file is dropped in the "Start Menu" folder (by default %AppData%\Roaming\Microsoft\Windows\Start Menu) to provide a shortcut to start the app from the Windows menu, the interface listing the installed programs accessible from the taskbar. Let’s note the "Start Menu" should not be confused with the "Startup" directory, which contains the list of software to start upon the boot of the OS.

Figure 8. The .appref-ms file’s default location

Figure 8. The .appref-ms file’s default location

Scenario 2: Deployment Through Non-MSEdge Browsers

A user clicking the "Install" button of the same "publish.htm" page from Scenario 1, but displayed in a browser other than MSEdge, triggers a different deployment scenario. With Chrome, for instance, instead of downloading the ClickOnce file and automatically launching rundll32.exe, Chrome only downloads the resource, and the user needs to manually click on the file to initiate deployment. The resource retrieved from the browser can be either the .application file (the ClickOnce deployment manifest) or the setup.exe (ClickOnce’s installer), as they can both start the deployment process. As a side note, it is a similar situation for MSEdge when the webpage hosts a link to "setup.exe" — the binary is not automatically launched and the user needs to manually start it.

Figure 9. Result of a user clicking on the ClickOnce “Install” button in Chrome

Figure 9. Result of a user clicking on the ClickOnce “Install” button in Chrome

When manually opening the .application file, the next steps of the deployment process remain the same as described in the first scenario. Upon opening the .application, rundll32.exe acts as a COM client and starts dfsvc.exe to perform the deployment. When using setup.exe, no rundll32.exe is involved, as it directly acts as the COM client and starts dfsvc.exe, which subsequently deploys the ClickOnce application.

Scenarios 3 and 4: Deployment Without Browsers

Let’s note that having the setup.exe installer or the .application file is enough to initiate the deployment, regardless of how they’ve been acquired. Users deploying ClickOnce applications from hard disk mediums thus introduce two additional deployment scenarios:

  • Scenario 3: The user initiates the deployment by clicking on a .application file
  • Scenario 4: The user initiates the deployment by clicking on the setup.exe installer 

Even if the deployment process does not fundamentally change, it is worth distinguishing it from previous scenarios, as it highlights the fact that deployment can be made without browsers being involved.

So far, we now have:

Figure 10. Deployment Scenarios 1, 2, 3, and 4

Figure 10. Deployment Scenarios 1, 2, 3, and 4

Scenario 5: Manual Deployment Using rundll32.exe 

Users can also manually initiate the deployment by running their own rundll32.exe process, rather than automatically triggering it by opening the .application file. This fifth scenario is also worth mentioning because it gives more flexibility for the file to use for the deployment — for instance, by letting users install an application from a remote server:

This can also allow threat actors to deploy an application using a ClickOnce deployment manifest with any extension. By using a benign extension instead of the legitimate ".application" extension, they gain stealthiness and increase the chances for the payload to fly under the radar of security products. This means threat actors would be able to initiate a ClickOnce deployment using a command line such as:

Alternatively, a .appref-ms file can be used. Let’s remember this file is dropped after a deployment only to give the user a way to launch the application from the Start Menu, which is why it is not used by vendors to initiate a deployment. However, .appref-ms files are processed by rundll32.exe similarly to .application files and trigger the deployment of the application as well. So, it is technically possible to use this resource as an initial deployment method, even if it wasn’t the file’s intended purpose. One noticeable difference lies in the function used from dfshim.dll, as the command line syntax would in this case be:

This gives us one final piece to add to the summary of deployment scenarios:

Figure 11. Summary of the most common deployment scenarios

Figure 11. Summary of the most common deployment scenarios

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:\Windows\System32. 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:\Windows\Microsoft.NET\Framework64\v4.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.

Figure 12. The dfsvc.exe process creation call, decompiled in IDA

Figure 12. The dfsvc.exe process creation call, decompiled in IDA

Dfsvc.exe: Initialization of the COM Server

Dfsvc.exe is a .NET binary that, similarly to dfldll.dll, lives in the default .NET repository. While it uses functionalities from the dedicated .NET library "System.Deployment.dll," dfsvc.exe also uses dfdll.dll to perform the deployment. 

Upon start, dfsvc.exe mostly performs initialization routines in order to set up the COM server that will receive deployment requests. One key API used for this is ole32!CoRegisterClassObject, which is called from the function dfdll!RegisterDeploymentServiceCom(). This function allows dfsvc.exe to register the COM server so other processes can communicate with it as COM clients. As a result of that call, an ALPC is exposed for clients to connect to.

Figure 13. Screenshot of System Informer showing the handles of dfsvc.exe

Figure 13. Screenshot of System Informer showing the handles of dfsvc.exe

Back to rundll32: Requesting the Deployment

Once the dfsvc.exe server is started, rundll32.exe needs to send the deployment request to dfsvc.exe. As shown in Figure 13, dfsvc.exe opens an ALPC port — whose name starts with "\RPC Control\OLE%" — so we can safely assume they rely on Remote Procedure Calls (RPC) to share information. But let’s dive into the internals to understand the technicalities of this communication. 

Within subsequent calls of dfdll!InvokeServer, we can observe a call to RPCRT4!NdrClientCall2, which we can also use to visualize their communication using tools like RPCMon

Figure 14. Screenshot of RPCMon showing the RPC request to dfsvc.exe

Figure 14. Screenshot of RPCMon showing the RPC request to dfsvc.exe

There are a few interesting things to note here. First, we see in Figure 14 that the protocol used is "LRPC" (Local Remote Procedure Calls), which makes sense, as the communication between the COM client rundll32.exe and its COM server dfsvc.exe occurs locally. We can also observe that the "endpoint" is an ALPC port, implying that under the hood, ALPC (Advanced/Asynchronous Local Procedure Calls) is being used. On the server side, we can retrieve the ALPC port created in the previous step, which confirms dfsvc.exe is ready to receive communications from COM clients like rundll32. 

If we dive into the subsequent calls of RPCRT4!NdrClientCall2, we eventually stumble upon the API ntdll!NtAlpcSendWaitReceivePort, which is the API call responsible for sending and receiving ALPC messages between a client and a server.

Figure 15. Callstack from the call to ntdll!NtAlpcSendWaitReceivePort

Figure 15. Callstack from the call to ntdll!NtAlpcSendWaitReceivePort

While not being official documentation, there is great research available online to tell us more about this key API. Among them are Alex Ionescu’s publication, "All about the ALPC, RPC, LPC, LRPC in your PC," and 0xcsandker’s blog post, which both describe the internals of ALPC and provide key takeaways on the ALPC mechanisms used within ClickOnce deployment. Their research allows us to draft a prototype of ntdll!NtAlpcSendWaitReceivePort:

We can observe the following arguments:

  • PortHandle, referring to the handle on the ALPC port held by the COM client (rundll32.exe in our case)
  • Flags indicating the type of ALPC message to be transmitted
  • SendMessage, which is a pointer to an ALPC_MESSAGE structure holding:
    • A PORT_MESSAGE that acts as a header, with information about the message including its length (more details of the structure can be found here)
    • The message itself, which is essentially a byte array of variable size
  • SendMessageAttributes, which specifies any optional attributes about the message being sent — it can be a security attribute holding information about the process to impersonate, a handle attribute to reference an object, or many others presented here

In our case, only the first three arguments matter to understand how rundll32.exe communicates with dfsvc.exe, so let’s focus on these. If we set a breakpoint on the ntdll!NtAplcSendWaitReceivePort call and intercept a few calls, we can observe the following:

Figure 16. Annotated breakpoint at ntdll!NtAlpcSendWaitReceivePort

Figure 16. Annotated breakpoint at ntdll!NtAlpcSendWaitReceivePort

We notice the first argument held in the rcx register is, as expected, a handle that points to an ALPC port, and the second argument held in rdx has the format of a flag. By diving into the code attached to 0xcsandker’s blog post, we can see the value "0x800000" is being defined as "ALPC_PORTFLG_LRPC_WAKE_POLICY3," offering us a potential interpretation of the flag. Regarding the third argument held in r8, we can assume it points to the ALPC_MESSAGE, composed of a PORT_MESSAGE and followed by the message buffer. So we first display the content of r8 as "WORD" values to identify the length of the message contained within the header. Then, we can display the full content of r8 using the retrieved "full length" as an array of bytes, hoping to find interesting information within the ALPC message buffer transmitted to dfsvc.exe. The last command shown in Figure 16 shows the content of one of these ALPC messages, where we can recognize the full path of the ClickOnce deployment manifest. As we expected, this shows rundll32.exe does use ALPC messages to communicate information about the deployment requests to dfsvc.exe. 

Once the deployment request has been sent, rundll32.exe has served its purpose of starting the server and requesting deployment and can exit, leaving the next steps to dfsvc.exe. 

Dfsvc.exe: Deploying the Application

If we attach a debugger to dfsvc.exe and set a breakpoint on ntdll!NtAlpcSendWaitReceivePort before the process receives the deployment request over ALPC, we can intercept the call and step into the operation flow of dfsvc.exe from the moment it receives the deployment request.

As the request contains the path to the deployment manifest, dfsvc.exe first downloads the file from the location indicated within the ALPC message into the ClickOnce application’s designated folder: %Temp%\Deployment\%Deploymentid%\%AppId%.application. As in our test, the source is local and we can observe several ReadFile() operations as the "local pull" of the file occurs. If the deployment manifest was hosted on a remote location, this is where we would see the download.

Figure 17. ProcessMonitor’s capture showing the download of the files

Figure 17. ProcessMonitor’s capture showing the download of the files

Then, dfsvc.exe parses the manifest to retrieve various information and verifies its validity, including the "subscription state" referring to whether or not the app was already installed, not present, etc. 

If the application has been published to be available offline, the System_Deployment!InstallApplication() function is called to ensure the installation into the system. If the publisher identity can’t be verified, this is when the deployment wizard asks for the user’s authorization to install the application, as shown in Figure 1. When the user has confirmed the installation or if the publisher identity has successfully passed the verification, the files from the %Temp% folder are copied into a more definitive folder in %Local%\Apps\2.0\%ID%\.

Figure 18. Migration of the ClickOnce application files

Figure 18. Migration of the ClickOnce application files

As last steps, the application reference file is dropped within the folder "%AppData%\Roaming\Microsoft\Windows\Start Menu\Programs\%AppName%\%AppName%.appref-ms" in order to create a shortcut for the user in the Start Menu. Finally, a registry entry is added under the key "HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall" to give the user the option to uninstall the app easily.

Figure 19. ClickOnce installed app entry

Figure 19. ClickOnce installed app entry

Finally, dfsvc.exe calls the System_Deployment!Activate() function that launches the binary from the folder where the software was installed into. And voilà, the deployment is done. 

Looking Back and Looking Ahead

In this first part, we’ve explored what the ClickOnce technology is and the unique features that differentiate it from other installation mechanisms. We’ve highlighted the multiple scenarios that can lead to the deployment of an app published with ClickOnce, and we’ve documented the internals of the deployment process beyond currently available documentation.

But beyond representing a user-friendly way to install applications, the mechanisms used to support ClickOnce deployment are powerful — and unfortunately can be leveraged by threat actors. In Part 2 of this blog series, we will dive into the various ways the ClickOnce technology can be hijacked and reveal a new attack surface that our research has uncovered.

Additional Resources

  • Read other technical blogs from CrowdStrike engineers here.
  • Dive deeper into topics like this at Fal.Con 2026 with expert-led sessions, hands-on training, and real-world insights.