Demystifying Ransomware Techniques Using .Net Assemblies: 5 Main Techniques
Ransomware attacks thrive on evading detection and then encrypting data on a system. In the analysis after a ransomware attack, we often read about how the attack used a combination of different types of files together with a variety of techniques.
So, what does it all actually mean? In this series, we will break it all down using the .Net software framework to show how these capabilities of ransomware are made possible.
In my previous three-part series on Malware Payloads and Beacons, the focus was on the Metasploit Penetration Testing Framework. We used its ready-made meterpreter malware payload to show various attacker techniques. The first article examined how malicious communications start, the attacker’s infrastructure, and forensic analysis of an attack. The second article looked at categories and types of payloads together with some in-memory manipulation techniques. The final part of that series focused on evasion and mitigation techniques.
In this series, we will create our own individual payload files (also known as assemblies) leveraging the .Net software framework but with a focus on ransomware. We shall begin by breaking down ransomware and malware capabilities into individual example techniques to understand how they work on their own. Some of these individual techniques are ultimately what is combined into a single malicious ransomware payload to often devastating effect.
Technique 1: Downloaders, droppers, and loaders
We start off by looking at how ransomware or malware can connect out from an infected network. This is the ability to connect to a remote system, download additional payloads, drop it on the compromised system, and run it (i.e., have it loaded into memory).
Below is an example of a .Net command line (console) application which:
- Acts as a downloader by downloading another remote executable application (putty.exe) from the Internet
- Drops the downloaded application into a temp folder on disk on the computer
- Renames the application to putty_new.exe
- Automatically runs the downloaded application on the computer so it is loaded into memory
When payload staging is used, which means having multiple malicious files doing different things, the Stager (initial small payload) may become both the downloader and also, loosely, the dropper for the Stage (main larger payload). It could also be the stage’s loader. The techniques employed will depend on the threat actor’s assessment of the risk of detection also known as operational security considerations.
A downloader is responsible for pulling down a payload from a remote source such as a web server or FTP server. This is usually over the Internet. A downloader will therefore require that some network connection be attempted in order to reach the remote source.
A dropper, on the other hand, is primarily responsible for delivering or dropping a payload onto a victim system. Therefore, a downloader can also be a dropper, but a dropper may not necessarily be a downloader because a dropper may already have the malicious payload embedded in it as portable executable (PE) files or DLLs. These file types will be discussed later. Droppers are commonly used in attacks; popular examples being the Solarwinds and Kaseya supply chain attacks. Both involved the use of compromised supplier agent software used as droppers for malicious payloads. The latter being used by the REvil ransomware group.
A loader is responsible for setting up the victim system to run another malicious payload, especially in the case of memory-only payloads. Here, setting up means ensuring the necessary memory space allocation often via injecting a DLL into another process’s memory space, then setting up the right memory permissions. The loader then launches the payload or executes the necessary threads.
Technique 2: EXE loading a DLL file
Ransomware payloads can be in the form of an EXE file or a DLL file. Next, we look at how a Windows executable file, also known as an EXE file, can load what is known as a dynamic link library (DLL) file to leverage the code it contains.
EXE and a DLL are two types of .Net assemblies which contain computer programming code instructions and associated information (metadata). These instructions and metadata are assembled together into a single resulting file – EXE or DLL .Net assembly. These two types of files allow computer programming code to be executed (EXE) on a Windows system or stored as a library file (DLL) which can then be ‘borrowed’ and read by other files. In the case of a DLL, this process is much like how multiple people can borrow the same book from a library at different times to read its contents. In the second part of this series, we will explore these two assemblies in more detail in relation to the .Net. software framework.
For now, here is a very simple example to demonstrate the use of these two types of .Net assemblies – an executable (EXE) which executes its own code and then goes on to load and read external code from a DLL file. The executable then passes some input into the loaded DLL code. Finally, the DLL uses the input received from the EXE to display a message back to the user who run the application. Below is the code in action:
This simple application also demonstrates the relationship between EXE and a DLL .Net assemblies. This type of relationship is used legitimately by many applications and operating systems (shared libraries), including the Windows operating system itself. Windows packages a lot of its own code as DLLs so that it can be shared by different applications.
The image below shows the programming code for both the EXE and DLL in the earlier example. The code is written using the C# programming language which is one of the languages supported by .Net. In the image, the DLL code references are highlighted for emphasis:
DLLs are an effective means of writing a piece of code once in a way that can then be used many times by different executables as a shared or dynamic library. As a result of this, it is also heavily used by many malware and ransomware families. Techniques such as DLL Side Loading and DLL Hijacking are common malicious techniques which leverages the relationship between these .Net assemblies.
Technique 3: Recon and launching living off the land binaries
We continue with a combination of important techniques: the ability to gather useful information about a target system (Discovery) and at the same time launch other binaries or executables on that system (Spawning). In the image here, our initial custom executable launches a native executable or binary on the target Windows system, showing a living off the land (LotL) attack.
The example shows our initial C# application running and then proceeding to gather some useful information about the target system, shown by the green text in the output. Notice the drive information that is gathered. This information can be leveraged by ransomware to target files on these drives and then be exfiltrated before encryption for a usually hefty ransom demand.
The application continues by launching an external system executable – the Windows command prompt (cmd.exe) executable. The custom application then passes some Windows commands to the Windows cmd.exe process to display (shown in red text), in this case version information of the Windows system. For the benefit of this article, the custom C# application displays the output of the actions it performs as well as information about the launched process. This ability to launch other external applications is also useful for starting victim processes to eventually inject malicious code into.
Technique 4: Data encoding
Another useful technique is data encoding. This is the process of using an algorithm to represent data in a different form. For example, one type of encoding, base64, is legitimately used in some web requests to pass data back and forth such as HTTP authorization and basic authentication in API calls. However, the same base64 encoding example can also help to hide certain text and commands used by a malicious program or payload. It can be used to obfuscate parts of code such as callback URLs or a file. Such a technique is shown below in our standalone C# program.
In this specific app example, the code takes some text which in this case is the URL “https://listener.malware.bad”, converts it to an array of computer bytes, and then runs the base64 encoding algorithm on the bytes to convert it to the alpha-numeric ASCII text of “aHR0cHM6Ly9saXN0ZW5lci5tYWx3YXJlLmJhZA==” shown under the encoder section of the application display above. This process can be programmatically reversed to get back the original text as shown in the decoder section. In so doing, the URL is hidden in plain sight and cannot be immediately determined for what it is – a malicious URL.
Technique 5: Encryption
Finally, we look at encryption. Encrypting files on a compromised system is what ransomware has become synonymous with. This again is a legitimate capability for securing data at rest which, like most of the other techniques, has come to be used for malicious purposes in ransomware.
In the example below, we have a C# encryption application. It first makes a copy of the file intended for encryption and then encrypts the copy, leaving the original intact.
Here, the original contents of the original file, Data1.txt, are copied to another file, Data1-Encrypted.txt, and then this new file is encrypted.
Encryption is one of the main techniques used by ransomware and forms the basis of holding compromised systems for ransom. It is can also be useful for hiding malware payloads or loaders in transit or at rest to evade detection.
Read part 2 of the series on May 22
The next article will explore Microsoft’s .Net software framework and associated C# programming language as a reference for some of the tactics and techniques shown here and how they are ultimately facilitated.
Learn more about how Illumio Zero Trust Segmentation can help you contain ransomware breaches.