The odd case of a Gh0stRAT variant

March 25, 2019  |  James Quinn

This is a guest post by independent security researcher James Quinn. This will be Part 1 of a series titled Reversing Gh0stRAT Variants. 

As 2018 drew to a close and 2019 took over, I began to see a different behavior from SMB malware authors.  Instead of massive, multi-staged cryptocurrency miners, I began to see more small, covert RATs serving as partial stage1’s.  Of these samples, there was one specific sample that stood out to me.  A Gh0stRAT variant, this sample not only changed the Gh0stRAT header from “Gh0st” to “nbLGX”, it also hid its traffic with an encryption algorithm over the entire TCP segment, in addition to the standard Zlib compression on the Gh0stRAT data.  Some key functionality is below:

  • Can download more malware

  • Offline Keylogger

  • Cleans Event logs.

[Screenshot 1] Encrypted Login Packet sent by Gh0stRAT infected PC

In addition to a standard malware analysis blog post, I’d also like to take this time to document and describe my methods for analysis, in the hopes that you as a reader will use these techniques in the future.

Malware Analysis

Before we begin the analyses, I’d like to clarify on some of the terms used.

Stage1 - Typically the first contact or entry point for malware.  This is the first part of the malware to arrive on a system.

SMB Malware - Any malware that uses the SMB protocol to spread.  SMB is typically used for file sharing between printers and other computers, however in recent years malware authors have been able to leverage this protocol to remotely infect hosts.

RAT - Remote Access Trojan.  This type of malware allows for the complete control of an infected computer.

Gh0stRAT - An open source RAT used primarily by Chinese actors. A more detailed analysis of the standard Gh0stRAT can be found here.

Despite being a Gh0stRAT sample, this variant is very different than your standard Gh0stRAT sample.  One of the most noticeable differences is the use of encryption over the entire TCP segment, as a way for it to evade detection.  Additionally, this seems to be a lightweight version of Gh0stRAT, as it only has 12 commands, compared to the 73 for a full Gh0stRAT sample; 3 of those commands are undocumented.  Also, unlike most samples that I receive on my honeypot, this sample did not start as a DLL that communicates to a distribution server in order to download the stage1.  Instead, dropped on my honeypot was a full exe that served as the dropper.

Domains

  • http://mdzz2019.noip[.]cn:19931
  • http://mdzz2019.noip[.]cn:3654/

From my analyses, I was able to identify http://mdzz2019.noip[.]cn:19931 as its main C2 url.  This is a dynamic DNS, meaning the actual IP changes quite frequently. Additionally, on that same url, http://mdzz2019.noip[.]cn:3654/ is used to distribute more versions of this Gh0stRAT sample, along with a .zip file containing ASPXSpy, a web shell.

Exploits

These 2 exploits are EternalBlue/Doublepulsar and are used to drop the Stage1 Dropper onto a system. 

Installation

The Gh0stRAT dropper arrives on a PC through the use of EternalBlue/DoublePulsar.  Once on a victim’s PC, the dropper executable is launched and it decrypts and loads the Gh0stRAT DLL into memory.  It then passes the config buffer to the extracted DLL and calls the exported function (Shellex)

[Screenshot 2] The mainthread of the code.  Note the call at the bottom that calls Shellex

Gh0stRAT dll functionality

An important note:  In its base state, this sample is damaged, therefore it will not install its services properly.  However, as the service information is included, I will list it anyways.  Additionally, samples downloaded from its distribution server DO install correctly,  and are downloaded during the base dll’s runtime.

Once Shellex is called, it first passes each of the items in the config buffer to their own strings.  Next, it creates a mutex using the filename and checks to see if the Service key for the service name exists.  If so, it opens it using service manager.  If not, it first saves a copy of itself to %Program Files (x86)%/DIFXE/svchost.exe.  Next, it creates the service and runs it. 

Once the service is running, it creates a new mutex using [C2URL]:[PORT] and connects to the C2 server.  It then sends the Implant_Heartbeat opcode, and then calls its payload function to grab

  • Version Information (x86 and x64)
  • Host information
  • SystemInfo
  • Processor Count and Write Speed
  • Global Memory Status

before formatting it, altering the InstallTime subkey, and sending all of the information back to its C2 in the Implant_Login buffer.

Techniques for Analysis

When I was analyzing this sample, the malware was unable to connect to its C2.  However, I was still able to analyze the network traffic of the sample.  How, you might ask?  Using a hex editor and a script I wrote to encrypt text using the algorithm that this sample uses, I encrypted my own C2 address (192.168.1.108:7721) and replaced the hardcoded C2 address with my own encrypted address.  I then opened a listener on my own IP on the respective port. 

 

