{
	"id": "597c242e-a6df-4fee-be43-956a997792c0",
	"created_at": "2026-04-06T01:29:43.233688Z",
	"updated_at": "2026-04-10T03:21:49.249874Z",
	"deleted_at": null,
	"sha1_hash": "8e5e07de07304ac7fd148730a95dc5bcbfbe4bc2",
	"title": "A Deep Dive into Zloader - the Silent Night - VinCSS Blog",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 126670,
	"plain_text": "A Deep Dive into Zloader - the Silent Night - VinCSS Blog\r\nBy Yến Hứa\r\nPublished: 2021-07-04 · Archived: 2026-04-06 01:10:42 UTC\r\nTable of Contents\r\n1. Overview\r\n2. Unpacking Zloader Core Dll\r\n3. Anti-analysis\r\n4. Decrypt wide string\r\n4.1. Use IDAPython\r\n4.2. Use IDA AppCall\r\n5. Decrypt ansi string\r\n5.1. Use IDAPython\r\n5.2. Use IDA AppCall\r\n6. List of Dlls used by Zloader\r\n7. Dynamic APIs resolve\r\n8. Process Injection Technique\r\n9. Decrypt Zloader config\r\n10. Collect and save configuration in Registry\r\n11. Persistence technique\r\n12. References\r\n1. Overview\r\nZloader, a notorious banking trojan also known as Terdot or Zbot. This trojan was first discovered in 2016, and\r\nover time its distribution number has also continuously increased. The Zloader’s code is said to be built on the\r\nleaked source code of the famous ZeuS malware. In 2011, when source code of ZeuS was made public and since\r\nthen, it has been used in various malicious code samples.\r\nZloader has all the standard functionality of a trojan such as being able to fetch information from browsers,\r\nstealing cookies and passwords, capturing screenshots, etc. and for making analysis difficult, it applies advanced\r\ntechniques, including code obfuscation and string encryption, masking Windows APIs call. Recently, CheckPoint\r\nexpert published an analysis of a Zloader distribution campaign whereby the infection exploited Microsoft’s\r\ndigital signature checking process. In addition, Zloader has also recently partnered with different ransomware\r\ngangs are Ryuk and Egregor. This can indicate that the actors behind this malware are still looking for different\r\nways to upgrade it to bypass the defenses. Here is the ranking of Zloader according to the rating from the AnyRun\r\nsite:\r\nMost recently, multiple telecommunication providers and cybersecurity firms worldwide partnered with\r\nMicrosoft’s security researchers throughout the investigative effort, including ESET, Black Lotus Labs, Palo Alto\r\nhttps://blog.vincss.net/re026-a-deep-dive-into-zloader-the-silent-night/\r\nPage 1 of 30\n\nNetworks’ Unit 42, and Avast. They took legal and technical steps to disrupt the ZLoader botnet, seizing control of\r\n65 domains that were used to control and communicate with the infected hosts.\r\nIn this article, we will provide detailed analysis and techniques that Zloader uses, including:\r\nHow to unpack to dump Zloader Core Dll.\r\nThe technique that Zloader makes difficult as well as time consuming in the analysis process.\r\nDecrypt strings used by Zloader by using both IDAPython and AppCall methods.\r\nApply AppCall to recover the Windows API calls.\r\nProcess Injection technique that Zloader uses to inject into the msiexec.exe process.\r\nDecrypt configuration information related to C2s addresses.\r\nHow Zloader collects and saves information in the Registry.\r\nThe Persistence technique.\r\nThe analyzed sample used in the article:\r\n034f61d86de99210eb32a2dca27a3ad883f54750c46cdec4fcc53050b2f716eb\r\n2. Unpacking Zloader Core Dll\r\nFirst, check the sample with Nauz File Detector:\r\nBy collecting and combining information about sections from ExeInfo, entropy in DiE as well as the size of the\r\nDLL file, we can confirm that this DLL is packed:\r\nhttps://blog.vincss.net/re026-a-deep-dive-into-zloader-the-silent-night/\r\nPage 2 of 30\n\nFor unpacking, use x64dbg to load Dll file, set a bp NtAllocateVirtualMemory. Then, modify the breakpoint’s\r\ncondition as follows:\r\nhttps://blog.vincss.net/re026-a-deep-dive-into-zloader-the-silent-night/\r\nPage 3 of 30\n\nExecute with F9 and wait until the breakpoint is hit (after about 1126120 hits):\r\nFollowing the allocated memory regions, after the 3rd hit, the core Dll of Zloader will be unpacked:\r\nhttps://blog.vincss.net/re026-a-deep-dive-into-zloader-the-silent-night/\r\nPage 4 of 30\n\nDump this Dll to disk, the file has MD5: 9b5589fcd123a3533584a62956f2231b.\r\n3. Anti-analysis\r\nTo consume time of the analyst, Zloader uses meaningless functions, or rewrites functions that look very\r\ncomplicated but only to perform simple tasks such as AND, OR, XOR, ADD, SUB, etc.\r\nFor example, a function that does a meaningless task, however it can cause a delay in execution in a sandbox\r\nenvironment:\r\nFunctions that perform AND, OR operations:\r\nhttps://blog.vincss.net/re026-a-deep-dive-into-zloader-the-silent-night/\r\nPage 5 of 30\n\n4. Decrypt wide string\r\n4.1. Use IDAPython\r\nAll strings that the core DLL uses are encrypted. The wide string decoder function will take two parameters as\r\ninput:\r\nFirst parameter: the address containing the encrypted string.\r\nSecond parameter: the address where the string is stored after decoding.\r\nThe pseudocode at the f_zl_decrypt_wstring decryption function looks confusing, but if we look closely, the\r\nfunction performs a simple xor loop with the decryption key is “PgtrIPF-2ftOj00Ox“:\r\nhttps://blog.vincss.net/re026-a-deep-dive-into-zloader-the-silent-night/\r\nPage 6 of 30\n\nBased on the above pseudocode, the python code that performs decryption as follows:\r\nWith the help of IDAPython, we can automate the whole process of string decoding and add annotations at the\r\ndecryption functions in IDA for further analysis. The entire python code is as follows:\r\nhttps://blog.vincss.net/re026-a-deep-dive-into-zloader-the-silent-night/\r\nPage 7 of 30\n\nThe results before and after the script execution will make the analysis easier:\r\nhttps://blog.vincss.net/re026-a-deep-dive-into-zloader-the-silent-night/\r\nPage 8 of 30\n\n4.2. Use IDA AppCall\r\nIf you don’t have time to dig into the decryption implementation of the function, or when the algorithm is too\r\ncomplex, we can use IDA’s useful feature known as AppCall, to help decrypt the data. Basically, Appcall is a\r\nmechanism used to call functions inside the debugged program from the IDA debugger. Before applying AppCall,\r\nthe first thing is to given a function with a correct prototype. For example, the function f_zl_decrypt_wstring has\r\nthe following protoype:\r\nwchar_t *__cdecl f_zl_decrypt_wstring(wchar_t *encString, wchar_t *decString);\r\nNote again that in order to use AppCall, the program must be debugged. As shown below, IDA is stopping at the\r\nbreakpoint set at DllEntryPoint:\r\nhttps://blog.vincss.net/re026-a-deep-dive-into-zloader-the-silent-night/\r\nPage 9 of 30\n\nThen execute the below python script to decode and add comments related to decoded strings at the functions:\r\nThe final result should be similar to the image below:\r\nhttps://blog.vincss.net/re026-a-deep-dive-into-zloader-the-silent-night/\r\nPage 10 of 30\n\n5. Decrypt ansi string\r\n5.1. Use IDAPython\r\nBesides the function to decode wide strings, Zloader also uses the function to decode ansi strings. This function\r\nalso accepts two arguments:\r\nFirst parameter: the address containing the encrypted string.\r\nSecond parameter: the address where the string is stored after decoding.\r\nSimilar to the above f_zl_decrypt_wstring function, the pseudocode of the f_zl_decrypt_string function looks\r\nquite messy, but it still uses an xor loop to decrypt with the decryption key still “PgtrIPF-2ftOj00Ox“:\r\nhttps://blog.vincss.net/re026-a-deep-dive-into-zloader-the-silent-night/\r\nPage 11 of 30\n\nHere is the full python code to automate the whole process of decoding strings and adding comments at functions:\r\nhttps://blog.vincss.net/re026-a-deep-dive-into-zloader-the-silent-night/\r\nPage 12 of 30\n\nThe results before and after the script execution\r\nhttps://blog.vincss.net/re026-a-deep-dive-into-zloader-the-silent-night/\r\nPage 13 of 30\n\n5.2. Use IDA AppCall\r\nTo use AppCall, same as above, need to define correctly the prototype for the f_zl_decrypt_string function as\r\nfollows: char *__cdecl f_zl_decrypt_string(char *encString, char *decString);\r\nSlightly modified the script used for decoding the wide strings above:\r\nhttps://blog.vincss.net/re026-a-deep-dive-into-zloader-the-silent-night/\r\nPage 14 of 30\n\nResult after running the script:\r\n6. List of Dlls used by Zloader\r\nIn the list of strings decrypted by the f_zl_decrypt_string function above, there is a string after the decryption\r\nthat is quite meaningless. Going to this address, after diving into it I noticed that the first parameter passed to the\r\nhttps://blog.vincss.net/re026-a-deep-dive-into-zloader-the-silent-night/\r\nPage 15 of 30\n\nfunction is an array containing the addresses of the encrypted strings. Based on the corresponding index value of\r\nthe array will access the address containing the corresponding encrypted string:\r\nGoing to the g_ptr_enc_dll_str array (renamed above) will see a list of addresses as shown below:\r\nModify the script to decode the specific Dll strings, the results obtained when executing the script are as follows:\r\nTo summarize, we have a list of indexes corresponding to the DLLs that Zloader can use to retrieve the addresses\r\nof APIs:\r\nIndex Dll Name\r\nhttps://blog.vincss.net/re026-a-deep-dive-into-zloader-the-silent-night/\r\nPage 16 of 30\n\n0 kernel32.dll\r\n1 user32.dll\r\n2 ntdll.dll\r\n3 shlwapi.dll\r\n4 iphlpapi.dll\r\n5 urlmon.dll\r\n6 ws2_32.dll\r\n7 crypt32.dll\r\n8 shell32.dll\r\n9 advapi32.dll\r\n10 gdiplus.dll\r\n11 gdi32.dll\r\n12 ole32.dll\r\n13 psapi.dll\r\n14 cabinet.dll\r\n15 imagehlp.dll\r\n16 netapi32.dll\r\n17 wtsapi32.dll\r\n18 mpr.dll\r\n19 wininet.dll\r\n20 userenv.dll\r\n21 bcrypt.dll\r\n7. Dynamic APIs resolve\r\nSimilar to other advanced malware… Zloader will also get the address of API function(s) through searching by\r\npre-computed hash value based on API function name.\r\nhttps://blog.vincss.net/re026-a-deep-dive-into-zloader-the-silent-night/\r\nPage 17 of 30\n\nAs shown in the above figure, the f_zl_resolve_api_func_ex function takes two parameters:\r\n(1): The first parameter is dll_index. Based on this parameter, the function will decode the name of the\r\ncorresponding Dll, then call the LoadLibraryA function to get the base address of this Dll.\r\n(2): The second parameter is pre_api_hash. This parameter is the pre-computed hash of the API function\r\nname. The function f_zl_resolve_api_func_ex will call f_zl_resolve_api_func to retrieve the\r\ncorresponding API address:\r\nThe pseudocode at the f_zl_resolve_api_func function as follows:\r\nhttps://blog.vincss.net/re026-a-deep-dive-into-zloader-the-silent-night/\r\nPage 18 of 30\n\nThe entire pseudocode of the function that performs the hash calculation by the API function name is as follows:\r\nBased on the above pseudocode, re-implement using Python code as follows:\r\nResults when using the above function to find API functions corresponding to hash values hash 0xFDA8B77,\r\n0xB1C1FE3, 0x8ADF2D1:\r\nhttps://blog.vincss.net/re026-a-deep-dive-into-zloader-the-silent-night/\r\nPage 19 of 30\n\nWith all the above analysis results, it is possible to write an IDAPython script to recover all the APIs that Zloader\r\nuses. However, to avoid having to dig into Zloader’s hashing algorithm for each analysis, here I will use AppCall\r\nto do this task. The python code that uses AppCall is as follows:\r\nNote, Zloader has many areas of code that call to the f_zl_resolve_api_func_ex function, but there will be areas\r\nof code that do not have any reference to it and that area has not been defined as a complete function. Therefore,\r\nto be able to run the above script, it is necessary to create functions for those first. The final result after executing\r\nthe script will be as follows:\r\nhttps://blog.vincss.net/re026-a-deep-dive-into-zloader-the-silent-night/\r\nPage 20 of 30\n\nHowever, as shown in the figure there are still places where the API function can’t be recovered, that’s because\r\nZloader has performed the previous calculation of the dll_index and pre_api_hash values and saved them in the\r\nregister. After that, call the f_zl_resolve_api_func_ex function:\r\n8. Process Injection Technique\r\nZloader, when executed, will inject Core Dll into the msiexec.exe process. The whole process is as follows:\r\nhttps://blog.vincss.net/re026-a-deep-dive-into-zloader-the-silent-night/\r\nPage 21 of 30\n\nUse the CreateProcessA API function to create the msiexec.exe process in the SUSPENDED state.\r\nGet SizeOfImage value of Zloader Dll being loaded by rundll32.exe/regsvr32.exe. Use the\r\nVirtualAllocEx API function to allocate new memory inside the msiexec.exe process:\r\nAllocate heap memory, copy the entire contents of the Dll into this heap:\r\nGenerate a random number and use it to encrypt the entire payload stored in the heap:\r\nhttps://blog.vincss.net/re026-a-deep-dive-into-zloader-the-silent-night/\r\nPage 22 of 30\n\nUse the WriteProcessMemory API function to write the entire encrypted payload from the heap to the\r\npreviously allocated memory in the msiexec.exe process:\r\nhttps://blog.vincss.net/re026-a-deep-dive-into-zloader-the-silent-night/\r\nPage 23 of 30\n\nContinue to use the VirtualAllocEx API function to allocate a second memory region has size of region\r\nare 66 bytes in the msiexec.exe process. This memory region will be used to decrypt the entire encrypted\r\nDll above. Update the STARTUPINFO structure created by the CreateProcessA function before, the data\r\nhere are the assembly code that will be used to decrypt the encrypted Dll. Then, call the\r\nWriteProcessMemory function to write the updated contents of STARTUPINFO to the newly created\r\nmemory region.\r\nhttps://blog.vincss.net/re026-a-deep-dive-into-zloader-the-silent-night/\r\nPage 24 of 30\n\nFinally, use the GetThreadContext, SetThreadContext, ResumeThread or CreateRemoteThread API\r\nfunctions to execute the msiexec.exe process. At this point, the entry point executed at msiexec.exe will be\r\nthe memory region that containing the code to perform the decrypting mission:\r\nAfter decrypting the entire Zloader Dll, it will jump to the RVA address of 0xF270 (File offset: 0xE670) to\r\nexecute the main tasks of the malware:\r\nhttps://blog.vincss.net/re026-a-deep-dive-into-zloader-the-silent-night/\r\nPage 25 of 30\n\n9. Decrypt Zloader config\r\nThe configuration info of the Zloader has been encrypted and stored in the .rdata section. The decrypt function\r\ntakes two parameters are the encrypted configuration data and the key used to decrypt:\r\nInside the function f_zl_decrypt_config will use the RC4 algorithm to decrypt the data:\r\nWith the analyzed results, we can use IDAPython code below to perform the decoding:\r\nhttps://blog.vincss.net/re026-a-deep-dive-into-zloader-the-silent-night/\r\nPage 26 of 30\n\nResult after executing the script:\r\n10. Collect and save configuration in Registry\r\nhttps://blog.vincss.net/re026-a-deep-dive-into-zloader-the-silent-night/\r\nPage 27 of 30\n\nWhen first executed, Zloader will collect information about the victim including volume_GUID,\r\nComputer_Name, Windows version, Install Date, create random folders at %APPDATA%, generate a random\r\nregistry key at HKEY_CURRENT_USERSoftwareMicrosoft, then encrypt all relevant information and save it\r\nin the created registry:\r\nThe information stored in the registry is similar to the following:\r\nTo decrypt the data stored in the above Registry, use the decoded embedded RC4 key above. With the support of\r\nCyberChef, we can easily decrypt data as follows below:\r\nhttps://blog.vincss.net/re026-a-deep-dive-into-zloader-the-silent-night/\r\nPage 28 of 30\n\n11. Persistence technique\r\nZloader reads the entire contents of the core Dll from disk into the memory region, then writes to a random dll in a\r\ndirectory created above at %APPDATA%:\r\nCreate persistence key at HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionRun:\r\nhttps://blog.vincss.net/re026-a-deep-dive-into-zloader-the-silent-night/\r\nPage 29 of 30\n\n12. References\r\nCan You Trust a File’s Digital Signature? New Zloader Campaign exploits Microsoft’sSignature\r\nVerification putting users at risk\r\nShining a light on “Silent Night” Zloader/Zbot\r\nThe DGA of Zloader\r\n2020-09-11- ZLOADER (SILENT NIGHT) INFECTION FROM MYRESUME.XLS\r\nHide and Seek | New Zloader Infection Chain Comes With Improved Stealth and EvasionMechanism\r\nZloader Installs Remote Access Backdoors and Delivers Cobalt Strike\r\nTran Trung Kien (aka m4n0w4r) \r\nMalware Analysis Expert\r\nR\u0026D Center – VinCSS (a member of Vingroup)\r\nSource: https://blog.vincss.net/re026-a-deep-dive-into-zloader-the-silent-night/\r\nhttps://blog.vincss.net/re026-a-deep-dive-into-zloader-the-silent-night/\r\nPage 30 of 30",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://blog.vincss.net/re026-a-deep-dive-into-zloader-the-silent-night/"
	],
	"report_names": [
		"re026-a-deep-dive-into-zloader-the-silent-night"
	],
	"threat_actors": [],
	"ts_created_at": 1775438983,
	"ts_updated_at": 1775791309,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/8e5e07de07304ac7fd148730a95dc5bcbfbe4bc2.pdf",
		"text": "https://archive.orkl.eu/8e5e07de07304ac7fd148730a95dc5bcbfbe4bc2.txt",
		"img": "https://archive.orkl.eu/8e5e07de07304ac7fd148730a95dc5bcbfbe4bc2.jpg"
	}
}