{
	"id": "1ae87bb1-8a7a-46e5-9d54-0c5d62fde035",
	"created_at": "2026-04-10T03:21:36.049251Z",
	"updated_at": "2026-04-10T03:22:18.140758Z",
	"deleted_at": null,
	"sha1_hash": "2255c251e7dc3e1f7a6f07416d93504c43bbb37d",
	"title": "The DGA of PadCrypt - Versions 2.2.86.0 and 2.2.97.1",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 82113,
	"plain_text": "The DGA of PadCrypt - Versions 2.2.86.0 and 2.2.97.1\r\nArchived: 2026-04-10 02:54:20 UTC\r\nEDIT 2016-03-06: I completely missed that Lawrence Abrams of BleepinComputer.com not only reversed the\r\nDGA of PadCrypt long before me, but also tweeted an updated version of the DGA. Many thanks to\r\nMalwareHunterTeam for letting me know, and apologies to Lawrence Abrams for my redundant post. I updated\r\nthe post and my reimplementation to reflect the second DGA too.\r\nEDIT 2: Someone asked me on Twitter how to reverse the DGA. See the Appendix for a short tutorial how to very\r\neasily decompile PadCrypt.\r\nPadCrypt is a Ransomware first mentioned in a tweet of @abuse_ch. BleepinComputer.com wrote two articles\r\narticles on PadCrypt. The MalwareHunterTeam mentioned the Domain Generation Algorithm (DGA) PadCrypt\r\nversion 2.2.86.1 in a tweet:\r\nBleepinComputer.com tweeted version 2.2.97.0:\r\nhttps://johannesbader.ch/2016/03/the-dga-of-padcrypt/\r\nPage 1 of 13\n\nHere are the 24 distinct domains generated on March 6, 2016 for version 2.2.86.1:\r\nhttps://johannesbader.ch/2016/03/the-dga-of-padcrypt/\r\nPage 2 of 13\n\nAnd these are the 72 distinct domains generated on March 6, 2016 for version 2.2.97.0:\r\nhttps://johannesbader.ch/2016/03/the-dga-of-padcrypt/\r\nPage 3 of 13\n\nhttps://johannesbader.ch/2016/03/the-dga-of-padcrypt/\r\nPage 4 of 13\n\nTo get a reimplementation of the DGA, I looked at this sample of PadCrypt 2.2.86.1 from Hybrid-Analysis:\r\nMD5\r\nf58072b9413886e7b79e826ad94bd89e\r\nSHA-256\r\n1ad70a64863c2c59390e4e956d97065524acf5e2ae53f786770d2cf6bd602141\r\nupload date\r\n2015-03-01 10:55:57 (CST)\r\nfilename\r\npackage.pdcr.bin\r\nPadCrypt version\r\n2.2.86.1\r\nfilesize\r\n1.3 MB\r\nlink\r\nlink\r\nThe following sample of PadCrypt 2.2.97.0 was provided by Lawrence Abrams here, you can download it for\r\nexample from Virusshare.com. The sample features a modified version of the DGA with subtle changes (see tweet\r\nabove).\r\nMD5\r\n7c0f7a734014022f249338a23881dc24\r\nSHA-256\r\nf0f8ef9a0cd40363aa4b06ba4c0fa286f23010830caa931addefacb087d7c678\r\nupload date\r\n2016-03-06 19:52:54\r\nfilename\r\nPadCrypt.exe\r\nPadCrypt version\r\n2.2.97.0\r\nfilesize\r\n1.4 MB\r\nlink\r\nlink\r\nDGA Design\r\nThe DGA of PadCrypt 2.2.86.1 generates 24 domains per day, the DGA of version 2.2.97.0 three times that (72).\r\nThe DGAs use SHA256 hashing as generation scheme. Other malware families that are based on hashing include\r\nBamital, Murofet, Gameover, Pushdo (all MD5) and Dyre (SHA-256).\r\nPadCrypt does not use magic numbers for seeding, only the current date along with the domain number (0 to 23)\r\nare hashed. The only difference between 2.2.86.1 and 2.2.97.0 is the separator between date and domain number.\r\nhttps://johannesbader.ch/2016/03/the-dga-of-padcrypt/\r\nPage 5 of 13\n\nFor the older version they are separated by : (e.g., 6-3-2016:17 ); the newer version uses | (e.g., 6-3-\r\n2017|17 )\r\nThe last nibble of the hash value determines the top level domain. The 4 bit value is used as an index into a hard-coded list of top level domains. The list only has 11 domains and for greater indices the first top level domain is\r\nused instead. This makes “.com” — the first domain — much more common than the rest. The nibbles 3 to 18\r\ndetermine the 16 second level characters. The second level characters are picked by mapping 0000 to 1001 to a\r\nhard-coded list of characters:\r\nThe remaining values 1010 to 1111 are mapped to the corresponding hex representation, i.e., “a” to “f”. Because\r\nthe letters a, b, c, d and f are also in the hard-coded mapping they occur twice as common as the remaining letters\r\n“enolmk”.\r\nReimplementation\r\nI reimplemented the DGA in Python. Use the -d or --date argument to set the date. If no date is provided then\r\nthe domains for the current day are generated. You can select the DGA version with -v or --version . You also\r\nfind the reimplementation with potential future improvements on my Github page.\r\n\"\"\"\r\n The DGA of PadCrypt\r\n See\r\n - https://twitter.com/BleepinComputer/status/705813885673201665\r\n - http://www.bleepingcomputer.com/news/security/padcrypt-the-first-ransomware-with-live-support-chat-and-an-\r\n - http://www.bleepingcomputer.com/news/security/the-padcrypt-ransomware-is-still-alive-and-kicking/\r\n - https://bin.re/blog/the-dga-of-padcrypt/\r\n\"\"\"\r\nimport argparse\r\nimport hashlib\r\nfrom datetime import datetime\r\nconfigs = {\r\n \"2.2.86.1\" : {\r\n 'nr_domains': 24,\r\n 'tlds': ['com', 'co.uk', 'de', 'org', 'net', 'eu', 'info', 'online',\r\n 'co', 'cc', 'website'],\r\n 'digit_mapping': \"abcdnfolmk\",\r\nhttps://johannesbader.ch/2016/03/the-dga-of-padcrypt/\r\nPage 6 of 13\n\n'separator': ':',\r\n },\r\n \"2.2.97.0\" : {\r\n 'nr_domains': 24*3,\r\n 'tlds': ['com', 'co.uk', 'de', 'org', 'net', 'eu', 'info', 'online',\r\n 'co', 'cc', 'website'],\r\n 'digit_mapping': \"abcdnfolmk\",\r\n 'separator': '|'\r\n }\r\n}\r\ndef dga(date, config_nr):\r\n config = configs[config_nr]\r\n dm = config['digit_mapping']\r\n tlds = config['tlds']\r\n for i in range(config['nr_domains']):\r\n seed_str = \"{}-{}-{}{}{}\".format(date.day, date.month, date.year,\r\n config['separator'], i)\r\n h = hashlib.sha256(seed_str.encode('ascii')).hexdigest()\r\n domain = \"\"\r\n for hh in h[3:16+3]:\r\n domain += dm[int(hh)] if '0' \u003c= hh \u003c= '9' else hh\r\n tld_index = int(h[-1], 16)\r\n tld_index = 0 if tld_index \u003e= len(tlds) else tld_index\r\n domain += \".\" + config['tlds'][tld_index]\r\n yield domain\r\nif __name__==\"__main__\":\r\n parser = argparse.ArgumentParser()\r\n parser.add_argument(\"-d\", \"--date\", help=\"date for which to generate domains\")\r\n parser.add_argument(\"-v\", \"--version\", help=\"dga version\",\r\n choices=[\"2.2.86.1\", \"2.2.96.1\"], default=\"2.2.86.1\")\r\n args = parser.parse_args()\r\n if args.date:\r\n d = datetime.strptime(args.date, \"%Y-%m-%d\")\r\n else:\r\n d = datetime.now()\r\n for domain in dga(d, args.version):\r\n print(domain)\r\nCharacteristics\r\nThose are the characteristics of the PadCrypt DGA:\r\nhttps://johannesbader.ch/2016/03/the-dga-of-padcrypt/\r\nPage 7 of 13\n\nproperty value\r\ntype TDD (time-dependent deterministic)\r\ngeneration scheme hashing\r\nseed current date\r\ndomain change frequency 1 day\r\ndomains per day 24 (version 2.2.86.1), 72 (version 2.2.97.0)\r\nsequence sequential\r\nwait time between\r\ndomains\r\nnone\r\ntop level domains\r\ncom , co.uk , de , org , net , eu , info , online , co , cc ,\r\nwebsite\r\nsecond level characters letters: “abcdefnolmk”\r\nsecond level domain\r\nlength\r\n16\r\nOnly 11 characters make up the character set of the second level domains. Together with the fixed length of 16\r\ncharacters, this makes the domain easy to attribute to PadCrypt. The distribution is:\r\na: 12.5 %\r\nb: 12.5 %\r\nc: 12.5 %\r\nd: 12.5 %\r\ne: 6.25 %\r\nf: 12.5 %\r\nk: 6.25 %\r\nl: 6.25 %\r\nm: 6.25 %\r\nn: 6.25 %\r\no: 6.25 %\r\nAmong the top level domains, .com is picked 37.5% of the time. The remaining 10 tlds are picked with\r\nprobability 6.25%.\r\nAppendix - How to Reverse\r\nSince I got asked by private message on Twitter, here’s how to easily reverse PadCrypt.\r\nhttps://johannesbader.ch/2016/03/the-dga-of-padcrypt/\r\nPage 8 of 13\n\nPadCrypt is written for .NET version 4.5. This allows us to open the binary in a .NET decompiler. I’m using the\r\nexcellent and free dnSpy. Naturally, the authors of PadCrypt are aware that decompiling intermediate languages is\r\neasy, so they use a protector. Both PadCrypt 2.2.86.1, 2.2.97.0 and later version 2.2.120.0 use DeepSea 4.1.\r\nOpening the obfuscated binary in dnSpy gives you very messy code. The following screenshot shows the\r\nobfuscated DGA:\r\nhttps://johannesbader.ch/2016/03/the-dga-of-padcrypt/\r\nPage 9 of 13\n\nhttps://johannesbader.ch/2016/03/the-dga-of-padcrypt/\r\nPage 10 of 13\n\nThe decompiled routine takes up 268 lines and is impossible to read. Fortunately, there are deobfuscators for many\r\nknown obfuscators. I’m relying on the free and open soure de4dot. It comes with 21 deobfuscators and often\r\nworks out of the box. I ran the following command on PadCrypt:\r\nde4dot.exe padcrypt_2.2.97.0.exe -o padcrypt_2.2.97.0_deobf.exe\r\nAgain looking at the DGA routine reveals a much shorter, very easy to ready C# code:\r\nhttps://johannesbader.ch/2016/03/the-dga-of-padcrypt/\r\nPage 11 of 13\n\nOr, if you prefer, Visual Basic:\r\nhttps://johannesbader.ch/2016/03/the-dga-of-padcrypt/\r\nPage 12 of 13\n\nSource: https://johannesbader.ch/2016/03/the-dga-of-padcrypt/\r\nhttps://johannesbader.ch/2016/03/the-dga-of-padcrypt/\r\nPage 13 of 13\n\n  https://johannesbader.ch/2016/03/the-dga-of-padcrypt/  \nHere are the 24 distinct domains generated on March 6, 2016 for version 2.2.86.1:\n   Page 2 of 13 \n\nlink DGA Design       \nThe DGA of PadCrypt 2.2.86.1 generates 24 domains per day, the DGA of version 2.2.97.0 three times that (72).\nThe DGAs use SHA256 hashing as generation scheme. Other malware families that are based on hashing include\nBamital, Murofet, Gameover, Pushdo (all MD5) and Dyre (SHA-256).   \nPadCrypt does not use magic numbers for seeding, only the current date along with the domain number (0 to 23)\nare hashed. The only difference between 2.2.86.1 and 2.2.97.0 is the separator between date and domain number.\n    Page 5 of 13",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://johannesbader.ch/2016/03/the-dga-of-padcrypt/"
	],
	"report_names": [
		"the-dga-of-padcrypt"
	],
	"threat_actors": [],
	"ts_created_at": 1775791296,
	"ts_updated_at": 1775791338,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/2255c251e7dc3e1f7a6f07416d93504c43bbb37d.pdf",
		"text": "https://archive.orkl.eu/2255c251e7dc3e1f7a6f07416d93504c43bbb37d.txt",
		"img": "https://archive.orkl.eu/2255c251e7dc3e1f7a6f07416d93504c43bbb37d.jpg"
	}
}