[Screenshot 3] comparison of My IP (Left) vs C2 IP (Right)

Next, using a debugger, I set a couple breakpoints in the Internet Communications function and ran the malware.  The malware sample then connected to my IP and sent information to me, which I was able to observe using Wireshark. 

After I’d captured the traffic, I was able to write another script to decrypt and decompress the traffic in order to view the data being sent. 

Additionally, I then wrote a socket script that detects the Gh0stRAT variant traffic, automatically decrypts the traffic, and then extracts the Implant_Opcodes for the sample.  A second version of the script allows commands to be sent back to the malware, after I enumerated the exact command format for the sample. 

[Screenshot 4] Output of Version 1 of the script

So far, the 2 opcodes that the sample has sent are 0x65 and 0x66, or Implant_Heartbeat and Implant_Login, respectively. 

“Hitting between the heartbeats”

When sending commands, first the sample must login in with 0x65, then you can send commands to it.  However, you have to move fast as the sample will send an Implant_Heartbeat followed by an Implant_Login every 10 seconds or so, and if you try to send a command to the sample as it is responding with either opcode, it will ignore the command. 

A proof of concept of the command script can be found here , while the Implant extraction script and the Command Script will be included in the Appendix.

Network Traffic Format

During my analysis of the sample,  I was able to enumerate not only the opcode commands, but also the format of the proprietary protocol, allowing me to send my own commands to the sample. 

First, just like the Gh0st in the dshell paper from SANS, the decrypted protocol consists of a 5 byte header (ngLGX), a 4byte packet length field, and finally another 4 byte uncompressed length field.  This is where the similarity ends as the Opcode and the data are compressed using ZLib, instead of just the data.  Additionally, the entire packet is encrypted with an algorithm making visual analysis of the Wireshark data challenging.  However, as the packet header is static, you can use the encrypted header as an identifier, like I did in my script.  The encrypted header is: “\xEA\xEE\xCC\xD3\xB8” and is unchanged throughout the malware’s runthrough.

Available Opcodes

As this sample is more of a lightweight version of Gh0stRAT, it only uses 12 commands, which are below along with their corresponding opcodes.

Opcode

Function Number

Name

0x00

0

Command_Actived

0x01

1

Command_Keylog_offline

0x02

1

Command_Keylog_offline

0x10

1

Command_Keylog_offline

0x1A

1

Command_Keylog_offline

0x1F

1

Command_Keylog_offline

0x20

1

Command_Keylog_offline

0x21

2

Command_Session

0x22

3

Command_Remove

0x23

4

Command_Down_Exec

0x24

5

Command_Update_Server

0x25

6

Command_Clean_Event

0x26

7

Command_Open_URL_Hide

0x27

8

Command_Open_URL_Show

0x28

9

Command_Rename_Host

0x2a

10

Command_Rename_Remark

0x2b

11

Command_Execute

0x2c

12

Command_Create&Inject

0x2d

1

Command_Keylog_offline

0x45

1

Command_Keylog_offline

0x49

1

Command_Keylog_offline

Command Definitions

While I tried to make the command names easily understandable based on the name, I will take some time to explain what each of the commands do:

Command_Actived: Uses InterlockedExchange to activate/deactivate the sample.

Command_Keylog_offline:  Load into memory a dll that contains the function “PluginMe”.  After researching and analyzing additional Gh0stRAT samples while trying to figure out what dll contains “PluginMe”, I found a DLL for keylogging (called Keylog.dll) in a Gh0stRAT 2.0 sample that exported “PluginMe”.  Using that and a cross-comparison of another Gh0stRAT sample that I’ve previously analyzed, I was able to determine that “PluginMe” is a offline keyboard manager.

Command_Session:  This command was the first command that I enumerated and first obtains the SeShutdownPrivilege before calling ExitWindowsEx to perform a variety of tasks, based on the data segment(It is treated as a flag) of the Gh0stRAT protocol.

Command Option

Flag

EWX_Logoff

0x00

EWX_Shutdown

0x01

EWX_Reboot

0x02

EWX_Poweroff

0x08

EWX_RestartApps

0x40

EWX_HybridShutdown

0x00400000

Command_Remove: This command takes filenames as an argument and searches for the filename before deleting it from the system.

Command_Down_exec: This command downloads and executes new modules.  It takes a url as the argument and uses that to download and execute files.

Command_Update_Server:  This command passes the string “Gh0st Update” to the malware sample before running the sample again.  When the sample restarts, it detects the “Gh0st Update” command line arg, and connects to the server in order to update the sample. 

