Using C# for post-PowerShell attacks
C# has received some recent attention in the security community, and the Microsoft.Workflow.Compiler.exe security issue recently identified by Matt Graber at SpecterOps prompted us to take a closer look at the potential for using this technique in real-world attacks. Firstly, we will look at how PowerShell fits into the ‘fileless’ attack ecosystem and talk about why attackers may find C# more attractive than PowerShell. Finally, we will look at why the newly found issue in Microsoft.Workflow.Compiler.exe may be useful but – in its current form – cannot be considered a truly ‘fileless’ technique.
So, what's the problem with executing code via yet another arcane utility? You may argue that an attacker who is already on the machine can likely run any code that he wants anyway. The problem with arbitrary code execution in Microsoft.Workflow.Compiler.exe is twofold:
- It allows the attacker to evade application whitelisting (after all it is an official .NET utility made by Microsoft).
- It gives the attacker a new way to hide his actions.
The first point above, application whitelisting, is very effective in combating threats, but it is typically not heavily utilized by organizations. That said, attackers pursuing some high security environments would likely be very keen to have a reliable means of bypassing whitelisting.
In the continual battle between attackers and defenders, attackers are constantly on the lookout for new techniques, and abusing Microsoft.Workflow.Compiler.exe may give them new opportunities. This utility lets the attacker compile and run C# code, which in turn can be leveraged to run arbitrary code.
Evolvement of fileless attacks and PowerShell
First, we should discuss the definition of ‘fileless attack’. As noted by Lenny Zeltser in a 2017 blog post, the common usage of the term ‘fileless’ doesn’t necessarily mean that there are no files involved anywhere in the infection chain. Rather, it is generally used to mean an attack that does not drop an executable file on the victim machine.
Often closely associated with ‘fileless’ scenarios – the rise in the use of PowerShell in attacks is related to the concept of ‘living off the land’: to avoid detection, attackers strive for only using the tools that are natively available on the target system. As part of this strategy it’s preferable to avoid dropping executable files on the file system.
As such, exploit kits (EKs) and malicious Office documents – the latter of which are very much files – are both common methods of launching a fileless attack. As part of the attack chain in these attacks, we frequently observe the use of PowerShell, which may be used for example to download additional scripts, run shellcode, or communicate with the adversaries’ server.
The rise of offensive C#
Owing to its popularity in fileless attacks, PowerShell has gained additional security features in recent years and a focus on improved logging has made it easier to discover PowerShell based intrusions. As a result, we are at a point where PowerShell attacks often do not work in high security environments, and many organizations with a lower degree of security have at least come to recognize the risks associated with PowerShell.
Of course, attackers are constantly on the lookout for new techniques, and the security improvements in PowerShell has naturally driven some creativity on the part of attackers.
Recently, C# has received some attention in the security community since it shares the same underlying technology (i.e. the .NET runtime) with PowerShell but is missing many security features that PowerShell has. This means moving from PowerShell to C# will let you avoid many PowerShell security protections, while still retaining access to existing .NET libraries.
A recent example of C# being used for offensive purposes is the PowerShell/C# ‘combo attack’ noted by Xavier Mertens earlier this month in which a malware sample used PowerShell to compile C# code on the fly. Also, a collection of adversary tools implemented in C# was released. Further, an improved way was published for injecting shellcode (.NET assembly) into memory via a C# application. This technique has some benefits for the attacker with regards to detection when compared to other methods of injecting shellcode via C#.
A not-quite-fileless attack against Microsoft.Workflow.Compiler.exe
A blog post by Forty North Security built on Matt Graber’s research into Microsoft.Workflow.Compiler.exe and demonstrated that you can use the technique to run shellcode on a machine. In both cases the authors used a local payload file and, while it may seem a minor difference, we wanted to see if it was possible to compile and execute a file hosted remotely.
In a real attack against Microsoft.Workflow.Compiler.exe, the initial infection vector would likely be either exploitation of some vulnerability - for example in a browser or PDF reader - or else by social engineering the victim into running an MS Office document that contains a VB macro, both leading to the execution of Microsoft.Workflow.Compiler.exe.
Either way, an unfortunate (for attackers) artefact of this method is the creation of a short-lived temporary DLL file, meaning that a purely fileless attack does not appear to be possible against Microsoft.Workflow.Compiler.exe. Despite it being deleted soon after creation, an endpoint protection product performing real-time monitoring will likely detect this DLL if the code contains known malicious patterns.
Against older Windows versions, such as the still-supported Windows 8.1, the attacker could use a fileless approach for part of the attack chain by hosting the C# payload remotely: a UNC path can reference a remote SMB file share where the C# code resides.
However, against recent versions of Windows 10, the partly fileless approach only works in non-standard configurations or, alternatively, on internal networks. The default configuration will no longer authenticate anonymously to an SMB v2 share, so you would have to either enable SMB v1 or allow SMB v2 connections to anonymous SMB shares via a registry setting. On internal networks, however, remotely hosting the payload will work also against the default configuration of Windows 10 by placing the C# payload on an existing network share that the victim can authenticate to. Given the level of access to the network required for this to work, technique is mostly useful in more advanced targeted attacks.
Further complicating matters is that on many networks outbound SMB traffic is blocked, which means that the greatest potential for having the payload stored remotely will likely be on internal networks. Again, this will likely be the sort of behavior associated with a larger attack, where attacks against Microsoft.Workflow.Compiler.exe is just one trick among others to penetrate the network further.
With that out of the way, let’s show an example of this partly fileless attack. We can make a C# payload that connects to a remote command and control (C&C) server. This payload is fetched from an SMB file share, and we can manually launch it like this:
After running the command, the following happens:
- Fileless: the C# source code is fetched from the SMB network share.
- Not fileless: the C# payload is compiled and executed.
- Fileless: the payload connects to the C&C server, which sends shellcode to the victim.
- Fileless: the shellcode is put in an executable memory area and then executed.
At this point the shellcode at the victim communicates with the C&C server, and C&C server operator has control over the victim. Figure 2 shows the operator’s remote shell running on the victim.
For attacking Microsoft.Workflow.Compiler.exe, there needs to be an initial infection vector such as a browser exploit or weaponized Office document for the attacker to be able to run a command on the victim machine.
Critically, the arbitrary code execution technique using Microsoft.Workflow.Compiler.exe relies only on the ability to call a command, not on PowerShell. There is no need for the attacker to use some known PowerShell technique that might be detected and blocked by a security solution in place. You gain benefits such as bypassing application whitelisting and new ways of obfuscating malicious behavior. That said, when abusing Microsoft.Workflow.Compiler.exe, a temporary DLL will be created and may be detected by anti-virus.
The C# source code can be hosted remotely within a local network, decreasing the footprint of the attacker. With older Windows versions, such as Windows 8.1, or with newer Windows versions with non-standard configurations, the C# source code could even be hosted on the public Internet. Since many organizations block outbound SMB requests at the perimeter, the greatest potential for having a remote payload for Microsoft.Workflow.Compiler.exe will likely be on internal networks.
A conceivable alternative approach would be including the C# code in, for example, a weaponized document and extracting it from an encoded data ‘blob’. It is unclear at this time how viable this method is and it would certainly require additional work and perhaps even, ironically, some PowerShell trickery.
All of that said, given recent trends it seems likely that we’ll start to see an increased number of attacks that utilize C# – or combinations of C# and PowerShell such as that featured in Xavier Mertens’ SANS blog – in the coming months.
Protection statement and additional recommendations
Forcepoint customers are protected against the threat of arbitrary code execution via Microsoft.Workflow.Compiler.exe at the following stages of attack:
- Stage 2 (Lure) – Malicious e-mails associated with this attack are identified and blocked.
- Stage 5 (Dropper File) – Malicious files are prevented from being downloaded.
Additionally, we recommend configuring a Windows Defender Application Control (WDAC) rule to block the usage of the arcane Microsoft.Workflow.Compiler.exe executable unless it is specifically required in your environment. Instructions on how to do this are available here.
If your organization does not yet block outgoing SMB traffic in the firewall, now is the time to implement that. There likely is no valid business need for accessing SMB shares over the public Internet.