StegBaus: Because Sometimes XOR Just Isn’t Enough

This past week, our team has identified a group of malware samples that matched behavioral heuristics for multiple known malware families. These samples all displayed their typical respective malware characteristics and contacted known command and control (C2) servers from those families. However, initial static analysis revealed that all of these samples appear to be identical on the surface, leading us to believe that we had discovered a new loader. The malware families identified at this time are DarkComet, LuminosityLink RAT, Pony, ImmenentMonitor, and some multiple variations of shellcode. We are calling the malicious loader StegBaus based on its use of custom steganography and a PDB string, which was found in an embedded DLL.

Because of the large number of infections that the aforementioned malware families have previously been involved in, any new loading techniques that could make it easier for an attacker to execute these malware families on a victim computer should be taken seriously and an attempt at identifying it pre-infection should be treated as a high-priority.

This loader is unique in numerous ways, most notably the steganography that is being used to hide the loader configuration, as well as the final payload. These features will be discussed in the analysis section below. The loader also uses common techniques, such as the RunPE method, to load final payload into memory as a new process. This method has been seen in the wild for a number of years and typically involves utilizing a host process, threading contexts, and memory allocation. Although these steps appear to be relatively static within the loader, there are slight differences we were able to identify based on the time of deployment. One such case is a sample that appears to have been used for testing at least 6 months before the majority of samples were seen in the wild.

UPDATE: The domains tags[.]bkrtx[.]com and sg[.]symcb[.]com were erroneously included in the list of domains below. On February 20, 2017, this blog post was updated to remove those domains from that list.

Distribution

The .NET executables with a code-base similar to the StegBaus loader were originally seen being tested in mid-2016 with much less obfuscation and the addition of testing phrases and strings. While hunting for related samples with the same characteristics, we were able to identify similar features in the KazyLoader .NET packer. KazyLoader provides a means for data hiding in BMP files and similar encryption schemes as well, and although these similarities exist, the increased sophistication in StegBaus and the limited visibility into the KazyLoader code-base makes linking these two families together very difficult.

The first known instance of StegBaus that Palo Alto Networks was able to identify was seen on December 30, 2016, with numerous samples being encountered since then. It should be noted that the malware families being distributed by StegBaus are all commodity malware and many of them have had their source-code leaked online in the past. This fact makes it difficult to determine if the author of StegBaus is generating his/her own custom samples, reusing samples found in the wild, or has a connection to the groups that use these malware families for criminal activities.

The most common filenames used to deliver StegBuas in the wild are:

image44.scr

barbiure.exe

image56.scr

image.scr

corben.exe

picture.scr

Netsparker.exe

The most common HTTP connection information is as follows:

Kimki[.]ru , POST , /chamber/panelnew/gate.php

kimki[.]ru, POST, /nelson/panelnew/gate.php

kimki[.]ru , POST , /emeka/panelnew/gate.php

oxylala[.]gdn , POST , /emeka/panelnew/gate.php

oxylala[.]gdn , POST , /charly/panelnew/gate.php

oxylala[.]gdn , POST , /asaba/panelnew/gate.php

oxylala[.]gdn , POST , /victor/panelnew/gate.php

oxylala[.]gdn , POST , /mandela/panelnew/gate.php

oxylala[.]gdn , POST , /asaba/panelnew/gate.php

minecon[.]co, POST, /Panel/gate.php

informer.pe[.]hu , POST , /Server/

The most common DNS queries are the following:

custom[.]generatione[.]tech

goodluckjayjay[.]duckdns[.]org

slyopeznetwr[.]ddns[.]net

11live[.]zapto[.]org

goodluckyugo[.]duckdns[.]org

akudon[.]chickenkiller[.]com

informer[.]pe[.]hu

files[.]catbox[.]moe

minecon[.]co

kimki[.]ru

oxylala[.]gdn

Analysis