Command_Clean_Event:  This command locates and deletes all of the event logs on the system.

Command_Open_URL_Hide:   This command covertly opens a supplied URL.

Command_Open_URL_Show:  Using Internet Explorer, this command takes a URL as an argument and opens a new Internet Explorer session, connecting to the supplied URL.

*Command_Rename_Host: This command opens the malware’s Services key and adds the term “Host” to the Key.

Command_Rename_Remark:  This command opens the malware’s Services key and adds the term “Remark” to the Key.

*Command_Execute: This command executes a dropped file.

*Command_Create&Inject:  This command creates a new process (using a supplied filename as the process name) and then injects malicious code into it.

The starred commands are undocumented commands.

Mitigation

As this sample installs itself through the use of EternalBlue, the targeted protocol is SMB.  Because of this, in order to best mitigate and avoid possible installations, you need your system updated to the latest security patches.  Specifically, you’d want to make sure that you have MS17-010 installed, as this is the security patch that patches the EternalBlue vulnerability.

However, if you DO get infected, you’ll want to delete the following registry keys (if they exist):

HKLM/System/CurrentControlSet/Services/DirecastX ytasda jrqq

HKLM/System/CurrentControlSet/Services/DirectX yta jsdrq

HKLM/System/CurrentControlSet/Services/DirectX ytsda jrq

Additionally, you’ll want to delete any copies of “svchost.exe” that you find in %Program Files (x86)%/DIFXE/, as these are the dropped copies of the malware.

IOC’s and YARA rules

Sample

MD5

Size

IP

IOC

TdxWCfg.exe

474b3cd073b0a40d656b1a2f5bb673cf

708KB

http://mdzz2019.noip.cn:19931

HKLM/System/CurrentControlSet/Services/DirecastX ytasda jrqq

 

%Program Files (x86)%/DIFXE/svchost.exe

Tdx_Dropped

9bce099b5b01c305a5d98f1fd262bce1

143.05KB

http://mdzz2019.noip.cn:19931

HKLM/System/CurrentControlSet/Services/DirecastX ytasda jrqq

 

dwm.exe

00aaf0ddcc8d9b197c148e44d9e72d8d

384KB

http://mdzz2019.noip.cn:19931

HKLM/System/CurrentControlSet/Services/DirectX yta jsdrq

%Program Files (x86)%/DIFXE/svchost.exe

dwm_dropped

a548c18aa678626dab9b60628712cc18

84KB

http://mdzz2019.noip.cn:19931

HKLM/System/CurrentControlSet/Services/DirectX yta jsdrq

 

 

Yara Rules:

rule gh0strat_variant_dropper

 

 

{

 

       meta:

 

           author = "James Quinn, @lazyactivist192"

 

           desc = "Identifies a Gh0stRAT dropper"

 


 

 

       strings:

 

           $s1 = "+gPp6bGvrqa9/fz2770A/amupqawrp8="

 

           $s2 = "Shellex"

 

           $s3 = "SUSRAIZCqllahrCohrlojSarZSalpecasZ"

 

           $s4 = "[printto("%1","%2","%3","%4")]"

 


 

 

           $s6 = "SYST%-\#urrENt#ONtrOLSEt\SErvICEs\"

 

      

 

       condition:

 

           2 of ($s1, $s2, $s4) and 1 of ($s3, $s6)

 

}

 

rule gh0strat_variant

 

{

 

       meta:

 

           author = "James Quinn, @lazyactivist192"

 

           desc = "Identifies a Gh0stRAT variant"

 

      

 

       strings:

 

           $s1 = "\\.\agmkis2"

 

           $s2 = "Shellex"

 

 

 

           $s3 = "Gh0st Update"

 

           $s4 = "PluginMe"

 

      

 

       condition:

 

           all of them

 

}

Appendix

Socket script Version 1: https://github.com/Jquinn147/Analysis-Automation/blob/master/Python/Gh0stRAT_Variant_Socket.py

Socket Script V2(Command Script): https://github.com/Jquinn147/Analysis-Automation/blob/master/Python/Gh0stRatSocket.py

Citations:

Martin, D. (n.d.). Gh0st in the dshell (Tech.). Sans.

Rights to tools

Screenshot 1 was created using  Wireshark.  Wireshark uses the GNU Public License V2.

Screenshot 2 was created using GHIDRA, an open source tool released by the NSA.

Screenshot 3 was created using wxHexEditor.  wxHexEditor uses the GNU Public License V2.

Screenshot 4 was created using a tool that I wrote.  I give AT&T and its affiliates permission to use my tool.

Share this with others

Get price Free trial