SUNBURST / Solorigate Backdoor Analysis

Lounge Fly
9 min readDec 22, 2020

Introduction

The purpose of this article is to provide a brief overview of the SolarWinds supply-chain attack and analysis of the infected DLL or backdoor dubbed ‘SUBNURST’ or ‘Solorigate’. In stepping through the code I hope to provide a glimpse into the malwares operations, which support much of the data currently provided by analysts at FireEye and Microsoft. I’m not a strong programmer so apologies if some of the terminology is off in my explanation.

Summary

Beginning on December 13th, security provider FireEye reported a supply chain attack trojanizing SolarWinds Orion business software updates in order to distribute malware dubbed as ‘SUNBURST’ or ‘Solorigate’. SolarWinds provides IT monitoring and management solutions to various companies around the world. The victims have included numerous companies in varied industries across the world. Initial analysis supported that the campaigns may have begun as early as March 2020 with recent speculation showing indications of compromise to SolarWinds back in October, 2019 where attackers were able to manipulate the code without installing the backdoor in an effort to what many are referring to as a ‘dry-run’.

The supply-chain attacks and subsequent developments continue to make waves within InfoSec and other sectors as it demonstrates the level of risk seemingly trusted applications and escalated privileges can produce and the wide breadth of impact when compromise occurs. SolarWinds reaches upwards of three-hundred thousand customers of which eighteen thousand had the Trojanized version of the application downloaded indicating the potential scope.

During the week of December 15th, Microsoft in collaboration with other providers initiated successful takeover of the initial domain used to communicate with the malware. These efforts were aimed to prevent further infection and communication by the threat actors as well as identify victims. The latest Microsoft reports have identified at least 40 organizations who’s infected SolarWinds resulted in post-intrusion activity.

Many questions remain unanswered and it is likely researchers, incident responders and analysts will continue to undercover new details as the analysis of various victim intrusions continue. In one of the latest reports by ReversingLabs, research unveiled conclusive details showing that Orion software build and code signing infrastructure was compromised. The source code of the affected library was directly modified to include malicious backdoor code, which was compiled, signed and delivered through the existing software patch release management system.

The backdoor itself that was injected into the software is simple, yet effective code. The attackers designed the backdoor code to look a lot like much of the rest of the application’s code and were careful to not draw attention to it using heavy obfuscation routines or unique naming conventions.

The code creates a new thread that runs the backdoor while the rest of the applications tasks remain untouched. The code then lies dormant for somewhere between 12 and 14 days after which it then conducts several checks to ensure it’s only run under certain conditions. These conditions are further examined in the technical analysis section. If all the conditions are met, such as the system meets the domain requirements, no blacklisted processes are running and network connectivity is established, the malware begins to use dynamically generated domains to begin to facilitate C2 communications with the attacker(s). Further post-infection activity is still being uncovered and may vary between victims. FireEye has reported compromise of offensive security tooling and espionage may be the likely goal of when it comes to others. Some have shown second-stage payloads, one of which was dubbed ‘TEARDROP’ by FireEye researchers. TEARDROP is a memory-only dropper that runs as a service to facilitate Cobalt Strike beacon activity.

Technical Analysis

The malicious code resides in the class OrionImprovementBusinessLayer, comprising of 13 subclasses and 16 methods. Its name blends in with the rest of the legitimate code.

Several conditions are in place to determine whether the code executes. Microsoft’s analysis of the code highlighted them well.

  • Verifies that the process hosting the malicious DLL is named solarwinds.businesslayerhost.exe
  • Checks that the last write-time of the malicious DLL is at least 12 to 14 days earlier
  • Delays execution by random amounts of time
  • Verifies that the domain name of the current device meets the following conditions:
  • The domain must not contain certain strings; the check for these strings is implemented via hashes.
  • The domain must not contain “solarwinds”
  • The domain must not match the regular expression (?i)([^a-z]|^)(test)([^a-z]|$), or in simpler terms, it must not look like a test domain
  • Checks that there are no running processes related to security-related software (e.g., Windbg, Autoruns, Wireshark)
  • Checks that there are no drivers loaded from security-related software (e.g., groundling32.sys)
  • Checks that the status of certain services belonging to security-related software meets certain conditions (e.g., windefend, sense, cavp)
  • Checks that the host “api.solarwinds.com” resolves to an expected IP address

We will dive into the code to illustrate how some of these checks are conducted. For analysis I’ve used the tool dnSpy within a virtual malware analysis environment.

Initialization & Hash

The initialize component is one of the first called and starts with a try-catch block. The if statement retrieves the current process name, lowers the case and hashes it using the GetHash method. It then compares it to the value ‘17291806236368054941UL’.

initialize

As explained by FireEye’s analysis, the hash is calculated by performing an FNV-1a 64-bit hash of the lowercase string then XOR by 6605813339339102567 as shown. This results in the value above equating to solarwinds.businesslayerhost. The hashing process used within the backdoor is shown here:

