In this post i want to talk about the SolarWinds breach occurred in 2020 giving the emphasize to the backdoor inside SolarWinds.Orion.Core.BusinessLayer.dll. This is not about threat intelligence but more to understand from a technical prospective how an APT is able to evade detection for such a long time and mantain persistence. At the end i will share some links if you are interested and want to explore more. Sunburst is a trojanized version of a signed plugin named SolarWinds.Orion.Core.BusinessLayer.dll.
It was inserted into the software build of SolarWinds Orion products using another malware named SUNSPOT (more here) The backdoor was then distributed throught software updates and installers to all of the customersThe backdoor is a 32 bit signed dll wrote in .NET.
The fact that is signed by SolarWinds private key make this malware extremely more evasive and difficult to detect Sunburst code begin at OrionImprovementBusinessLayer.Initialize().
Here the hash of the string solarwinds.businesslayerhost.exe is being calculated and compared to the current process hash. This ensure thath the program is running in the right context. After that the method make a time check ensuring that sunburst is inside the system for at least 2 weeks, making the malware even more evasive under the radars of sandboxes trying to run it.
This method is called by a legitimate method in the program called RefreshInternal()
So basically whenever the dll will execute this normal routine the backdoor will be executed too in the background by another thread.
This is the hashing algorithm that will be always present from now on
Doing a reasearch online about the constants in the algorithm we can see its using FNV hash function All the reverse-enginereed hashes are available here
The program then continues calling OrionImprovementBusinessLayer.GetOrCreateUserID
This method has the purpose of creating an Unique ID of the machine. The UID is composed of:
- MAC address of the first network interface
- Domain name
- HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\MachineGuid
All of that is then passed to a MD5 hashing function. This function will be crucial for the DGA implemented inside the malware
At the end of the method another method OrionImprovementBusinessLayer.Update is called, this method contain the all logic of sunburst.
Enviroment check
At execution Sunburst goes trought an extensive list of known security process, drivers and services to ensure its not being executed inside a machine dedicated for analysis The method responsable for this is OrionImprovementBusinnesLayer.TrackProcess
OrionImprovementBusinnesLayer.ProcessTracker.SearchAssemblies compare all the running processes to a hardcoded list of hash of security related processes
Then Sunburst before initilazing the connection with the C2 check if the host api.solarwinds.com resolve to an expected IP address
The above encoded string is passed as the parameter hostName and decoded gave: api.solarwinds.com
Domain Generation Algorithm
A Domain Algorithm Generator is the capability for a malware to dynamically generate domain hostname on the fly. DGA has a lot of benefits, the major one is probabily the capacity to evade domain blacklisting
Talking about sunburst we can say that is not a real DGA beacouse the top level domain always remain the same (avsvmclod.com), this has a big downside, its possibile to make detection rule by simply doing something like: *.avsvmcloud.com
What standout with sunburst is how the domain prefixes were generated in an unique way.
This is an example of URL generated by sunburst and used for C2 comunications:
04jrge684mgk4eq8m8adfg7.appsync-api.us-east-2.avsvmcloud.comYou can find a list here
Starting with appsync-api.us-east-2.avsvmcloud.com
OrionImprovementBusinessLayer.GetStatus is responsable for concatenating the strings in the domain
domain1, domain2 and domain3 are hardcoded and defined as follow
domain3 can vary between the fours different strings
The backdoor has also the capability to generate a pseudo-random URI
Here a little snippet not the full method
As you can see all the URIs are hardcoded inside the code. Other generated URIs are:
- fonts/woff/
- swipt/upd/
- swip/Events/
- swip/Upload.ashx/
A new thread will be spawned and will run httpHelper.Initialize method used to comunicate with the C2
After this sunburst composes a JSON payload with informations about the infected host and sends it to the C2 server. the payload contains data such as UID and session ID
Another way used by Sunburst to blend it self inside the traffic is to modify the User-Agent of the requests. Depending on situation and the use case the user agent could have taken two different values:
- Microsoft-CryptoAPI/
- SolarWindsOrionImprovementClient/
This is especially useful to mimicize legitimate traffic, Microsoft-CryptoAPI was used at early stage of the attack inside the DNS queries. Starting the HTTP comunications the backdoor switch user-agent and start using SolarWindsOrionImprovementClient masquerading as OIP (Orion Improvement Program) protocol.
The anatomy of the operations was basically to use DNS at the early stage for listening and information gathering, once all the checks were done the comunications switched to HTTP and the backdoor start execute commands
Sunburst capabilities as a backdoor are very basic, inside the program are defined as jobs
Everything a normal backdoor would do like modify files, kill/run processes, upload stuff...
DNS hostname encoding
Inside 04jrge684mgk4eq8m8adfg7.appsync-api.us-east-2.avsvmcloud.com we have seen how sunburst concatenate .appsync-api and .us-east-2 subdomains but not how the random 04jrge684mgk4eq8m8adfg7 is generated
This is how the random string subdomain can be divided
| encoded_UID | + | char | + | encoded_domain |
One of the first method encountered was OrionImprovementBusinessLayer.GetOrCreateUserID, as we have seen it basically get a UID using current system configurations (domain name, reg key and MAC address of first available network interface). The UID returned from this function is encoded using CreateSecureString method throught OrionImprovementBusinessLayer.CryptoHelper.Base64Encode
The encoded string: K8gwSs1MyzfOMy0tSTfMskixNCksKkvKzTYoTswxN0sGAA= resolve to ph2eifo3n5utg1j8d94qrvbmk0sal76c
This value is then concatenated with a character generated by OrionImprovementBusinessLayer.CryptoHelper.CreateString.
Other methods responsible for the random subdomain generation are GetPreviusString, GetNextString, GetNextStringEx
The last part of the generated subdomain is the encoded domain name of the machine defined in OrionImprovementBusinessLayer.CryptoHelper.dnStrLower
The value of OrionImprovementBusinessLayer.CryptoHelper.dnStr is passed in the constructor of CryptoHelper class using OrionImprovementBusinessLayer.CryptoHelper.DecryptShort method
CryptoHelper class is then initializated as this
UserID is the previously generated ID and domain4 is the domain of the compromised machine
DecryptShort method first check if all the characters of the domain are part of this string: 0123456789abcdefghijklmnopqrstuvwxyz-_. If it is the case the domain will be encoded using OrionImprovementBusinessLayer.CryptoHelper.Base64Decode Otherwise will be prepended with "00" and encoded using OrionImprovementBusinessLayer.CryptoHelper.base64Encode
Conclusion
Thats all, you can find a python script for decoding the domains name generated with the DGA algorithm here
Links i used for researching
- https://vx-underground.org/Samples/Families/SolarwindsBreach --> samples
- https://www.techtarget.com/whatis/feature/SolarWinds-hack-explained-Everything-you-need-to-know
- https://www.cisa.gov/news-events/analysis-reports/ar21-105a
- https://cloud.google.com/blog/topics/threat-intelligence/evasive-attacker-leverages-solarwinds-supply-chain-compromises-with-sunburst-backdoor
- https://www.microsoft.com/en-us/security/blog/2020/12/18/analyzing-solorigate-the-compromised-dll-file-that-started-a-sophisticated-cyberattack-and-how-microsoft-defender-helps-protect/
- https://cloud.google.com/blog/topics/threat-intelligence/sunburst-additional-technical-details
- https://securelist.com/sunburst-connecting-the-dots-in-the-dns-requests/99862/
- https://mp.weixin.qq.com/s/v-ekPFtVNZG1W7vWjcuVug