Here are my notes on the latest malware sample using CVE-2019-0541 to target Poland and drop .NET RAT. I’m going to focus on finding similarities between this case, and previous .NET rat connecting to the same IP address dropped by a COVID-19 document.
2020-04-07 CHM uses CVE-2019-0541 to drop .NET RAT targeting Poland 🇵🇱— W3ndige (@w3ndige) April 7, 2020
cc: @malwrhunterteam @James_inthe_box @JAMESWT_MHT @VK_Intel https://t.co/Bt5MEcsf4p pic.twitter.com/eK9CAgPxHp
Firstly, we’ll start the investigation from the older sample, that was used together with COVID-19 document lure, potentially targeting Ukraine. Unfortunately, at the time that I’ve noticed the sample, the C2 wasn’t responding so we’ll have to stick with the already finished Any.Run reports.
Looking at the process graph of the infection, we can see some characterstics about it.
- Payload was dropped by initial document sample.
- Payload was executed with
- Payload executed a bunch of commands via
Let’s focus on the
EXE. It’s an
.NET executable so reverse engineering it shouldn’t be to hard.
$ file conhost.exe conhost.exe: PE32 executable (GUI) Intel 80386 Mono/.Net assembly, for MS Windows
As the function names were not clearly not easy to distinguish, we can pass it to
de4dot tools in order to change it inot something more readable.
Starting out, here is hardcoded domain of the C2 together with the
User-Agent used in communication.
Now let’s take a look at the characteristics of this RAT. First of all is the function that gathers some information about the system in order to, then, identify itself to the C2 servers. Information consists of:
- User Name.
- Machine Name.
- Network Interfaces.
- MD5 of the currently executing file.
Later on, that information is sent to the C2 in a
POST request, with information passed in
X-Reg header. Value of
Set-Cookie, returned by the server will be saved in a variable, and used in every further request to the server.
Regarding further communication with C2, all is done with
GET requests. In
Cookie field, we have a value previously passed to us from the C2. Further more, C2 will serve us with two informations - data to track executed commands and a base64 encoded command, that will be later on decoded and executed via
Last network method is used to exfiltrate base64 encoded data from the infected system to the C2. To track, to which command sample responds, in the
Cookie field the first value from the previous GET request is added.
And that’s whole communication with the C2, basically also most of the functionality of the RAT - executing commands from the C2 and exfiltrating returned data. Nothing fancy and complicated. To bring a little context, here is the function that executes commands.
Moving on to the next sample, this one was used together with CVE-2019-0541 exploit in a .CHM file. Firstly looking at the functions we can see a different type of obfuscation, functions name consist only of
First thing that is noticable in the sample is a bunch of encrypted strings used later in the RATs workflow. Algorithm is very simple, we have one array that is key and a bunch of arrays - all of the numbers in arrays are xored with a corresponding number in key array, modulo key length.
Here’s a small Python script and the output of it.
strings = [ [134,118,64,232,198,146,78,142,253,144,229,96,162,102,166,99,228,108,217,184,57,116,213,138,207,31,143,248,133,245,23,227,95,249,57,187,35,214,253,45,19,161,235,142,95,205,173,233,176,34,193,88,187,34,181,48,153,229,42,12,161,130,181,103,245,133,242,249,96,230,88,164,104,160,68,203,168,114,85,168,138,189,71,211,167,211,176,111,189,8,225,61,174,48,151,255,44,20,182,158,222,124,192,174,223,167,41,165,4,252,58,174,48,152,235,92,94,230,133,201,22,143,248,144,230,113,179,31,251,62], [163,109,78,241,217,196,0,142,165,215,182,50,229,66,160,107,244,46,198,164,113,87,175,217,142,78,194,173], [240,64,105,194,151], [140,92,110], [155,86,105,213], [239,109,83,236,207,145,90,213], [239,106,89,243,207,155,65], [239,109,67,241,207], [239,108,74,237,197,159,75],[ 168,116,94,175,207,134,74], [228,122,26], [153,92,125,161,235,186,107,129,128,245,150,21,214,109,140,98,238,112,193,167,124,26,174,220,222,108,206,172,219,133,33,237,84,239,34,244,35,252,142,94,101,197,253,177,125,229,232,145,177,96,188,4,255,61,177,35,129,173], , , ,, , [179,43], [151,69,20,221,216,145,64,213,148,221,188,45,252,3], [152,92,118,196,233,170,15,139,232,248,135,15,199,17,152,100,238,48,156,148,90,85,236,218,139,91,196,186,237,172,51,254,84,162], [152,92,118,196,233,170,15,139,232,248,135,15,199,17,152,100,238,48,156,148,90,85,236,218,139,91,196,186,237,172,51,254,84,162,93,242,108,202,190,122,78], [133,120,87,228], [134,120,84,244,204,159,76,213,189,204,176,50], [134,118,94,228,198], [130,125,95,239,222,151,73,216,161,208,178,14,255,92,173,104,242], , , [151,59,18,233,222,138,95,210,247,132,137,111,214,30,230,35,170,60,242,233], [151,59,97,192,135,164,78,140,178,227,239,110,160,109,237],  ] key = [203,25,58,129,170,254,47,161,200,190,213,64,138,49,207,13,128,3,174] for string in strings: out = '' for i in range(0, len(string)): out += chr(string[i] ^ key[i % len(key)]) print(out) # Output # Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.74 Safari/537.36 Edg/79.0.319.43 # https://microsoft-hohm.space # ;YSC= # GET # POST # $timeout # $screen # $type # $upload # cmd.exe # /c # REG ADD HKCU\\Console /v CodePage /t REG_DWORD /d 65001 /f # : # " # ' # & # , # x2 # \\.\root\cimv2 # SELECT * FROM Win32_ComputerSystem # SELECT * FROM Win32_ComputerSystemProduct # Name # Manufacturer # Model # IdentifyingNumber # 0 # 1 # \"(https?:\/\/).*?\" # \"[A-Za-z]:.*\" # |
Generally, apart from the function names, this code uses a lot more of
CallSite than the previous sample. For example, here is a function that generates
SHA1 hash of a file currently executed, substringed from the 10+ index.
In addition, here we have a function that, recovers information about the infected system, this time using WMI and
Together with strings recovered from the sample, we can immedietaly see used information that will be recovered from the system and later on, passed to the C2 server. In these there are:
- User Name.
- Computer Name.
- Network Interfaces.
- SHA1 Hash of a file currently executed.
\\.\root\cimv2 SELECT * FROM Win32_ComputerSystem SELECT * FROM Win32_ComputerSystemProduct Name Manufacturer Model IdentifyingNumber
return ll1001o.<>o__7.<>p__18.Target(ll1001o.<>o__7.<>p__18, typeof(string), Environment.UserName, lll0l0o1oo010l.ll0o01o010000, arg, lll0l0o1oo010l.ll0o01o010000, arg2, lll0l0o1oo010l.ll0o01o010000, arg3, lll0l0o1oo010l.ll0o01o010000, arg4, lll0l0o1oo010l.ll0o01o010000, lll0lo1llo11001.llol011lllo11);
Moving on, we have functions used to communicate with C2. Once again, we have three functions that perform communication with C2 - first one used to identify to the server, second to get commands and third to return data from this commands. First command is POST request to the C2 that uses
Referer field to pass all the gather information. Once again, value from the
Set-Cookie will be saved and used in later communication in a
Here, we have another function that will use a GET request to get commands from the C2 server. It’s functioning is mostly identical to the function from the previous sample, so we won’t dig into this much further.
Lastly, there is a function to send back data, from the executed commands. Using POST request, base64 encoded data will be sent back to the C2.
So, it seems that both C2 protocols seem to be pretty consistent. In this sample, commands will be once again executed with
cmd.exe. In addition, we have one more feature to the RAT that wasn’t there in the previous version - taking screenshots of screen. Here is the function responsible for that, which base64 encodes the picture.
microsoft-hohm[.]space|145.239.23[.]7 cloud-security.ggpht[.]ml|145.239.23[.]7 d2b81c4f5d075daa681f823cc9a5e4c0 485c4b9a688dcecb56084f0402f35cac 74572fba26f5e988b297ec5ea5c8ac1c 0acecad57c4015e14d9b3bb02b433d3e