How To Reverse Engineer the SolarWinds Hack

When it comes to security incidents involving malware, most of us rely on the information provided by the investigating firm to understand what the malware does, why it does it, and how to find it in our own environment. However, if you are interested in more in-depth details like us, you also want to know how to find that data for yourself.

With that in mind, Charles Dardaman, a Senior Adversarial Engineer of CyberOne, and I have outlined the basic steps you can use to reverse engineer malware by showing you how it can be done on currently the biggest malware topic in the industry, the SolarWinds backdoor.

How It’s Done:

When looking at any form of malware, you first want to investigate its starting point, including what first landed on disk, memory, or in someone’s inbox that led to the rest of the compromise. In this case, that was the SolarWinds Orion DLL backdoor named SolarWinds.Orion.Core.BusinessLayer.DLL (b91ce2fa41029f6955bff20079468448), also called the SUNBURST Backdoor by many. For our sake, we used the excellent writeup provided by FireEye.

The first task a reverse engineer needs to do is to determine the type of binary or file they are working with. Luckily for us, the SUNBURST DLL is a .NET library so we can leverage several different tools to reverse out the contents of the .NET assembly to as close to the original source code as possible. The tool we used in this walkthrough is dotPeek from JetBrains.

When you initially load the SUNBURST DLL into the dotPeek application, it displays some basic information along with metadata, references, and classes as seen in the below screenshot.

61dcff40dc72016b49d86340 SolarWinds Fig 1
Figure 1: SUNBURST DLL in dotPeek

With this now loaded, we can do a few different things; we can either export it to a Visual Studio project or just directly navigate the decompiled code through the dotPeek application.

If you wish to export for the simplicity of using grep or other command-line tools, either right-click the imported DLL or highlight it on the assembly explorer toolbar and select the icon with Visual Studio on it. This will export the whole DLL into a Visual Studio project folder and convert these different classes into .cs files.

61dcff406139978c9dc2b50a SolarWinds Fig 2
Figure 2: Export function on Visual Studio project

Moving on to the backdoor discovered by FireEye and others working on the SolarWinds investigation. FireEye stated that the malware resided in the class SolarWinds.Orion.Core.BusinessLayer.OrionImprovementBusinessLayer, which you should be able to find that class if you extend the SolarWinds.Orion.Core.BusinessLayer section in dotPeek.

61dcff40a26af83c3729606d SolarWinds Fig 3
Figure 3: Finding the backdoor class in dotPeek

Double-clicking the backdoor class will cause dotPeek to decompile the source as closely as possible to its original value. Keep in mind that it will not be a one-for-one translation, but you will still have enough data to continue your investigation.

If you are like us, you will want to comment in-line on any code that looks malicious, or suspicious, but dotPeek does not give you that ability, unfortunately. You can however copy all of the decompiled code and save it to a new file with the .cs extension.

With the decompiled code, it’s easy to begin to get a handle on what it is doing. To start with, we can see a large number of obfuscated strings that appear to be base64 encoded.

61dcff415e3e4e324547884c SolarWinds Fig 4

In order to know the value of these strings, you can jump down to the Unzip method shown below to look at the try-catch block.

61dcff40f0eb77e8f065ce7f SolarWinds Fig 5 768x182 1

As you can see, the Unzip function is converting from base64, decompressing (by deflating the data), and then encoding it into UTF-8. With this knowledge in hand, we can either write a quick script to deobfuscate this data or just throw it into CyberChef here.

61dcff40ad4d5771bf7efa68 SolarWinds Fig 6

The tool easily decodes the strings and you can now have a better idea of what the malicious code is attempting to do. By deobfuscating all the encoded strings inside the malware, you can already see the points called out by FireEye, including the domain that the malware phones home to.

61dcff411b5534b0270dd052 SolarWinds Fig 7

With this extra data, you can now investigate the core functionality of the malware. In this case, we navigated to the Initialize() function which is used to start the malware by doing a number of checks and tricks in order to bypass sandboxes while not running on every machine.

61dcff411b553470d60dd053 SolarWinds Fig 8

To start, the malware will verify that its process name is “solarwinds.businesslayerhost” by hashing the lowercase name of the process and comparing it with the hardcoded hash. It will then only execute if the file write time was roughly two weeks prior. It does this because sandboxes have a significantly shorter runtime and the malicious code will not run inside of the sandbox. This can give people a false sense of security if they never dig any further.

61dcff41ad4d5748d27efa7a SolarWinds Fig 9

The malware will then create a named pipe in order to ensure that it doesn’t run multiple instances.

61dcff41fd38e9fca8baabf8 SolarWinds Fig 10

After which, it will read the configuration file by the same name in the folder. As long as the number is either a 4 or 5 and not a 3, it will continue to run.

61dcff412c873c5e12e1715c SolarWinds Fig 11

To see how that works, you can jump down to the ReadReportStatus() method and take note of which report status is being returned and how the Initiate() function is looking for the return value of Truncate or 3 in order to fail.

61dcff41edd2918a3319ac31 SolarWinds Fig 12

The malware then gets its domain name.

61dcff412a259d0886474396 SolarWinds Fig 13

And creates a UserID based on the machine’s network interface, the domain name, and the GUID.

61dcff41a26af8e925296070 SolarWinds Fig 14

Now that we know the checks the malware will do before it runs, you can look for some other interesting functionalities. One thing that we like to look for is what kinds of jobs or commands the malware might be able to act upon.

In this sample, we can easily see what the malware is capable of by looking at the JobEngine.

61dcff43af40a0b2a281f96e SolarWinds Fig 15

From here, it’s easy to find the corresponding function and understand exactly how it works, such as jumping to ReadRegistryValue as shown below.

61dcff41fd38e978cebaabf9 SolarWinds Fig 16

Understanding the malware’s capabilities is obviously very important, but we also want to discern how it communicates with the attacker’s Command and Control (C2). For this, you can look at the update function that is the main loop inside of the malware. This logic shows the malware creating a cryptoHelper object which it then uses to generate the DNS domains it reaches out to.

61dcff412c873c7630e1715e SolarWinds Fig 17

The UpdateNotification() below is called to validate that the malware has an Internet connection by checking if it can reach api.solarwinds.com.

61dcff417569692d1dd1734a SolarWinds Fig 18

While checking the Internet connection, it will call the TrackProcesses() function which contains a long list of AV/EDR tools to avoid. You can then dig further into it by brute-forcing the hashes that it compares with.

61dcff413d2f9ffa53b05d5e SolarWinds Fig 19

With these blocklists passed, the malware will reach out to the partially randomized domain and check-in with the C2 by starting a thread to handle the communication and job requests that the C2 responds with.

61dcff412c873c6293e1715f SolarWinds Fig 20

You can then follow this to the http.Initialize function that builds the JSON payload and acts on any job that might be received from the C2 server. Inside this function, we noticed a CreateUploadRequest that creates the actual JSON request sent to the server. Partway down the code where we commented, the json that it uses for the request is visible.

61dcff429c406673ce46520c SolarWinds Fig 21

Even further down the http.Initalize function, you can see where the malware parses the response from the C2 server and acts on any jobs passed down to it.

61dcff42ea584262417a1c31 SolarWinds Fig 22

While there is a lot more functionality to this malware, we hope this basic reverse engineering overview and examples can help you get started reversing the binaries. These techniques are not unique to this sample and can be used with other malware.

About the Author

By Quentin Rhodes-Herrera