{
	"id": "a73a79be-8cac-4d5c-b330-c33fae9aa692",
	"created_at": "2026-04-06T00:17:29.875719Z",
	"updated_at": "2026-04-10T03:31:57.097207Z",
	"deleted_at": null,
	"sha1_hash": "fe4118b12ef6374ac98402ffe6896b70a3cf9600",
	"title": "Earth Kitsune Delivers New WhiskerSpy Backdoor via Watering Hole Attack",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 1207969,
	"plain_text": "Earth Kitsune Delivers New WhiskerSpy Backdoor via Watering\r\nHole Attack\r\nBy By: Joseph C Chen, Jaromir Horejsi Feb 17, 2023 Read time: 9 min (2517 words)\r\nPublished: 2023-02-17 · Archived: 2026-04-05 13:28:30 UTC\r\nAPT \u0026 Targeted Attacks\r\nWe discovered a new backdoor which we have attributed to the advanced persistent threat actor known as Earth\r\nKitsune, which we have covered before. Since 2019, Earth Kitsune has been distributing variants of self-developed backdoors to targets, primarily individuals who are interested in North Korea.\r\nIntroduction\r\nWe discovered a new backdoor which we have attributed to the advanced persistent threat actor known as Earth\r\nKitsunenews article, which we have covered before. Since 2019, Earth Kitsune has been distributing variants of\r\nself-developed backdoors to targets, primarily individuals who are interested in North Korea. In many of the\r\ncases, we have investigated in the past, the threat actor used watering hole tactics by compromising websites\r\nrelated to North Korea and injecting browser exploits into them. In the latest activity we analyze here, Earth\r\nKitsune used a similar tactic but instead of using browser exploits, employed social engineering instead.\r\nAt the end of 2022, we discovered that the website of a pro-North Korean organization was compromised and\r\nmodified to distribute malware. When a targeted visitor tries to watch videos on the website, a malicious script\r\ninjected by the attacker displays a message prompt notifying the victims with a video codec error to entice them to\r\ndownload and install a trojanized codec installer. The installer was patched to load a previously unseen backdoor,\r\nthat we dubbed “WhiskerSpy.” In addition, we also found the threat actor adopting an interesting persistence\r\ntechnique that abuses Google Chrome’s native messaging host.\r\nIn this blog post, we are going to reveal the infection chain and technical details of the WhiskerSpy backdoor\r\nemployed by Earth Kitsune.\r\nDelivery analysis\r\nAt the end of 2022, we noticed that a pro-North Korean website had a malicious script injected in their video\r\npages. The script showed a popup window with a fake error message, designed to entice victims to install a\r\nmalicious package disguised as an Advanced Video Codec - AVC1.\r\nhttps://www.trendmicro.com/en_us/research/23/b/earth-kitsune-delivers-new-whiskerspy-backdoor.html\r\nPage 1 of 11\n\nopen on a new tab\r\nFigure 2. Social engineering attack prompt on a compromised pro-North Korean website\r\nThe webpages were configured to deliver the malicious script only to visitors from a list of targeted IP addresses\r\n(visitors that did not have these IP addresses would not receive the malicious payload). This configuration makes\r\nthe attack difficult to discover. Fortunately, we managed to find a text file on the threat actor’s server containing a\r\nregular expression matching the targeted IP addresses. These include:\r\n1. An IP address subnet located in Shenyang, China\r\n2. A specific IP address located in Nagoya, Japan\r\n3. An IP address subnet located in Brazil\r\nThe IP addresses in Shenyang and Nagoya are likely to be their real targets. However, we found the targeted IP\r\naddresses in Brazil mostly belonged to a commercial VPN service. We believe that the threat actor used this VPN\r\nservice to test the deployment of their watering hole attacks. It also provided us with an opportunity to verify the\r\nwatering hole attack by using the same VPN service to successfully receive the malicious script.\r\nopen on a new tab\r\nFigure 3. A comparison of the webpage content between the original page (left) and the page with\r\nthe injected script (right)\r\nThe website loads a malicious JavaScript (popup.js) with the following redirection code:\r\nhttps://www.trendmicro.com/en_us/research/23/b/earth-kitsune-delivers-new-whiskerspy-backdoor.html\r\nPage 2 of 11\n\nopen on a new tab\r\nFigure 4. Embedded JavaScript redirecting to a malicious installer download\r\nThe patched installer\r\nThe installer file is an MSI installer that wraps another NSIS installer. The threat actor abused a legitimate\r\ninstaller (windows.10.codec.pack.v2.1.8.setup.exe –\r\ne82e1fb775a0181686ad0d345455451c87033cafde3bd84512b6e617ace3338e) and patched it to include malicious\r\nshellcode. The patch includes an increased number of sections, from 5 to 6 (red brackets in Figure 5) and \r\nincreased image size to create extra room for the malicious shellcode (green brackets in Figure 5).\r\n open\r\non a new tab\r\nFigure 5. Original (above) and patched (below) installer. Sizes for certain parameters are increased\r\nand one more section is added in the patched version\r\nThe entry point of the patched installer is changed to immediately jump to the shellcode. The shellcode is\r\nencrypted with a simple key (XOR 0x01).\r\nhttps://www.trendmicro.com/en_us/research/23/b/earth-kitsune-delivers-new-whiskerspy-backdoor.html\r\nPage 3 of 11\n\nopen on a new tab\r\nFigure 7. The entry point of the patched installer jumps into the code in the .odata section\r\nAfter decryption, the shellcode runs several PowerShell commands to download additional stages of malware.\r\nThese files are executable files with a few hundred bytes from the beginning XORed with   one-byte key.\r\nopen on a new tab\r\nFigure 8. Shellcode in the .odata section calls several PowerShell commands to download additional\r\nloaders\r\nIt then restores the original entry point (15 bytes in total) to ensure that the original installer runs as expected.\r\n open on\r\na new tab\r\nFigure 9. Shellcode in the .odata section restores the original entry point of the installer\r\nDownloaded binaries: loaders\r\nThis contains the path \\microsoft\\onedrive\\vcruntime140.dll, which is the location where another downloaded file\r\n(bg.jpg) gets dropped under the name vcruntime140.dll.\r\nThis is a patched version of vcruntime140.dll (Microsoft C Runtime library). In this instance, the function memset\r\nwas patched, as seen in Figures 10 and 11. The return from function (retn) was replaced with a jump to overlay (in\r\nthe newly adde .odata section), where an injected code reads bytes from the overlay, XORs them with a 1-byte key\r\nand injects the embedded payload into the werfautl.exe process. The shellcode in the overlay is a loader of the\r\nmain backdoor.\r\nhttps://www.trendmicro.com/en_us/research/23/b/earth-kitsune-delivers-new-whiskerspy-backdoor.html\r\nPage 4 of 11\n\nopen on a new tab\r\nFigure 10. The original memset function. Note that the instruction at address 0x18000C7D1 is\r\nreturn (retn)\r\nopen on a new tab\r\nFigure 11. The patched memset function. Note that the instruction at address 0x18000C7D1 is jump\r\n(jmp) to overlay with the shellcode\r\nThe file is placed into the %LOCALAPPDATA%\\microsoft\\onedrive\\ directory, which is a default per-user\r\ninstallation location for the OneDrive application. It was previously reported that the threat actors exploited\r\nOneDrive side-loading vulnerabilities by placing fake DLLs into this OneDrive directory to achieve persistence in\r\na compromised machine.\r\nThis is an installer package that contains Installer.exe (a Google Chrome extension installer), NativeApp.exe (a\r\nnative messaging host) and Chrome extension files (background.js, manifest.json, and icon.png).\r\nhttps://www.trendmicro.com/en_us/research/23/b/earth-kitsune-delivers-new-whiskerspy-backdoor.html\r\nPage 5 of 11\n\nNativeApp.exe is a native messaging host that communicates with Chrome extensions using standard input (stdin)\r\nand standard output (stdout). Note the type = “stdio” in the extension manifest.\r\nopen on a new tab\r\nFigure 12. The extension manifest. Note the extension ID (allowed_origins) path leading to the\r\ndropped executable and the type = standard input/output.\r\nopen on a new tab\r\nFigure 13. Malicious extension as viewed in a Google Chrome extension tab\r\nThe Background.js extension script adds a listener to the onStartup message. This listener sends the “inject”\r\ncommand to the native messaging host, effectively acting as a somewhat unique method of persistence, since the\r\nmalicious payload is executed every time the Chrome browser is started.\r\n open on a new tab\r\nFigure 14. The handler of the onStartup event (the startup of the Chrome browser)\r\nNativeApp uses messages in JSON format to exchange data with Chrome extensions, and implements three\r\ncommands: execute, load, and inject.\r\nThe format of the message is as follows: xx xx xx xx {“cmd”:””,”data”:””}, where xx xx xx xx is length of the\r\nmessage in bytes.  The “cmd” key must contain one of the implemented command values (execute, load, and\r\nhttps://www.trendmicro.com/en_us/research/23/b/earth-kitsune-delivers-new-whiskerspy-backdoor.html\r\nPage 6 of 11\n\ninject), while the “data” key may contain additional parameters like path and the program to be executed.\r\nThe following are examples of valid JSON messages:\r\n{\"cmd\":\"execute\",\"data\":[\"c:\\\\windows\\\\system32\\\\notepad.exe\"]}\r\n{\"cmd\":\"load\",\"data\":[\"c:\\\\temp\\\\hello-world-x64.dll\",\"MessageBoxThread\"]}\r\n{\"cmd\":\"inject\",\"data\":[\"\"]}\r\nNote that each message must be preceded with a 4-byte little-endian length value. Passing non-printable characters\r\n(0x00 as shown in Figure 15) can be achieved by using PowerShell and its Get-Content cmdlet with the -raw\r\nparameter, then redirecting this content via pipe “|” to the NativeApp. If the cmd.bin file contains the same content\r\nas shown in Figure 15, NativeApp.exe will run notepad.exe.\r\npowershell Get-Content .\\cmd.bin -raw | NativeApp.exe\r\nopen on a new tab\r\nFigure 15. Message instructing the execution of notepad.exe. The first DWORD 0x0000003f is the\r\nlength of the following JSON message\r\nIn the current implementation, the inject command has no parameters. Instead, it connects to the hardcoded URL\r\naddress http://\u003cdelivery server\u003e/help[.]jpg, downloads, decodes and runs the main payload, which is a backdoor.\r\nThis is a shellcode that loads another embedded executable —  the main backdoor payload which we named\r\nWhiskerSpy.\r\nThe main payload: WhiskerSpy\r\nWhiskerSpy uses elliptic-curve cryptography (ECC) to exchange encryption keys between the client and server.\r\nThe following are the implemented backdoor commands:\r\ninteractive shell\r\ndownload file\r\nupload file\r\ndelete file\r\nlist files\r\ntake screenshot\r\nload executable and call its export\r\ninject shellcode into process\r\nhttps://www.trendmicro.com/en_us/research/23/b/earth-kitsune-delivers-new-whiskerspy-backdoor.html\r\nPage 7 of 11\n\nThe machine ID is computed as a 32-bit Fowler-Noll-Vo hash (FNV-1) of the 16-byte UUID located in the System\r\nInformation Table  of the System Management Bios (SMBIOS). For more details about the UUID value, see page\r\n33 of the SMBIOS Specification. The function GetSystemFirmwareTable is called with the parameter “RSMB” to\r\nretrieve the raw SMBIOS table, It is then parsed to locate the 16-byte UUID, which has its FNV-1 hash computed.\r\nFor communication with the command-and-control (C\u0026C) server, the backdoor generates a random 16-byte AES\r\nkey. It computes the session ID from this key as a 32-bit Murmur3 hash.\r\nAs mentioned, the backdoor uses Elliptic-curve cryptography (ECC). We can determine the Elliptic-curve domain\r\nparameters from hardcoded values stored in the “.data” section. In figure 16, you can see the prime (p, yellow\r\ncolor), the first coefficient a (red color), the second coefficient b (green color), generator (base point, blue color),\r\nand the cofactor (h, orange color). Knowing these parameters helps us determine that \"secp256r1\" is the used\r\ncurve, as we can see all the important constants for most popular elliptic curves listed, for example, in tinyec\r\nproject.\r\nThere is one more value shown in Figure 16 (brown color) which represents the hardcoded server’s public key.\r\nThen a series of computations (Elliptic-curve Diffie–Hellman or ECDH key exchange) follows:\r\n1. Generate random 32-byte client private key (clientPrivKey)\r\n2. Compute client public key by multiplying the client private key by the curve generator\r\n(clientPubKey = clientPrivKey * curve.g)\r\n3. Compute sharedKey by multiplying the client private key by the server public key\r\n(sharedKey = clientPrivKey * serverPubKey)\r\nThe result of these computations are uploaded to the C\u0026C server as a 64-byte binary blob, where the first 32 bytes\r\nare the x-coordinate of the client public key, since a a commonly used shared function f(P) is to take the x-coordinate of the point P. The second 32 bytes are derived from a random 16-byte AES key.\r\nC\u0026C communication begins by registering the machine ID (function number = 3; POST request with\r\n“l\u003cmachineID\u003e*”).\r\nThe uploading of the 64-byte file with the x-coordinate of the client public key and the encrypted AES key follows\r\n(function number = 1; POST request with “l\u003cmachineID\u003e\u003csessionID\u003e”.\r\nWhiskerSpy then periodically requests the C\u0026C server for any tasks it should perform (function number = 2;\r\nPOST request with “h\u003cmachineID\u003e*”.\r\nReceived packets (the content of the file h\u003cmachineID\u003e) can either be encrypted or in plain text, depending on the\r\npacket’s purpose. For example, the alive packet has 0x14 bytes, starts with the 0x104B070D magic value, and is\r\nnot encrypted. Its Murmur hash must be equal to the hardcoded value 0x89EECD7C. Other packets are listed in\r\nTable 1.\r\nPacket type Magic Length Murmur hash Encrypted with AES\r\nDo nothing . 1   No\r\nhttps://www.trendmicro.com/en_us/research/23/b/earth-kitsune-delivers-new-whiskerspy-backdoor.html\r\nPage 8 of 11\n\nAlive 0x104B070D 0x14 0x89EECD7C No\r\nGenerate new session key 0xC8C9427E 0x20 0xDA348CF2 No\r\nCommand packet 0xF829EA31     Yes\r\nTable 1. Special types of messages\r\nWhiskerSpy implements standard functions. While analyzing the code, we noticed a few status codes designed to\r\nreport the state of the task, with the first words (two bytes) of the received message being the command ID. Note\r\nthat, in the case of the command packet, the magic value is the same for all commands: it is found before the\r\ncommand ID and is not displayed in Table 2. In the case of  the alive packet, the first word (2 bytes) of the magic\r\nvalue is used as the command ID, therefore the 0x70D value can be found in the table.\r\nCommand\r\nID\r\nFunction Status codes\r\n1\r\nInteractive shell (run\r\ncommand line task)\r\nCPF                      CommandLine Process Fail\r\nCPS                      CommandLine Process Success\r\n[empty]\r\n2\r\nDownload file to the\r\nclient\r\nUTOF                   Open File\r\nFWS                     File Write Success\r\nUTWF                  Write File\r\nBAD                      error\r\n3 Upload file to the server\r\nUTOF                  Open File\r\nUTRF                   Read File\r\nFIB                       File Input Big (\u003e200MB)\r\nFIE                       File Input Empty (zero length)\r\nBAD                     error\r\n4,8 List files  \r\n5 Delete file\r\nOK\r\nBAD\r\n6 Not supported  \r\n7 Exit process  \r\n9\r\nEncrypt file and upload it\r\nto the C\u0026C server\r\n \r\nhttps://www.trendmicro.com/en_us/research/23/b/earth-kitsune-delivers-new-whiskerspy-backdoor.html\r\nPage 9 of 11\n\n10 Take screenshot\r\nIPS                        Incorrect Pixel Specification\r\n                             (!=24 and !=32)\r\nDIBF                     Device-Independent bitmap (DIB) Fail\r\n11\r\nLoad module and run\r\nexport\r\nBAD                     unable to load module\r\nOK\r\n12\r\nInject shellcode to\r\nanother process\r\nBAD\r\nOK\r\n0x70D Checks if it is alive\r\nResponds to server with the bytes „e7 94 9f“, which is also the\r\nUTF-8 encoding of the Chinese character 生(shēng = life)\r\nTable 2. Backdoor commands of WhiskerSpy\r\nSimilar backdoors\r\nOlder versions of WhiskerSpy are 32-bit executables and implement only subsets of the previously mentioned\r\nfunctions ( 1-5,8,0x70D are the same, 6 = exit process; 7 = drop file to temp and execute it). The remaining\r\nfunctions are missing.\r\nThe communication is not via HTTP protocol, but via FTP protocol. This means that the FTP name and password\r\nmust be hardcoded in the binary to enable communication. This approach leaks the current number of victims as\r\nl\u003cmachineID\u003e\u003csessionID\u003e and h\u003cmachineID\u003e files that are visible to anyone who knows the login credentials.\r\nThe FTP version of the backdoor also checks for the presence of the debugger. If present, the status code\r\n„HELO\u003e“ is sent to the C\u0026C server.\r\nAttribution\r\nOur findings allow us to attribute this attack to the Earth Kitsune threat actor with medium confidence. Injecting\r\nmalicious scripts into North Korean-related websites shows a similar modus operandi and victimology to the\r\nprevious activities of the group. Furthermore, the delivery server and the C\u0026C server of WhiskerSpy used in this\r\nattack have two infrastructure overlaps with our previous research on Operation Earth Kitsune.\r\n1. The first overlap we noticed is that both WhiskerSpy's C\u0026C domain londoncity[.]hopto[.]org and Earth\r\nKitsune’s domain rs[.]myftp[.]biz were resolved to the same IP address 45[.]76[.]62[.]198.\r\n2. The second overlap is that WhiskerSpy’s C\u0026C domains londoncity[.]hopto[.]org and\r\nupdategoogle[.]servehttp[.]com, plus the domain of the delivery server microsoftwindow[.]sytes[.]net were\r\nall resolved to 172[.]93[.]201[.]172. This IP address was also mapped from the domain\r\nselectorioi[.]ddns[.]net which was used by Earth Kitsune’s agfSpy backdoor.\r\nhttps://www.trendmicro.com/en_us/research/23/b/earth-kitsune-delivers-new-whiskerspy-backdoor.html\r\nPage 10 of 11\n\nopen on a new tab\r\nFigure 20. The infrastructure overlap with Earth Kitsune (click the image for a larger version)\r\nConclusion\r\nThis threat is very interesting from a technical perspective. It patches the legitimate installers to hide its activities,\r\nuses lesser-known hashing algorithms to compute machine IDs and session IDs and employs ECC to protect\r\nencryption keys. In addition, the presented methods of persistence are also quite unique and rare. This shows that\r\nEarth Kitsune are proficient with their technical abilities and are continuously evolving their tools, tactics, and\r\nprocedures TTPs.\r\nTo help organizations defend themselves from advanced threats, We recommend using a multilayered security\r\napproach and technologies that can detect and block these types of threats from infiltrating the system\r\nthrough endpointsproducts, serversproducts, networksproducts, and emailsproducts.\r\nIndicators of Compromise\r\nThe indicators of compromise for this entry can be found here.\r\nTags\r\nSource: https://www.trendmicro.com/en_us/research/23/b/earth-kitsune-delivers-new-whiskerspy-backdoor.html\r\nhttps://www.trendmicro.com/en_us/research/23/b/earth-kitsune-delivers-new-whiskerspy-backdoor.html\r\nPage 11 of 11",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"ETDA",
		"Malpedia",
		"MISPGALAXY"
	],
	"references": [
		"https://www.trendmicro.com/en_us/research/23/b/earth-kitsune-delivers-new-whiskerspy-backdoor.html"
	],
	"report_names": [
		"earth-kitsune-delivers-new-whiskerspy-backdoor.html"
	],
	"threat_actors": [
		{
			"id": "6158a31d-091c-4a5a-a82b-938e3d0b0e87",
			"created_at": "2023-11-17T02:00:07.61151Z",
			"updated_at": "2026-04-10T02:00:03.459947Z",
			"deleted_at": null,
			"main_name": "Earth Kitsune",
			"aliases": [],
			"source_name": "MISPGALAXY:Earth Kitsune",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "3f6650a3-9f50-47c4-bd7a-008b63bde191",
			"created_at": "2022-10-25T16:07:23.949232Z",
			"updated_at": "2026-04-10T02:00:04.803815Z",
			"deleted_at": null,
			"main_name": "Operation Earth Kitsune",
			"aliases": [],
			"source_name": "ETDA:Operation Earth Kitsune",
			"tools": [
				"SLUB",
				"WhiskerSpy",
				"agfSpy",
				"dneSpy"
			],
			"source_id": "ETDA",
			"reports": null
		}
	],
	"ts_created_at": 1775434649,
	"ts_updated_at": 1775791917,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/fe4118b12ef6374ac98402ffe6896b70a3cf9600.pdf",
		"text": "https://archive.orkl.eu/fe4118b12ef6374ac98402ffe6896b70a3cf9600.txt",
		"img": "https://archive.orkl.eu/fe4118b12ef6374ac98402ffe6896b70a3cf9600.jpg"
	}
}