{
	"id": "e6537796-7b7e-498a-bf01-7e5dd45df14f",
	"created_at": "2026-04-06T01:31:26.288211Z",
	"updated_at": "2026-04-10T03:21:41.896019Z",
	"deleted_at": null,
	"sha1_hash": "728fff2f69e437e3ee448e2d3e09df956fd503c4",
	"title": "XWORM Returns to Haunt Systems with Ghost Crypt",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 3813635,
	"plain_text": "XWORM Returns to Haunt Systems with Ghost Crypt\r\nBy Otavio Passos, Ryan Hicks, Marc Messer\r\nPublished: 2025-08-20 · Archived: 2026-04-06 00:28:21 UTC\r\nThis article has been authored by Otavio Passos, Ryan Hicks, Marc Messer.\r\n \r\nKey Findings\r\nA known cyber threat called XWORM is now using a sneaky new method using Ghost Crypt to infect\r\ncomputers, hiding inside a seemingly harmless but fake PDF reader app.\r\nThe attack involves a zipped archive containing a PDF reader, a DLL and a PDF file. When the user opens\r\nthe PDF, the malicious DLL is side-loaded, initiating the malware execution.\r\nGhost Crypt uses a technique called Process Hypnosis to inject the final payload into csc.exe (a Visual C#\r\ncompiler), leveraging Windows APIs to stealthily execute the malware.\r\nStarting in July 2025, Kroll has observed a new delivery method coming from the XWORM malware family.\r\nPreviously known to leverage a self-contained executable in order to drop the final payload, XWORM now uses\r\nGhost Crypt which is a service publicized on HackForums and used to exploit DLL side-loading vulnerabilities in\r\nknown applications. The service includes support for a range of malware families, including LUMMASTEALER,\r\nBLUELOADER, RHADAMANTHYS, XWORM, DCRAT, PURELOADER, STEALC and others.\r\nGhost Crypt delivers a zipped archive to the victim containing a PDF Reader application, a DLL and a PDF file.\r\nWhen the archive is extracted and the application is launched to open the PDF, it also sideloads the DLL from the\r\nsame directory. This DLL is the malicious component of the attack.\r\nIn the second stage of Ghost Crypt's execution chain, the DLL leverages the so-called \"process hypnosis\"\r\ntechnique targeting csc.exe, a command line Visual C# compiler. The technique consists of creating a process with\r\nthe CreateProcessW API together with the DEBUG_ONLY_THIS_PROCESS flag. With the new process created,\r\nGhost Crypt uses the VirtualAllocEx API to allocate memory in the created process's address space, writing the\r\nfinal payload in the created process with the WriteProcessMemoryAPI. Finally, the execution is resumed with the\r\nSetThreadContextAPI, together with DebugActiveProcessStop API.\r\nThe previously mentioned PDF Reader application is HaiHaiSoft PDF Reader, which is known to have a DLL\r\nside-loading vulnerability, previously exploited to deliver REMCOS, NodeStealer and PureRAT.\r\nBelow is a diagram of XWORM's new delivery method: \r\nhttps://www.kroll.com/en/publications/cyber/xworm-returns-haunt-systems-ghost-crypt\r\nPage 1 of 10\n\nFigure 1: XWORM’s new delivery method\r\nGhost Crypt Unpacking\r\nIn this campaign, Ghost Crypt exploits a weak dependency in the file 1095-A_PDF.exe, which is a renamed\r\nversion of hpreader.exe, the legitimate HaiHaiSoft PDF Reader. Once this executable is run, it eventually loads the\r\noledlg.dll from within the same directory it was executed.\r\nFigure 2: IHaiHaiSoft PDF Reader side-loading oledlg.dll (Ghost Crypt)\r\nThe DLL, being Ghost Crypt, is responsible for applying the \"process hypnosis\" technique targeting csc.exe. To\r\nretrieve the dropped payload, we can inspect the process tree of 1095-A_PDF.exe, which has csc.exe alongside\r\ncmd.exe, Conhost.exe, and reg.exe.\r\nFigure 3: HaiHaiSoft PDF Reader process tree\r\nIt is also noted how persistence is achieved by Ghost Crypt. First, the contents of oledlg.dll are copied to the file\r\nSensor57380.dll, then the DLL's entry point is set as a \"run\" registry key by the following command:\r\nhttps://www.kroll.com/en/publications/cyber/xworm-returns-haunt-systems-ghost-crypt\r\nPage 2 of 10\n\ncmd.exe /C reg add \"HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\" /v \"CriticalUpdater3\" /t\r\nREG_SZ /d \"rundll32.exe \\\"C:\\Users\\arcana\\Documents\\Sensor57380.dll\\\",EntryPoint\" /f \u0026 exit\r\nOpening csc.exe's memory, you can see an unusual RWX memory at the address 0xd30000, of size 56kb. \r\nExploring the hex dump for this range of memory unveils a MZ Header together with the PE Headers.\r\nFigure 4: In-memory XWORM variant\r\nXWORM Technical Analysis\r\nXWORM is known to be a plugin-based Remote Access Tool (RAT) with capabilities that range from info stealing\r\nto ransomware. Each plugin being a different class in the decompiled view of the binary.\r\nThe first procedure XWORM employs is to decrypt its own configuration using the AES-128 algorithm in ECB\r\nMode. The key generation is done through computing the MD5 Hash of the bytes of the hard-coded mutex name.\r\nAn example key, for the hard-coded mutex \"zLF4NWhVIr2DD3Ht\", would be\r\n7644e1414b0cc46eb9f4eaea2a86c97644e1414b0cc46eb9f4eaea2a86c92700\r\nBelow is the decrypted config for this sample:\r\nhttps://www.kroll.com/en/publications/cyber/xworm-returns-haunt-systems-ghost-crypt\r\nPage 3 of 10\n\nFigure 5: Decrypted XWORM config\r\nAfter decrypting its own configuration, XWORM proceeds to check whether the victim is already infected with\r\nitself. This is done via the creation of the mutex zLF4NWhVIr2DD3Ht. If this mutex is already existent in the\r\nsystem, the program terminates.\r\nhttps://www.kroll.com/en/publications/cyber/xworm-returns-haunt-systems-ghost-crypt\r\nPage 4 of 10\n\nhttps://www.kroll.com/en/publications/cyber/xworm-returns-haunt-systems-ghost-crypt\r\nPage 5 of 10\n\nFigure 6: Mutex check\r\nIf it does not exist in the system, it proceeds to connect to the value of the host key via TCP to the server and send\r\nthe return of the Info() procedure via the send method. The Info() procedure sends the following data to the TA's\r\nC2 server.\r\nFigure 7: Example of the information sent to the operator\r\nAfter sending this information, XWORM will call the BeginReceive method to receive new instructions from the\r\nmalware's operator. XWORM will also register a callback to ping the C2 server from time to time. The ping data\r\nis the following:\r\nPING! \u003cXwormmm\u003e [Active Window Title] \u003cXwormmm\u003e [Uptime]\r\nThe BeginReceive will eventually call the BeginRead method, which will eventually call the Read method. The\r\nRead method is responsible for dispatching the routines related to the C2's commands.\r\nhttps://www.kroll.com/en/publications/cyber/xworm-returns-haunt-systems-ghost-crypt\r\nPage 6 of 10\n\nFigure 8: XWORM command dispatch routine\r\nThe command dispatch routine is severely control-dependent on a state variable. Being retrieved by the decryption\r\nof the operator's command, and then separated from the \u003cXwormmm\u003e string, the resulting string is then used as\r\nhttps://www.kroll.com/en/publications/cyber/xworm-returns-haunt-systems-ghost-crypt\r\nPage 7 of 10\n\ncondition for the switch-case expression.\r\nBelow is a table of all commands available, and their meaning:\r\nCommand Description\r\npong Send a \"pong \" message\r\nrec Closes the mutex and restart the malware\r\nCLOSE Shutdowns the connection\r\nuninstall Uninstalls the malware\r\nupdate Moves the current application's content to a random-named file within %TEMP%\r\nDW\r\nStarts either a powershell script with powershell.exe -ExecutionPolicy Bypass -File, or\r\ncreates a process for a file in disk\r\nFM Loads an in-memory assembly, and runs it\r\nLN Downloads and executes an arbitrary file\r\nUrlopen Starts a process from an URL\r\nUrlhide Retrieves an executable via the HTTP GET method, and executes it\r\nPCShutdown Executes shutdown.exe /f /s /t 0\r\nPCRestart Executes shutdown.exe /f /r /t 0\r\nhttps://www.kroll.com/en/publications/cyber/xworm-returns-haunt-systems-ghost-crypt\r\nPage 8 of 10\n\nCommand Description\r\nPCLogoff Executes shutdown.exe -L\r\nRunShell Runs an arbitrary command in a shell\r\nStartDDos Infinitely creates threads, each one sending infinite HTTP requests\r\nStopDDos Aborts the StartDDos method\r\nStartReport Retrieves a list of active processes\r\nStopReport Aborts the StartReport method\r\nXchat Send the string \"Xchat \" to the C2\r\nHosts Opens \\\\drivers\\\\etc\\\\hosts and sends the content to the C2\r\nShosts Modifies the \\hosts file\r\nDDos\r\nSend the string \"DDos\" to the C2, most likely to initiate an external DDos targeting the\r\nvictim\r\nplugin Send the string \"sendPlugin\" to the C2, calling Decompress with the response\r\nsavePlugin Decompress the received Plugin and write it to the victim's registry\r\nRemovePlugins RemovePlugins\r\nhttps://www.kroll.com/en/publications/cyber/xworm-returns-haunt-systems-ghost-crypt\r\nPage 9 of 10\n\nCommand Description\r\nOfflineGet SendError(\"ERROR + \"OfflineKeylogger Not Enabled\");\r\n$Cap Screenshot's victim's screen\r\nSource: https://www.kroll.com/en/publications/cyber/xworm-returns-haunt-systems-ghost-crypt\r\nhttps://www.kroll.com/en/publications/cyber/xworm-returns-haunt-systems-ghost-crypt\r\nPage 10 of 10",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://www.kroll.com/en/publications/cyber/xworm-returns-haunt-systems-ghost-crypt"
	],
	"report_names": [
		"xworm-returns-haunt-systems-ghost-crypt"
	],
	"threat_actors": [],
	"ts_created_at": 1775439086,
	"ts_updated_at": 1775791301,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/728fff2f69e437e3ee448e2d3e09df956fd503c4.pdf",
		"text": "https://archive.orkl.eu/728fff2f69e437e3ee448e2d3e09df956fd503c4.txt",
		"img": "https://archive.orkl.eu/728fff2f69e437e3ee448e2d3e09df956fd503c4.jpg"
	}
}