{
	"id": "752636fa-f20c-4646-8a57-6a1db7a99039",
	"created_at": "2026-04-06T00:07:57.0523Z",
	"updated_at": "2026-04-10T03:32:46.191249Z",
	"deleted_at": null,
	"sha1_hash": "922f13962c9070ed2741964333fdaf26ff3aed83",
	"title": "The DGA of Zloader",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 141762,
	"plain_text": "The DGA of Zloader\r\nArchived: 2026-04-05 20:17:15 UTC\r\nZloader — also known as Terdot, DELoader or Zeus Sphinx 1 — is a malware from May 2016 that has resurged in\r\nthe last few weeks 2 \r\n3\r\n \r\n4\r\n \r\n5\r\n \r\n6\r\n. The last two references 5 \r\n6\r\n are posts by Brad Duncan that mention and list random\r\ndomain names:\r\n[…] then it started generating DNS queries for random 20-character alphabetic strings with .com as the\r\ntop level domain (TLD). I’ve included some examples below.\r\njgqhigsjkulmsvvhshmk.com\r\nwapjdxlstholqwakofgi.com\r\naiavxvlshmkweccksfky.com\r\nliswrfujohqsnbnohetn.com\r\nhciqylualwcnyvajdkqq.com\r\npdtlshacpbacpnhcndpd.com\r\nkdacggcctwcavdgvpbmk.com\r\nwapwtpwciertrhkdaxrp.com\r\nshyjgiyhyegxeqqpdtya.com\r\ngccggcctwcerlshacpba.com\r\ncpnhcndpdkylibtlbeco.com\r\nbxhwpdkqdakbplfvfqwn.com\r\nbioonshmwrbecckfcavh.com\r\nSimilar 20-character domains had also been referenced by Twitter User TomasP, who apparently also reverse\r\nengineered the domain generation algorithm (DGA) 7, yet did not publish it. Twitter User DynamicAnalysis\r\nsubsequently published DGA domains on Pastebin — for example 8 \r\n9\r\n — but only for one particular seed.\r\nThis blog post shows how to reverse engineer the algorithm and presents as a result a reimplementation in Python.\r\nThe post is based on the following sample, but I also looked at other samples to find additional seeds.\r\nMD5\r\nafdf2fbc0756ed304d1a33083a5f2b0f\r\nSHA1\r\nf3a25627f925390097a64a84ef34c952fe8af036\r\nSHA256\r\na947c216ea52ce23457b3babb1e1eb6275cabe2150d3995553e4de4b8c3d97f4\r\nSize\r\n323 KB (330752 Bytes)\r\nCompile Timestamp\r\n2019-05-27 07:19:22 UTC\r\nhttps://johannesbader.ch/blog/the-dga-of-zloader/\r\nPage 1 of 14\n\nLinks\r\nMalwareBazaar, URLHaus, Twitter, VirusTotal\r\nFilenames\r\nantiamsi.bin (MalwareBazaar), antiamsi.bin (VirusTotal)\r\nDetections\r\nMalwareBazaar: ZLoader, Virustotal: 52/74 as of 2020-04-25 03:46:18 -\r\nTrojanSpy:Win32/Glupteba.ef0afc48 (Alibaba), Trojan:Win32/Glupteba.RRS!MTB (Microsoft),\r\nWin32.Trojan-spy.Zbot.Lscl (Tencent), Trojan-Spy.Win32.Zbot.zzac (ZoneAlarm)\r\nThe sample is — as is customary — packed. Unpacking it leads to this sample:\r\nMD5\r\nc844efe1b7e76cbdea36ce62ff788de9\r\nSHA1\r\nd8143cf09bff7b0ca2a0c777912746a5922104ee\r\nSHA256\r\n835048e00ba3babf6f920c9a4c2863865a5dcf8e0b6ede4f57c63aeb9cb5c147\r\nSize\r\n184 KB (188416 Bytes)\r\nCompile Timestamp\r\n2020-04-08 18:19:58 UTC\r\nLinks\r\nMalwareBazaar, Malpedia, Dropped_by_md5, VirusTotal\r\nDetections\r\nVirustotal: 30/74 as of 2020-04-25 20:55:07 - a variant of Win32/Spy.Zbot.ADI (ESET-NOD32),\r\nW32/Zbot.ADI!tr (Fortinet), HEUR:Backdoor.Win32.Dridex.vho (Kaspersky),\r\nBehavesLike.Win32.Adopshel.ch (McAfee-GW-Edition), HEUR:Backdoor.Win32.Dridex.vho\r\n(ZoneAlarm)\r\nThis sample creates a new Windows installer process msiexec.exe in suspended state. It then writes an\r\nencrypted copy of itself into msiexec.exe , as well as a decryption stub. The thread context is set to the stub and\r\nexecution of the thread is resumed. The decryption stub decrypts the injected binary and jumps to the first\r\nsubroutine at offset 0x1C90. I dumped the sample with entry point set to this starting point. It should be\r\n“runnable” if loaded with image base 0x03090000 :\r\nMD5\r\n5c76c41f9d0cc939240b3101541b5475\r\nSHA1\r\nda361ec6976d3d9225ce40951b26d1d8ecdb7fd1\r\nSHA256\r\n4029f9fcba1c53d86f2c59f07d5657930bd5ee64cca4c5929cbd3142484e815a\r\nSize\r\n208 KB (212992 Bytes)\r\nCompile Timestamp\r\nhttps://johannesbader.ch/blog/the-dga-of-zloader/\r\nPage 2 of 14\n\n2020-04-08 18:19:58 UTC\r\nLinks\r\nMalwareBazaar, Malpedia, Dropped_by_md5, VirusTotal\r\nDetections\r\nVirustotal: 22/74 as of 2020-04-25 20:55:24 - Win32/Spy.Zbot.ADI (ESET-NOD32), BScope.Trojan-Spy.Zbot (VBA32)\r\nThe following analysis is based on this last sample (f3f2393a838d417ff8f823a235bd83f2) loaded at image base\r\n0x03091CD2.\r\nReverse Engineering\r\nThe analysis of the sample is complicated mainly by three techniques:\r\n1. The strings are encrypted. I chose the Appcall functionality of IDA Pro to decrypt them dynamically.\r\n2. API calls are hidden by dynamically resolving them using function hashes. Again, Appcalls to evaluate the\r\nroutine that resolves the API reveal most API names.\r\n3. Constant unfolding, dead code insertion and artithmetic substitution via indentities. The first two are\r\nmostly removed by the Hex Rays decompiler, and the arithemetic identities can be easily simplified with\r\nbasic logical equivalences. I’ll show an example of this when analysing the DGA\r\nDecryption of strings takes one function argument - the offset to the ciphertext:\r\n.text:03091CDB 68 B4 CA 0B 03 push offset dword_30BCAB4\r\n.text:03091CE0 E8 1B 17 01 00 call decrypt_string ; BOT-INFO\r\nThe comment next to the decrypt_string function call with the plaintext was found by running the following\r\nIDA script:\r\nfrom idc import *\r\nfrom idautils import *\r\nimport idaapi\r\nimport sys\r\nimport string\r\nimport re\r\nRESOLVER_TYPE_DEC = \"char *__cdecl decrypt_string(char *a1, char *a2);\"\r\nm = re.search(\"\\s([^ (@]+)[(@]\", RESOLVER_TYPE_DEC)\r\nRESOLVER_NAME = m.group(1)\r\nresolver_addr = get_name_ea_simple(RESOLVER_NAME)\r\nif resolver_addr == idaapi.BADADDR:\r\n print(RESOLVER_NAME + \" not defined\")\r\n sys.exit()\r\nhttps://johannesbader.ch/blog/the-dga-of-zloader/\r\nPage 3 of 14\n\nresolver = idaapi.Appcall.typedobj(RESOLVER_TYPE_DEC)\r\nresolver.ea = resolver_addr\r\ndef previous_heads(ea):\r\n \"\"\" iterator to get previous instructions of an address (no including itself) \"\"\"\r\n if not idc.is_head(idc.get_full_flags(ea)):\r\n ea = idaapi.next_head(ea, ea+1000)\r\n ea = idaapi.prev_head(ea,0)\r\n while ea != idaapi.BADADDR:\r\n yield ea\r\n ea = idaapi.prev_head(ea, 0)\r\ndef do():\r\n \"\"\" count the nr of references to the resolver function \"\"\"\r\n xrefs = list(CodeRefsTo(resolver_addr,1))\r\n \"\"\" iterate over all references \"\"\"\r\n for i, xr in enumerate(xrefs):\r\n print(\"[-] tackling {:08X}\".format(xr))\r\n args = []\r\n for x in previous_heads(xr):\r\n args.append(get_operand_value(x, 0))\r\n if len(args) \u003e= 1:\r\n break\r\n empty = Appcall.buffer(\" \", 1000)\r\n args.append(empty)\r\n try:\r\n r = resolver(*args)\r\n except Exception as e:\r\n print(\"FAILED: appcall failed: {}\".format(e))\r\n continue\r\n try:\r\n name = empty.value\r\n except:\r\n print(\"FAILED: to read back buffer)\r\n continue\r\n print(\"OK: found {}\".format(name))\r\n set_cmt(xr, name, True)\r\ndo()\r\nWindows API functions such as InternetConnectA are dynamically resolved and then called:\r\n.text:030917DC 68 E1 75 E7 0A push 0AE775E1h\r\n.text:030917E1 6A 13 push 13h\r\n.text:030917E3 E8 88 19 01 00 call resolve_api ; wininet_InternetConnectA\r\nhttps://johannesbader.ch/blog/the-dga-of-zloader/\r\nPage 4 of 14\n\n.text:030917E8 83 C4 08 add esp, 8\r\n.text:030917EB 0F B7 4D 10 movzx ecx, [ebp+arg_8]\r\n.text:030917EF 6A 00 push 0\r\n.text:030917F1 6A 00 push 0\r\n.text:030917F3 6A 03 push 3\r\n.text:030917F5 6A 00 push 0\r\n.text:030917F7 6A 00 push 0\r\n.text:030917F9 51 push ecx\r\n.text:030917FA 53 push ebx\r\n.text:030917FB 56 push esi\r\n.text:030917FC FF D0 call eax\r\nA similar IDA Pro script as the one to decrypt the strings was used to find the API names and comment the\r\ndisassembly.\r\nListing all references to the string decryption routine, we see one producing the plaintext “.com”:\r\nBecause the strings are deciphered immediatly before they are used, the decryption call for .com leads to the DGA\r\nroutine. IDA Pro does a very good job of decompiling the routine. I renamed a few variables and subroutines to\r\nget to this C code:\r\nhttps://johannesbader.ch/blog/the-dga-of-zloader/\r\nPage 5 of 14\n\nint __cdecl the_dga(int dwSeed, int nNumberOfDomains, int pArrayOfDomains)\r\n{\r\n int result; // eax\r\n unsigned int r; // esi\r\n int i; // edi\r\n unsigned int offset; // ebx\r\n char the_letter; // al\r\n unsigned int dwSeedXored_1; // ebx\r\n char *szTLD_1; // eax\r\n int i_1; // [esp-10h] [ebp-48h]\r\n char szTLD[19]; // [esp+1h] [ebp-37h]\r\n _DWORD the_domain_object[3]; // [esp+14h] [ebp-24h]\r\n unsigned int dwSeedXored; // [esp+20h] [ebp-18h]\r\n int iDomainNr; // [esp+24h] [ebp-14h]\r\n char szDomain[13]; // [esp+2Bh] [ebp-Dh]\r\n if ( nNumberOfDomains )\r\n {\r\n r = dwSeed;\r\n result = 0;\r\n dwSeedXored = dwSeed ^ 0x81716ECC;\r\n do\r\n {\r\n iDomainNr = result;\r\n initialize(the_domain_object);\r\n i = 0;\r\n do\r\n {\r\n offset = r % get_nr_25();\r\n the_letter = offset + get_nr_97();\r\n dwSeedXored_1 = dwSeedXored;\r\n szDomain[0] = the_letter;\r\n update_domain_object(szDomain);\r\n r = dwSeedXored_1 ^ or(~(r + szDomain[0]) \u0026 0x81716ECC, (r + szDomain[0]) \u0026 0x7E8E9133, 0);\r\n i_1 = i++;\r\n plus(i_1, 1, 0, 0);\r\n }\r\n while ( i != get_nr_20() );\r\n szTLD_1 = decrypt_string(szTLDCiphertext, szTLD);\r\n concatenate(szTLD_1);\r\n save_in_array((_DWORD *)pArrayOfDomains, (int)the_domain_object);\r\n reset(the_domain_object);\r\n result = plus_0(iDomainNr + 0x6A6E645D, 1u, 0) - 0x6A6E645D;\r\n }\r\n while ( result != nNumberOfDomains );\r\n }\r\nhttps://johannesbader.ch/blog/the-dga-of-zloader/\r\nPage 6 of 14\n\nreturn result;\r\n}\r\nThe code is already pretty readable. The only non obvious part is the random number calculation — variable r —\r\nwhich requires some basic logical computation. Let the seed dwSeed be s, and szDomain[0] be l, then the next\r\nnumber is determined as follows ( ⋅ , ⊕ , and + stand for logical and, xor and or respectively):\r\n𝑟 = (𝑠 ⊕ 0x81716ECC) ⊕ ( ∼ (𝑟 + 𝑙) ⋅ 0x81716ECC) + ((𝑟 + 𝑙) ⋅ 0x7E8E9133)\r\nThe two constants have the following relationship:\r\n0𝑥81716𝐸𝐶𝐶 =∼ 0𝑥7𝐸8𝐸9133 mod 2\r\n32\r\nFuthermore\r\n𝑎 ⊕ 𝑏 = ( ∼ 𝑎 ⋅ 𝑏) + (𝑎 ⋅ ∼ 𝑏)\r\nSo by setting k= 0x81716ECC we get:\r\n𝑟 = (𝑠 ⊕ 𝑘) ⊕ ( ∼ (𝑟 + 𝑙) ⋅ 𝑘) + ((𝑟 + 𝑙) ⋅ ∼ 𝑘)\r\n= 𝑠 ⊕ 𝑘 ⊕ ((𝑟 + 𝑙) ⊕ 𝑘)\r\n= 𝑠 ⊕ (𝑟 + 𝑙)\r\nThis leads to the following Python code for the DGA:\r\ndef dga(seed, nr_of_domains):\r\n domains = []\r\n r = seed;\r\n for i in range(nr_of_domains):\r\n domain = \"\"\r\n for j in range(20):\r\n letter = ord('a') + (r % 25)\r\n domain += chr(letter)\r\n r = seed ^ ( (r + letter) \u0026 0xFFFFFFFF)\r\n domain += \".com\"\r\n print(domain)\r\nLooking at the caller of the domain generation routine, we see how the seed is calculated:\r\n.text:03095540 push ebp\r\n.text:03095541 mov ebp, esp\r\n.text:03095543 push ebx\r\n.text:03095544 push edi\r\n.text:03095545 push esi\r\n.text:03095546 sub esp, 16Ch\r\n.text:0309554C lea edi, [ebp+pS]\r\n.text:03095552 mov [ebp+var_1C], ecx\r\nhttps://johannesbader.ch/blog/the-dga-of-zloader/\r\nPage 7 of 14\n\n.text:03095555 push edi\r\n.text:03095556 call decrypt_config_rc4\r\n.text:0309555B add esp, 4\r\n.text:0309555E lea esi, [ebp+pArrayOfDomains]\r\n.text:03095561 mov ecx, esi\r\n.text:03095563 call sub_30BA8E0\r\n.text:03095568 call get_today_at_0UTC\r\n.text:0309556D mov [ebp+dwSeed], eax\r\n.text:03095570 call sub_30A5260\r\n.text:03095575 lea ecx, [ebp+dwSeed]\r\n.text:03095578 push edi\r\n.text:03095579 push eax\r\n.text:0309557A push ecx\r\n.text:0309557B call rc4_encrypt\r\n.text:03095580 add esp, 0Ch\r\n.text:03095583 mov edi, [ebp+dwSeed]\r\n.text:03095586 call get_nr_of_domains\r\n.text:0309558B push esi\r\n.text:0309558C push eax\r\n.text:0309558D push edi\r\n.text:0309558E call the_dga\r\nFirst, the config of Zloader is decrypted with RC4. The RC4 key djluflczrgefphtiwegc is hardcoded in the\r\nsample. The config contains the hardcoded domains which are contacted before the DGA domains are used — if\r\nat all. At the end of the config, there is a new RC4 key q23Cud3xsNf3 which is used for seeding the DGA:\r\ns\r\nTelegramCrypt\r\nAntiAMSIdoc\r\nhttp://wmwifbajxxbcxmucxmlc.com/post.php\r\nhttp://pwkqhdgytsshkoibaake.com/post.php\r\nhttp://snnmnkxdhflwgthqismb.com/post.php\r\nhttp://iawfqecrwohcxnhwtofa.com/post.php\r\nhttp://nlbmfsyplohyaicmxhum.com/post.php\r\nhttp://fvqlkgedqjiqgapudkgq.com/post.php\r\nhttp://cmmxhurildiigqghlryq.com/post.php\r\nhttp://nmqsmbiabjdnuushksas.com/post.php\r\nhttp://fyratyubvflktyyjiqgq.com/post.php\r\nq23Cud3xsNf3\r\nThe seed is based on the unix timestamp for the current date at time 00:00 UTC. This 32bit value is representated\r\nin little endian order, and the four bytes are RC4 encrypted with the key from the config, i.e., q23Cud3xsNf3 . The\r\nresult is then interpreted as the little endian representation of the seed. The following Python snippet shows the\r\nseeding procedure.\r\nhttps://johannesbader.ch/blog/the-dga-of-zloader/\r\nPage 8 of 14\n\nkey = \"q23Cud3xsNf3\"\r\nrc4 = RC4(key)\r\nd = d.replace(hour=0, minute=0, second=0)\r\ntimestamp = int((d - datetime(1970, 1, 1)).total_seconds())\r\np = struct.pack(\"\u003cI\", timestamp)\r\nc = rc4.encrypt(p)\r\nseed = struct.unpack(\"\u003cI\", c)[0]\r\nWith the seeding procedure and the DGA finished, we can now give a complete reimplementation of the DGA.\r\nReimplementation in Python\r\nThe following Python code can be used to generate the Zloader domains for any date and RC4 seed value. For\r\nexample, to generate the domains for April 25, 2020 and seed q23Cud3xsNf3 do dga.py -d 2020-04-25 --rc4\r\nq23Cud3xsNf3 . You also find the algorithm in my domain generation GitHub repository.\r\nfrom datetime import datetime\r\nimport struct\r\nimport argparse\r\nclass RC4:\r\n def __init__(self, key_s):\r\n key = [ord(k) for k in key_s]\r\n S = 256*[0]\r\n for i in range(256):\r\n S[i] = i\r\n j = 0\r\n for i in range(256):\r\n j = (j + S[i] + key[i % len(key)]) % 256\r\n S[i], S[j] = S[j], S[i]\r\n self.S = S\r\n self.i = 0\r\n self.j = 0\r\n def prng(self):\r\n self.i = (self.i + 1) % 256\r\n self.j = (self.j + self.S[self.i]) % 256\r\n self.S[self.i], self.S[self.j] = self.S[self.j], self.S[self.i]\r\n K = self.S[(self.S[self.i] + self.S[self.j]) % 256]\r\n return K\r\nhttps://johannesbader.ch/blog/the-dga-of-zloader/\r\nPage 9 of 14\n\ndef encrypt(self, data):\r\n res = bytearray()\r\n for d in data:\r\n c = d ^ self.prng()\r\n res.append(c)\r\n return res\r\n def __str__(self):\r\n r = \"\"\r\n for i, s in enumerate(self.S):\r\n r += f\"{i}: {hex(s)}\\n\"\r\n return r\r\ndef seeding(d, key):\r\n rc4 = RC4(key)\r\n d = d.replace(hour=0, minute=0, second=0)\r\n timestamp = int((d - datetime(1970, 1, 1)).total_seconds())\r\n p = struct.pack(\"\u003cI\", timestamp)\r\n c = rc4.encrypt(p)\r\n seed = struct.unpack(\"\u003cI\", c)[0]\r\n return seed\r\ndef dga(seed, nr_of_domains):\r\n r = seed\r\n for i in range(nr_of_domains):\r\n domain = \"\"\r\n for j in range(20):\r\n letter = ord('a') + (r % 25)\r\n domain += chr(letter)\r\n r = seed ^ ((r + letter) \u0026 0xFFFFFFFF)\r\n domain += \".com\"\r\n print(domain)\r\nif __name__ == \"__main__\":\r\n parser = argparse.ArgumentParser()\r\n parser.add_argument(\"-d\", \"--date\", help=\"date when domains are generated\")\r\n parser.add_argument(\"-r\", \"--rc4\",\r\n help=\"rc4 key from config\",\r\n choices=[\"q23Cud3xsNf3\",\"41997b4a729e1a0175208305170752dd\", \"kZieCw23gffpe43Sd\"],\r\n default=\"q23Cud3xsNf3\")\r\n args = parser.parse_args()\r\nhttps://johannesbader.ch/blog/the-dga-of-zloader/\r\nPage 10 of 14\n\nif args.date:\r\n d = datetime.strptime(args.date, \"%Y-%m-%d\")\r\n else:\r\n d = datetime.now()\r\n seed = seeding(d, args.rc4)\r\n dga(seed, 32)\r\nOther Samples - Other Seeds\r\nFor reference, this section lists three more samples that I have analyzed and which have resulted in two additional\r\nseeds. You find precalculated lists of the DGA domains for all three seeds in my domain generation GitHub\r\nrepository 10.\r\nmd5 seed list of domains\r\nafdf2fbc0756ed304d1a33083a5f2b0f q23Cud3xsNf3 list\r\n2169e871d4ca668d1872722d1a0695dc q23Cud3xsNf3 list\r\nfa9b3dfdb4b97dfe0db5991472f89399 41997b4a729e1a0175208305170752dd list\r\n306212efebc6ac92000687393e56a5cb kZieCw23gffpe43Sd list\r\n2169e871d4ca668d1872722d1a0695dc\r\nMD5\r\n2169e871d4ca668d1872722d1a0695dc\r\nSHA1\r\nadd2bbbac042c328ed71c9fd2efcb9cbce5a89f7\r\nSHA256\r\ncc87e6581ca91f941f65332b2de0e681d58491b54aff9d0b30afae828a5f5790\r\nSize\r\n539 KB (552448 Bytes)\r\nCompile Timestamp\r\n2020-04-14 11:20:46 UTC\r\nLinks\r\nMalwareBazaar, URLhaus, VirusTotal\r\nFilenames\r\nSecuriteInfo.com.Win32.GenKryptik.EILT.4491 (MalwareBazaar), output.155861665.txt, Thusput,\r\nThusput.DLL, znvmzdd.dll, ZnVmZdD.dll, april14.dll (VirusTotal)\r\nDetections\r\nVirustotal: 42/75 as of 2020-04-18 16:11:27\r\nunpacks to\r\nhttps://johannesbader.ch/blog/the-dga-of-zloader/\r\nPage 11 of 14\n\nMD5\r\n6a900d6f8af3a1a0e31ca5bb63637d03\r\nSHA1\r\n221ab3d8ab16a0a7790026aab9b26904be6db436\r\nSHA256\r\ne4d0a79d2463c5d3a71874e3389fa753f480b96639ad32baf1997baf8e5f714a\r\nSize\r\n187 KB (191488 Bytes)\r\nCompile Timestamp\r\n2020-04-08 18:20:42 UTC\r\nLinks\r\nMalwareBazaar, Malpedia, Dropped_by_md5, VirusTotal\r\nDetections\r\nVirustotal: 29/75 as of 2020-04-25 20:58:26\r\nThe config is encrypted with RC4 key edykepkrqahpyxabcwgm . These are the hardcoded domains:\r\nhttp://wmwifbajxxbcxmucxmlc.com/post.php\r\nhttp://ojnxjgfjlftfkkuxxiqd.com/post.php\r\nhttp://pwkqhdgytsshkoibaake.com/post.php\r\nhttp://snnmnkxdhflwgthqismb.com/post.php\r\nhttp://iawfqecrwohcxnhwtofa.com/post.php\r\nhttp://nlbmfsyplohyaicmxhum.com/post.php\r\nhttp://fvqlkgedqjiqgapudkgq.com/post.php\r\nhttp://cmmxhurildiigqghlryq.com/post.php\r\nhttp://nmqsmbiabjdnuushksas.com/post.php\r\nhttp://fyratyubvflktyyjiqgq.com/post.php\r\nThe RC4 key for the DGA seed is q23Cud3xsNf3 .\r\nfa9b3dfdb4b97dfe0db5991472f89399\r\nMD5\r\nfa9b3dfdb4b97dfe0db5991472f89399\r\nSHA1\r\n5677f26e926c8c8d7f7bf7eb085a9e48549a268b\r\nSHA256\r\n3648fe001994cb9c0a6b510213c268a6bd4761a3a99f3abb2738bf84f06d11cf\r\nSize\r\n512 KB (524288 Bytes)\r\nCompile Timestamp\r\n2020-04-20 10:48:16 UTC\r\nLinks\r\nMalwareBazaar, URLHaus, Twitter, VirusTotal\r\nhttps://johannesbader.ch/blog/the-dga-of-zloader/\r\nPage 12 of 14\n\nFilenames\r\nf.dll (MalwareBazaar), Letter ease, Letter ease.DLL, f.dll (VirusTotal)\r\nDetections\r\nMalwareBazaar: ZLoader, Virustotal: 50/75 as of 2020-04-24 02:51:48\r\nunpacks to\r\nMD5\r\n133b1861b3590bf00308509227f82872\r\nSHA1\r\neb6f12759da7aa84077143e3e2694b6fda3d5631\r\nSHA256\r\ndd11381223ab1902db2963df4cbe3299e42064a5857545560f913647c1f70c5a\r\nSize\r\n187 KB (191488 Bytes)\r\nCompile Timestamp\r\n2020-04-08 18:20:42 UTC\r\nLinks\r\nMalwareBazaar, Malpedia, Dropped_by_md5, VirusTotal\r\nDetections\r\nVirustotal: 29/74 as of 2020-04-25 21:00:11\r\nThe config is encrypted with RC4 key dqhfltvppmucpvebkqtn . These are the hardcoded domains:\r\nhttps://dcaiqjgnbt.icu/wp-config.php\r\nhttps://nmttxggtb.press/wp-config.php\r\nThe RC4 key for the DGA seed is 41997b4a729e1a0175208305170752dd .\r\n306212efebc6ac92000687393e56a5cb\r\nMD5\r\n306212efebc6ac92000687393e56a5cb\r\nSHA1\r\ndc0b678e9ad7cadd5de907bf80fa351d5d3347cc\r\nSHA256\r\n8d5a770975e52ce1048534372207336f6cc657b43887daa49994e63e8d7f6ce1\r\nSize\r\n856 KB (877056 Bytes)\r\nCompile Timestamp\r\n2020-04-05 16:19:02 UTC\r\nLinks\r\nMalwareBazaar, VirusTotal\r\nFilenames\r\nhttps://johannesbader.ch/blog/the-dga-of-zloader/\r\nPage 13 of 14\n\nJtVhjtbGMAbrWft.dll (MalwareBazaar), FfIYXQPKpCQymHQ.exe, PkRWAytIAsEHwhy.exe,\r\nqKMCMByhJjQpfmZ.exe, FmgJjYLZmscJaur.exe, gGwBVwnpxkyFNlc.exe, ZhbIdJYZzrkPQGs.exe,\r\neIGmAdVpMFJxmrk.exe, VUCJyZshHrMGvdT.exe, WHFQhvaOzqkkTFk.exe, dFVlQGPNqrdhrCE.exe,\r\ntnXoUCMnjELKOYm.exe, dTEAUJnMdnADEVG.exe, omih.dll, ikhaapd.dll, 2020-04-07-ZLoader-DLL-binary.bin, etidwuv.dll, ekydn.dll, upiqwoq.dll, ryubn.dll, JtVhjtbGMAbrWft.exe, icobyg.dll,\r\nGnbjtDwFOsvocUW.exe, CbxfejTbfqXuuIT.exe, JtVhjtbGMAbrWft.bin (VirusTotal)\r\nDetections\r\nVirustotal: 58/75 as of 2020-04-20 00:40:47\r\nunpacks to\r\nMD5\r\n4a74e2d34230bbc705f39e6943c859d3\r\nSHA1\r\n410c1c03a52dbd56e78b0487ec532e68eb1c64e4\r\nSHA256\r\n60544c6694620488b69e568b15c96b33971dd7343ba63da31f993332852871c2\r\nSize\r\n172 KB (176640 Bytes)\r\nCompile Timestamp\r\n2020-03-30 18:35:43 UTC\r\nLinks\r\nMalwareBazaar, Malpedia, Dropped_by_md5, VirusTotal\r\nDetections\r\nVirustotal: 34/75 as of 2020-04-25 20:59:59\r\nThe config is encrypted with RC4 key cbstobypqnbsnnpehdtb . These are the hardcoded domains:\r\nhttps://knalc.com/sound.php\r\nhttps://namilh.com/sound.php\r\nhttps://ronswank.com/sound.php\r\nhttps://stagolk.com/sound.php\r\nhttps://mioniough.com/sound.php\r\nhttps://ergensu.com/sound.php\r\nThe RC4 key for the DGA seed is kZieCw23gffpe43Sd .\r\nSource: https://johannesbader.ch/blog/the-dga-of-zloader/\r\nhttps://johannesbader.ch/blog/the-dga-of-zloader/\r\nPage 14 of 14",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://johannesbader.ch/blog/the-dga-of-zloader/"
	],
	"report_names": [
		"the-dga-of-zloader"
	],
	"threat_actors": [
		{
			"id": "e90ec9cb-9959-455d-b558-4bafef64d645",
			"created_at": "2022-10-25T16:07:24.222081Z",
			"updated_at": "2026-04-10T02:00:04.903184Z",
			"deleted_at": null,
			"main_name": "Sphinx",
			"aliases": [
				"APT-C-15"
			],
			"source_name": "ETDA:Sphinx",
			"tools": [
				"AnubisSpy",
				"Backdoor.Oldrea",
				"Bladabindi",
				"Fertger",
				"Havex",
				"Havex RAT",
				"Jorik",
				"Oldrea",
				"PEACEPIPE",
				"njRAT",
				"yellowalbatross"
			],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "3fff98c9-ad02-401d-9d4b-f78b5b634f31",
			"created_at": "2023-01-06T13:46:38.376868Z",
			"updated_at": "2026-04-10T02:00:02.949077Z",
			"deleted_at": null,
			"main_name": "Cleaver",
			"aliases": [
				"G0003",
				"Operation Cleaver",
				"Op Cleaver",
				"Tarh Andishan",
				"Alibaba",
				"TG-2889",
				"Cobalt Gypsy"
			],
			"source_name": "MISPGALAXY:Cleaver",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		}
	],
	"ts_created_at": 1775434077,
	"ts_updated_at": 1775791966,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/922f13962c9070ed2741964333fdaf26ff3aed83.pdf",
		"text": "https://archive.orkl.eu/922f13962c9070ed2741964333fdaf26ff3aed83.txt",
		"img": "https://archive.orkl.eu/922f13962c9070ed2741964333fdaf26ff3aed83.jpg"
	}
}