{
	"id": "fee37dd5-eeca-4375-ac33-cc6f51034ceb",
	"created_at": "2026-04-06T00:22:28.930704Z",
	"updated_at": "2026-04-10T13:11:26.414522Z",
	"deleted_at": null,
	"sha1_hash": "2b31f3438d2367ecc3cc2748b5a16f6521585e91",
	"title": "#ShortAndMalicious — DarkGate",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 467593,
	"plain_text": "#ShortAndMalicious — DarkGate\r\nBy DCSO CyTec Blog\r\nPublished: 2023-09-19 · Archived: 2026-04-05 21:45:08 UTC\r\n4 min read\r\nSep 19, 2023\r\nPress enter or click to view image in full size\r\nA dark gate / Jae Lo Presti on Unsplash\r\nIf you follow malware news, you’ve surely heard of the DarkGate loader by now. Using a rather exotic\r\ncombination of AutoIt automation scripts and the Delphi programming language, its purpose is malware delivery\r\nand credential theft.\r\nGiven its apparent popularity with miscreants currently, DCSO’s CSIRT decided to investigate.\r\nWhile most of its capabilities have been covered in great detail already such as here, here and here, we noticed\r\nduring our analysis that the key log encryption apparently had evolved since the great write-up by Strotz Friedberg\r\npublished in early August 2023.\r\nhttps://medium.com/@DCSO_CyTec/shortandmalicious-darkgate-d9102a457232\r\nPage 1 of 5\n\nThus, for this #ShortAndMalicious we’ll show the new, convoluted process of deriving the key log encryption key\r\n(and bot ID!), and we also provide updated tooling for the community over on our GitHub.\r\nBlog post authored by Johann Aydinbas\r\nKey log files\r\nOne of the features of DarkGate is key logging. Key strokes are recorded into encrypted log files and regularly\r\nuploaded to the C2 server. The files are encrypted using AES, but while earlier DarkGate versions appear to have\r\nused a fixed key, current versions have moved away from it.\r\nInstead, the key is derived from the bot ID now, which in turn is derived from system specs, with intermediate\r\nsteps involving some hashing and custom encoding.\r\nFor reasons more clear after reading the following, we’re releasing 3 separate tools to handle encrypted key log\r\nfiles:\r\nA Windows tool to read the necessary system specs needed to calculate the bot ID\r\nA Python script to use that info to derive the bot ID and AES key\r\nA Delphi tool to decrypt log files with a key from the previous step and an encrypted log file\r\nCalculating the AES key\r\nIn order to calculate the AES key used for key log files, we first need to determine the bot ID (aka hwid) of the\r\nsystem for which we want to decrypt the key log files.\r\nThe outline of the bot ID generation is as follows:\r\nFetch system information\r\nCalculate MD5 sum of system information\r\nUse a custom encoding for the MD5 digest\r\nBot ID generation\r\nFor the bot ID generation, DarkGate gathers five pieces of information:\r\n1. Computer name\r\n2. User name\r\n3. Processor information from the registry value\r\nHKLM\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0\\ProcessorNameString\r\n4. Windows product ID from the registry value HKLM\\SOFTWARE\\Microsoft\\Windows\r\nNT\\CurrentVersion\\ProductId\r\n5. Number of processors via API GetSystemInfo\r\nThe number of processors is appended to the processor info in the form of “@ x Cores”, and then it combines all\r\nthese into a string and calculates the MD5 digest for it:\r\nhttps://medium.com/@DCSO_CyTec/shortandmalicious-darkgate-d9102a457232\r\nPage 2 of 5\n\ndigest = MD5(product_id+processor+user+computer)\r\nAnd finally, it takes the 16 byte MD5 digest and encodes it using a custom alphabet by using it as a lookup table\r\nnibble-wise (half bytes, that is). Reimplemented in Python, it looks like this:\r\ndef custom_encode(s):\r\n lookup = b\"abcdefKhABCDEFGH\"\r\n out = bytearray()\r\n for i in range(len(s)):\r\n upper_nibble = (s[i] \u0026 0xF0) \u003e\u003e 4\r\n lower_nibble = s[i] \u0026 0x0F\r\n out.append(lookup[upper_nibble])\r\n out.append(lookup[lower_nibble])\r\n return out\r\nAES key derivation\r\nFor the AES key derivation, then, we need the following ingredients:\r\nHardcoded string “mainhw”\r\nBot ID as calculated before\r\nConfig value internal_mutex\r\nThe latter can be extracted using the most excellent DarkGate config extractor published by Fabian Marquardt\r\nover on the Telekom Security blog.\r\nGet DCSO CyTec Blog’s stories in your inbox\r\nJoin Medium for free to get updates from this writer.\r\nRemember me for faster sign in\r\nWith these pieces of information, the calculation is as follows:\r\nCalculate and encode the MD5 digest as with the bot ID:\r\ndigest = MD5(\"mainhw\"+bot_id+internal_mutex)\r\nencoded = custom_encode(digest)\r\nThen finally, the AES key used by DarkGate to encrypt the key log files is the first 7 letters, lowercased:\r\naes_key = encoded[:7].lower()\r\nhttps://medium.com/@DCSO_CyTec/shortandmalicious-darkgate-d9102a457232\r\nPage 3 of 5\n\nSo in summary the complete process looks like this:\r\ndigest = MD5(product_id+processor+user+computer)\r\nbot_id = custom_encode(digest)\r\ndigest2 = MD5(\"mainhw\"+bot_id+internal_mutex)\r\nencoded = custom_encode(digest2)\r\naes_key = encoded[:7].lower()\r\nDecrypting log files\r\nNow that we have the AES key, we want to decrypt log files, but it turns out it is not that simple. Long story short,\r\nthe AES implementation used is incompatible to most readily available implementations used in, say, Python.\r\nOr in more detail: DarkGate uses the function EncryptString offered by the Delphi library dcpcrypt.\r\nEncryptString has three quirks though:\r\n1. It feeds the given key to SHA1 then uses the 160 bit output as key value. AES is only standardized for\r\n128/192/256 bit key sizes, but Rijndael, the algorithm behind the AES standard can actually use 160 bit\r\nsizes, so technically, this is using Rijndael and not AES\r\n2. It uses a custom cipher mode to turn the Rijndael block cipher into a stream cipher which it calls CFB8Bit\r\nmode.\r\n3. If that wasn’t enough, it is a known bug that dcpcrypt produces key schedules incompatible with other\r\nRijndael implementations for non-standard key sizes, such as — unfortunately — the 160 bit used in\r\nDarkGate.\r\nGiven all these hurdles, we followed the example of AON’s Cyber Labs and simply developed a decryption tool in\r\nDelphi using the same library and it’s… quirks.\r\nOur tool takes as input a 7 letter AES key as generated by the aforementioned algorithm, as well as an input file\r\npath and an output file path, and then simply decrypts the file.\r\nBelow is an example of a decrypted key log file. The hex-encoded string between the encwindow markers is the\r\nUTF16-encoded window title for which the input was captured, followed by the input captured for this window:\r\nPress enter or click to view image in full size\r\nhttps://medium.com/@DCSO_CyTec/shortandmalicious-darkgate-d9102a457232\r\nPage 4 of 5\n\nDecrypted key log file\r\nHead over to our GitHub for the tools!\r\nSource: https://medium.com/@DCSO_CyTec/shortandmalicious-darkgate-d9102a457232\r\nhttps://medium.com/@DCSO_CyTec/shortandmalicious-darkgate-d9102a457232\r\nPage 5 of 5",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://medium.com/@DCSO_CyTec/shortandmalicious-darkgate-d9102a457232"
	],
	"report_names": [
		"shortandmalicious-darkgate-d9102a457232"
	],
	"threat_actors": [],
	"ts_created_at": 1775434948,
	"ts_updated_at": 1775826686,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/2b31f3438d2367ecc3cc2748b5a16f6521585e91.pdf",
		"text": "https://archive.orkl.eu/2b31f3438d2367ecc3cc2748b5a16f6521585e91.txt",
		"img": "https://archive.orkl.eu/2b31f3438d2367ecc3cc2748b5a16f6521585e91.jpg"
	}
}