{
	"id": "7a9d9135-ead6-4f6f-8920-9e102e3724d6",
	"created_at": "2026-04-06T00:20:20.109343Z",
	"updated_at": "2026-04-10T03:25:23.143725Z",
	"deleted_at": null,
	"sha1_hash": "2c2f98f4d2d94d3d7a72c7329d3f3c200e65c7a9",
	"title": "The Hunt for the Lost Soul: Unraveling the Evolution of the SoulSearcher Malware | FortiGuard Labs",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 899500,
	"plain_text": "The Hunt for the Lost Soul: Unraveling the Evolution of the\r\nSoulSearcher Malware | FortiGuard Labs\r\nBy Rotem Sde-Or\r\nPublished: 2022-02-25 · Archived: 2026-04-05 17:43:36 UTC\r\nA threat report published by Symantec in October 2021 recently caught our attention. It discusses an unknown\r\nthreat actor conducting an espionage campaign in Southeast Asia using a new custom malware arsenal. What\r\npiqued our curiosity most was the mention of a DLL payload loaded from the registry that had yet to be\r\ndiscovered.\r\nThe reason the module was difficult to find became apparent after analyzing its loader. The module is stored as a\r\ncompressed blob with a custom header in the registry. It is never written to disk, rendering it unlikely to appear in\r\ndatasets like VirusTotal.\r\nAnd so, we embarked on a journey to hunt for the lost module. We have now uncovered a sample of the module\r\nand a plethora of components and variants dating as far back as 2017. Reverse engineering the samples has\r\nallowed us to observe the progression of the development of this malware throughout the years. Over time, custom\r\ncode was added, components were upgraded, capabilities expanded, the code became neater, and modularity\r\nincreased.\r\nThis blog will examine the different components of this malware and their progression over time, thereby\r\nmapping the evolution of the Soul malware framework.\r\nAffected Platforms: Windows\r\nImpacted Users: Windows Users\r\nImpact: Collects sensitive information and executes additional malicious modules\r\nSeverity Level: Critical\r\nTheory of Evolution\r\nIn the earliest phase, the attackers used a backdoor that incorporated code of the open-source Gh0st RAT and\r\nNetBot Attacker tools, albeit with considerable modifications. The backdoor is embedded as a compressed blob in\r\nits dropper executable, which writes it to disk and runs it.\r\nWithin a year, the backdoor’s code was refactored and had custom code added to it, completing its transformation\r\ninto what we refer to as a Soul module. Its loader, which we dubbed SoulSearcher, changed as well. Instead of\r\ndropping the payload to disk, the compressed module is stored in the registry and is loaded in-memory.\r\nSince the beginning of 2020, we have detected increasingly intricate SoulSearcher variants, some of which\r\nsupport loading multiple modules from the registry. They have significantly transformed over time, and their\r\nconfiguration artifacts shed light on possible Soul module capabilities.\r\nhttps://www.fortinet.com/blog/threat-research/unraveling-the-evolution-of-the-soul-searcher-malware\r\nPage 1 of 31\n\nAside from the backdoors, additional tools were used, such as keyloggers and a custom-compiled 7zr tool\r\n(reduced standalone 7-zip).\r\nA complete timeline of the various components is depicted below, beginning in 2017 with the first keylogger and\r\nbackdoor and ending with the recent SoulSearcher variants found in November 2021.\r\nhttps://www.fortinet.com/blog/threat-research/unraveling-the-evolution-of-the-soul-searcher-malware\r\nPage 2 of 31\n\nhttps://www.fortinet.com/blog/threat-research/unraveling-the-evolution-of-the-soul-searcher-malware\r\nPage 3 of 31\n\nFigure 1: Timeline of the Soul malware framework\r\nSide note: This timeline is based on compilation timestamps, and although these can be tampered with, in the case\r\nof this malware framework, we consider them to be authentic. This is partly because the time distribution of the\r\ncollected samples correlates with our understanding of the components’ capabilities and their sightings in the wild.\r\nFurthermore, related samples such as loaders and their payloads were compiled within seconds of each other.\r\nSeveral characteristics are common in all of the components we found:\r\nDynamiCall import obfuscation from the leaked source code of the notorious Hacking Team’s\r\nRCS backdoor\r\nStack strings\r\nData structure similarity, such as the configuration structure\r\nEncryption and compression algorithms\r\nNames of mutexes, events, and file mappings\r\nAdjacent compilation timestamps\r\nThe Original Soul Backdoor\r\nThis is the backdoor used in the earliest phase by the threat actor. It was compiled in October 2017 and used\r\nrevised code from public repositories and other malware leaked online, such as:\r\nDynamiCall\r\nGh0st RAT\r\nFile manipulation functions\r\nCMD shell code\r\nCommunication messages and structures\r\nHTran (an open-source connection bouncer tool)\r\n7zip\r\nThe backdoor is a DLL dropped to the disk by a simple dropper. The dropper LZMA-decompresses the backdoor\r\nand a configuration that they both share. The dropper writes the backdoor to a path specified by the configuration\r\nand appends the configuration to it as an overlay. Depending on the command-line argument passed to the\r\ndropper, the backdoor is executed with LoadLibrary or rundll32.exe. Finally, the dropper deletes itself from the\r\ndisk.\r\nhttps://www.fortinet.com/blog/threat-research/unraveling-the-evolution-of-the-soul-searcher-malware\r\nPage 4 of 31\n\nConfiguration\r\nThe backdoor reads its configuration from its file overlay and decrypts it by subtracting and XORing each byte\r\nwith 0x13.\r\nThe configuration begins with a sequence of bytes whose significance is unknown but is identical in all the\r\nsamples we found. Other fields are the backdoor file name or full path, the C2 address, and the port in little-endian. The configuration also contains a service name and description, both unused. In one sample, the string\r\n“NetBot” is set as the file name.\r\nFigure 2: Configuration for the backdoor\r\nTwo other fields, an array of DWORDs and a flag (highlighted at offset 0x1f0), control if and when the backdoor\r\nshould suppress command-related communication.\r\nThe array's values determine the days and hours to accept commands. In this sample, all values are 2. Each index\r\nrepresents a particular day of the week and the hour of the day. If the value at a given index is 0, requests for\r\ncommands are withheld on the corresponding day and hour.\r\nhttps://www.fortinet.com/blog/threat-research/unraveling-the-evolution-of-the-soul-searcher-malware\r\nPage 5 of 31\n\nThe flag determines if receiving commands should be suppressed while there is activity on the machine, according\r\nto the following conditions:\r\nOther than the current session, there is an active console session in the system\r\nOther than the current session, there is an active or connected RDP session in the system\r\nThe sessions are monitored by using the WTSRegisterSessionNotification and WTSEnumerateSessions APIs.\r\nDepending on the configuration, the backdoor can receive commands in active mode (as a client) or passive mode\r\n(as a server). There are two port numbers, one for each mode.\r\nIf the server port is not 0, the backdoor contacts the server to receive commands.\r\nIf the listening port is not 0, the backdoor listens on that port and awaits commands from incoming\r\nconnections (only one connection may be active at a time).\r\nCommunication\r\nMessages to the C2 server, including requests for commands, have a fixed structure. Every request to the server is\r\ncomposed of hardcoded HTTP headers impersonating legitimate network traffic to taboola[.]com.\r\nFigure 3: Constant HTTP headers sent in requests to the server\r\nThe structure of the HTTP body sent to the server is depicted below. CompressedBuffer is zlib-deflated data.\r\nhttps://www.fortinet.com/blog/threat-research/unraveling-the-evolution-of-the-soul-searcher-malware\r\nPage 6 of 31\n\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\nstruct BackdoorRequest {\r\nDWORD MessageType;\r\nDWORD DecompressedBufferSize;\r\nDWORD DecompressedBufferSize;\r\nDWORD CompressedBufferSize;\r\nBYTE CompressedBuffer[CompressedBufferSize];\r\n};\r\nFigure 4: Format of message body sent by the backdoor\r\nReceipt of commands begins when the backdoor sends information about the machine to the server with a\r\nMessageType of 0x11000000:\r\nHostname\r\nIP address(es)\r\nCPU architecture\r\nRAM size\r\nThe server response structure is similar to that of the request:\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\nstruct ServerResponse {\r\nDWORD CommandType;\r\nDWORD DecompressedBufferSize;\r\nDWORD DecompressedBufferSize;\r\nDWORD CompressedBufferSize;\r\nBYTE CompressedBuffer[CompressedBufferSize];\r\n};\r\nFigure 5: Format of server response message body for backdoor requests\r\nIn a separate thread, the backdoor may signal the server if command receipt suppression is currently in effect with\r\nMessageType 0x1100000B.\r\nCommands\r\nWhen the server sends a command, it is one of the CommandType values in the table below, and the\r\nCompressedBuffer field is empty. The backdoor sends out an additional request for the command's parameters,\r\nwith a MessageType value specified according to the specific command.\r\nType Name\r\nhttps://www.fortinet.com/blog/threat-research/unraveling-the-evolution-of-the-soul-searcher-malware\r\nPage 7 of 31\n\n0xFFFFFFFF There are no commands to run.\r\n0x20000000 Close the socket and stop receiving commands.\r\n0x21000000\r\nFile manipulation functions that include moving, copying, deleting, downloading, and/or\r\nuploading files.\r\n0x23000000\r\nIt opens an interactive CMD shell, allowing the attacker to execute CMD commands until\r\nterminating the shell by sending the “Exit” command.\r\n0x38000000 transmitdata function of HTran.\r\nFigure 6: Table of commands implemented by the backdoor\r\nThe same is true when the backdoor works in passive mode, except it is limited to handling file manipulation,\r\nCMD, and close socket commands.\r\nThe Soul-Searching Loaders\r\nSoulSearcher is a type of second-stage loader seen in the wild since November 2018. All the samples we found are\r\nDLLs with a similar flow of operation. They are responsible for executing the Soul module payload and parsing\r\nits configuration.\r\nThe major differences between the SoulSearcher variants are the type of configuration passed to the payload and\r\nthe location where the configuration and payload are stored.\r\nConfiguration Format Date of Earliest Sample Configuration Location Payload Location\r\nBinary Nov 2018\r\nOverlay + registry\r\nFile\r\nOverlay\r\nFile\r\nXML Apr 2020\r\nRegistry\r\nFile mapping\r\nFile\r\nRegistry\r\nhttps://www.fortinet.com/blog/threat-research/unraveling-the-evolution-of-the-soul-searcher-malware\r\nPage 8 of 31\n\nSemicolon-separated Aug 2021 Embedded in SoulSearcher Registry\r\nFigure 7: Table of SoulSearcher types\r\nBinary SoulSearcher\r\nThese are the earliest SoulSearcher samples in our possession. One of these samples has its payload—a Soul\r\nmodule—embedded in it. Every sample exports two functions: DumpAnalyze and DumpAnalyzeEx.\r\nFirst, SoulSearcher searches for the module and configuration, either in its overlay data or files on the disk. If they\r\nare found, it saves the module to the registry. Regardless, SoulSearcher then fetches the payload from the registry,\r\nreflectively loads it, and passes the configuration to it as an argument.\r\nThe configuration is located at the end of the overlay and is decrypted using SUB-XOR 0x13. It has the same\r\nformat as that of the original Soul backdoor, with an additional field that determines the size of the compressed\r\nSoul module in the overlay. Another part of the configuration is retrieved from the HKCU\\Software\\OIfkO2i1\r\nregistry value and decrypted with SUB-XOR 0x79. If it doesn’t exist, this path is also queried in the other users’\r\nregistry hives.\r\nIf the argument “-h \u003cHANDLE\u003e” was passed to the SoulSearcher’s export, the configuration and the payload are\r\nextracted from sdc-integrity.dat instead of the overlay. They are extracted in the exact same way as before. The\r\nsupplied argument is a handle to a DLL used to retrieve the directory path in which the .dat file resides.\r\nIn any case, the module is saved to the registry at HKCU\\Software\\kuhO6Ba0kT.\r\nXML SoulSearcher\r\nEvery XML SoulSearcher begins with obtaining the configuration previously dropped by an unknown component.\r\nMost samples retrieve it from the registry, and some have the option of retrieving it from a file mapping object or\r\na file on the disk.\r\nFor example, one sample retrieves the configuration from one of the following, depending on whether it is running\r\nas a service:\r\nA value name in the format of a GUID under the service parameters at\r\nHKLM\\SYSTEM\\CurrentControlSet\\Services\\\u003cServiceName\u003e\\Parameters\r\nA file mapping object named Global\\CacheDataMapping\r\nThe retrieved binary data has the following structure:\r\n 1\r\n 2\r\n 3\r\n 4\r\nstruct StoredConfiguration {\r\nDWORD Magic;\r\nDWORD Unused;\r\nBYTE LzmaProperties[5];\r\nhttps://www.fortinet.com/blog/threat-research/unraveling-the-evolution-of-the-soul-searcher-malware\r\nPage 9 of 31\n\n5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\nDWORD ConfigSize;\r\nDWORD CompressedConfigSize;\r\nBYTE ConfigMD5[0x21];\r\nBYTE CompressedConfigMD5[0x21];\r\nBYTE CompressedConfig[CompressedConfigSize];\r\n};\r\nFigure 8: Structure of configuration fetched from the registry\r\nThe structure is processed in the following manner to retrieve the XML configuration:\r\n1. Verify that the size of CompressedConfig is equal to CompressedConfigSize\r\n2. Verify that CompressedConfigSize and ConfigSize are not 0\r\n3. Verify that both MD5 checksums are not 0\r\n4. Ensure that Magic holds the byte sequence 86 AE 00 00\r\n5. Perform MD5 checksum validation of the compressed configuration\r\n6. LZMA-decompress the configuration\r\n7. Perform MD5 checksum validation of the decompressed configuration\r\nIn one variant, an extra step is taken at the start to decrypt the registry data using AES-256 CBC. The key is\r\nretrieved from one of two hardcoded paths.\r\nOlder samples deserialize the resulting string with the CreateXmlReader API, while newer samples use the\r\nTinyXML open-source library. The XML attribute names shed light on the Soul modules loaded from the registry.\r\nSemicolon SoulSearcher\r\nBeginning in August 2021, SoulSearcher variants began using a hardcoded semicolon-separated configuration\r\ninstead of an XML one from the registry. The first variant of this type was compiled just over a full month before\r\nthe release of Symantec’s report.\r\nFigure 9: Example of a semicolon-separated configuration\r\nThis configuration lacks the indicative XML attribute names, like those in the XML configurations, resulting in a\r\nmore obscure tool. Nevertheless, here is what we can say about some of these fields:\r\nWe believe the first field, do5Kc1diLHgq5f6 represents the configuration type. In the XML configurations,\r\nthe type is represented by the string X6bmLMbAL29AlxB.\r\nOne of the values states whether the SoulSearcher was installed as a service. If so, the configuration\r\nincludes fields for details about the service, such as its name.\r\nSome of the values determine which Soul modules should be loaded.\r\nOne field may contain a registry path from which to load a Soul module (while other modules are loaded\r\nfrom hardcoded paths).\r\nhttps://www.fortinet.com/blog/threat-research/unraveling-the-evolution-of-the-soul-searcher-malware\r\nPage 10 of 31\n\nWhen the Soul is Found\r\nOlder SoulSearcher variants load a single Soul module, while some more recent XML and Semicolon\r\nSoulSearchers may load up to four, depending on their configuration.\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\nstruct StoredModule {\r\nDWORD Unused;\r\nQWORD ModuleSize;\r\nQWORD CompressedModuleSize;\r\nBYTE ModuleMD5[0x21];\r\nBYTE CompressedModule[CompressedModuleSize];\r\n};\r\nFigure 10: Structure of the payload fetched from the registry\r\nEvery module is fetched from the registry in a similar manner as the configuration:\r\n1. Verify that the size of CompressedModule is equal to CompressedModuleSize\r\n2. LZMA-decompress the module\r\n3. Perform MD5 checksum validation of the decompressed module\r\n4. Ensure that the architecture of the module matches the architecture of the SoulSearcher\r\nThis procedure is identical in every SoulSearcher sample apart from the Binary SoulSearchers, whose structure\r\nslightly differs.\r\nThe SoulSearcher reflectively loads the module in-memory and calls its Construct export. Some earlier variants\r\nalso call additional exports of the module.\r\nSoul Backdoor Reincarnated\r\nWe found that one Binary SoulSearcher sample from November 2018 had an embedded payload.\r\nThis Soul module closely resembles the original backdoor in terms of functionality, although its code is much\r\nneater. Thorough examination revealed that the code of the original backdoor was reorganized as various exports.\r\nFor instance, the code responsible for sending and receiving HTTP messages was divided into the SendMsg and\r\nRecvMsg exports.\r\nhttps://www.fortinet.com/blog/threat-research/unraveling-the-evolution-of-the-soul-searcher-malware\r\nPage 11 of 31\n\nFigure 11: Soul backdoor module exported functions\r\nConfiguration\r\nThe SoulSearcher calls the module’s BeginConnect export with the configuration as an argument. The\r\nconfiguration has the same binary format as the original backdoor’s configuration but without the service-related\r\nfields.\r\nFigure 12: Configurations of the original backdoor (left) and the newer backdoor module (right)\r\nCommunication\r\nUnlike the original backdoor, this Soul module only receives commands as a client.\r\nIf resolving the server address via gethostbyname API fails, the backdoor also tries querying two hardcoded DNS\r\nservers using an undocumented feature of the DnsQuery API:\r\n193.0.14.129 (DNS root server)\r\nhttps://www.fortinet.com/blog/threat-research/unraveling-the-evolution-of-the-soul-searcher-malware\r\nPage 12 of 31\n\n8.8.8.8 (Google Public DNS)\r\nThe constant headers of the request have been changed to impersonate traffic to s-microsoft[.]com, and the\r\nGetSubInfo export collects the machine information.\r\nFigure 13: New constant HTTP headers sent in requests to the server\r\nCommands\r\nThe message structures are the same as those of the original backdoor. As seen in the table below, several new\r\ncommand codes were not present in the original backdoor. When one of the five named commands is received, the\r\nbackdoor downloads and executes a DLL from the server. The command names are disclosed in the binary and are\r\npassed to the command DLLs as part of their arguments. Because the DLLs themselves are unknown to us, we can\r\nonly speculate on their functionality based on their names and the implementations of the same command types in\r\nthe original backdoor code.\r\nType Name\r\n0xFFFFFFFF There are no commands to run.\r\n0x20000000 Close the socket and stop receiving commands.\r\nhttps://www.fortinet.com/blog/threat-research/unraveling-the-evolution-of-the-soul-searcher-malware\r\nPage 13 of 31\n\n0x21000000 File\r\n0x23000000 Cmd\r\n0x38000000 Htran\r\n0x39000000\r\nUpdate configuration in the registry. The server response buffer is ADD-XOR 0x79\r\nencrypted before being written to the registry (hardcoded path).\r\n0x3A000001 Free command structures and release command-related mutexes.\r\n0x3B000000 MemoryLoader\r\n0x3C000000 UsbNtf\r\nFigure 14: Table of commands implemented by the backdoor module\r\nAn additional socket connection is created to download a command DLL from the server. First, the backdoor\r\nsends a message of type 0x1100000C with a buffer that contains the constant value 0x4096C083. Like all\r\nrequests, it is sent via SendMsg in the aforementioned BackdoorRequest structure. Next, it sends another message\r\nof the same type, but this time the buffer is structured as shown below. The Architecture field contains a value of\r\neither 32 or 64 depending on the backdoor’s architecture.\r\n1\r\n2\r\n3\r\n4\r\nstruct CommandRequest {\r\nDWORD CommandType;\r\nBYTE Architecture[6];\r\n};\r\nFigure 15: Structure of request for a command DLL from the server\r\nThe server replies to the backdoor with the following structure:\r\n 1\r\n 2\r\nstruct CommandResponse {\r\nDWORD Unused0;\r\nhttps://www.fortinet.com/blog/threat-research/unraveling-the-evolution-of-the-soul-searcher-malware\r\nPage 14 of 31\n\n3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\nBYTE Unused1[6];\r\nQWORD ModuleSize;\r\nQWORD CompressedModuleSize;\r\nBYTE ModuleMD5[0x21];\r\nBYTE CompressedModuleMD5[0x21];\r\nQWORD Unused2;\r\nBYTE CompressedModule[CompressedModuleSize];\r\n};\r\nFigure 16: Structure of server response for a command DLL\r\nThe backdoor uses the structure to load the command DLL in the following manner:\r\n1. Validate MD5 checksum of compressed module\r\n2. LZMA-decompress the compressed module\r\n3. Validate MD5 checksum of decompressed module\r\n4. If steps 2 or 3 fail, reissue the request to the server\r\n5. Reflectively load the module in memory\r\n6. Call the module’s Construct export with arguments that include, among other things:\r\n1. The constant value 0x4096C083 (same value sent to the server priorly)\r\n2. The name of the command (such as “File” or “UsbNtf”)\r\n3. The backdoor configuration\r\n4. The CommandResponse structure received from the server\r\nMore Souls Than One\r\nAs mentioned earlier, each XML SoulSearcher parses an XML-formatted configuration that contains attributes\r\nwith informative names. Based on such artifacts, we were able to classify potential payloads of various samples in\r\nour possession.\r\nBackdoor\r\nThese SoulSearcher samples are closely coupled to their payloads to the extent that they are intricate orchestrators\r\nrather than plain loaders. In addition to parsing a configuration, they invoke multiple exported functions of the\r\nSoul module to create full backdoor logic. The configuration fields and imported function names indicate remote\r\nshell capability and the utilization of Dropbox.\r\nConfiguration Fields Exports Names\r\nIp\r\nDns\r\nCntPort\r\nConstruct\r\nConnectHost1\r\nForceCloseSocket\r\nhttps://www.fortinet.com/blog/threat-research/unraveling-the-evolution-of-the-soul-searcher-malware\r\nPage 15 of 31\n\nLstPort\r\nBlog\r\nDropboxBlog\r\nSvcName\r\nSvcDisp\r\nSvcDesc\r\nSvcDll\r\nOlPass\r\nOlTime\r\nSelfDestroy\r\nCopyReserveMem\r\nRecv\r\nRecvEx\r\nSend\r\nSendEx\r\nBindShell\r\nAccept\r\nTransmitData_htran\r\nKillChildenProcessTree\r\nExtractIPToConnect\r\nExtractIPToConnect1\r\nGetDeviceInfoString1\r\nGetPseudoSocketInfo\r\nDecrypt_ByteToByte\r\nFigure 17: Configuration fields and imported function names seen in older SoulSearcher versions\r\nAdvanced RAT\r\nOne SoulSearcher parses numerous configuration fields different from the backdoor:\r\nAesPass\r\nClipBoardMntEnable\r\nDestroyDate\r\nDestroyDay\r\nDestroyMode\r\nDestroyWiFiName\r\nDestroyWiFiSearchMinu\r\nDirDiskInternal\r\nDropboxAppToken1\r\nDropboxAppToken2\r\nDropboxAppToken3\r\nEnableDropbox\r\nEnableFileMnt\r\nEnableHijack1\r\nEnableKeyLog\r\nEnableService\r\nExcludeDir\r\nFileExt\r\nFileSizeMb\r\nHijack1DllPath\r\nRegSubKey_Exist\r\nRegSubKey_Rec\r\nRegValueDataSz\r\nRegValueName_Exist\r\nRegValueName_Rec\r\nSaveInFile\r\nSaveInReg\r\nScreenMngEnable\r\nServiceDescription\r\nServiceDisplayName\r\nServiceDllPath\r\nServiceHide\r\nServiceImagePath\r\nServiceName\r\nServiceRegValueName_Cfg\r\nServiceRegValueName_MemMod1\r\nServiceRegValueName_MemMod2\r\nServiceRegValueName_MemMod3\r\nServiceSessionIsolationBypass\r\nTriggerTime\r\nhttps://www.fortinet.com/blog/threat-research/unraveling-the-evolution-of-the-soul-searcher-malware\r\nPage 16 of 31\n\nHijack1RegSubKey_MemMod1\r\nHijack1RegValueName_Cfg\r\nHijack1RegValueName_MemMod1\r\nIncludeDir\r\nRecDataPath\r\nRegKey_Exist\r\nRegKey_Rec\r\nUsbExt\r\nUsbExtMode\r\nz7zPass\r\nz7zSizeMb\r\nz7zStoreDir\r\n \r\nFigure 18: Configuration fields found in one SoulSearcher sample\r\nIf the EnableDropbox attribute is set to true, the SoulSearcher loads a module from the path specified by\r\nServiceRegValueName_MemMod3. If the EnableKeylog  is set, a module is loaded from the path specified by\r\nServiceRegValueName_MemMod1.\r\nProxy\r\nThese samples’ configuration indicates proxy capabilities over HTTP and HTTPS, as well as the ability to run\r\nCMD commands.\r\nCmdPrefix\r\nCmdSuffix\r\nEnableHttps1\r\nPort\r\nPort2\r\nProxyIP1\r\nProxyIP2\r\nProxyPort1\r\nProxyPort2\r\nProxyUserName1\r\nProxyUserName2\r\nProxyUserPass1\r\nEnableHttps2\r\nInterval\r\nMachineGUID\r\nProxyUserPass2\r\nRegPath\r\nRegRootKey\r\nRegValueName_Cfg\r\nRegValueName_Svr32\r\nRegValueName_Svr64\r\nURL2\r\nUrl\r\nFigure 19: Configuration fields related to proxy functionality\r\nAdditional Components\r\nFirst Stage Loader\r\nAs mentioned before, SoulSearcher is a second-stage component. We also identified a first-stage loader of the\r\nBinary SoulSearcher variant.\r\nhttps://www.fortinet.com/blog/threat-research/unraveling-the-evolution-of-the-soul-searcher-malware\r\nPage 17 of 31\n\nThis loader is a DLL with a single exported function, named SntpService, and depends on a utility DLL named\r\nSntpService.dll, which is expected to already reside on disk. These names are likely used to resemble a legitimate\r\nsecurity software product of Sophos of the same name (as seen here).\r\nThe loader checks if its process name is either MSDTC.exe or svchost.exe prior to running SntpService in a new\r\nthread. In the latter case, a mutex named DBWinMutex_1 is created (also used in the Soul module).\r\nThe loader performs two operations. First, it decrypts two .dat files from its directory and saves the output to the\r\nregistry:\r\nsdc-integrity.dat is written to HKCR\\.rat\\PersistentHandler\\TypeFace\r\nscs-integrity.dat is written to HKCR\\.rat\\PersistentHandler\\MagicNumber\r\nThe decryption scheme is AES-256 CBC with the SHA256 hash of a hardcoded value used as the key. Both files\r\nare then deleted from the disk, implying this procedure occurs only on initial infection or when updates are\r\ndeployed.\r\nSecond, the data from the TypeFace value is used to load SoulSearcher. It consists of a structure that contains a\r\nbuffer and its size. The loader skips the buffer’s last 0x3d0 bytes, as those are its configuration, and passes the rest\r\nof the buffer to the Decrypt_ByteToByte function of SntpService.dll. The output is a PE, which the loader\r\nreflectively loads and then invokes its DumpAnalyze export. The loader passes a handle of itself to the\r\nSoulSearcher as an argument, both as a pointer and in string format: “-h \u003cHANDLE\u003e”.\r\n Additional exports of SntpService.dll are also resolved:\r\nhttps://www.fortinet.com/blog/threat-research/unraveling-the-evolution-of-the-soul-searcher-malware\r\nPage 18 of 31\n\nhttps://www.fortinet.com/blog/threat-research/unraveling-the-evolution-of-the-soul-searcher-malware\r\nPage 19 of 31\n\nFigure 20: Imported functions from SntpService.dll\r\nWe found a variant of the utility DLL uploaded to VirusTotal with the name of Kaspersky Antivirus’s AvpCon.dll.\r\nSimilar to the Sophos case cited earlier, this is likely done to appear legitimate. Despite its exports being named\r\n“Encrypt” and “Decrypt”, all functions actually perform LZMA compression or decompression. This correlates\r\nwith a Binary SoulSearcher sample that we found compressed, not encrypted.\r\nFigure 21: Exports of AvpCon.dll\r\nKeyloggers\r\nThe keyloggers were compiled between mid-2017 to late 2020. They all share very similar code, with few changes\r\nbetween them. In addition to the keyloggers Symantec reported on, we found another sample from September\r\n2020. Although its keylogging function is identical to the other samples, the rest of the code has significant\r\ndifferences.\r\nThe keyloggers read their configuration from a file with the same name but with the .dll extension trimmed. Our\r\nsample, however, uses a configuration from the registry, and the file acts as a kill-switch: if it exists, the keylogger\r\nterminates. This sample also has stack strings and DynamiCall obfuscations not present in previous samples.\r\nThe keylogger ensures it is running in Explorer.exe and retrieves its configuration by reading its own last\r\n0x208 bytes and decrypting them. The decryption is done by adding and XORing each byte with constant values.\r\nNext, the encrypted configuration is set in the registry at HKCU\\Software\\F32xhfHX. On future executions, the\r\nconfiguration will be fetched from this key. The configuration contains two paths:\r\nKeylogger module file – C:\\Windows\\SndVolSSO.DLL\r\nKeylogging output file – C:\\users\\minh\\AppData\\Local\\OneDrive\\Cache.dat\r\nhttps://www.fortinet.com/blog/threat-research/unraveling-the-evolution-of-the-soul-searcher-malware\r\nPage 20 of 31\n\nInterestingly, the output file path includes a username, hinting that this sample may have been intended for a\r\nspecific target machine.\r\nThe keylogger monitors keystrokes using GetRawInputData and clipboard data and logs them in an output file as\r\nplaintext. The output file is timestomped to make its timestamp identical to svchost.exe on the infected machine.\r\nErrors returned from GetRawInputData are logged to C:\\ProgramData\\Users.inf. The keylogger also logs IME\r\nvirtual-key codes, which support some Asian languages.\r\nFigure 22: Example of keylogger output file “Cache.dat”\r\nCommand-Line Executer Service\r\nThis is a lightweight service DLL that executes a CMD command from the registry key HKCR\\.c\\Type\\Type00. It\r\nruns the command on 20:00, and if no process named powershell.exe is active on the system. It is compiled with\r\nDynamiCall obfuscation.\r\n7zr.exe\r\nThis custom-compiled 7zr executable is modified to include DynamiCall obfuscation.\r\nConclusion\r\nThe Soul malware framework has been in active use since 2017, and the threat actors have been steadily evolving\r\ntheir tools and capabilities to this day. It should be emphasized that despite the reliance of the earlier tools on\r\nopen-source code, custom keyloggers were already in use at the time, and significant development of custom code\r\nhas transpired since. Its modular, multi-stage, reflectively executed payloads demonstrate competent adversarial\r\ntradecraft and are signs of a well-resourced group. Although the attackers’ identity is currently unknown, we\r\nbelieve that they are possibly state-sponsored.\r\nThe details shared in this report stem from the comprehensive analysis of numerous samples. Nevertheless, we\r\nhave a feeling that this is just the tip of the iceberg, with more payloads and capabilities in the group’s arsenal to\r\nexpose in the future.\r\nFortinet Solutions\r\nhttps://www.fortinet.com/blog/threat-research/unraveling-the-evolution-of-the-soul-searcher-malware\r\nPage 21 of 31\n\nFortiEDR detects and blocks these threats out-of-the-box without any prior knowledge or special configuration. It\r\ndoes this using its post-execution prevention engine to identify malicious activities:\r\nFigure 23: FortiEDR blocking the Soul backdoor communication to the C2 server\r\nAll network IOCs have been added to the FortiGuard WebFiltering blocklist.\r\nThe FortiGuard AntiVirus service engine is included in Fortinet’s FortiGate, FortiMail, FortiClient,\r\nand FortiEDR solutions. FortiGuard AntiVirus has coverage in place as follows:\r\nW64/SoulSearcher.B7D1!tr\r\nW32/SoulSearcher.B7D1!tr\r\nW64/SoulSearcherKeyLogger.B7D1!tr.spy\r\nW32/SoulSearcher.B7D1!tr \r\nData/SoulSearcher.B7D1!tr\r\nIn addition, as part of our membership in the Cyber Threat Alliance, details of this threat were shared in real-time\r\nwith other Alliance members to help create better protections for customers.\r\nAppendix A: MITRE ATT\u0026CK Techniques\r\nID Description\r\nT1569.002 System Services: Service Execution\r\nT1055 Process Injection\r\nhttps://www.fortinet.com/blog/threat-research/unraveling-the-evolution-of-the-soul-searcher-malware\r\nPage 22 of 31\n\nT1112 Modify Registry\r\nT1567 Exfiltration Over Web Service\r\nT1041 Exfiltration Over C2 Channel\r\nT1132 Data Encoding\r\nT1082 System Information Discovery\r\nT1083 File and Directory Discovery\r\nT1140 Deobfuscate/Decode Files or Information\r\nT1071.001 Application Layer Protocol: Web Protocols\r\nT1056.001 Input Capture: Keylogging\r\nT1059.003 Command and Scripting Interpreter: Windows Command Shell\r\nT1115 Clipboard Data\r\nT1592 Gather Victim Host Information\r\nT1090.001 Proxy: Internal Proxy\r\nT1070.006 Indicator Removal on Host: Timestomp\r\nAppendix B: IOCs\r\nhttps://www.fortinet.com/blog/threat-research/unraveling-the-evolution-of-the-soul-searcher-malware\r\nPage 23 of 31\n\nIOC Type Details\r\n1af5252cadbe8cef16b4d73d4c4886ee9cecddd3625e28a59b59773f5a2a9f7f\r\nSHA-256\r\nSoulSearcher\r\na6f75af45c331a3fac8d2ce010969f4954e8480cbe9f9ea19ce3c51c44d17e98\r\nSHA-256\r\nSoulSearcher\r\nc4efb58723fd75d51eb92302fbd7541e4462f438282582b5efa3c6c7685e69fd\r\nSHA-256\r\nSoulSearcher\r\nedb14233eccb5b6e2d731831e7b18b8b17ea6a3f8925fb5899ce2ef985a66b68\r\nSHA-256\r\nSoulSearcher\r\nfdf0db7f6b60d7563268c15c634adb47e8eec34adfcbf9b10e973916c7517157\r\nSHA-256\r\nSoulSearcher\r\nc7481d6975646b605aba3fb11686e34ee205f7e280069e9d5bf0c1c2eca79be8\r\nSHA-256\r\nSoulSearcher\r\n0f7af0cad4aade0e7058051a449059b35358ddda075d88b2d289625adc02deef\r\nSHA-256\r\nSoulSearcher\r\n3cb4887bec169c75f58bc4ed1c6fd3703cc46512596e62186cf8329448dbb47b\r\nSHA-256\r\nSoulSearcher\r\ncb954f06c94493c87f25651271657aeb1e3e24f26b6552d3e616bbc2dc660679\r\nSHA-256\r\nSoulSearcher\r\n78feb564c4f6c240ddb17dd0f49ae96df04ee594ed24df81f583136fccf60c1d\r\nSHA-256\r\nSoulSearcher\r\nhttps://www.fortinet.com/blog/threat-research/unraveling-the-evolution-of-the-soul-searcher-malware\r\nPage 24 of 31\n\nbc91a4fb16f14fb1c436c2bdc7c80b87a02caa5de17897614d07bc7bda200590\r\nSHA-256\r\nSoulSearcher\r\n7edd7d406159ab0eecb22ddbd6060de7c24a4eb0b61fa527935310b94d3b9db4\r\nSHA-256\r\nSoulSearcher\r\nb02b8b6c3d517c6b8652b898963068ba12cd360b5cdcf0aad5fe6ff64f0e9920\r\nSHA-256\r\nSoulSearcher\r\nec164902cbe8daaa88ae923719c5dac900715f3e32d4cea6e71ca04c7cecf3e2\r\nSHA-256\r\nSoulSearcher\r\nbac4b50727c69ca7cc3c0a926bb1b75418a8a0eabd369a4f7118bb9bba880e06\r\nSHA-256\r\nFirst stage\r\nloader for\r\nSoulSearcher\r\n69a9ab243011f95b0a1611f7d3c333eb32aee45e74613a6cddf7bcb19f51c8ab\r\nSHA-256Original Soul\r\nbackdoor\r\n579fa00bc212a3784d523f8ddd0cfc118f51ca926d8f7ea2eb6e27157ec61260\r\nSHA-256Original Soul\r\nbackdoor\r\n8ff18b6fb5fe4f221cd1df145a938c57bdd399dc24e1847b0dc84a7b8231458f\r\nSHA-256Original Soul\r\nbackdoor\r\nf97161aaa383e51b2b259bb618862a3a5163e1b8257832a289c72a677adec421\r\nSHA-256\r\nOriginal Soul\r\nbackdoor\r\ndropper\r\nd3647a6670cae4ff413caf9134c7b22b211cb73a172fc1aa6a25b88ff3657597\r\nSHA-256Original Soul\r\nbackdoor\r\nhttps://www.fortinet.com/blog/threat-research/unraveling-the-evolution-of-the-soul-searcher-malware\r\nPage 25 of 31\n\nf5cd13b2402190ec73c526116abea5ebab7bd94bcdb68cc2af4f3b75a69ba9c5\r\nSHA-256\r\nKeylogger\r\na15eda7c75cf4aa14182c3d44dc492957e9a9569e2d318881e5705da2b882324\r\nSHA-256\r\nKeylogger\r\n967e8063bd9925c2c8dd80d86a6b01deb5af54e44825547a60c48528fb5f896d\r\nSHA-256\r\nKeylogger\r\n64f036f98aad41185163cb328636788a8c6b4e1082ae336dad42b79617e4813d\r\nSHA-256\r\nKeylogger\r\n7b838fcad7a773bfd8bc26a70f986983553d78b4983d0f2002174f5e56f7f521\r\nSHA-256Soul\r\nbackdoor\r\n40fda8137d8464d61240314b6de00ae5c14ed52019e03e4dcadfc00b32c89d23\r\nSHA-256\r\nCommand-line executer\r\nservice\r\n5dee99beb0b6ba1ebdb64515be1d9307262d9b57b0900310d57290dca40bb427\r\nSHA-256\r\n7zr.exe\r\n6b70ad053497f15b0d4b51b5edabeced3077dddb71b28346df7c7ea18c11fcdf\r\nSHA-256\r\n7zr.exe\r\n852c98a6fbd489133411848775c19a2525274eac9a89a09a09d511915c7cbafc\r\nSHA-256\r\nAvpCon.dll\r\ngmy.cimadlicks[.]net Network -\r\napp.tomelife[.]com Network -\r\nhttps://www.fortinet.com/blog/threat-research/unraveling-the-evolution-of-the-soul-searcher-malware\r\nPage 26 of 31\n\ncommunity.weblives[.]net Network -\r\n23.91.108[.]12 Network -\r\nGlobal\\vQVomit4 Mutex -\r\nGlobal\\mFNXzY0g Mutex -\r\nGlobal\\DefaultModuleMutex Mutex -\r\nGlobal\\DBWinMutex_1 Mutex -\r\nGlobal\\DBWinMutex_2 Mutex -\r\nGlobal\\VirusScanWinMsg Event -\r\nGlobal\\3GS7JR4S Event -\r\nGlobal\\SecurityEx Event -\r\nGlobal\\CacheDataMappingFile\r\nFile\r\nmapping\r\n-\r\nC:\\Windows\\System32\\wlbsctrl.dll\r\nFile\r\nname\r\n-\r\nC:\\Windows\\System32\\ikeext2.dll\r\nFile\r\nname\r\n-\r\nhttps://www.fortinet.com/blog/threat-research/unraveling-the-evolution-of-the-soul-searcher-malware\r\nPage 27 of 31\n\nC:\\Windows\\System32\\d6w48ttth.dll\r\nFile\r\nname\r\n-\r\nC:\\Windows\\System32\\shsvc.dll\r\nFile\r\nname\r\n-\r\nC:\\Windows\\System32\\netcsvc.dll\r\nFile\r\nname\r\n-\r\nC:\\Windows\\System32\\fc2qhm7r9.dll\r\nFile\r\nname\r\n-\r\nC:\\Windows\\SndVolSSO.DLL\r\nFile\r\nname\r\n-\r\nSvrLdr_xpsservices.dll\r\nFile\r\nname\r\n-\r\ntimedateapi.dll\r\nFile\r\nname\r\n-\r\nmsfte.dll\r\nFile\r\nname\r\n-\r\nwsecapi.dll\r\nFile\r\nname\r\n-\r\nC:\\Programdata\\Microsoft\\svchost.exe\r\nFile\r\nname\r\n-\r\nNvStreamer.dll\r\nFile\r\nname\r\n-\r\nhttps://www.fortinet.com/blog/threat-research/unraveling-the-evolution-of-the-soul-searcher-malware\r\nPage 28 of 31\n\nHelpsvc32.dll\r\nFile\r\nname\r\n-\r\nSVCLDR64.dll\r\nFile\r\nname\r\n-\r\nDataOper64.dll\r\nFile\r\nname\r\n-\r\nC:\\ProgramData\\Users.inf\r\nFile\r\nname\r\n-\r\n%LOCALAPPDATA%\\OneDrive\\Cache.dat\r\nFile\r\nname\r\n-\r\nC:\\ProgramData\\Security_checker\\sc.dll\r\nFile\r\nname\r\n-\r\nC:\\ProgramData\\Xps viewer\\xpsservices.dll\r\nFile\r\nname\r\n-\r\nC:\\Program Files (x86)\\Common Files\\System\\ado\\msado28.dll\r\nFile\r\nname\r\n-\r\nC:\\ProgramData\\networks.dat\r\nFile\r\nname\r\n-\r\nC:\\ProgramData\\Microsoft\\Crypto\\RSA\\Keys.dat\r\nFile\r\nname\r\n-\r\nSntpService.dll\r\nFile\r\nname\r\n-\r\nhttps://www.fortinet.com/blog/threat-research/unraveling-the-evolution-of-the-soul-searcher-malware\r\nPage 29 of 31\n\nsdc-integrity.dat\r\nFile\r\nname\r\n-\r\nsds-integrity.dat\r\nFile\r\nname\r\n-\r\nHKCR\\.z\\OpenWithProgidsEx Registry -\r\nHKCR\\.z\\OpenWithListEx Registry -\r\nHKCR\\.sbr\\Order Registry -\r\nHKCR\\.sbr\\StartOverride Registry -\r\nHKU\\\u003cany_key\u003e\\Software\\kuhO6Ba0kT Registry\r\nHKU\\\u003cany_key\u003e\\Software\\OIfkO2i1 Registry -\r\nHKU\\\u003cany_key\u003e\\Software\\7QAEGXJc Registry -\r\nHKCR\\.c\\Type\\Type00 Registry -\r\nHKR\\Software\\Microsoft\\EventSystem\\8C345CCE-5C37-446E-9E36-\r\nB57A54FC9C45\r\nRegistry -\r\nHKLM\\SYSTEM\\CurrentControlSet\\Services\\\r\n\u003cservice\u003e\\Parameters\\8C345CCE-5C37-446E-9E36-B57A54FC9C45\r\nRegistry -\r\nHKR\\.kci\\PersistentHandler Registry -\r\nhttps://www.fortinet.com/blog/threat-research/unraveling-the-evolution-of-the-soul-searcher-malware\r\nPage 30 of 31\n\nHKCR\\.3gp2\\Perceived-Type Registry -\r\nHKCR\\.3gp2\\Content-Type Registry -\r\nHKCR\\.rat\\PersistentHandler\\MagicNumber Registry -\r\nHKCR\\.rat\\PersistentHandler\\TypeFace Registry -\r\nHKCU\\Software\\Microsoft\\FTP\\MostRecentApplication Registry -\r\nHKCU\\Software\\Microsoft\\FTP\\UserInfo Registry -\r\nHKCU\\Software\\F32xhfHX Registry -\r\nLearn more about Fortinet’s FortiGuard Labs threat research and intelligence organization and the FortiGuard\r\nSecurity Subscriptions and Services portfolio. \r\nSource: https://www.fortinet.com/blog/threat-research/unraveling-the-evolution-of-the-soul-searcher-malware\r\nhttps://www.fortinet.com/blog/threat-research/unraveling-the-evolution-of-the-soul-searcher-malware\r\nPage 31 of 31",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://www.fortinet.com/blog/threat-research/unraveling-the-evolution-of-the-soul-searcher-malware"
	],
	"report_names": [
		"unraveling-the-evolution-of-the-soul-searcher-malware"
	],
	"threat_actors": [
		{
			"id": "a3687241-9876-477b-aa13-a7c368ffda58",
			"created_at": "2022-10-25T16:07:24.496902Z",
			"updated_at": "2026-04-10T02:00:05.010744Z",
			"deleted_at": null,
			"main_name": "Hacking Team",
			"aliases": [],
			"source_name": "ETDA:Hacking Team",
			"tools": [],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "e90c06e4-e3e0-4f46-a3b5-17b84b31da62",
			"created_at": "2023-01-06T13:46:39.018236Z",
			"updated_at": "2026-04-10T02:00:03.183123Z",
			"deleted_at": null,
			"main_name": "Hacking Team",
			"aliases": [],
			"source_name": "MISPGALAXY:Hacking Team",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		}
	],
	"ts_created_at": 1775434820,
	"ts_updated_at": 1775791523,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/2c2f98f4d2d94d3d7a72c7329d3f3c200e65c7a9.pdf",
		"text": "https://archive.orkl.eu/2c2f98f4d2d94d3d7a72c7329d3f3c200e65c7a9.txt",
		"img": "https://archive.orkl.eu/2c2f98f4d2d94d3d7a72c7329d3f3c200e65c7a9.jpg"
	}
}