Downloaders and droppers (aka malware that delivers other malware) have been forced to live in the shadow of more famous stages of the exploit kit chain, like landing pages or the malware that's eventually dropped. One reason they are often overlooked and not analyzed as often is because they typically (and conveniently) wipe themselves from compromised hosts once they completely deliver their malicious payload.
But don't mistake the lack of attention for lack of importance. Downloaders and droppers play a vital role in the web exploitation ecosystem. They're often used across multiple exploit kits and they are effective at delivering a broad menu of malware including ransomware, banking trojans, credential stealers etc.
SmokeLoader is an older downloader that continues to be actively developed and utilized to deliver other malware. Fidelis Threat Research observed a SmokeLoader sample delivered through the Sundown Exploit Kit. We're sharing our findings with the security community to keep them updated on this evolving threat.
This blog post covers four key points:
- The delivery method we've observed using SmokeLoader and the delivery method that we used to track this and other threats.
- An overview of the crypter that continues to be actively used.
- The process a malware researcher could use to investigate a similar sample, including string decryption and C&C (command and control) traffic decryption.
- Overview of IOCs that an be used to detect SmokeLoader.
This SmokeLoader sample was delivered from the Sundown Exploit Kit. This sample has been consistently delivered by this exploit kit as noted by researchers at Malwarebytes in late 2016.
A number of chains related to the Sundown Exploit Kit have been analyzed after it began including CVE-2016-0189, coupled with either their own or an affiliate's consistent usage of SmokeLoader. Then in January 2017 we began tracking what appeared to be two distinct instances of Sundown traffic similar to what we saw in the Malwarebytes post.
One exploit kit thread using minimal obfuscation was delivered through malvertising campaigns and pretended to be affiliated with EmpowerNetwork, a popular blogging and webhosting platform. While the EmpowerNetwork thread was largely in the clear with minimal obfuscation, the second exploit kit thread had an obfuscated landing page and favored .mobi registered domains for a period of time during our observation. Both threads delivered SmokeLoader, which in turn downloaded a diverse range of malware.
The crypter is one that has been showing up recently using NSIS with an encrypted payload. The crypter normally works in three stages.
- A DLL is called that will set up proper memory permissions.
- The code will decode out the function names that will be used and find the next code to run, which is typically also in a DLL.
- This next DLL will then be used to decode the encoded payload. Following this, the first DLL will load the next stage DLL, which will then take over reading the encoded payload. In this case, it included the encoded payload and all the needed encoded function names.
After decoding the function names and allocating memory with VirtualAlloc, the crypter decodes a small section of bytecode that basically performs a sleep by looping 0x18f06 * 0x1644a times. As analysis continued, we found many instances of useless code such as this one. After decoding out the payload, the malware is injected into a new process of itself. Then the current thread is hijacked using GetThreadContext/SetThreadContext before finally resuming the program. There are a variety of methods for breaking into a child process. In this example, the entry pointer was overwritten with custom code to gain control of execution.
After breaking in with the debugger, the bytes can be easily changed back to their original version.
After the new unpacked code is run, the bot begins XORing sections of its code, leading to a few debugger checks almost immediately after. The bot takes the isbeingdebugged flag and uses it to XOR a byte of its next code section -- so if it is being debugged then the bot will break.
The same check is then performed using the NtGlobalFlag:
Upon successfully passing these checks, the bot decodes a large section of itself, which is then decompressed using APLIB. Once this section is decompressed, the final stage of the bot is revealed.
The final stage has two noticeable sections of encoded data. Both RC4 encrypted sections are decrypted using a hardcoded 4 byte key that is passed to the routines (“zVsO”).
This next stage, ultimately, has two paths that it can take. The first performs a bunch of system checks looking to see if it’s being analyzed or running in a virtual environment before injecting itself into a new explorer.exe process. The second is intended to be run after it has been injected into Explorer. This is where the malware performs the following tasks:
- Harvests system information, such as version
- Creates a hash based on computer name and other data
- Checks for system connectivity using an onboard URL (for example, bing.com)
- Constructs and encrypts the data to be POSTed to the C2 (command and control)
As previously mentioned, the strings are obfuscating using a 4 byte key. They are then split using a separator value, which in this case was ‘\x01’. The bot has a routine designed to pass any number in the block of decoded strings that it wants to be used for decoding.
This routine is only called twice, and does so with different blocks of data. This means there are two blocks of strings to be decoded.
Here is the address and size being passed in to the string decryption routine.
At first glance, it seems this information is used to write a string decoder, but after checking the results, the URLs are not decoded. A little digging and pivoting off referenced addresses (found near the two blocks of data) result in the discovery of another decoding routine.
A quick overview of this additional routine shows that each block of encoded data is prepended with a crc32 hash that is checked against the decoded data.
The decoding routine looks confusing at first, but by taking small pieces and verifying that the decoded data is the same as the data in the bot, the decoding function can be understood quickly:
We know that the first 4 bytes are the CRC32 hash, but glancing at the code shows that the beginning of the data block addressis used to XOR each byte pulled out of the other register. We can see that the first byte of the CRC32 hash is used as an XOR key against every two bytes independently, followed by a subtraction of the output of that calculation.
A python script for use in IDA to decode out the URLs in the sample is included in this report.
Command and Control (C2)
This variant of SmokeLoader performs a POST containing RC4 encrypted data to one of its C2 URLs that it keeps onboard.
As long as a response is received after the POST (even a 404), then the data will attempt to be read. As can be seen in the figure above, the 4 byte RC4 key is generated using the rdtsc command. After encrypting the data, the 4 byte key is loaded onto the front of the encrypted data. Decryption then becomes straightforward:
key = posted_data[:4]
rc4 = ARC4.new(key)
decoded_data = rc4.decrypt(posted_data[4:])
Downloaders and other delivery systems seek to obscure their payloads using a variety of techniques. This post explored techniques used by SmokeLoader, a downloader currently deployed via Sundown Exploit Kit, to confuse analysts and deter detection. In our estimation, these techniques will be observed with greater frequency in the coming years, which calls out the need for more thorough detection capabilities across the entire chain of events at multiple levels.
Fidelis customers are protected from SmokeLoader and Sundown Exploit Kit by a variety of mechanisms designed to detect malware throughout the infection chain. Learn more at www.fidelissecurity.com.
-- Fidelis Threat Team Researcher Jason Reaves