Threat Analysis Unit

VMware Carbon Black TAU Threat Analysis: The Evolution of Lazarus

On February 14, 2020 the U.S. Department of Homeland Security (DHS) released a Malware Analysis Report (MAR-10271944-1.v1) which provided information about a trojan they referred to as HotCroissant. DHS attributed the trojan to a threat group based in North Korea, often referred to as Hidden Cobra. This group, also known as the Lazarus Group, continues to be very active. Over the previous year they’ve targeted organizations in South Korea, Russia, and the United States with motives that range from espionage and sabotage to attacks purely for financial gain. At first glance HotCroissant might appear as a new tool in the Lazarus Group’s tool box but as we’ll see it holds many similarities to an earlier trojan they’ve used before.

HotCroissant

Overview

The HotCroissant trojan is a fairly straightforward remote access trojan (RAT). On startup, it decodes the address of its C2 server and then attempts to connect to it. If it is successful then it will send out basic host information to the C2 and await further commands. The HotCroissant sample shared in the DHS Malware Analysis Report had a compilation timestamp of 2019-07-25 15:38:54. During this research we were able to find samples with compilation timestamps dating back to 2018-10-26 15:38:22 as well as a newer sample with a compilation timestamp of 2019-07-29 07:08:01.

HotCroissant samples with a compilation timestamp older than the one listed in the DHS report are all almost identical. The main difference in samples is the C2 server IP address. There are a few interesting differences that are worth mentioning. One of the samples appeared to have the basic string obfuscation disabled and in turn the C2 server IP address is easily identifiable. Another of the samples had a C2 server IP address in the reserved private IP address range along with a few additional debug messages. This appears to be a testing version of the trojan.

The most recent HotCroissant sample found, while almost functionally equivalent to the DHS sample, is far more obfuscated. First, the sample is UPX packed. Next, in addition to the basic string obfuscation of earlier samples, this newer sample has a second string obfuscation technique used. Some of the strings are RC4 encrypted with the key ANONYBR and then base64 encoded. FInally, the newest sample uses dynamic API lookups to attempt to make static disassembly harder to understand. The most recent sample does have some new functionality as well. When the trojan starts up it will attempt to install a scheduled task with the name of “Java Maintenance64” to keep itself running. There are also a handful of new C2 commands not seen in earlier versions.

C2 protocol

The C2 protocol is fairly robust. Requests from the C2 server and responses from the trojan make use of a specific command format as seen below:

type Command struct {

    Opcode uint32

    TxnID  int32

    Opt1   int32

    Opt2   int32

    Size   uint32

    Data   []byte

}

The Opcode field indicates the action the C2 server is requesting or information the trojan is sending back to the C2. TxnID is a transaction number sent from the C2 server that is echoed back in some responses from the trojan. Opt1 and Opt2 get used in commands as additional parameters. The Size field indicates how many bytes are expected in the Data field. The Data field is used for string parameters for the commands to be executed.

The entire command structure gets compressed with zlib and then encrypted using a custom stream cipher. This encoded information then gets an additional header added and sent across the network. The encoded structure can be seen below:

type EncodedCommand struct {

    Size        uint32

    DecodedSize uint32

    Data        []byte

}

A full list of Opcodes and command descriptions can be found at the end of this document.

Rifdoor

Overview

According to an AhnLab report, Rifdoor dates back to a 2015 attack on exhibitors in the Seoul International Aerospace & Defense Exhibition (ADEX). It was sent to exhibitors in an email with an Excel or Word document containing macros, pretending to be from the organizer of the event. This trojan continued to be seen in attacks well into 2016.

Rifdoor is another basic remote access trojan. On first launch the trojan will make a copy of itself, adding four additional bytes to the end of the file. This changed version is then saved as C:\ProgramData\Initech\Initech.exe. A new registry entry is created at HKEY_CURRENT_USERS\Software\Microsoft\Windows\CurrentVersion\Run\Graphics with a value of “C:\ProgramData\Initech\Initech.exe” /run. When the trojan is launched with the /run flag it will decode its C2 server IP address and attempt to connect to it. If it is successful then it will send out basic host information and await further commands.

C2 protocol