StegBaus is originally distributed in a .NET-compiled executable that uses Confuser v1.9.0.0 obfuscation. Initial static analysis of the sample reveals multiple portable network graphics (PNG) image files that are embedded as .NET resources. These can be seen in the figure below.

Figure 1 PNG resource files

Upon execution, StegBaus loads a new DLL into its memory space and execution is transferred to the DLL’s main function, which in later samples has been renamed to a singular letter (A, K, or Q). This DLL is completely deobfuscated and its internal name was found to be A.dll in each variation that we analyzed. The functions contain no obfuscation and can be clearly read, as shown in Figure 2.

Figure 2 Function list

As can be seen from the function list above, StegBaus contains a number of functions that appear to do relatively simple things. After analysis of these functions, it is clear that the functions actually do exactly what their names suggest. Full anlaysis of each of these functions will not be provided, but some of the most interesting ones will be discussed throughout the explanation of the data hiding techniques.

After analyzing the original, heavily obfuscated, executable and finding the embedded resources, we chose to investigate this DLL for any resources as well. It turns out that the author used this resource section to embed numerous blobs of base64-encoded data as seen below in Figure 3.

Figure 3 Embedded base64-encoding

The resources seen in Figure 3 both contain base64-encoded data, which each decode into a separate DLL. These DLLs are named img2data.dll and CreateShortct.dll respectively. The CreateShortct.dll file is used to locate the current users Startup folder and creates a shortcut to the original executable using a random 8 character name. The img2data.dll, however, is a little more interesting and will be discussed in the Data Hiding section.

The CreateShortct.dll contains the following PDB string that was used in naming the malware:

Data Hiding

The img2data.dll file contains custom functionality to convert images into a data stream by using numerous libraries included in the .NET Framework. The actual code for the function can be seen below:

Figure 4 ImagesToData function

The reimplementation of this code is provided here and can be compiled as C# in Visual Studio by adding a library reference to System.Drawing. The provided decoder will take a directory name that contains all of the PNG resource files with their original names and provide a binary output file that can be used to continue analysis.

The img2data.dll is utilized by the ConvertImagesToData function in A.dll. This function simply loads the DLL into memory via .NET module loading techniques and creates a buffer for data storage. Essentially, the img2data.dll will locate the resources in the original executable and read all of the raw bytes into a memory stream before being manipulated. After this data has been converted into a usable data stream and stored in the global buffer, it is then decrypted multiple times, as discussed below.

Encryption

Although data hiding with steganography is unusual, it is an extremely effective means of concealing information, the malware authors found it necessary to also use AES encryption. Specifically, the RinjndaelManaged function that belongs to System.Security.Cryptography is used to decrypt data using AES-128.

While debugging the malware and stepping through the crypto routines, we can easily identify the initial password that is used to generate the key and initialization vector (IV) for the AES routine. The password is gathered by identifying the timestamp from the STARTUP_INFORMATION structure of the original executable and this value is then run through a sequence of arithmetic operations. This information is then used to create a new GUID, which in turn is truncated to 8 characters, and then used as the password. The password for the sample analyzed is “d1ee1095”, which is easily identifiable during debugging and execution. This value is then run through the Password-Based Key Derivation Function 2 (PBKDF2) and we can hex-encode this result for both a 32-byte and 16-byte value. The return value for the 32-byte value is the key and the 16-byte value is the IV.

Once the key and iv are produced, the decryption proceeds by using AES with CBC. The following script can be used to decrypt the data once the password has been identified:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

from PBKDF2 import PBKDF2

from Crypto import Random

from Crypto.Cipher import AES

import sys,binascii

with open(sys.argv[1],mode='rb')asfile:

data=file.read()

password=sys.argv[2]

p=pbkdf2.PBKDF2(password,password[:8])

key=binascii.hexlify(p.read(32))

iv=binascii.hexlify(p.read(16))

mode=AES.MODE_CBC

e=AES.new(key,mode,iv)