hashing

Dormancy

Following the hash function, if the SolarWinds process is running, the code then retrieves the last write time and stores it in a variable. Then, it assigns a random number between 288 and 336 to num. One of the first details mentioned of the malware was regards to the specific dormant period of up to two weeks, later shown to be 12–14 days specifically.

The last line appears to compare the current time with the results from GetLastWriteTime and if the result is greater than zero, in other words, the random hour between 288 and 336 has elapsed (12–14 days); the next block of code is executed.

dormancy

Domain Checks

The domain of the machine is retrieved using the GetIPGlobalProperties method and stored in variable domain4. It performs a quick check to determine if the domain is NULL or invalid based on certain criteria.

domain retrieval

The IsNullOrInvalidName function as shown below parses the domain name to compare to a list of per-defined hashes and regex using the previously discussed GetHash function.

domain conditions

The patternHashes list correspond to the blacklisted domains, which have recently been reported to have been decoded as the following:

Domains

  • dev.local
  • lab.local
  • lab.na
  • lab.rio
  • cork.lab
  • apac.lab
  • lab.brno
  • pci.local
  • dmz.local
  • swdev.local
  • saas.swi
  • swdev.dmz
  • emea.sales

These are currently believed to be internal SolarWinds domains.

domain blacklist

In addition to the hashes, some regex is checked against from the patternList.

domain regex

These result in the following regex:

  • (?i)([^a-z]|^)(test)([^a-z]|$)
  • (?i)(solarwinds)

Encoding & Decoding

The Unzip function is continually used throughout the code for obfuscating some the strings used in a number of checks making it worth examining.

FromBase64String() is responsible for the first part of decoding the strings which is then passed to the Decompress function.

unzip

Looking at the Decompress function we’re able to observe the usage of DeflateStream, which provides native methods and properties for compressing and decompressing streams by using the Deflate algorithm. More information can be found in examples here.

Understanding how the encoding and compression functions we’re able to decode many of these values using a tool such as CyberChef.

cyberchef

Services

Later in the initialize function there’s a call to ReadServiceStatus.

call to ReadServiceStatus
ReadServiceStatus

This function is responsible for the checks against services on the machine that will prevent the malware from executing further. All of the values have been cracked and outlined in FireEye’s list.

service list

Communications

Finally, if all checks pass, the Update method is used for initializing cryptographic helpers for the generation of the random C2 subdomains.

Subdomains are generated by concatenating a victim userId with a reversible encoding of the victim’s local machine domain name.

update function

The code tries to resolve api.solarwinds.com to test network connectivity. The Base64 encoded string represented below is decoded to api.solarwinds.com. Just below it, the domain1 variable is shown and results in our avsvmcloud[.]com domain. Other variables shown here are also used to help construct the domain such as appsync-api, us-east1, us-east2 etc.

The malware also has a delay period invoked between the generations of C2 domains as highlighted in the DelayMin function below.

delaymin

The DNS A record of generated domains is checked against a hardcoded list of IP address blocks, which control the malware’s behavior. Records within the following ranges will prevent the malware from executing further. The obfuscated list of networks is contained in the nList list. The nList is read from GetAddressFamily.

nlist

Decoded list of networks:

  • 10.0.0.0/8
  • 172.16.0.0/12
  • 192.168.0.0/16
  • 224.0.0.0/3
  • fc00:: — fe00::
  • fec0:: — ffc0::
  • ff00:: — ff00::
  • 20.140.0.0/15
  • 96.31.172.0/24
  • 131.228.12.0/22
  • 144.86.226.0/24

The remainder of the Update function consists of the malware expecting a CNAME response from the DNS query where if received, a new thread is spawned via the httpHelper.Initialize method. This thread is responsible for additional C2 communications.

cname response

Operations

The backdoor receives instructions from C2 and can conduct a number of operations within JobEngine. As outlined in the FireEye analysis, the following jobs can be observed as summarized below.

jobengine

Additional Info

Reports surfaced that suggest the breach of SolarWinds dated back to at least October 2019 in which the attackers did not place a backdoor into the code, but rather conducted a “dry run” to see if the code manipulation would be successful. Analysis of earlier samples have shown the code manipulation to contain the same class within the DLL, however the inserted code only contained a simple check of the operating systems architecture. The following is taken from a25cadd48d70f6ea0c4a241d99c5241269e6faccb4054e62d16784640f8e53bc which has the creation time of 10–10–2019.

Supporting Resources

Microsoft, 2020. Analysing Solorigate, the compromised DLL file that started a sophisticated cyberattack, and how Microsoft Defender helps protect customers

Microsoft, 2020. Analyzing Solorigate, the compromised DLL file that started a sophisticated cyberattack, and how Microsoft Defender helps protect customers