The C2 protocol is a string based request and response type. Commands like “$exec <filename>” are sent to the trojan and the trojan sends back responses. The requests sent over the network have some additional header information included as seen in the structure below:

type Command struct {

    Opcode   uint32

    Checksum int32

    TxnID    int32

    Size     uint32

    Data     []byte

}

The Opcode field indicates the type of request. The Checksum is calculated based on host system information. TxnID is a transaction number sent from the C2 server that is echoed back in some responses from the trojan. The Size field indicates how many bytes are expected in the Data field. The Data field contains the string commands or the responses. The Data field is encrypted using a custom stream cipher.

A full list of commands can be found at the end of this document.

Similarities

Even though the Rifdoor and HotCroissant campaigns are separated by more than two years there are numerous similarities in the code of the two trojans.

String obfuscation

As mentioned previously, both HotCroissant and Rifdoor have a form of basic string obfuscation. If we take a look at when the trojans decode their C2 server IP addresses we can see that they both use the same technique, a simple one byte XOR with the value 0xF.

Figure 1: HotCroissant string decoding

Figure 2: Rifdoor string decoding

Host information collection

After decoding their C2 server IP addresses, from obfuscated strings, both trojans will attempt to collect host information and send it to the C2 server. The trojans do not collect identical host information. However, as can be seen in the functions collecting the Windows product name below, some functions are almost identical, including the use of the same obfuscated strings.

Figure 3: HotCroissant product name collection

Figure 4: Rifdoor product name collection

Network sockets

Every application using sockets for network communication will have similar API calls in order to connect to a server. What is interesting about the socket code below is that we see both trojans setting the same socket options. Both call setsockopt to enable SO_KEEPALIVE and then call WSAIoctl to set the keep alive time and interval to the same values of 180000 and 5000 respectively.

Figure 5: HotCroissant server connect

Figure 6: Rifdoor server connect

Network data encryption

Both trojans encrypt the data that they send to the C2 servers. While the encryption is not identical, they do have similarities. Both encryption algorithms are, at their core, a stream cipher. Seed values are used to generate a keystream the same length as the data to be encrypted. This keystream is then XOR’ed with the data. Both algorithms make use of 3 different 32-bit seed values for the keystream. The difference lies only with how the keystream is derived.

Figure 7: HotCroissant stream cipher

Figure 8: Rifdoor stream cipher

C2 protocol

While the commands that each trojan understands are different there are some similarities in the C2 protocol that are worth mentioning. Both protocols make use of a 32-bit Opcode field to identify what type of request should be processed. In the case of Rifdoor there is only a very limited number of opcodes. Both trojans also support a TxnID field. This field is included in requests and will be echoed back to the C2 server in responses. This appears to be a way for the C2 server to keep track of requests and responses.

Conclusion

Whether HotCroissant and Rifdoor are truly the same malware family or not is hard to say with certainty. It is safe to say that they both share sections of code as well as similarities in their network protocol. More importantly, HotCroissant shows a clear evolution of the sophistication of the Lazarus Group’s toolset. With Rifdoor we saw a basic trojan that supported three or four different commands. With HotCroissant there are over twenty different commands that the trojan understands, including more sophisticated ones like real time screen viewing. With the most recent HotCroissant sample we see the Lazarus Group working to make detection more complicated by using additional obfuscation, dynamic API usage and packers. One thing is certain, they show no signs of slowing down, and we will continue to monitor their activity to provide insight and information to our customers.

MITRE ATT&CK TIDs

TID Tactic Description
T1140 Defense Evasion Deobfuscate/Decode Files or Information
T1082 Discovery System Information Discovery
T1033 Discovery System Owner/User Discovery
T1005 Collection Data from Local System
T1113 Collection Screen Capture
T1059 Execution Command-Line Interface
T1094 Command And Control Custom Command and Control Protocol
T1024 Command And Control Custom Cryptographic Protocol
T1132 Command And Control Data Encoding
T1065 Command And Control Uncommonly Used Port

 

Indicators of Compromise (IOCs)

