Dissecting REMCOS RAT: An in-depth analysis of a widespread 2024 malware, Part One By Cyril François, Samir Bousseaden Published: 2024-04-24 · Archived: 2026-04-10 03:00:04 UTC In the first article in this multipart series, malware researchers on the Elastic Security Labs team give a short introduction about the REMCOS threat and dive into the first half of its execution flow, from loading its configuration to cleaning the infected machine web browsers. Introduction Elastic Security Labs continues its examination of high-impact threats, focusing on the internal complexities of REMCOS version 4.9.3 Pro (November 26, 2023). Developed by Breaking-Security, REMCOS is a piece of software that began life as a red teaming tool but has since been adopted by threats of all kinds targeting practically every sector. When we performed our analysis in mid-January, it was the most prevalent malware family reported by ANY.RUN. Furthermore, it remains under active development, as evidenced by the recent announcement of version 4.9.4's release by the company on March 9, 2024. All the samples we analyzed were derived from the same REMCOS 4.9.3 Pro x86 build. The software is coded in C++ with intensive use of the std::string class for its string and byte-related operations. REMCOS is packed with a wide range of functionality, including evasion techniques, privilege escalation, process injection, recording capabilities, etc. This article series provides an extensive analysis of the following: Execution and capabilities Detection and hunting strategies using Elastic’s ES|QL queries Recovery of approximately 80% of its configuration fields Recovery of about 90% of its C2 commands Sample virtual addresses under each IDA Pro screenshot And more! https://www.elastic.co/security-labs/dissecting-remcos-rat-part-one Page 1 of 16 REMCOS execution diagram For any questions or feedback, feel free to reach out to us on social media @elasticseclabs or in the Elastic Community Slack. Loading the configuration The REMCOS configuration is stored in an encrypted blob within a resource named SETTINGS . This name appears consistent across different versions of REMCOS. REMCOS config stored in encrypted SETTINGS resource The malware begins by loading the encrypted configuration blob from its resource section. https://www.elastic.co/security-labs/dissecting-remcos-rat-part-one Page 2 of 16 0x41B4A8 REMCOS loads its encrypted configuration from resources To load the encrypted configuration, we use the following Python script and the Lief module. import lief def read_encrypted_configuration(path: pathlib.Path) -> bytes | None: if not (pe := lief.parse(path)): return None for first_level_child in pe.resources.childs: if first_level_child.id != 10: continue for second_level_child in first_level_child.childs: if second_level_child.name == "SETTINGS": return bytes(second_level_child.childs[0].content) We can confirm that version 4.9.3 maintains the same structure and decryption scheme as previously described by Fortinet researchers: Fortinet reported structure and decryption scheme We refer to the “encrypted configuration” as the structure that contains the decryption key and the encrypted data blob, which appears as follows: struct ctf::EncryptedConfiguration { uint8_t key_size; uint8_t key[key_size]; uint8_t data }; https://www.elastic.co/security-labs/dissecting-remcos-rat-part-one Page 3 of 16 The configuration is still decrypted using the RC4 algorithm, as seen in the following screenshot. 0x40F3C3 REMCOS decrypts its configuration using RC4 To decrypt the configuration, we employ the following algorithm. def decrypt_encrypted_configuration( encrypted_configuration: bytes, ) -> tuple[bytes, bytes]: key_size = int.from_bytes(encrypted_configuration[:1], "little") key = encrypted_configuration[1 : 1 + key_size] return key, ARC4.ARC4Cipher(key).decrypt(encrypted_configuration[key_size + 1 :]) The configuration is used to initialize a global vector that we call g_configuration_vector by splitting it with the string \x7c\x1f\x1e\x1e\x7c as a delimiter. 0x40EA16 Configuration string is split to initialize g_configuration_vector We provide a detailed explanation of the configuration later in this series. UAC Bypass When the enable_uac_bypass_flag (index 0x2e ) is enabled in the configuration, REMCOS attempts a UAC bypass using a known COM-based technique. https://www.elastic.co/security-labs/dissecting-remcos-rat-part-one Page 4 of 16 0x40EC4C Calling the UAC Bypass feature when enabled in the configuration Beforehand, the REMCOS masquerades its process in an effort to avoid detection. 0x40766D UAC Bypass is wrapped between process masquerading and un-masquerading REMCOS modifies the PEB structure of the current process by replacing the image path and command line with the explorer.exe string while saving the original information in global variables for later use. 0x40742E Process PEB image path and command line set to explorer.exe The well-known technique exploits the CoGetObject API to pass the Elevation:Administrator!new: moniker, along with the CMSTPLUA CLSID and ICMLuaUtil IID, to instantiate an elevated COM interface. REMCOS then uses the ShellExec() method of the interface to launch a new process with administrator privileges, and exit. https://www.elastic.co/security-labs/dissecting-remcos-rat-part-one Page 5 of 16 0x407607 calling ShellExec from an elevated COM interface 0x4074FD instantiating an elevated COM interface https://www.elastic.co/security-labs/dissecting-remcos-rat-part-one Page 6 of 16 This technique was previously documented in an Elastic Security Labs article from 2023: Exploring Windows UAC Bypasses: Techniques and Detection Strategies. Below is a recent screenshot of the detection of this exploit using the Elastic Defend agent. UAC bypass exploit detection by the Elastic Defend agent disabling UAC Disabling UAC When the disable_uac_flag is enabled in the configuration (index 0x27 ), REMCOS disables UAC in the registry by setting the HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\SystemEnableLUA value to 0 using the reg.exe Windows binary." Install and persistence When enable_install_flag (index 0x3 ) is activated in the configuration, REMCOS will install itself on the host machine. https://www.elastic.co/security-labs/dissecting-remcos-rat-part-one Page 7 of 16 0x40ED8A Calling install feature when the flag is enabled in configuration The installation path is constructed using the following configuration values: install_parent_directory (index 0x9 ) install_directory ( 0x30 ) install_filename ( 0xA ) The malware binary is copied to {install_parent_directory}/{install_directory}/{install_filename} . In this example, it is %ProgramData%\Remcos\remcos.exe . Sample detected in its installation directory If the enable_persistence_directory_and_binary_hiding_flag (index 0xC ) is enabled in the configuration, the install folder and the malware binary are set to super hidden (even if the user enables showing hidden files or https://www.elastic.co/security-labs/dissecting-remcos-rat-part-one Page 8 of 16 folders the file is kept hidden by Windows to protect files with system attributes) and read-only by applying read-only, hidden, and system attributes to them. 0x40CFC3 REMCOS applies read-only and super hidden attributes to its install folder and files Install files set as read-only and super hidden After installation, REMCOS establishes persistence in the registry depending on which of the following flags are enabled in the configuration: enable_hkcu_run_persistence_flag (index 0x4 ) HKCU\Software\Microsoft\Windows\CurrentVersion\Run\ enable_hklm_run_persistence_flag (index 0x5 ) HKLM\Software\Microsoft\Windows\CurrentVersion\Run\ enable_hklm_policies_explorer_run_flag (index 0x8 ) HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run\ https://www.elastic.co/security-labs/dissecting-remcos-rat-part-one Page 9 of 16 0x40CD0D REMCOS establishing persistence registry keys The malware is then relaunched from the installation folder using ShellExecuteW , followed by termination of the initial process. 0x40D04B Relaunch of the REMCOS process after installation Process injection When the enable_process_injection_flag (index 0xD ) is enabled in the configuration, REMCOS injects itself into either a specified or a Windows process chosen from an hardcoded list to evade detection. 0x40EEB3 Calling process injection feature if enabled in the configuration https://www.elastic.co/security-labs/dissecting-remcos-rat-part-one Page 10 of 16 REMCOS running injected into iexplore.exe The enable_process_injection_flag can be either a boolean or the name of a target process. When set to true (1), the injected process is chosen in a “best effort” manner from the following options: iexplorer.exe ieinstal.exe ielowutil.exe Note: there is only one injection method available in REMCOS, when we talk about process injection we are specifically referring to the method outlined here REMCOS uses a classic ZwMapViewOfSection + SetThreadContext + ResumeThread technique for process injection. This involves copying itself into the injected binary via shared memory, mapped using ZwMapViewOfSection and then hijacking its execution flow to the REMCOS entry point using SetThreadContext and ResumeThread methods. It starts by creating the target process in suspended mode using the CreateProcessW API and retrieving its thread context using the GetThreadContext API. https://www.elastic.co/security-labs/dissecting-remcos-rat-part-one Page 11 of 16 0x418217 Creation of target process suspended mode Then, it creates a shared memory using the ZwCreateSection API and maps it into the target process using the ZwMapViewOfSection API, along with the handle to the remote process. 0x418293 Creating of the shared memory 0x41834C Mapping of the shared memory in the target process The binary is next loaded into the remote process by copying its header and sections into shared memory. 0x41836F Mapping the PE in the shared memory using memmove Relocations are applied if necessary. Then, the PEB ImageBaseAddress is fixed using the WriteProcessMemory API. Subsequently, the thread context is set with a new entry point pointing to the REMCOS entry point, and process execution resumes. 0x41840B Hijacking process entry point to REMCOS entry point and resuming the process Below is the detection of this process injection technique by our agent: Process injection alert https://www.elastic.co/security-labs/dissecting-remcos-rat-part-one Page 12 of 16 Process injection process tree Setting up logging mode REMCOS has three logging mode values that can be selected with the logging_mode (index 0x28 ) field of the configuration: 0: No logging 1: Start minimized in tray icon 2: Console logging 0x40EFA3 Logging mode configured from settings Setting this field to 2 enables the console, even when process injection is enabled, and exposes additional information. REMCOS console displayed while injected into iexplore.exe https://www.elastic.co/security-labs/dissecting-remcos-rat-part-one Page 13 of 16 Cleaning browsers When the enable_browser_cleaning_on_startup_flag (index 0x2B ) is enabled, REMCOS will delete cookies and login information from the installed web browsers on the host. 0x40F1CC Calling browser cleaning feature when enabled in the configuration According to the official documentation the goal of this capability is to increase the system security against password theft: Currently, the supported browsers are Internet Explorer, Firefox, and Chrome. 0x40C00C Supported browsers for cleaning features The cleaning process involves deleting cookies and login files from browsers' known directory paths using the FindFirstFileA , FindNextFileA , and DeleteFileA APIs: https://www.elastic.co/security-labs/dissecting-remcos-rat-part-one Page 14 of 16 0x40BD37 Cleaning Firefox cookies 1/2 0x40BD37 Cleaning Firefox cookies 2/2 When the job is completed, REMCOS prints a message to the console. REMCOS printing success message after cleaning browsers It's worth mentioning two related fields in the configuration: enable_browser_cleaning_only_for_the_first_run_flag (index 0x2C ) browser_cleaning_sleep_time_in_minutes (index 0x2D ) The browser_cleaning_sleep_time_in_minutes configuration value determines how much time REMCOS will sleep before performing the job. https://www.elastic.co/security-labs/dissecting-remcos-rat-part-one Page 15 of 16 0x40C162 Sleeping before performing browser cleaning job When enable_browser_cleaning_only_for_the_first_run_flag is enabled, the cleaning will occur only at the first run of REMCOS. Afterward, the HKCU/SOFTWARE/{mutex}/FR registry value is set. On subsequent runs, the function directly returns if the value exists and is set in the registry. That’s the end of the first article. The second part will cover the second half of REMCOS' execution flow, starting from its watchdog to the first communication with its C2. Source: https://www.elastic.co/security-labs/dissecting-remcos-rat-part-one https://www.elastic.co/security-labs/dissecting-remcos-rat-part-one Page 16 of 16 https://www.elastic.co/security-labs/dissecting-remcos-rat-part-one 0x407607 calling ShellExec from an elevated COM interface 0x4074FD instantiating an elevated COM interface Page 6 of 16