{
	"id": "0e175dcb-1f7a-458e-9b3b-ef2b55dfafc0",
	"created_at": "2026-04-06T15:53:45.513548Z",
	"updated_at": "2026-04-10T03:36:11.312093Z",
	"deleted_at": null,
	"sha1_hash": "c01e78a7ead2556bcc9a04a555dfda425a07ad0f",
	"title": "The Brothers Grim | Group-IB Blog",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 267248,
	"plain_text": "The Brothers Grim\r\nThe reversing tale of GrimAgent malware used by Ryuk\r\nJuly 2, 2021 · min to read · Malware Analysis\r\nGrimAgent Malware Ransomware Threat Intelligence\r\nExecutive summary\r\n← Blog\r\nbalance of shadow universe\r\nhttps://www.group-ib.com/blog/grimagent/\r\nPage 1 of 32\n\nRansomware activity increased drastically over the past couple of years and became the face of\r\ncybercrime by 2021.\r\nAccording to the “Ransomware Uncovered 2020-2021” report, the number of ransomware attacks\r\nincreased by more than 150% in 2020. The attacks grew in not only number but also scale and\r\nsophistication — the average ransom demand increased by more than twofold and amounted to\r\n$170,000 in 2020. The norm is shifting toward the millions: the Colonial Pipeline allegedly paid USD\r\n5 million to get its business back. The case propelled the question of ransomware to the top of the\r\npolitical agenda.\r\nIn the meantime, 2021 continues to prove that no company is immune to the ransomware plague.\r\nRansomware operators are not concerned about the industry so long as the victim can pay the\r\nransom. The prospect of quick profits motivates new players to join big game hunting. Ransomware\r\noperations show no signs of slowing down. The gangs evolve. They change their tactics, defense\r\nevasion techniques, and procedures to ensure that their illicit business thrives.\r\nGiven that ransomware attacks are conducted by humans, understanding the modus operandi and\r\ntoolset used by attackers is essential for companies that want to avoid costly downtimes. Ultimately,\r\nknowing how ransomware gangs operate and being able to thwart their attacks is more cost-effective than paying ransoms.\r\nOne of the underlying trends of 2021 to keep in mind is the use of commodity malware. The\r\ninfamous ransomware gang Ryuk, which is responsible for many high-profile cyber heists (including\r\nthe attack on the Baltimore County Public Schools system) followed suit. The most recent addition\r\nto their arsenal, which is yet to be explored, is the malware called GrimAgent.\r\nOur team did the first comprehensive analysis of the GrimAgent backdoor. It is intended mainly for\r\nreverse engineers, researchers and blue teams so that they can create and implement rules that\r\nhelp monitor this cyber threat closely. Group-IB’s Threat Intelligence team has created Yara and\r\nSuricata rules as well as mapped GrimAgent’s TTPs according to the MITRE ATT\u0026CK® matrix.\r\nIntroduction\r\nGrimAgent is a malware classified as a backdoor and that has been used as a prior stage to Ryuk\r\nransomware. The ransomware family appeared in 2018 and was mistakenly linked to North Korea.\r\nLater on, it was attributed to two threat actors, FIN6 and Wizard Spider.\r\nhttps://www.group-ib.com/blog/grimagent/\r\nPage 2 of 32\n\nGiven the limited knowledge about the links between Ryuk and GrimAgent, we decided to research\r\nGrimAgent samples discovered in the wild and show how GrimAgent is connected to Ryuk. The\r\narticle analyzes the execution chain, TTPs, and the malware’s relevant characteristics.\r\nThe first known GrimAgent sample (SHA-256:\r\n03ec9000b493c716e5aea4876a2fc5360c695b25d6f4cd24f60288c6a1c65ce5) was uploaded to\r\nhttps://www.group-ib.com/blog/grimagent/\r\nPage 3 of 32\n\nVirusTotal on August 9, 2020 at 19:20:54. It is noteworthy that an embedded binary into the\r\ninitial malware was employed and had a timestamp of 2020-07-26, the timestamp could have been\r\naltered but the dates coincide with our hypothesis about the new malware.\r\nFrom a functionality point of view the malware is a backdoor, but it behaves like a bot. We analyzed\r\na completely different custom network protocol where the infected computer would register on the\r\nserver side and provide a reconnaissance string of the client, after which it would constantly make\r\nrequests to the C\u0026C server asking which are the next commands to be executed. During our\r\nresearch we performed several tests with the aim to get the next stage payload. We infected several\r\ntesting devices with different settings, but did not manage to obtain any payloads. Based on our\r\nfindings, it is likely that the actor implemented different defense and delivery mechanisms to protect\r\nthe integrity of its systems and ensure that the operations are flawless — which is not uncommon\r\nand we have witnessed this in the past. This means that GrimAgent developers potentially\r\nimplemented threat detection systems capable of detecting sandboxes or bot requests in order to\r\nprotect themselves from things such as analysis, added filters based on geolocation and\r\nblacklists/whitelists. The extreme meticulousness shown by the actors behind the malware and their\r\nattention to detail when carrying out attacks is both relevant and remarkable.\r\nAccording to Group-IB’s Threat Intelligence \u0026 Attribution system, Ryuk operators used different\r\ncommodity malware over time (including Emotet, TrickBot, Bazar, Buer, and SilentNight) to deploy\r\nransomware. However, the big blows suffered by Trickbot and Emotet could have prompted Ryuk\r\noperators to partner with GrimAgent. A detailed analysis of the latest TTPs used by various\r\nransomware strains is available in the Ransomware Uncovered 2020/2021 report.\r\nWelcome to the world of Threat\r\nIntelligence\r\nDefeat threats efficiently and identify attackers proactively with a revolutionary cyber\r\nthreat intelligence platform by Group-IB\r\nLearn more\r\nhttps://www.group-ib.com/blog/grimagent/\r\nPage 4 of 32\n\nConnections to Ryuk\r\nAnalyzing the GrimAgent Command and Control domain revealed an interesting URL. When making\r\na request on the domain, the Command and Control server returns a content designed for victims\r\nof the Ryuk ransomware, in addition to revealing its location on the TOR network.\r\nCommand and control landing page:\r\nFig. 1: C2 landing page\r\nCommand and control landing page source code:\r\n\u003c html \u003e \u003c body \u003e \u003c style \u003e p:hover {\r\n background: black;\r\n color:white\r\n} \u003c /style\u003e \u003c p onclick = 'info()' style = 'font-weight:bold;font-size:127%;\r\ntop:0;left:0;border: 1px solid black;padding: 7px 29px;width:85px;' \u003e \r\ncontact \u003c /p\u003e \u003c div style = 'font-size: 551%;font-weight:bold;width:51%;height:51%;overflo\r\ny\r\nu\r\nk \u003c /div\u003e \u003c /body\u003e\r\nhttps://www.group-ib.com/blog/grimagent/\r\nPage 5 of 32\n\nFig. 2: Ryuk Cpanel (TOR)\r\nThese findings show that the GrimAgent backdoor is being used as a part of Ryuk’s operations.\r\nWe have not observed any selling or advertising related to GrimAgent on underground forums, nor\r\nany use of the malware in the infection chain of any other malware besides Ryuk. Based on the\r\nabove facts we believe that this malware is used by the same TA that uses Ruyk ransomware and\r\ndoes not use MaaS.\r\nGrimAgent in a nutshell\r\nFile Information\r\nMD5 015E5A1FA9D8151EE51D6E53E187FBB2\r\nSHA1 163917CED2D1B33023FA47ECA8BEEC3EA871D517\r\nSHA256 63BD614434A70599FBAADD0EF749A9BB68F712ACA0F92C4B8E30A3C4B4DB5CAF\r\nCPU 32-bit\r\nhttps://www.group-ib.com/blog/grimagent/\r\nPage 6 of 32\n\nSize 270,945 (bytes)\r\nCompiler\r\nstamp\r\nOct 31 22:57:25 2020\r\nDebugger\r\nstamp\r\nOct 31 22:57:25 2020\r\nResource\r\nlanguage\r\nRussian\r\nFunctionality\r\nRetrieve information about the victim:\r\nIP and country code\r\nDomain\r\nVendor\r\nBuild version\r\nOS\r\nArch\r\nUsername\r\nPrivileges\r\nuser_id (computed to identify infected clients)\r\nAES key obtained from C2 to encrypt the communications\r\nExecute\r\nExecute shellcode (MZ launcher)\r\nDownload and execute\r\nUpdate\r\nExecute DLL (MZ launcher trampoline)\r\nhttps://www.group-ib.com/blog/grimagent/\r\nPage 7 of 32\n\nEncryption/decryption scheme\r\nTwo decryption keys used to decrypt the strings (decrypted by the same algorithm).\r\nFour keys are used:\r\n1. Hardcoded server public RSA key: Used to encrypt the first request to the Command and\r\nControl server and register the infected client on the server side.\r\n2. Generated client RSA public and private keys: Both stored at the config file.\r\na. Public RSA key\r\ni. Used to compute the user_id in order to track and identify infected users.\r\nii. Sent to C2 on the first request along with client reconnaissance; used to encrypt\r\nthe AES key sent by C2.\r\n3. Used to compute the user_id in order to track and identify infected users.\r\nb. Private RSA key: Used to decrypt the AES key received.\r\n4. AES key: Used on command and control further communications (symmetric encryption).\r\nhttps://www.group-ib.com/blog/grimagent/\r\nPage 8 of 32\n\nFig. 3: Execution flow diagram\r\n*Command 6 has been added on new versions of the malware, check “Dealing with newer\r\nGrimAgent versions” section.\r\nIn-depth analysis\r\nhttps://www.group-ib.com/blog/grimagent/\r\nPage 9 of 32\n\nThis section details the malware’s behavior. It covers the following points:\r\nBypassing anti-analysis mechanisms\r\nOverlapping instruction obfuscation\r\nOur investigation involved dealing with anti-analysis techniques, which complicated our task of\r\nanalyzing the malware in addition to breaking the IDAPro Hex-Rays display view.\r\nBasically, the execution flow has been altered with the entire code region between the pusha and\r\npopa instructions, as well as the stack usage. This code region does not perform any relevant\r\nactions while executing the binary, so we can NOP all these instructions.\r\nFig. 4: Anti-analysis technique at WinMain\r\nBypassing anti-analysis mechanisms\r\nMalware execution\r\nNetwork protocol\r\nhttps://www.group-ib.com/blog/grimagent/\r\nPage 10 of 32\n\nOnce done, we can set WinMain as a function and try to visualize the pseudocode as well as the\r\nIDA graph mode.\r\nString encryption\r\nWhen executing the WinMain routine, the first step is to decrypt the key that will later be used to\r\ndecrypt the sensitive strings needed to continue its execution. In order to decrypt the key, the\r\nmalware uses a function which may vary depending on the sample.\r\nThen, decrypt some basic strings to be able to execute their most basic actions and decrypt the\r\nsecond key that will be used on the decryption of all the necessary strings for their complete and\r\ncorrect execution.\r\nIDA Python script\r\nSince, in most cases, it is better to automate than perform a task manually, we use IDA Python to\r\nensure it is done quickly.\r\nIDAPro script:\r\nhttps://github.com/apriegob/GrimAgent/blob/main/IDAPro/IDAPro_string_decryptor.py\r\nThe “decrypt_strings_func” and “decrypt_strings2_func” values should be changed to the memory\r\nlocation where they are placed. The value of key1 and key2 will be the buffers that contain the keys\r\nused by the malware (which are easily obtained through the debugger).\r\nMalware execution\r\nThe execution of GrimAgent from can be divided into the following subsections.\r\nDecrypting strings and calculating indirect calls\r\npath_mutex_buffer\r\nMutex\r\nConfiguration file\r\nFirst launch of the malware\r\nHandling commands\r\nhttps://www.group-ib.com/blog/grimagent/\r\nPage 11 of 32\n\nDecrypting strings and calculating indirect calls\r\nThis is the first step the malware must take because it needs to decrypt the sensitive and relevant\r\nstrings as well as calculate the indirect calls in order to continue with its normal execution flow.\r\npath_mutex_buffer (deprecated)\r\nOne of the most relevant features of GrimAgent is that it uses the last 64 bytes of the binary for two\r\npurposes:\r\nThis means that after decrypting strings and calculating indirect calls, GrimAgent will read itself, and\r\nmore specifically its last 64 bytes. Henceforth we will call this set of bytes “path_mutex_buffer“.\r\nDealing with newer GrimAgent versions\r\n1. Compute mutex name\r\n2. Check path for store malware configuration\r\nhttps://www.group-ib.com/blog/grimagent/\r\nPage 12 of 32\n\nFig. 5: GrimAgent sections\r\nMutex\r\nThe function that creates the mutex will iterate over the 64 bytes, checking if the value is\r\nalphanumeric and, if it is not, the function will try to transform it into an alphanumeric value.\r\nIf the name of the mutex created is not valid, it will create a mutex with the hardcoded name\r\n“mymutex”. In case of an error, the execution will terminate.\r\nhttps://www.group-ib.com/blog/grimagent/\r\nPage 13 of 32\n\nFig. 6: Computing Mutex\r\nConfiguration file\r\nThe malware will check if it has a specific path hardcoded. The path corresponds to the buffer that\r\nit read in its last 64 bytes (“path_mutex_buffer“).\r\nCustom path syntax (deprecated):\r\nTo do so, the malware will make recursive calls to check if the SHA256 of the different writable\r\npaths and filenames matches with the buffer retrieved.\r\nIn terms of writing its config, the malware has three possibilities:\r\nSHA256 [unicode(FilePath)] + SHA256 [unicode(Filename)] → length of SHA256 x 2 = 64 (0x40)\r\nbytes\r\nhttps://www.group-ib.com/blog/grimagent/\r\nPage 14 of 32\n\nWith the config path defined, the malware checks if there is a valid config file:\r\nA valid configuration file will contain three different objects:\r\nFirst launch of the malware\r\nWhen the malware is executed, the first step is to decrypt the strings and create a mutex based on\r\nthe last 64 bytes (path_mutex_buffer), but there are cases where GrimAgent binaries have been\r\ncompiled without these last bytes.\r\nUnable to read its last 64 bytes\r\nThis execution branch can only occur on malware first execution. If we enter this execution branch,\r\nthe malware will perform the following actions:\r\nCustom Path → SHA256[unicode(Path)] + SHA256[unicode(FileName)]: The malware will start\r\nfrom “C:\\” path, and it will call a function recursively (find_custompath) in which it will compute\r\nthe SHA256 of the different directories to see if it matches with the first 32 bytes of\r\n“path_mutex_buffer” and, if It does, it will try to find the filename by performing the SHA256 of\r\nevery filename in the matched directory by checking the next 32 bytes.\r\n1.\r\n2. Hardcoded path 1 → C:\\Users\\Public\\config; used if unable to get the custom path.\r\n3. Hardcoded path 2 → C:\\Users\\Public\\reserve.sys\r\na. This path will be used when a custom path is matched with the character ‘ * ‘, for example:\r\n“C:\\Users\\*”\r\nb. There is a string “reserve.exe” that will replace the last 3 characters from “exe” to “sys” during\r\nexecution time.\r\nIf the config file is less than 0x32 bytes in size, it has no valid config. Otherwise, the config\r\nwill be considered as valid and continue the execution to an infinite loop that will perform C2\r\nrequests asking for new commands to execute.\r\nGenerated client public RSA key: to compute user_id and encrypt the AES key that the C2 will\r\nsend.\r\n1.\r\n2. Generated client private RSA key: to decrypt the AES key sent by C2.\r\n3. AES encrypted key received from C2: to encrypt/decrypt C2 communications.\r\nRetrieve the writable path\r\nCompute the new path_mutex_buffer based writable path and filename\r\nCopy itself into the writable path\r\nhttps://www.group-ib.com/blog/grimagent/\r\nPage 15 of 32\n\nReconnaissance\r\nAt this point, the malware will have been able to get its path to store its configuration file where it will\r\nstore the keys necessary for its execution and communication with C2 as well as for creating a\r\nmutex to avoid conflicts if it is executed several times.\r\nGrimAgent will then perform a system reconnaissance and collect device information. It will\r\ncollect the following fields:\r\nTo retrieve fields such as the internet IP address and country code, which will append into the\r\nreconnaissance string, the malware will use public resources. In our case, this means performing a\r\nGET request to api.myip.\r\nRSA key generation and user_id\r\nAppend the new path_mutex_buffer at the end of the new copied binary\r\nSet persistence of the copied binary\r\nTask scheduler\r\nRegistry key\r\nExecute copied malware\r\nDelete old sample\r\nExits\r\nCountry code (api.myip.com)\r\nIP (api.myip.com)\r\nVendor\r\nDomain\r\nBuild Version\r\nOS\r\nArchitecture\r\nUsername\r\nPrivileges (A/U)\r\nA = Admin\r\nU = User\r\nhttps://www.group-ib.com/blog/grimagent/\r\nPage 16 of 32\n\nGrimAgent calls a function in order to compute a user_identifer (used to identify the infected user)\r\nand generates the client RSA public and private keys:\r\nThe next screenshot shows the finished string obtained by the malware with the value of user_id\r\nadded at the end.\r\nFig. 7 – Complete victim reconnaissance. NB: Country code and IP address values are invalid\r\nbecause we executed the malware in a controlled environment without internet access.\r\nExample of a reconnaissance string:\r\n\u003cpre\u003evendor=\u003cvendor_id\u003e\u0026country=\u003ccountry\u003e\u0026ip=\u003cip\u003e\u0026domain=\u003cdomain\u003e\u0026build_version=\r\n\u003cbuild_version\u003e\u0026systemOS=\u003cOS\u003e\u0026registry=\u003c32/64\u003e\u0026username=\u003cusername\u003e\u0026privileges=\r\n\u003cU/A\u003e\u0026id=\u003cuser_id\u003e\u003c/pre\u003e\r\n1. Generates the client RSA public and private keys by using CryptGenKey.\r\nRetrieves the new generated client RSA public key in PEM format (with the headers ‘—–\r\nBEGIN PUBLIC KEY—–‘ and ‘—–END PUBLIC KEY—–‘).\r\n2.\r\nComputes the hash for that key, which generates a random id to be included in the\r\nreconnaissance string (used as a user identifier): This user_id would be different for every\r\nexecution but, to be able to identify the infected user and not generate a random key each time,\r\nthe new key will be stored and used to compute the user_id when needed.\r\n3.\r\n4. Retrieves the generated client RSA private key.\r\n5. Stores both public and private keys in the config file.\r\nhttps://www.group-ib.com/blog/grimagent/\r\nPage 17 of 32\n\nNext, the malware sends this information along with the generated client public RSA key to the\r\nCommand and Control server and waits until the reply contains ‘fr’ or ‘ar’ as the first characters in\r\nthe reply. Only if the first characters received are ‘fr’ will the malware store the reply as hex values.\r\nThe reply from C2 will be a symmetric encryption key (AES) that the malware will use from\r\nthen on in order to interact with the Command and Control server.\r\nThe malware will JMP to the ‘exist_conf‘ location and proceed with the execution.\r\nHandling commands\r\nWe land in this section once the malware obtains a valid configuration and is about to enter an\r\ninfinite loop where it will make requests for new commands to the Command and Control server. For\r\nGrimAgent, the configuration file will be valid if it is ≥ 32 bytes.\r\nReading config: the AES Key\r\nIn this case, the malware will decrypt and import the AES key received from the C2 which will be in\r\nthe config file. Then, the key will be used in order to encrypt and decrypt subsequent\r\ncommunications between the infected client and the C2.\r\nCommands\r\nGrimAgent will start an infinite loop (while 1) in order to request the next commands to execute to\r\nthe Command and Control server. The loop is made up of three points:\r\nCommand table:\r\nCommand id Functionality\r\n1 Execute\r\n2 Execute Shellcode (MZ Launcher)\r\n3 Download and Execute (Schtask)\r\n1. C2 request and decryption\r\n2. Execute command\r\n3. Sleep [180-190] seconds and start again\r\nhttps://www.group-ib.com/blog/grimagent/\r\nPage 18 of 32\n\nCommand id Functionality\r\n4 Update\r\n5 Execute DLL (MZ trampoline)\r\n6 Download and Execute (ShellExecuteW)\r\nThe commands and other malware features have been updated in newer versions of the malware,\r\nexplained at Dealing with newer GrimAgent versions section.\r\nOn receiving the C2 reply, the malware parses the command and executes it.\r\nCommand 1: Execute\r\nAt this point, the malware uses the same logic for execution that we have already seen. It creates a\r\ntask with a random name and length 8. The task will be executed through the task scheduler with\r\nmaximum privileges. Afterwards, the malware removes the task to avoid being detected.\r\nCommand 2: Execute shellcode (MZ launcher)\r\nWhen command ‘2’ is received, the malware parses the shellcode received as an argument. The\r\nmalware checks for ‘\\\\’ and ‘x’ bytes, which are common delimiters used in binary data.\r\nAfter parsing the shellcode, the malware calls the ‘drop_and_execute_shellcode’ function, which\r\ndrops an executable MZ (embedded into initial binary) with the appended shellcode into a\r\nwritable directory that will act as a launcher of the received binary data. The embedded MZ\r\ncontains the compiler stamp from July 2020. This point in time could be when the first version of\r\nGrimAgent appeared. Moreover, it contained another embedded MZ with the same behavior, but\r\ndesigned for 64b architecture systems. The 64b launcher has nearly the same time stamp.\r\nhttps://www.group-ib.com/blog/grimagent/\r\nPage 19 of 32\n\nFig. 8: MZ Shellcode/DLL launcher properties\r\nThe most interesting part of the new executable is how it executes the shellcode using sentinel\r\nbytes, with two possibilities:\r\nIn both cases, the malware parses the sentinel bytes and executes the shellcode/DLL.\r\nThe sentinel bytes are used to calculate where the shellcode is located and be able to\r\nexecute the malicious code.\r\nOnce dropped, this MZ launcher will be executed through task scheduler with a random name of 8\r\nalphanumeric characters.\r\nBy executing this command, the malware will also try to privesc by executing the payload as the\r\nhighest privileges possible. It will then sleep for 195-205 seconds, after which the malware will delete\r\nthe newly created task.\r\nCommand 3: Download and Execute (Schtask)\r\nThis is the basic functionality found in many malware families. It is the common download and\r\nexecute command functionality.\r\n1. @@@@@@@ + shellcode\r\n2. @@@@@@d + DLL path + ‘:’ + arguments (used at command 5)\r\nhttps://www.group-ib.com/blog/grimagent/\r\nPage 20 of 32\n\nIn order to receive the payload after the request of a new command, GrimAgent performs a request\r\nto obtain the payload to the specified URI received as an argument. The payload will be dropped\r\ninto a writable folder and executed through the task scheduler, as in command 1.\r\nCommand 4: Update\r\nWhen this command is received, the malware updates itself by dropping the new updated\r\nGrimAgent file into its current directory and appending padding bytes (this action will change the\r\nfile hash, used as a defensive mechanism) as well as the same path_mutex_buff at the end of the\r\nnew binary. By appending these bytes, the malware creates the same mutex and checks for the\r\nsame custom path for the config file. When finished, it runs the new updated binary\r\n(ShellExecuteW) and exits the process.\r\nFig. 9: Updated GrimAgent\r\nCommand 5: Execute DLL\r\n(MZ launcher trampoline) This command is very similar to command 2. The function is called with\r\nthree parameters:\r\n1. Payload size to be received by C2 on the next request\r\n2. DLL arguments\r\n3. Bool if the DLL is 32b or 64b\r\nhttps://www.group-ib.com/blog/grimagent/\r\nPage 21 of 32\n\nAs in previous commands, the malware will receive the URI to download the payload and, once\r\nexecuted, it will obtain a writable directory in order to be able to drop payloads. It will then perform a\r\nGET request to the URI in order to download the DLL to be executed.\r\nNext, the malware will drop the DLL launcher (MZ) with the sentinel bytes “@@@@@@d” and\r\nappend (at the next bytes) the path of the DLL to be executed + “:” + arguments. The file extension\r\nof the DLL launcher will be “.exe”. On the other hand, it will also drop the DLL to be executed (with\r\nthe file extension .dll).\r\nSentinel bytes syntax:\r\n@@@@@@d DLL_path : arguments\r\nOnce everything has been prepared, the malware will execute the launcher through the task\r\nscheduler and this will act as a stepping stone for executing the DLL, sending the previously\r\nobtained arguments.\r\nFig. 10: DLL execution\r\nCommand 6: Download and Execute (ShellExecuteW)\r\nhttps://www.group-ib.com/blog/grimagent/\r\nPage 22 of 32\n\nThis command obtains the payload by making a request to the URI (received as the command\r\nargument), drops it into the current directory and executes through a ShellExecuteW call.\r\nThis command was found in the newer versions of the malware.\r\nDealing with newer versions of GrimAgent\r\nWhile working on this article, we found some new GrimAgent samples in the wild with variations\r\nfrom the version explained above.\r\nAs a sample of the different changes detailed below, we have the hash SHA256 –\r\nD6EE553F52F20127301F737237B174EF6241EC9049AB22155DCE73144EF2354D, which presents\r\nvariations such as:\r\nHardcoded mutex name “T10”: This malware version does not generate a mutex name; instead,\r\nit creates one based on a hardcoded value.\r\nHardcoded config path “\\Users\\Public\\microsoft.cfg”: As with the mutex, a path is no longer\r\ndefined for the configuration; instead, it is hardcoded in the sample.\r\nCopies itself into a hardcoded path and filename (“\\Users\\Public\\svchost.exe”), and then sets\r\npersistence through the registry Run key. The execution is done directly through the call\r\nShellExecuteW \u003cpath\u003e instead of schtask.\r\nThe function that searches writable directories by creating and writing a new file with a\r\nrandom integer inside has been removed.\r\nHardcoded payload path: Commands that used writable paths found now use a hardcoded\r\npath “\\Users\\Public\\system+\u003crandom\u003e.exe“, for example command 3 (download and execute)\r\nand command 5 (execute DLL).\r\nAdded command 6 (drop and execute into the current path): The file will be executed through a\r\nShellExecuteW call.\r\nIt does not contain path_mutex_buffer (last 64 bytes in the binary).\r\nUpdated command 4: The screenshot below compares the command 4 (update) of both\r\nGrimAgent versions. On the left is the old one (already explained in the article) and on the right is\r\nthe updated one, which appends ’00’ bytes in the last 64 bytes of the updated binary and\r\nignores whether or not it can read the last 64 bytes of the binary.\r\nhttps://www.group-ib.com/blog/grimagent/\r\nPage 23 of 32\n\nFig. 11: Comparison of GrimAgent command 4 versions\r\nThe changes mean that the malware is being actively developed and it is highly likely that it will\r\npresent even more different versions and changes over time. The fact that some forms of execution\r\nhave been changed (such as the use of “path_mutex_buffer“) does not mean that a threat actor will\r\nnever use the former malware version again, so we must remain attentive and follow any new\r\nupdates closely.\r\nNetwork protocol\r\nBase protocol\r\nGrimAgents implements a custom network protocol in order to interact with the Command and\r\nControl server, and it follows the following syntax:\r\nHeader = MSG Flag Padding Padding Size\r\nMSG: The message to be sent.\r\nFlag: The value used to indicate what kind of connection needs to be made with the C2.\r\na: On requests for new commands. It makes a POST request to the Command and Control\r\nserver.\r\nd: First request to the C2. It makes a POST request to the Command and Control server to\r\nregister the client on the server side.\r\n*r: It is used internally in the malware, although it is not added directly in the request to the\r\nC2. When the function responsible for contacting the Command and Control server is\r\ncalled with this flag, the malware will make a GET request to a URI in order to obtain (read)\r\nthe payload (the next stage).\r\nPadding: Random generated values.\r\nhttps://www.group-ib.com/blog/grimagent/\r\nPage 24 of 32\n\nRandomization of connection fields\r\nTo establish a connection with the C2, GrimAgent randomizes some values as an evasive\r\nmechanism and tries to change request fields on the C2 request, such as User-Agent, referer,\r\ncontent-length and language.\r\nAs an interesting detail, if you look at the languages that the malware tries to adopt in the ‘Accept-Language’ field when connecting to the Command and Control server, it is possible that there is a\r\nrelationship with the group’s current targets. If so, they would be the following:\r\nDetection opportunities\r\nWe have examined how GrimAgent behaves throughout its execution, when and what it does. We\r\nwill now analyze the various opportunities to detect the malware. We can use the way in which it\r\nexecutes these actions to monitor the behavior in the different defense mechanisms or match\r\nthem using Sigma, Yara or Suricata rules.\r\nDetection opportunity 1: Persistence\r\nOn the first run, the malware copies itself to another directory, runs while establishing persistence on\r\nitself, and deletes the old file. A common path the malware uses is C:/Users/Public. GrimAgent carries\r\nout specific calls and they can be monitored to identify related behaviors.\r\nCheck the IOC section for the full information about the commands used on the malware\r\npersistence.\r\nDetection opportunity 2: Mutex (old malware version)\r\nOne of GrimAgent’s most characteristic factors is using the last 64 bytes of the binary to compute\r\nthe name of the mutex. The characteristic can be used to create a behavior rule and therefore\r\npredict what mutex name it will create in the system.\r\nPadding Size: The last two bytes are the decimal value of padding length – 3 (decimal format).\r\nUnited Kingdom\r\nUnited States\r\nSpain\r\nFrance\r\nhttps://www.group-ib.com/blog/grimagent/\r\nPage 25 of 32\n\nAll we have to do is to recreate the algorithm used in your different solutions by taking the last 64\r\nbytes of the file and compute the possible mutex name. You can spot the algorithm used by the\r\nmalware in the Mutex section.\r\nDetection opportunity 3: Network\r\nThe first domain to contact is “api.myip.com” in order to obtain the country code and client IP\r\n(http://ip-api.com/csv/?fields=query,countryCode) and then make the request to the C2 to obtain\r\nthe AES key. Once finished, it will make periodic requests to the C2 infrastructure to obtain the\r\nfollowing commands and/or to get next stage payloads. We can take advantage of the usage of the\r\npath “/gate.php” in conjunction with specific fields such as the referer (google.com, youtube.com,\r\netc.) when contacting the C2.\r\nLink to Suricata rule.\r\nDetection opportunity 4: Payload drop\r\nWhile executing the malware commands related to executing shellcode and DLLs, it uses a binary\r\nembedded in the initial malware. We can create detection rules for this binary and alert our defense\r\nteams if a match is found.\r\nThe following Yara rule was created to detect shellcode and DLL launchers (32b/64b) embedded in\r\nGrimAgent.\r\nLink to Yara rule.\r\nDetection opportunity 5: Payload execution\r\nAs we have shown throughout the article, to execute payloads GrimAgent uses both the\r\nShellExecute call and indirect execution through scheduled tasks. Given that it always uses the\r\nsame syntax on schtasks, we can try to match these actions. As it is suspicious behavior to create a\r\nscheduled task and try to execute it nearly at the same time as its creation, try to execute it with\r\nmaximum privileges and delete it.\r\nCheck the IOC section for the full information about the commands used on the payload execution.\r\nHunt or be hunted\r\nWe have created various behaviors as well as static and network rules in order to be able to hunt\r\nand detect the GrimAgent malware family. The following screenshot shows Group-IB’s Managed\r\nhttps://www.group-ib.com/blog/grimagent/\r\nPage 26 of 32\n\nXDR and how the GrimAgent sample has been detonated and detected.\r\nFig. 12 – Group-IB Managed XDR detecting GrimAgent malware\r\nConclusion\r\nThere can be no doubt that we are facing a meticulous, careful and highly skilled adversary. Many\r\nhave already fallen victim to Ryuk ransomware, which is known to target large companies, encrypt\r\ntheir content, and ask for large sums of money. When it comes to such threats, all defensive\r\nmeasures are not enough and we believe that we must direct our IR teams and companies in\r\nintelligence-based environments. We must get ahead of the adversary before they carry out their\r\nattack.\r\nTo help the cyber community better detect the adversary, IOC and Rules sections are provided\r\nbelow.\r\nI would like to give a special thank you to my father, who has always supported me and lent me a\r\nhelping hand when I have needed him. Thank you, always.\r\nAlbert\r\nhttps://www.group-ib.com/blog/grimagent/\r\nPage 27 of 32\n\nMITRE ATT\u0026CK\r\nhttps://www.group-ib.com/blog/grimagent/\r\nPage 28 of 32\n\nIndicators of Compromise\r\nHashes\r\nName GrimAgent\r\nMZ Shellcode Launcher\r\n32b\r\nMZ Shellcode Launcher\r\n64b\r\nMD5\r\n015E5A1FA9D81\r\n51EE51D6E53 E187FBB2\r\n5F28D4AB1992685115\r\nBD46726189C92B\r\n530D2FF5A0F1B5FCDF\r\n4442655B570FCA\r\nSHA1\r\n163917CED2D1B33023FA\r\n47ECA8BEEC3E A871D517\r\n2A2C0DB4D7D018B9AC13\r\n268D1BE0AC9985464691\r\nE8621C3BA3B91EB4D0F8\r\nFB6371028B73CA19626\r\nSHA256\r\n63BD614434A70599FBAA\r\nDD0EF749A9BB68F712AC\r\nA0F92C4B8E30A3C4B4DB\r\n5CAF\r\nAEC3BF81EA6DF2C7F820\r\n10A7D6144CFF67B106BFA\r\n7BDBDDA8A39FC501\r\nF5D908C\r\n8D20AC7EBB09B5E41594\r\n3B5B07596CEA7E7DC4C3\r\nD39BEFFA7AD4E3F7FDF8\r\nCPU 32-bit 32-bit 64-bit\r\nTask scheduler arrow_drop_down\r\nFile deletion arrow_drop_down\r\nRegistry arrow_drop_down\r\nDirectories and files arrow_drop_down\r\nCommand and Control server arrow_drop_down\r\nhttps://www.group-ib.com/blog/grimagent/\r\nPage 29 of 32\n\nName GrimAgent\r\nMZ Shellcode Launcher\r\n32b\r\nMZ Shellcode Launcher\r\n64b\r\nRansomware Uncovered 2020/2021\r\nThe complete guide to the latest tactics, techniques, and procedures of ransomware\r\noperators based on MITRE ATT\u0026CK®\r\nShare this article\r\nFound it interesting? Don't hesitate to share it to wow your friends or colleagues\r\nDownload report\r\nhttps://www.group-ib.com/blog/grimagent/\r\nPage 30 of 32\n\nResources\r\nResearch Hub\r\nSuccess Stories\r\nKnowledge Hub\r\nCertificates\r\nWebinars\r\nPodcasts\r\nTOP Investigations\r\nRansomware Notes\r\nAI Cybersecurity Hub\r\nProducts\r\nThreat Intelligence\r\nFraud Protection\r\nManaged XDR\r\nAttack Surface Management\r\nDigital Risk Protection\r\nBusiness Email Protection\r\nCyber Fraud Intelligence\r\nPlatform\r\nUnified Risk Platform\r\nIntegrations\r\nPartners\r\nPartner Program\r\nMSSP and MDR Partner\r\nProgram\r\nTechnology Partners\r\nPartner Locator\r\nCompany\r\nAbout Group-IB\r\nTeam\r\nCERT-GIB\r\nCareers\r\nInternship\r\nAcademic Aliance\r\nSustainability\r\nMedia Center\r\nContact\r\nAPAC: +65 3159 3798\r\nSubscription plans Services Resource Center\r\nSubscribe to stay up to date with the\r\nlatest cyber threat trends\r\nContact\r\nhttps://www.group-ib.com/blog/grimagent/\r\nPage 31 of 32\n\nEU \u0026 NA: +31 20 226 90 90\r\nMEA: +971 4 568 1785\r\ninfo@group-ib.com\r\n© 2003 – 2026 Group-IB is a global leader in the fight against cybercrime, protecting customers\r\naround the world by preventing breaches, eliminating fraud and protecting brands.\r\nTerms of Use Cookie Policy Privacy Policy\r\nhttps://www.group-ib.com/blog/grimagent/\r\nPage 32 of 32",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MITRE"
	],
	"references": [
		"https://www.group-ib.com/blog/grimagent/"
	],
	"report_names": [
		"grimagent"
	],
	"threat_actors": [
		{
			"id": "12517c87-040a-4627-a3df-86ca95e5c13f",
			"created_at": "2022-10-25T16:07:23.61665Z",
			"updated_at": "2026-04-10T02:00:04.689Z",
			"deleted_at": null,
			"main_name": "FIN6",
			"aliases": [
				"ATK 88",
				"Camouflage Tempest",
				"FIN6",
				"G0037",
				"Gold Franklin",
				"ITG08",
				"Skeleton Spider",
				"Storm-0538",
				"TAAL",
				"TAG-CR2",
				"White Giant"
			],
			"source_name": "ETDA:FIN6",
			"tools": [
				"AbaddonPOS",
				"Agentemis",
				"AmmyyRAT",
				"Anchor_DNS",
				"BlackPOS",
				"CmdSQL",
				"Cobalt Strike",
				"CobaltStrike",
				"FlawedAmmyy",
				"FrameworkPOS",
				"Grateful POS",
				"JSPSPY",
				"Kaptoxa",
				"LOLBAS",
				"LOLBins",
				"Living off the Land",
				"LockerGoga",
				"MMon",
				"Magecart",
				"Meterpreter",
				"Mimikatz",
				"More_eggs",
				"NeverQuest",
				"POSWDS",
				"Reedum",
				"Ryuk",
				"SCRAPMINT",
				"SONE",
				"SpicyOmelette",
				"StealerOne",
				"Taurus Loader Stealer Module",
				"Terra Loader",
				"TerraStealer",
				"Vawtrak",
				"WCE",
				"Windows Credential Editor",
				"Windows Credentials Editor",
				"cobeacon",
				"grabnew"
			],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "f6f91e1c-9202-4497-bf22-9cd5ef477600",
			"created_at": "2023-01-06T13:46:38.86765Z",
			"updated_at": "2026-04-10T02:00:03.12735Z",
			"deleted_at": null,
			"main_name": "WIZARD SPIDER",
			"aliases": [
				"TEMP.MixMaster",
				"GOLD BLACKBURN",
				"DEV-0193",
				"UNC2053",
				"Pistachio Tempest",
				"DEV-0237",
				"Storm-0230",
				"FIN12",
				"Periwinkle Tempest",
				"Storm-0193",
				"Trickbot LLC"
			],
			"source_name": "MISPGALAXY:WIZARD SPIDER",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "bc119938-a79c-4e5f-9d4d-dc96835dfe2e",
			"created_at": "2024-06-04T02:03:07.799286Z",
			"updated_at": "2026-04-10T02:00:03.606456Z",
			"deleted_at": null,
			"main_name": "GOLD BLACKBURN",
			"aliases": [
				"ITG23 ",
				"Periwinkle Tempest ",
				"Wizard Spider "
			],
			"source_name": "Secureworks:GOLD BLACKBURN",
			"tools": [
				"BazarLoader",
				"Buer Loader",
				"Bumblebee",
				"Dyre",
				"Team9",
				"TrickBot"
			],
			"source_id": "Secureworks",
			"reports": null
		},
		{
			"id": "ea7bfe06-7c23-481d-b8ba-eafa6cda3bc9",
			"created_at": "2022-10-25T15:50:23.317961Z",
			"updated_at": "2026-04-10T02:00:05.280403Z",
			"deleted_at": null,
			"main_name": "FIN6",
			"aliases": [
				"FIN6",
				"Magecart Group 6",
				"ITG08",
				"Skeleton Spider",
				"TAAL",
				"Camouflage Tempest"
			],
			"source_name": "MITRE:FIN6",
			"tools": [
				"FlawedAmmyy",
				"GrimAgent",
				"FrameworkPOS",
				"More_eggs",
				"Cobalt Strike",
				"Windows Credential Editor",
				"AdFind",
				"PsExec",
				"LockerGoga",
				"Ryuk",
				"Mimikatz"
			],
			"source_id": "MITRE",
			"reports": null
		},
		{
			"id": "b3acfb48-b04d-4d3d-88a8-836d7376fa2e",
			"created_at": "2024-06-19T02:03:08.052814Z",
			"updated_at": "2026-04-10T02:00:03.659971Z",
			"deleted_at": null,
			"main_name": "GOLD FRANKLIN",
			"aliases": [
				"FIN6 ",
				"ITG08 ",
				"MageCart Group 6 ",
				"Skeleton Spider ",
				"Storm-0538 ",
				"White Giant "
			],
			"source_name": "Secureworks:GOLD FRANKLIN",
			"tools": [
				"FrameWorkPOS",
				"Metasploit",
				"Meterpreter",
				"Mimikatz",
				"PowerSploit",
				"PowerUpSQL",
				"RemCom"
			],
			"source_id": "Secureworks",
			"reports": null
		},
		{
			"id": "63061658-5810-4f01-9620-7eada7e9ae2e",
			"created_at": "2022-10-25T15:50:23.752974Z",
			"updated_at": "2026-04-10T02:00:05.244531Z",
			"deleted_at": null,
			"main_name": "Wizard Spider",
			"aliases": [
				"Wizard Spider",
				"UNC1878",
				"TEMP.MixMaster",
				"Grim Spider",
				"FIN12",
				"GOLD BLACKBURN",
				"ITG23",
				"Periwinkle Tempest",
				"DEV-0193"
			],
			"source_name": "MITRE:Wizard Spider",
			"tools": [
				"TrickBot",
				"AdFind",
				"BITSAdmin",
				"Bazar",
				"LaZagne",
				"Nltest",
				"GrimAgent",
				"Dyre",
				"Ryuk",
				"Conti",
				"Emotet",
				"Rubeus",
				"Mimikatz",
				"Diavol",
				"PsExec",
				"Cobalt Strike"
			],
			"source_id": "MITRE",
			"reports": null
		},
		{
			"id": "ee3363a4-e807-4f95-97d8-b603c31b9de1",
			"created_at": "2023-01-06T13:46:38.485884Z",
			"updated_at": "2026-04-10T02:00:02.99385Z",
			"deleted_at": null,
			"main_name": "FIN6",
			"aliases": [
				"SKELETON SPIDER",
				"ITG08",
				"MageCart Group 6",
				"ATK88",
				"TA4557",
				"Storm-0538",
				"White Giant",
				"GOLD FRANKLIN",
				"G0037",
				"Camouflage Tempest"
			],
			"source_name": "MISPGALAXY:FIN6",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "e6a21528-2999-4e2e-aaf4-8b6af14e17f3",
			"created_at": "2022-10-25T16:07:24.422115Z",
			"updated_at": "2026-04-10T02:00:04.983298Z",
			"deleted_at": null,
			"main_name": "Wizard Spider",
			"aliases": [
				"DEV-0193",
				"G0102",
				"Gold Blackburn",
				"Gold Ulrick",
				"Grim Spider",
				"ITG23",
				"Operation BazaFlix",
				"Periwinkle Tempest",
				"Storm-0230",
				"TEMP.MixMaster",
				"Wizard Spider"
			],
			"source_name": "ETDA:Wizard Spider",
			"tools": [
				"AdFind",
				"Agentemis",
				"Anchor_DNS",
				"BEERBOT",
				"BazarBackdoor",
				"BazarCall",
				"BazarLoader",
				"Cobalt Strike",
				"CobaltStrike",
				"Conti",
				"Diavol",
				"Dyranges",
				"Dyre",
				"Dyreza",
				"Dyzap",
				"Gophe",
				"Invoke-SMBAutoBrute",
				"KEGTAP",
				"LaZagne",
				"LightBot",
				"PowerSploit",
				"PowerTrick",
				"PsExec",
				"Ryuk",
				"SessionGopher",
				"TSPY_TRICKLOAD",
				"Team9Backdoor",
				"The Trick",
				"TheTrick",
				"Totbrick",
				"TrickBot",
				"TrickLoader",
				"TrickMo",
				"Upatre",
				"bazaloader",
				"cobeacon"
			],
			"source_id": "ETDA",
			"reports": null
		}
	],
	"ts_created_at": 1775490825,
	"ts_updated_at": 1775792171,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/c01e78a7ead2556bcc9a04a555dfda425a07ad0f.pdf",
		"text": "https://archive.orkl.eu/c01e78a7ead2556bcc9a04a555dfda425a07ad0f.txt",
		"img": "https://archive.orkl.eu/c01e78a7ead2556bcc9a04a555dfda425a07ad0f.jpg"
	}
}