Indicator Type Context
a9915977c810fb2d61be8ff9d177de4d10bd3b24bdcbb3bb8ab73bcfdc501995 SHA256 Rifdoor 32-bit executable
57d1df9f6c079e67e883a25cfbb124d33812b5fcdb6288977c4b8ebc1c3350de SHA256 Rifdoor 32-bit executable
0a0c09f81a3fac2af99fab077e8c81a6674adc190a1077b04e2956f1968aeff3 SHA256 Rifdoor 32-bit executable
c9455e218220e81670ddd3c534011a68863ca9e09ab8215cc72da543ca910b81 SHA256 Rifdoor 32-bit executable
192.99.223.115 TCP/80

TCP/443

Rifdoor C2
165.194.123.67 TCP/8008 Rifdoor C2
111.68.7.74 TCP/443 Rifdoor C2
7ec13c5258e4b3455f2e8af1c55ac74de6195b837235b58bc32f95dd6f25370c SHA256 HotCroissant 32-bit executable
0ea57d676fe7bb7f75387becffffbd7e6037151e581389d5b864270b296bb765 SHA256 HotCroissant 32-bit executable
b689815a0c97414e0bba0f6cf72029691c8254041e105ed69f6f921d49e88a4d SHA256 HotCroissant 32-bit executable
8ee7da59f68c691c9eca1ac70ff03155ed07808c7a66dee49886b51a59e00085 SHA256 HotCroissant 32-bit executable
315c06bd8c75f99722fd014b4fb4bd8934049cde09afead9b46bddf4cdd63171 SHA256 HotCroissant 32-bit executable
172.93.110.85 TCP/80 HotCroissant C2
176.31.15.195 TCP/8445 HotCroissant C2
94.177.123.138 TCP/8088 HotCroissant C2
51.254.60.208 TCP/443 HotCroissant C2

 

Rifdoor C2 Commands

Opcode Name Description
0x9e2 Beacon Sent when Rifdoor starts up. The command data contains basic host information like IP Address, User Name and Windows version.
0x4e3a CommandRequest The request data is text based with spaces separating specific commands and arguments. The following keywords are understood:

 

$interval <minutes>

 

$download <url> <filename>

 

$exec <filename>

 

$downloadexec <url> <filename>

 

By default if the command data doesn’t start with any of the previous keywords then the string will simply be sent to a command prompt for execution.

0xa021 CommandResponse The response data is also text based. Response strings are usually surrounded with carriage return and line feeds.
0x1055 EndRequest Indicates that the client or server is done sending requests or responses.

 

HotCroissant C2 Commands