f=open('outputDecrypted.bin',"wb")

f.write(e.decrypt(data))

f.close()

After decrypting the data, the results are not as we expected…there is no human readable data. This leads us to further debugging to identify any other techniques being used. In this case, the authors decided that using steganography and AES encryption wasn’t enough they had to encrypt the data twice using the same AES implementation. Using the same script as above and the decimal representation of the previously returned timestamp, “1484648550”, we are able to determine the key and IV for the second iteration of decryption. This time we are provided with what appears to be a human readable configuration file, which contains the following data:

Emulation

Install

Notify

Options.Compress

Options.CheckVM

Options.CheckSandbox

Options.DelayTime

Options.MonitorPackage

Options.MonitorRegistry

Options.MonitorSelf

Options.HostIndex

Options.UACBypass

Files.Main

Files.Count

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

000000001c0c09456d756c6174696f6e00010c07|...Emulation....|

00000010496e7374616c6c00000c064e6f746966|Install....Notif|

000000207900000c104f7074696f6e732e436f6d|y....Options.Com|

00000030707265737300010c0f4f7074696f6e73|press....Options|

000000402e436865636b564d00000c144f707469|.CheckVM....Opti|

000000506f6e732e436865636b53616e64626f78|ons.CheckSandbox|

0000006000000c114f7074696f6e732e44656c61|....Options.Dela|

000000707954696d6507000000000c164f707469|yTime.......Opti|

000000806f6e732e4d6f6e69746f725061636b61|ons.MonitorPacka|

00000090676500000c174f7074696f6e732e4d6f|ge....Options.Mo|

000000a06e69746f72526567697374727900000c|nitorRegistry...|

000000b0134f7074696f6e732e4d6f6e69746f72|.Options.Monitor|

000000c053656c6600000c114f7074696f6e732e|Self....Options.|

000000d0486f7374496e64657807000000000c0a|HostIndex.......|

000000e046696c65732e4d61696e02fa dc010000|Files.Main......|

[TRUNCATED]

0001dde0fc e8 f9 d1 f3 b3 f5 fc3f0c0b46696c6573|........?..Files|

0001ddf02e436f756e7407000000000c114f7074|.Count.......Opt|

0001de00696f6e732e5541434279706173730000|ions.UACBypass..|

0001de1010101010101010101010101010101010|................|

0001de209b35e828ca4ced be43380e85ec f4 ac12|.5.(.L..C8......|

Finally, after the aforementioned decryption is finished, the StegBaus configuration options become visible as we see in the figure below. These options dictate which additional functions are going to be called in A.dll. As shown before, there are a number of additional functions, but they are not used unless the configuration has the options enabled. Along with the configuration options, the decrypted data also contains the final payload and is represented in two different forms in the samples we analyzed.

Figure 5 Decrypted data forms (plaintext vs. zlib)

As seen in the figure above, the two different data representations in the decrypted data buffer are plaintext and a zlib-compressed data blob. In some of the first samples identified, the decryption stage mentioned above is actually the final stage of data hiding and this executable is then loaded into memory via the RunPE method. The newest samples analyzed utilize zlib compression to further hide the final payload within the decrypted data buffer. The decompression is completed in the Decompress function, which can be seen in Figure 2 as part of A.dll. When the final payload is decompressed, it is loaded into memory as a new process via the RunPE method as well.

Conclusion

The StegBaus loader that was identified contains many advanced data hiding techniques and has been seen delivering numerous different commodity malware families.

Currently, the loader itself is being identified as malware by WildFire and can be seen in Autofocus as well. Palo Alto Networks is detecting this malicious loader via behavioral identifiers and is also identifying the malware families being delivered by these measures.

I would like to thank threat analyst Brandon Levene for bringing this unique malware family to my attention. The characteristics identified within the analyzed samples led to the discovery of more than 250 samples utilizing the StegBaus loader, all of which were identified as malware in WildFire.