FireEye, 2020. SUNBURST Countermeasures

FireEye, 2020. Highly Evasive Attacker Leverages SolarWinds Supply Chain to Compromise Multiple Global Victims With SUNBURST Backdoor

ReversingLabs, 2020. SunBurst: the next level of stealth

IOCs

Hashes

a25cadd48d70f6ea0c4a241d99c5241269e6faccb4054e62d16784640f8e53bc

019085a76ba7126fff22770d71bd901c325fc68ac55aa743327984e89f4b0134

02af7cec58b9a5da1c542b5a32151ba1

08e35543d6110ed11fdf558bb093d401

1817a5bf9c01035bcf8a975c9f1d94b0ce7f6a200339485d8f93859f8f6d730c

1acf3108bf1e376c8848fbb25dc87424f2c2a39c

1b476f58ca366b54f34d714ffce3fd73cc30db1a

292327e5c94afa352cc5a02ca273df543f2020d0e76368ff96c84f4e90778712

2c4a910a1299cdae2a4e55988a2f102e

2f1a5a7411d015d01aaee4535835400191645023

32519685c0b422e4656de6e6c41878e95fd95026267daab4215ee59c107d6c77

32519b85c0b422e4656de6e6c41878e95fd95026267daab4215ee59c107d6c77

47d92d49e6f7f296260da1af355f941eb25360c4

4f2eb62fa529c0283b28d05ddd311fae

53f8dfc65169ccda021b72a62e0c22a4db7c4077f002fa742717d41b3c40f2c7

56ceb6d0011d87b6e4d7023d7ef85676

5e643654179e8b4cfe1d3c1906a90a4c8d611cea

6fdd82b7ca1c1f0ec67c05b36d14c9517065353b

75af292f34789a1c782ea36c7127bf6106f595e8

76640508b1e7759e548771a5359eaed353bf1eec

846e27a652a5e1bfbd0ddd38a16dc865

a25cadd48d70f6ea0c4a241d99c5241269e6faccb4054e62d16784640f8e53bc

ac1b2b89e60707a20e9eb1ca480bc3410ead40643b386d624c5d21b47c02917c

b820e8a2057112d0ed73bd7995201dbed79a79e13c79d4bdad81a22f12387e07

b91ce2fa41029f6955bff20079468448

bcb5a4dcbc60d26a5f619518f2cfc1b4bb4e4387

c09040d35630d75dfef0f804f320f8b3d16a481071076918e9b236a321c1ea77

c15abaf51e78ca56c0376522d699c978217bf041a3bd3c71d09193efa5717c71

c2c30b3a287d82f88753c85cfb11ec9eb1466bad

ce77d116a074dab7a22a0fd4f2c1ab475f16eec42e1ded3c0b0aa8211fe858d6

d0d626deb3f9484e649294a8dfa814c5568f846d5aa02d4cdad5d041a29d5600

d130bd75645c2433f88ac03e73395fba172ef676

d3c6785e18fba3749fb785bc313cf8346182f532c59172b69adfb31b96a5d0af

dab758bf98d9b36fa057a66cd0284737abf89857b73ca89280267ee7caf62f3b

e257236206e99f5a5c62035c9c59c57206728b28

eb6fab5a2964c5817fb239a7a5079cabca0a00464fb3e07155f28b0a57a2c0ed

6e4050c6a2d2e5e49606d96dd2922da480f2e0c70082cc7e54449a7dc0d20f8d

ebe711516d0f5cd8126f4d53e375c90b7b95e8f2

Domains

avsvmcloud[.]com

webcodez[.]com

virtualwebdata[.]com

solartrackingsystem[.]net

seobundlekit[.]com

lcomputers[.]com

kubecloud[.]com

globalnetworkissues[.]com

digitalcollege[.]org

databasegalore[.]com

deftsecurity[.]com

ervsystem[.]com

freescanonline[.]com

highdatabase[.]com

incomeupdate[.]com

panhardware[.]com

infinitysoftwares[.]com

virtualdataserver[.]com

thedoccloud[.]com

websitetheme[.]com

zupertech[.]com

IPs

196.203.11.89

20.141.48.154

13.27.184.217

8.18.145.181

8.18.145.157

8.18.145.150

8.18.145.139

8.18.145.136

8.18.145.134

8.18.145.131

8.18.145.36

8.18.145.33

8.18.145.21

8.18.145.3

8.18.144.188

8.18.144.180

8.18.144.170

8.18.144.165

8.18.144.158

8.18.144.156

8.18.144.149

8.18.144.136

8.18.144.135

8.18.144.130

8.18.144.62

8.18.144.44

8.18.144.40

8.18.144.20

8.18.144.9

8.18.144.12

8.18.144.11

12.227.230.4

65.153.203.68

167.114.213.199

51.89.125.18

204.188.205.176

5.252.177.21

5.252.177.25

139.99.115.204

--

--