Opcode Name Description
0x7c5 ShutdownNow Immediately calls exit() (Only seen in sample b689815a0c97414e0bba0f6cf72029691c8254041e105ed69f6f921d49e88a4d)
0x7c7 KeepAlive Prevents connection from closing due to time out.
0x7c8 Beacon Send victim host information to the C2 server. This is sent on the first connection to the C2 server.
0x7d2 ProcessList Retrieve a list of running processes.
0x7d3 ProcessKill Kill a process on the victim machine. The Data value is the process name to terminate.
0x7d4 WindowList List names of all open windows.
0x7d7 WindowClose Close an open window. The Data value is the window name to close. Note: WindowList must be called first in order for this to work.
0x7da DriveList Retrieve a list of drives and what type of drive they are.
0x7dc DirectoryList Retrieve a list of files in a given directory. The Data value is the directory.
0x7de FileCopy Copy a file. The Data value specifies the source and destination separated by a ‘|’.
0x7e0 FileDelete Delete a file. The Data value specifies the file to delete.
0x7e2 FileMove Move a file. The Data value specifies the source and destination separated by a ‘|’
0x7e4 TransferData After initiating a download or upload, file data is transferred in the Data field in 0x3A70 sized chunks.
0x7e5 TransferComplete Sent after all file data has been sent.
0x7e6 DownloadFile Start the download of a file from the victim machine to the C2 server. The Data value contains two strings separated by a ‘|’ character. The first string is a job name and the second string is the file to download.
0x7e7 DownloadStatus Sent after a download is initiated and after each chunk of data. The Data value contains text providing the status of the download. For example: “0 Bytes / 79760 Bytes”.
0x7e8 FileFind Recursively search a directory. The Data value contains two strings separated by a ‘|’ character. The first string is the search string. The second string is the directory to search.
0x7ea Execute Use ShellExecuteA to open an application. Opt1 indicates if the window should be hidden or not. Data contains the file to execute.
0x7ed UploadFile Start the upload of a file from the C2 server to the victim machine. A 0x7ed response is sent back to the C2 server with Opt1 indicating the file handle to use in the following TransferData and TransferComplete requests.
0x7ee DownloadDirectory Download all the files in a given directory. The Data value indicates the directory to download.
0x7ef DownloadDirectoryComplete Sent from the victim machine to the C2 after each file in a directory has been transferred.
0x7f0 DownloadFileOffset Used to resume downloading a file from a specific offset. Opt1 is the file handle and Opt2 is the file offset. (Only seen in sample 315c06bd8c75f99722fd014b4fb4bd8934049cde09afead9b46bddf4cdd63171)
0x802 ScreenCaptureStart Start capturing the victim machine’s screen. A 0x802 response is sent back containing BITMAPINFO indicating the dimensions and color of the screen.
0x803 ScreenCaptureData Victim machine sends the initial screen capture image back in 0x3a70 chunks to the C2 server.
0x804 ScreenCaptureStop Stop capturing the victim machine’s screen.
0x805 ScreenCaptureDataUpdate Victim machine sends screen capture updates back to the C2 server.
0x820 ServiceList Retrieve a list of services.
0x821 ServiceStart Start a service. The Data value is the service name to start.
0x822 ServiceStop Stop a service. The Data value is the service name to start.
0xbc2 AppList Retrieve a list of apps from the “SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths” registry key.
0xfa1 CmdShellStart Start a cmd shell on the victim machine.
0xfa2 CmdShellData The Data value contains the string to execute in the started cmd shell. A 0xfa2 response is sent back with the output.
0xfa3 CmdShellStop Stop the cmd shell running on the victim machine.
0x1389 Uninstall Attempts to clean up any installed files and then delete itself from the victim’s machine. (Only seen in sample 315c06bd8c75f99722fd014b4fb4bd8934049cde09afead9b46bddf4cdd63171)
0x138a Shutdown Sets a flag instructing the malware to gracefully shut down. (Only seen in sample 315c06bd8c75f99722fd014b4fb4bd8934049cde09afead9b46bddf4cdd63171)
0x138b DownloadStop Stop the download of a given file. Opt2 has to be set on the initial download request and then this command can be sent to stop the download. (Only seen in sample 315c06bd8c75f99722fd014b4fb4bd8934049cde09afead9b46bddf4cdd63171)

 

Yara Rule

rule lazarus_hotcroissant_2020_Q1 : TAU APT Lazarus

{

    meta:

        author = “CarbonBlack Threat Research” // sknight

        date = “2020-Mar-25”

        Validity = 10

        severity = 10

        Jira = “TR-4456”

        TID = “T1140, T1082, T1033, T1005, T1113, T1094, T1024, T1132, T1065”

        description = “Lazarus HotCroissant backdoor”

        link = “https://www.us-cert.gov/ncas/analysis-reports/ar20-045d”

        rule_version = 1

        yara_version = “3.11.0”

        Confidence = “Prod”

        Priority = “Medium”

        TLP = “White”

        exemplar_hashes = “8ee7da59f68c691c9eca1ac70ff03155ed07808c7a66dee49886b51a59e00085, 7ec13c5258e4b3455f2e8af1c55ac74de6195b837235b58bc32f95dd6f25370c”

 

    strings:

        // Crypto keys

        $b1 = { 8b d6 b8 00 [1-6] 17 [1-6] 29 70 49 02 }

 

        // Crypto algorithm

        $b2 = { 8A 1C 3E 32 DA 32 D8 32 D9 88 1C 3E 8A D8 32 D9 22 DA 8B 55 FC 8D 3C D5 00 00 00 00 33 FA 81 E7 F8 07 00 00 C1 E7 14 C1 EA 08 0B D7 8D 3C 00 33 F8 22 C8 C1 E7 04 33 F8 32 CB 8B D8 83 E7 80 C1 E3 07 33 FB C1 E7 11 C1 E8 08 }

 

    condition:

        uint16(0) == 0x5A4D and 

        uint32(uint32(0x3C)) == 0x00004550 and

        filesize < 200KB and

        any of ($b*)

}