{
	"id": "3ac29232-1191-4018-aabb-d0db053a4170",
	"created_at": "2026-04-06T00:22:00.850011Z",
	"updated_at": "2026-04-10T03:33:16.698719Z",
	"deleted_at": null,
	"sha1_hash": "795149a18b94342beeffc6a681df347ab135112f",
	"title": "HelloKitty Linux version malware analysis",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 1189686,
	"plain_text": "HelloKitty Linux version malware analysis\r\nPublished: 2021-07-17 · Archived: 2026-04-05 14:51:57 UTC\r\nPlease read the disclaimer\r\nIntroduction\r\nThis report contains technical details of the new linux version of HelloKitty that targets VMware ESXi servers.\r\nThe encryption used by this variant is AES_CBC and Elliptic-curve Diffie–Hellman (ECDH) to protect the\r\nkeys.\r\nEncryption Overview\r\nThe malware generates an ECDH keypair, then using the hardcoded public key of the threat actor, it generates an\r\nECDH secret key, then an AES KEY/IV are randomly generated at run time, this key will be used to encrypt a\r\nfile.\r\nNote: the AES KEY/IV are different for each file.\r\nThe AES KEY/IV is encrypted using a randomly generated IV and the previous ECDH secret key with AES\r\nalgorithm.\r\nFinally a structure is populated with the ECDH public key of the malware, the encrypted AES KEY/IV used for\r\nfile encryption and other stuff.\r\nThe structure is appended with the ransom note and the encrypted file .crypt\r\nThe Threat actor can recover the ECDH secret to decrypt the encrypted AES KEY/IV used for encrypting the file\r\nwith his Private ECDH key and the malware Public ECDH key.\r\nRansom Note\r\nhttps://soolidsnake.github.io/2021/07/17/hellokitty_linux.html\r\nPage 1 of 17\n\nFigure: Ransom note\r\nTechnical Analysis\r\nCommandLine arguments\r\nFigure: Parsing commandLine arguments\r\nhttps://soolidsnake.github.io/2021/07/17/hellokitty_linux.html\r\nPage 2 of 17\n\noption Functionality\r\n-k Kill VM processes\r\n-d Run as daemon\r\n-e Encrypt VM files\r\n-v Enable verbose\r\nDynamically loading libcrypto API\r\nThe malware loads some OpenSSL API from libcrypto.so using dlopen/dlsym.\r\nFigure: Dynamically loading libcrypto API\r\nLooking at the array, we can see that each entry is a structure of 3 pointers:\r\n1\r\n2\r\n3\r\n4\r\n5\r\n{\r\nunsigned char* new_function_name;\r\nunsigned char* old_function_name;\r\nvoid* pointer_to_api;\r\n}\r\nhttps://soolidsnake.github.io/2021/07/17/hellokitty_linux.html\r\nPage 3 of 17\n\nFirst the ransomware tries to get the address of the function name stored in new_function_name, if not found\r\n(which means the library is old) it uses old_function_name, if the API was found , it’s pointer will be stored in\r\npointer_to_api\r\nFigure: Array of libcrypto API names and addresses\r\nWe can rename the pointer_to_api with this pythonIDA script, it gets new_function_name string and it then set\r\nthe name for pointer_to_api\r\n1\r\n2\r\n3\r\n4\r\n5\r\nstart = get_name_ea(0, \"array_func_name\")\r\nfor i in xrange(0x39):\r\nfunc_name = get_strlit_contents(Qword(start))\r\nset_name(start+0x10, func_name)\r\nstart += 0x18\r\nIgnores signals\r\nThe malware will ignore the following signals, so that it won’t be interrupted during encryption, this will prevent\r\nhalf encrypting files which leads to file corruption.\r\nSIGCHLD\r\nhttps://soolidsnake.github.io/2021/07/17/hellokitty_linux.html\r\nPage 4 of 17\n\nSIGTSTP\r\nSIGTTOU\r\nSIGTTIN\r\nSIGHUP\r\nSIGTERM\r\nFigure: Malware ignores some signals\r\nList VM processes\r\nIt executes the command esxcli vm process list to list every VirtualMachine processes currently running on\r\nthe infected machine. It then parses through the output to extract Process ID and Config File which is basically\r\nthe path to the VMX file of the VM This data is saved in a array of stucture of type\r\n{\r\nuint64_t Process_ID;\r\nunsigned char *Vmx_Path;\r\n}\r\nkill VM porcesses\r\nUsing the previous array, the malware first tries to kill the processes with a soft kill esxcli vm process kill -\r\nt=soft -w=\u003cProcess_PID\u003e if it fails it uses a hard kill option esxcli vm process kill -t=hard -w=\r\n\u003cProcess_PID\u003e .\r\nRecursive file search\r\nIt uses the paths given as command line arguments and explore recursively the directories using opendir readdir.\r\nFor each file read, it first checks if the file is not . or .. and does not contain the strings .crypt or\r\n.README_TO_RESTORE\r\nhttps://soolidsnake.github.io/2021/07/17/hellokitty_linux.html\r\nPage 5 of 17\n\nSwitch (file type)\r\ncase directory:\r\nIt checks if it is not one of the following directories:\r\n/bin\r\n/boot\r\n/dev\r\n/etc\r\n/lib\r\n/lib32\r\n/lib64\r\n/lost+found\r\n/proc\r\n/run\r\nhttps://soolidsnake.github.io/2021/07/17/hellokitty_linux.html\r\nPage 6 of 17\n\n/sbin\r\n/usr/bin\r\n/usr/include\r\n/usr/lib\r\n/usr/lib32\r\n/usr/lib64\r\n/usr/sbin\r\n/sys\r\n/usr/libexec\r\n/usr/share\r\n/var/lib\r\nIn case the check pass, it calls recursively the same function with the new directory path as argument.\r\nFigure: Recursive directory search\r\ncase file:\r\nIn case it was a file and the -e option was specified in command line arguments, it will check if the file does not\r\ncontain the following strings .crypt, .tmp_, .README_TO_RESTORE, then checks if it contains one of the\r\nfollowing strings\r\n.vmdk\r\n.vmx\r\n.vmsd\r\n.vmsn\r\nhttps://soolidsnake.github.io/2021/07/17/hellokitty_linux.html\r\nPage 7 of 17\n\nif -e was not specified, it will check if the filename does not contain one of the following strings\r\n.crypt\r\n.READ_ME_TO_RESTORE\r\n.tmp_\r\n.a\r\n.so\r\n.la\r\nFinally if the size of the file is bigger than 256 bytes, it saves the path to the file for later usage (encrypting it… of\r\ncourse)\r\nswitch to daemon process\r\nIf the -d option was specified in command line arguments the malware calls daemon to detach itself from the\r\ncontrolling terminal and run in the background as system daemons.\r\nhttps://soolidsnake.github.io/2021/07/17/hellokitty_linux.html\r\nPage 8 of 17\n\nFigure: Detach and run as daemon\r\nstart thread\r\nit starts a thread at address 0x402AA2 then creates 2 strings, filename + .crypt and filename + .tmp_\r\nA function is called that tries to set a lock on the file using fcntl , if it fails it will get the PID of the process that\r\nis currently locking the file\r\nFigure: Malware try to set a lock on the file\r\nIf the PID is greater than 10 (not a system process), it will kill it with the command kill -9 \u003cPID\u003e\r\nThe malware then rename the file to filename + .tmp_ then it will call a function (0x405D64) to encrypt the\r\nfile. In case of failure it will roll back to the original filename\r\nIn case of successful encryption it will rename the .tmp_ to .crypt\r\nEncryption\r\nGeneration of keys\r\nIt derives an AES_256_CBC KEY and IV with libcrypto function EVP_BytesToKey with a randomly generated\r\nsalt and data using RAND_bytes API that will be used for file content encryption.\r\nhttps://soolidsnake.github.io/2021/07/17/hellokitty_linux.html\r\nPage 9 of 17\n\nFigure: Generate AES KEY/IV\r\nFigure: Official documentation of OpenSSL API\r\nhttps://www.openssl.org/docs/man1.0.2/man3/EVP_BytesToKey.html\r\nAfterwards it generates the malware ECDH private/public keys.\r\nFigure: Generate client ECDH keypair\r\nhttps://soolidsnake.github.io/2021/07/17/hellokitty_linux.html\r\nPage 10 of 17\n\nNext it will call a function at address 0x4054F1 (I named it func_compute_secret) with the newly generate\r\nEC_KEY and the public key of the author\r\nFigure: Author public key\r\nThen It calls libcrypto api ECDH_compute_key to generate an ECDH shared secret.\r\nFigure: Generate ECDH secret\r\nAfter that it populate a custom structure (I named it custom_structure00) of the following type with the AES\r\nKEY, IV and the size of the file.\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n{\r\nunsigned char* save_AES_IV[0x10];\r\nunsigned char* save_AES_KEY[0x20];\r\nunsigned __int64 size_of_file;\r\nunsigned int defined_constant;\r\nunsigned int alignemnt;\r\n} custom_structure00;\r\nhttps://soolidsnake.github.io/2021/07/17/hellokitty_linux.html\r\nPage 11 of 17\n\nFigure: Populate the above structure with AES key data\r\nFigure: Example of the structure populated with data\r\nThen it encrypts the structure custom_structure00 using the ECDH secret and a randomly generated IV of 16\r\nbytes with AES algorithm.\r\nFigure: Encrypt the above structure with the ECDH secret\r\nAfter that, it populates yet another important structure custom_structure01 of following type:\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n{\r\n// The IV used to encrypt the custom_structure00 structure. | offset 0 - 0x10\r\nunsigned char secret_IV[0x10];\r\n// The size of custom_structure00 | offset 0x10 - 0x14\r\nunsigned int size_of_custom_structure00;\r\n// Encrypted custom_structure00 | offset 0x14 - 0x34\r\ncustom_structure00 encrypted_custom_structure00;\r\n// Size of the client public key | offset 0x58 - x5c\r\nunsigned int size_of_public_key ;\r\n// Client public key | offset 0x5c - 0xa0\r\nunsigned char public_key[0x44];\r\n// Size of the sig | offset 0xa0 - 0xa4\r\nunsigned int size of sig;\r\n// Sig | offset 0xa4 - 0xf0\r\nhttps://soolidsnake.github.io/2021/07/17/hellokitty_linux.html\r\nPage 12 of 17\n\n15\r\n16\r\nunsigned char sig[0x47];\r\n} custom_structure01;\r\nFinally it writes to filename + .README_TO_RESTORE the ransomware note, then it append the previous structure\r\nat the end of the file. It also append the SHA256 of the \u003coriginal file content + appended data\u003e (see next)\r\nExample:\r\n.README_TO_RESTORE file tail, showcasing the above structure (custom_structure01) and the SHA256\r\nhash of the file\r\nIt then appended the same structure (custom_structure01) to the target file.\r\nhttps://soolidsnake.github.io/2021/07/17/hellokitty_linux.html\r\nPage 13 of 17\n\nFigure: Original content of the file + (custom_structure01)\r\nFinally it reads the data of the target file and uses the file encryption AES key to encrypt it.\r\nFigure: Malware encrypt the content of the target file\r\nhttps://soolidsnake.github.io/2021/07/17/hellokitty_linux.html\r\nPage 14 of 17\n\nFigure: File encrypted\r\nFinally it append again the structure + the sha256 of the file.\r\nhttps://soolidsnake.github.io/2021/07/17/hellokitty_linux.html\r\nPage 15 of 17\n\nFigure: Encrypted file + custom_structure01 + sha256\r\nConclusion\r\nThis linux variant can target Virtual machines files, which can be crucial to companies without backup and\r\nreplication.\r\nThe encryption scheme used utilize ECDH (Elliptic-curve Diffie–Hellman) algorithm, which means without the\r\nprivate key owned by the threat actor, it will be near impossible to decrypt the encrypted files.\r\nYARA Rule\r\nrule hellokitty_linux {\r\n meta:\r\n description = \"YARA rule HelloKitty linux variant ransomware\"\r\n reference = \"https://soolidsnake.github.io/2021/07/17/hellokitty_linux.html\"\r\n author = \"@soolidsnakee\"\r\n date = \"2021-07-17\"\r\n strings:\r\nhttps://soolidsnake.github.io/2021/07/17/hellokitty_linux.html\r\nPage 16 of 17\n\n$str1 = \".crypt\"\r\n $str2 = \".README_TO_RESTORE\"\r\n $str5 = \"switch to daemon\"\r\n $str6 = \"esxcli vm process kill -t=hard -w=%d\"\r\n $str7 = \"work.log\"\r\n $str8 = \"m:vdekc:\"\r\n condition:\r\n all of ($str*)\r\n}\r\nSource: https://soolidsnake.github.io/2021/07/17/hellokitty_linux.html\r\nhttps://soolidsnake.github.io/2021/07/17/hellokitty_linux.html\r\nPage 17 of 17",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://soolidsnake.github.io/2021/07/17/hellokitty_linux.html"
	],
	"report_names": [
		"hellokitty_linux.html"
	],
	"threat_actors": [
		{
			"id": "1f6ae238-765f-4495-9d54-6a7883d7a319",
			"created_at": "2022-10-25T16:07:24.573456Z",
			"updated_at": "2026-04-10T02:00:05.037738Z",
			"deleted_at": null,
			"main_name": "TA511",
			"aliases": [
				"MAN1",
				"Moskalvzapoe"
			],
			"source_name": "ETDA:TA511",
			"tools": [
				"Agentemis",
				"Chanitor",
				"Cobalt Strike",
				"CobaltStrike",
				"Ficker Stealer",
				"Hancitor",
				"NetSupport",
				"NetSupport Manager",
				"NetSupport Manager RAT",
				"NetSupport RAT",
				"NetSupportManager RAT",
				"cobeacon"
			],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "542cf9d0-9c68-428c-aff8-81b6f59dc985",
			"created_at": "2023-02-15T02:01:49.554105Z",
			"updated_at": "2026-04-10T02:00:03.347115Z",
			"deleted_at": null,
			"main_name": "Moskalvzapoe",
			"aliases": [
				"MAN1",
				"TA511"
			],
			"source_name": "MISPGALAXY:Moskalvzapoe",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		}
	],
	"ts_created_at": 1775434920,
	"ts_updated_at": 1775791996,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/795149a18b94342beeffc6a681df347ab135112f.pdf",
		"text": "https://archive.orkl.eu/795149a18b94342beeffc6a681df347ab135112f.txt",
		"img": "https://archive.orkl.eu/795149a18b94342beeffc6a681df347ab135112f.jpg"
	}
}