# Just another analysis of the njRAT malware – A step-by-step approach **[cybergeeks.tech/just-another-analysis-of-the-njrat-malware-a-step-by-step-approach/](https://cybergeeks.tech/just-another-analysis-of-the-njrat-malware-a-step-by-step-approach/)** Summary njRAT (Bladabindi) is a .NET RAT (Remote Access Trojan) that allows attackers to take control of an infected machine. This malware has been used by APT actors in targeted attacks in Colombia (https://www.welivesecurity.com/2021/01/12/operation-spalax-targeted-malware-attacks[colombia/), by SideCopy (https://blog.talosintelligence.com/2021/07/sidecopy.html) and has been](https://blog.talosintelligence.com/2021/07/sidecopy.html) distributed via phishing emails (https://labs.k7computing.com/index.php/malspam-campaignsdownload-njrat-from-paste-sites/). The version number in our analysis is 0.6.4 and the campaign ID is “splitgateukrayna”. The following commands have been implemented: “proc”, “rss”, “rs”, “rsc”, “kl”, “inf”, “prof”, “rn”, “inv”, “ret”, “CAP”, “P”, “un”, “up”, “RG”. njRAT can also act as a keylogger because it records the pressed keys in a file which can be exfiltrated using the “kl” command. The rest of the commands will be explained in great detail in the Technical analysis section. **Analyst:** [@GeeksCyber](https://twitter.com/GeeksCyber) Technical analysis **Disclaimer: We’re aware that there are some njRAT builders available that can be used to** generate executables however, we’re not interested in these tools, and we’ve performed the analysis with zero knowledge from those. SHA256: 833f86074592648c0a758098e34ab605a2b922d94dbab7141e2ce87acec03c35 The analysis has been performed using dnSpy. The malware tries to open a mutex called “49e91d08e684b1770e0cefa60401157a” using the OpenExisting method. If the mutex already exists, the process exits: Figure 1 A new mutex named “49e91d08e684b1770e0cefa60401157a” is created by calling the Mutex constructor: Figure 2 ----- The path for the executable file that started the application is compared with “%AppData%\services64.exe”. The malware authors implemented a function called “CompDir”, which compares the name of the files and the name of the directories: Figure 3 Figure 4 If the above file exists (“services64.exe”), it’s deleted using the Delete function: Figure 5 The initial executable file is copied to “%AppData%\services64.exe”. The new file is executed using the Start method, and the current process exits: Figure 6 The binary sets the environment variable “SEE_MASK_NOZONECHECKS” to 1, which removes the open file security warnings: Figure 7 A new program-based exception is added to Windows Firewall using netsh (the program being the newly created executable): ----- Figure 8 A new entry called “49e91d08e684b1770e0cefa60401157a” is added to the Run registry key. This represents a persistence mechanism, and the malware will run whenever the current user logs on: Figure 9 Figure 10 There is a 2nd persistence mechanism that is not enabled in the malware. It would copy the executable to the Startup folder, as shown below: Figure 11 The RAT initializes a new instance of the Thread class by specifying the ThreadStart method: Figure 12 A new TcpClient object is created by the executable. The malware establishes a connection to the C2 server 44gang44.duckdns[.]org (dynamic DNS service) on port 2222: Figure 13 The volume serial number for the C drive is extracted using the GetVolumeInformation API: ----- Figure 14 The file retrieves the computer name and user name using the GetComputerName and GetUserName functions: Figure 15 Figure 16 The last write time of the executable is obtained from the LastWriteTime property, as highlighted in figure 17: Figure 17 The full operating system name is retrieved from the OSFullName property: Figure 18 njRAT determines the architecture of the system by checking the existence of the “Program Files (x86)” directory (it only exists on 64-bit systems): ----- Figure 19 The capGetDriverDescriptionA API is utilized to check for the existence of a Webcam: Figure 20 GetForegroundWindow is used to get a handle to the foreground window (the window with which the user is currently working). The GetWindowText function copies the text of the foreground window’s title bar into a buffer. GetWindowThreadProcessId is used to retrieve the thread’s identifier that created the foreground window, along with the process’ identifier that created the window. The result of the function is represented by the MainWindowTitle property of the process extracted before, which is Base64 encoded: ----- Figure 21 The malware creates the “HKEY_CURRENT_USER\Software\49e91d08e684b1770e0cefa60401157a” registry key: Figure 22 The buffer that contains the following information is sent to the C2 server: Base64 of Campaign ID + volume serial number Computer name User name Last write time of the malicious file Operating system name + system’s architecture Whether a Webcam is detected njRAT Version Base64 of the main window title of the process ----- Figure 23 The C2 response is copied into a buffer using the Receive method: Figure 24 The C2 server was emulated using FakeNet. The binary expects a response that contains instructions separated by the “|’|’|” separator. Multiple commands are implemented by njRAT, as we’ll describe later on: Figure 25 **Keylogger functionalities** Every pressed key is compared with multiple function/special keys: Figure 26 If the keys aren’t function/special keys, they’re mapped from virtual-key code into a scan code or character value by calling the MapVirtualKey function. GetKeyboardLayout is utilized to retrieve the active input locale identifier. The ToUnicodeEx API is utilized to translate the virtual-key code and keyboard state to the corresponding Unicode character: ----- Figure 27 The GetAsyncKeyState API is utilized to determine whether a key is up or down: Figure 28 The window title of the process where the input is detected is also included in the logs file: Figure 29 The binary creates a file called “services64.exe.tmp” in the same directory, where the keylogger data is stored. The WriteAllText method is utilized to populate the file: Figure 30 An example of a log file is displayed in figure 31: ----- Figure 31 Now we describe the commands implemented by njRAT. **“proc” command** Case 1 – “proc|’|’|~” (OK.Y == |’|’|) – retrieve information about the current process and the other running processes The current process ID is retrieved and sent to the C2 server by calling the GetCurrentProcess function. The number of processes running on the host is also transmitted to the C2 server: Figure 32 The malware extracts the description of the files using the FileVersionInfo.FileDescription property, and then encodes it using the Base64 algorithm. For each process, a string that contains the process ID, the full path to the process, and the encoded file description (if available), is constructed: Figure 33 ----- In the case of Windows processes, the execution flow is different however, the scope is the same: Figure 34 The buffer that contains the concatenation of the strings computed above is exfiltrated to the C2 server: Figure 35 Case 2 – “proc|’|’|k|’|’|” – kill a process The process that corresponds to the process ID transmitted by the C2 server is stopped by calling the Kill method. If successful, the malware sends a custom message to the server, otherwise it sends an exception message: ----- Figure 36 Case 3 – “proc|’|’|kd|’|’|” – kill a list of processes and delete the module files Firstly, the binary repeats the same procedure from above. It also extracts the full path to the process: Figure 37 The RAT tries to delete the file that corresponds to the above process. If successful, it sends a confirmation message to the C2 server: Figure 38 Case 4 – “proc|’|’|re|’|’|” – restart a process The binary repeats the same procedure from above. It also extracts the full path to the process: ----- Figure 39 njRAT executes the file extracted above. If successful, it sends a confirmation message to the C2 server: Figure 40 **“rss” command – start a hidden command prompt and redirect the StandardOutput and** StandardError to the C2 server The malware creates a “cmd.exe” process object and sets to true multiple values that indicate the following: the error output should be written to StandardError, the input should be read from StandardInput, and the output should be written to StandardOutput. The method that will handle the OutputDataReceived and ErrorDataReceived events of the newly created process is set to a function called “RS”. The method that will handle the Process.Exited events is set to a function called “ex”. The new process is started, and it begins read operations on the redirected StandardOutput and StandardError streams of the application: Figure 41 ----- The RAT retrieves a late-bound value called Data, which represents the StandardError/StandardOutput of the cmd.exe process that is Base64 encoded and sent to the C2 server: Figure 42 The output of the cmd.exe process can be seen in the network traffic: Figure 43 Figure 44 displays the cmd.exe process as the child of the initial process (Process Hacker tool): Figure 44 In the case of a Process.Exited event, the “ex” function just sends the string “rsc” to the C2: Figure 45 **“rs|’|’|” command – send a command to be executed by the hidden** command prompt The C2 server can specify a command that is decoded using the Base64 algorithm, which is given as input to the cmd.exe process created earlier: Figure 46 It’s important to mention that the malware performs sanity checks and sends an exception message to the C2 if any error occurs in any case: ----- Figure 47 **“rsc” command – kill the hidden command prompt created earlier** The command prompt process created earlier is killed by the RAT: Figure 48 **“kl” command – exfiltrate the keylogger’s log file** The content of the Logs variable, which is the output of the keylogger described above, is Base64 encoded and exfiltrated to the C2 server: Figure 49 **“inf” command – retrieve information about the volume serial number and malware configuration** (C2 server, process name, etc.) The file checks the “HKCU\Software\49e91d08e684b1770e0cefa60401157a\vn” registry value, which doesn’t exist at this time. The binary extracts again the volume serial number for the C drive and combines it with the following information: C2 server, C2 port number, the AppData folder, the name of the executable, and the process name. The resulting string is transmitted to the C2: ----- Figure 50 **“prof” command** Case 1 – “prof|’|’|~|’|’||’|’|” – create a registry value in a specific registry key The malware creates a value under “HKEY_CURRENT_USER\Software\49e91d08e684b1770e0cefa60401157a” and writes some data to it: Figure 51 ----- Case 2 – prof| | |!| | || | | - create a registry value in a specific registry key and retrieve the “!” registry value The binary repeats the same operation from above: Figure 52 The RAT is looking to extract a value called “!” from the same registry key. The value’s content is sent to the C2 server: Figure 53 Figure 54 Case 3 – “prof|’|’|@|’|’|” – delete a registry value from a specific registry key njRAT deletes the specified value from the same registry key, as highlighted in figure 55: Figure 55 **“rn” command** ----- Case 1 – rn| | || | | – download and run a file from the URL The executable downloads the resource specified by the URL and stores the result as a Byte array by calling the DownloadData method: Figure 56 The array computed above will be stored in a file that is created in the TEMP directory. The file name is randomly generated and consists of 10 lowercase letters: Figure 57 Figure 58 The new file is executed by calling the Start function, and a confirmation message is transmitted to the C2: Figure 59 Case 2 – “rn|’|’||’|’|” – decode, decompress, and execute the executable ----- The file decodes the Base64 encoded content and then decompresses it using the ZIP function (depending on the flag, this function could also be used to Gzip compress content): Figure 60 Figure 61 As in the first case, the content will be written to a file in the TEMP directory, and a confirmation message is sent to the C2 server. **“inv|’|’||’|’||’|’|” command – njRAT has plugins that can be** downloaded, saved in registry keys, and then executed The RAT checks the existence of the RegistryValue value under “HKCU\Software\49e91d08e684b1770e0cefa60401157a”: ----- Figure 62 Whether the above value doesn’t exist and array[3] has a length of 1, the malware sends a message to the C2 and finishes the command: Figure 63 Whether the above value exists, its content is decoded using Base64, and a different message is forwarded to the C2 server: Figure 64 From our analysis, this file is supposed to be a plugin of njRAT. The assembly is loaded via a function call to Assembly.Load and all the modules that are part of it are extracted using the GetModules method. The binary extracts the types defined in each module and expects some of them to have a name that ends with “.A” (a class called “A” should be defined). For each of these types found, the process creates an instance of it using the system activator: Figure 65 ----- Figure 66 The binary calls the LateSet method multiple times in order to execute multiple late-bound field write calls. Basically, variables such as “h”, “p”, “osk”, “off” are set to OK.H (C2 domain), OK.P (C2 port number), array[2] (this is provided by the C2) and “true”. The malware calls the plugin’s function called “start”: Figure 67 Whether the registry value mentioned above doesn’t exist and array[3] has a length greater than 1, array[3] is Base64 decoded, and then Gzip decompressed: Figure 68 The RegistryValue value is created under “HKEY_CURRENT_USER\Software\49e91d08e684b1770e0cefa60401157a”. The content from above that was decompressed is encoded using Base64 and stored in this value: Figure 69 The same steps starting with loading the assembly (above figure 65) are executed one more time. ----- **ret| | || | | command – similar to the inv command, this command** can be used to execute a malicious assembly found in a registry key or transmitted by the C2 server The process checks the existence of the RegistryValue value under “HKCU\Software\49e91d08e684b1770e0cefa60401157a”: Figure 70 Whether the above value doesn’t exist and array[2] has a length of 1, the malware sends a message to the C2 and finishes the command: Figure 71 Whether the above value exists, its content is decoded using Base64, and a different message is forwarded to the C2 server: Figure 72 The same execution flow as above figure 65 is followed (starting with Assembly.Load etc.). A variable called “GT” is retrieved by calling the LateGet method; it is encoded using the Base64 algorithm and exfiltrated to the C2 server: ----- Figure 73 Whether the registry value mentioned above doesn’t exist and array[2] has a length greater than 1, array[2] is Base64 decoded, and then Gzip decompressed: Figure 74 The RegistryValue value is created under “HKEY_CURRENT_USER\Software\49e91d08e684b1770e0cefa60401157a”. The content from above that was decompressed is encoded using Base64 and stored in this value: Figure 75 The same steps starting with loading the assembly (above figure 65) are executed again. **“CAP|’|’||’|’|” command – take screenshots** The RAT creates a new Bitmap object used to create a new Graphics object by calling the Graphics.FromImage function. The CopyFromScreen method is utilized to perform a bit-block transfer of color data from the screen to the Graphics object: Figure 76 The binary initializes a new instance of the Rectangle class with a specific position and size and then draws the cursor on the Graphics object within the bounds: ----- Figure 77 This command is used to take screenshots. GetThumbnailImage is utilized to obtain a thumbnail for the bitmap image, which is saved in the jpeg format using the Image.Save function. The malware computes the MD5 hash of the image: Figure 78 Figure 79 The JFIF file is exfiltrated to the C2 server byte-by-byte: Figure 80 **“P” command – “Ping”** The process just sends the “P” letter to the C2: ----- Figure 81 **“un” command** Case 1 – “un|’|’|~” – completely uninstall the RAT The NtSetInformationProcess API is used to set the process as “normal” (it can be killed without crashing the OS and resulting in a BSOD, 0x1d = 29 = BreakOnTermination). The binary deletes the value created for persistence at “HKCU\Software\Microsoft\Windows\CurrentVersion\Run\49e91d08e684b1770e0cefa60401157a”: Figure 82 Figure 83 njRAT deletes the configured program exception from Windows Firewall. The “HKCU\Software\49e91d08e684b1770e0cefa60401157a” registry key is deleted, and the initial executable file is deleted as well: Figure 84 Case 2 – “un|’|’|!” – kill the current process The malicious process repeats the NtSetInformationProcess API call from above and exits: ----- Figure 85 Case 3 – “un|’|’|@” – restart the current process The binary repeats the NtSetInformationProcess API call from above and spawns the initial executable: Figure 86 **“up” command** Case 1 – “up|’|’|” – similar to the “rn” command, it’s used to update the RAT DownloadData is utilized to download an executable from a URL specified by the C2 server: Figure 87 The malicious process creates a registry value at “HKCU\di” and saves the downloaded content in a randomly generated file name located in the TEMP directory: Figure 88 The malware sends a message to the C2 server regarding the update confirmation. The newly created executable is run with the “UP:” parameter that contains the current process ID. When the “HKCU\di” value is equal to “!”, then the malware executes the uninstall operation: Figure 89 Case 2 – “up|’|’|” – similar to the “rn” command, it’s used to update the RAT The RAT decodes the Base64 encoded content and then decompresses it using the ZIP function: ----- Figure 90 The execution flow that starts with creating the “HKCU\di” key is followed one more time. **“RG” command** Case 1 – “RG|’|’|~|’|’|” – enumerate the registry key The process opens the specified registry key using the GetKey function: Figure 91 Figure 92 The executable constructs a string based on the registry key from above, which will be exfiltrated later on: Figure 93 The GetSubKeyNames and GetValueNames methods are used to retrieve an array of strings that contains the subkey names and the value names associated with the key. The concatenation of the arrays is transmitted to the C2: ----- Figure 94 Case 2 – “RG|’|’|!|’|’||’|’||’|’||’|’|” – create and set a registry value The SetValue function is utilized to create a value under the specified registry key, which contains data provided above: Figure 95 Case 3 – “RG|’|’|@|’|’||’|’|” – delete a registry value The DeleteValue method is used to delete the specified value from the registry key: Figure 96 Case 4 – “RG|’|’|#|’|’||’|’|” – create a sub key CreateSubKey is used to create a new subkey, as shown in figure 97: ----- Figure 97 Case 5 – “RG|’|’|$|’|’||’|’|” – delete a sub key and any child sub keys recursively DeleteSubKeyTree is utilized to delete the subkey and any child subkeys recursively: Figure 98 References [MSDN: https://docs.microsoft.com/en-us/dotnet/api/,](https://docs.microsoft.com/en-us/dotnet/api/) https://docs.microsoft.com/enus/windows/win32/api/ dnSpy: [https://github.com/dnSpy/dnSpy](https://github.com/dnSpy/dnSpy) Fakenet: [https://github.com/fireeye/flare-fakenet-ng](https://github.com/fireeye/flare-fakenet-ng) VirusTotal: https://www.virustotal.com/gui/file/833f86074592648c0a758098e34ab605a2b922d94dbab7141e2c e87acec03c35 Any.run: [https://app.any.run/tasks/78913e0b-1419-4571-8611-ac3372ffd578/](https://app.any.run/tasks/78913e0b-1419-4571-8611-ac3372ffd578/) ESET: https://www.welivesecurity.com/2021/01/12/operation-spalax-targeted-malware-attackscolombia/ Talos: [https://blog.talosintelligence.com/2021/07/sidecopy.html](https://blog.talosintelligence.com/2021/07/sidecopy.html) K7Computing: https://labs.k7computing.com/index.php/malspam-campaigns-download-njrat-frompaste-sites/ INDICATORS OF COMPROMISE C2 domain: 44gang44.duckdns[.]org:2222 ----- SHA256: 833f86074592648c0a758098e34ab605a2b922d94dbab7141e2ce87acec03c35 Registry keys and values: HKCU\Software\49e91d08e684b1770e0cefa60401157a HKCU\Software\Microsoft\Windows\CurrentVersion\Run\49e91d08e684b1770e0cefa60401157a HKCU\di Files: C:\Users\\AppData\Roaming\services64.exe C:\Users\\AppData\Roaming\services64.exe.tmp Mutex: 49e91d08e684b1770e0cefa60401157a -----