Phishing has always been a luck of the draw situation for me on engagements. Many people say that phishing is the easiest step and while I typically agree (since you only need one successful payload to run), I find it is one of the most common areas to tip off incident responders that there is a malicious campaign occurring. On one recent engagement, phishing was quite a pain point for me as their users were very well trained and the layers of defense that my email had to go through were mind blowing. It was not long before I received notifications from spamhaus and watched responders diving in on my initial endpoints.
Thanks to the NetSPI team, I just recently discovered my new favorite phishing technique that I wish I had used in that tough case! While playing with it, I made a slight modification which hopefully will provide a demo of one of many methods of modifying this technique.
The team over at NetSPI has done an excellent job covering this topic so I don’t want to rewrite anything unnecessarily. Basically, ClickOnce is a wrapper around a .NET application which allows you to “deploy” it through Internet Explorer while leveraging the trust architecture in the Internet Zones. For a much better explanation and walk through, please see their writeup linked up above. tl;dr… In Visual Studio, you can simply code a C# console application and choose to publish it to a ClickOnce online application. This allows you to easily trick a user into executing your malicious console application with minimal interaction.
To weaponize the ClickOnce package, they include a Veil-Evasion executable and use C# Process.Start to execute the included executable. Next, they phish with a webpage that opens the .application package which starts the ClickOnce installer. The installer package (including Veil-Evasion executable) is downloaded into a temporary direction and executed. While Veil-Evasion continues to defeat and avoid anti-virus, I felt the additional executable on disk and variability in anti-virus detection on different payloads warranted further investigation on how to use this method of phishing.
Using SharpPick to Add Value
In general, I try to minimize the on disk footprint that I have during engagements. By minimizing the on disk footprint, you will naturally minimize your chance of getting quarantined by AV during an on-access scan and you will prevent defenders from finding these artifacts easily. In the case of the ClickOnce technique, the malicious console application will always be put to disk so it is not possible to be memory only. The temporary package will be created here:
When playing with this technique before a big engagement, I wanted to discover a way to use the console application to start my malicious payload without putting anything additional to disk. Several possibilities came to mind…
- Perform the injection from within C#
- Use C# to execute a PowerShell one-liner with Process.Start
- Use SharpPick
SharpPick is a component of the PowerPick project that was presented at CarolinaCon11. It is a capability that implements PowerShell Runspaces in .NET projects through the use of the System.Management.Automation assembly. This is a perfect use case where PowerPick could be used to remove the need for an additional Veil-Evasion executable. By using SharpPick inside of the ClickOnce executable, you are able to run any PowerShell script/command you want inside of the single executable without starting any additional processes. You could also do things like encode/encrypt the PowerShell script in the application to be more AV resistant on disk.
Why use PowerShell instead of a malicious executable? I could go on for quite a bit on this one but in general, it allows you the flexibility to perform a ton of different actions easily including injecting a malicious payload or stager. That is exactly what I was able to put together and use! I built my C# console application that implemented the RunPS function from SharpPick and then had the application perform a RunPS using an encoded version of Invoke-Shellcode from the PowerSploit project. The RunPS function uses the System.Management.Automation function to execute a script inside of a PowerShell runspace without ever starting a PowerShell process. The Invoke-Shellcode command spawned a hidden notepad, injected the Meterpreter stager and called back to my C2 sever without any additional executables on disk.
Lets Get Down to Business!
A full walkthrough to demo these combined techniques might be helpful! Some of this will be repeat from the NetSPI guys but never hurts to see it twice…
- Create the Visual Studio C# Application
- Add the reference by path: c:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0\System.Management.Automation.dll
- Set the target version of .NET in the project properties. NetSPI recommended 3.5.
- Add the SharpPick code
- Compose the script that you wish to execute on the remote target. For my case, I added the Invoke-Shellcode script and added some commands to start a hidden process and inject into it
- Base64 encode the script
- Add the C# code to run the encoded script on your target
- Publish the project. You must select to publish it from a “site” and choose online only!
- Move the site contents over to your exploit server. Make sure the permissions are set properly. You can build a site to launch the .application file or phish directly with the .application file.
- They browse or hit the .application file
- A trust prompt will be provided to ask them to run the file
- Your console application will launch
- The PowerShell code will launch and you should receive your callback!
There are obvious downsides to this method worth mentioning!
- Complexity – This adds an extra layer of complexity which is often times undesired in blackbox phishing situations
- Indicators – Adds additional indicators that can be detected and stopped. For defensive discussion, please reference the SharpPick post mentioned above.
- Slightly less flexible – Due to the specific way I implemented it in this test situation, the payload is not able to be swapped in and out as easily. However, I could design a method using an encoded script blob appended to the executable to allow for slightly more flexible payloads
I hope this was helpful in demonstrating how people can take already existing AWESOME techniques and expand upon them to introduce variance and sophistication where necessary. This post might be overkill and many may laugh, but it is enjoyable to find how many different places we can use PowerShell offensively.