# Zloader Reversing **aaqeel01.wordpress.com/2021/10/18/zloader-reversing/** Ali Aqeel October 18, 2021 Aka: ZeusLoader, Deloader, Terdot, Zbot is a malware family that downloads Zeus [OpenSSL. Parts of the source code of Zeus were leaked back in 2010 [1] and since couple](https://github.com/Visgean/Zeus) of versions been forked. Each of the version has its malicious capabilities, but all in common do info stealing specially banking information. Zeus in its core does wild stuff from stealing HTTPS session before being encrypted; to split stolen data and send it in multiple channels [over different C2 server based on the stolen info-type [2]. The sent data is being encrypted](https://www.honeynet.it/wp-content/uploads/Papers/04-Titans%20revenge.pdf) using RC4 algorithm. Given that major parts of the Zeus being well known and very detectable by almost every AV; Zloader is not just a loader/packer to Zeus core functionality. There are some complicated obfuscation techniques and visual encryption implemented on every single unpacked version of Zloader that bypass security and difficulty extracting configuration. Uncommon attack vector like using Google AdSense has been observed lately [[3] also attacker signs Zloader with a certificate compromised from legitimate software in](https://www.sentinelone.com/labs/hide-and-seek-new-zloader-infection-chain-comes-with-improved-stealth-and-evasion-mechanisms/) order to evade detection. In this post, we gonna take a look of common Zloader 123 botnet attack that uses maldoc vector. Quickly analyze maldoc, downloader, and the well known unpacking technique with observed behavior which simple and not quite interesting. However, the second part is going to be deep dive into analyzing and reversing techniques of Zloader unpacked version. **Maldoc** **SHA256 500856ee3fc13326cad564894a0423e0583154ef10531de4ab6e6d5df90d4e31** ----- **File Type Office Open XML Spreadsheet** **Name tn4598151.xlsm** **Size 182.62 KB (187002 bytes)** **Creation Time 2021-10-04 13:17:51** **Links** [MalwareBazaar,](https://bazaar.abuse.ch/sample/500856ee3fc13326cad564894a0423e0583154ef10531de4ab6e6d5df90d4e31/) [VirusTotal,](https://www.virustotal.com/gui/file/500856ee3fc13326cad564894a0423e0583154ef10531de4ab6e6d5df90d4e31/details) [Any.run](https://app.any.run/tasks/983208f5-e42d-4127-ab76-022f4e6ce4bb/) In clear text on sheet2, the maldoc give away downloader URL, directory where it’s been dropped, and shell command to run a Dll which is the Zloader. Enable macro is required to run the above in VBA script. Downloaded test.dll is just an HTML! that downloads logs.php which is a Zloader Dll file! ----- **Dll Zloader** **SHA256 c4ab81d7b7d44dd6dfc4f2b69dbe3f22fbf23c1ae49ab8edac2d26f85ae4514d** **File Type Win32 DLL** **Names suqyatda.dll, ewviv.dll, ehev.dll, cyvi.dll, logs.php** **Size 1.13 MB (1189888 bytes)** **Compiler Time-stamp Mon Sep 23 01:29:14 2019** **First Submission 2021-10-04 18:23:00** **Links** [MalwareBazaar,](https://bazaar.abuse.ch/sample/c4ab81d7b7d44dd6dfc4f2b69dbe3f22fbf23c1ae49ab8edac2d26f85ae4514d/) [VirusTotal,](https://www.virustotal.com/gui/file/c4ab81d7b7d44dd6dfc4f2b69dbe3f22fbf23c1ae49ab8edac2d26f85ae4514d) [Tria.ge](https://tria.ge/s?q=c4ab81d7b7d44dd6dfc4f2b69dbe3f22fbf23c1ae49ab8edac2d26f85ae4514d) Zloader Dll file is been downloaded and runned in temp location. After Zloader runs: 1. Create new process msiexec.exe and inject its loader in it. 2. Loader sets new registry values using random hive and key names in: HKCU\Software\Mircosoft\bbxk\uuwk HKCU\Software\Mircosoft\bbxk\ziox ----- 3. Deletes original downloader and copy itself to %AppData%\Roaming\ random name\*.dll The registry value calls the new directory for persistent in case of host rebooted. Both registry values are encrypted with RC4 but more to that in next section ----- Running Process and Registry Value change When checking memory strings for any forensics it spells out great number of C2 values. Noticed that 20 URLs has random name with fixed length. Those are called Domain Generated Algorithm DGA, unlike hardcode C2 URLs those are queried during running. More to that later in next section. Using pe-sieve64 tool is good way to dump the unpacked Zloader from the running process which is valid PE file to be analyzed. However, just a quick debugging would give same [result. In SquirrelWaffle and QakBot recent analysis [4]](https://elis531989.medium.com/the-squirrel-strikes-back-analysis-of-the-newly-emerged-cobalt-strike-loader-squirrelwaffle-937b73dbd9f9) [[5] it’s been observed that Zloader](https://twitter.com/aaqeel87/status/1443255927000424449?s=20) among other malwares are using same crypters/decryptor for unpacking mechanism for their [loaders before injecting them in process. Following the same debugging method in [4] would](https://elis531989.medium.com/the-squirrel-strikes-back-analysis-of-the-newly-emerged-cobalt-strike-loader-squirrelwaffle-937b73dbd9f9) reveal the packed Zloader. ----- ----- **Unpacked Zloader** **SHA256** 3A4CA58B0A2E72A264466A240C6636F62B8742FFBC96CE14E2225F0E57012E96 **File Type Win32 DLL** **Name unpacked_zloader_21_10_4.dll,** **Size 146.00 KB (149504 bytes)** **Compiler Time-stamp Wed Jul 14 08:04:16 2021** **First Submission 2021-10-18 15:32:37** **Links** [MalwareBazaar,](https://bazaar.abuse.ch/sample/3a4ca58b0a2e72a264466a240c6636f62b8742ffbc96ce14e2225f0e57012e96/) [VirusTotal,](https://www.virustotal.com/gui/file/3a4ca58b0a2e72a264466a240c6636f62b8742ffbc96ce14e2225f0e57012e96/detection) [Tria.ge](https://tria.ge/211018-sym56aegfp) ----- The unpacked Zloader is a master piece of obfuscated functions that waste lots of analysis time to dig into. API strings among other static indicators would not be a good clue for analyzing Zloader. Beside, this malware family is known for API hashing, Visual Encryption using XOR, and RC4 encryption to encrypt strings. There are five main topics we are going to discuss in this section when reversing Zloader: API hashing, XORing string, extracting Configuration, DGA routine, and Zeus function. **API Hashing:** Statically analyzing Zloader is a bit of a challenge. However, with a new amazing IDA plugin [called HashDB from OpenAnalysis Labs [6] it’s amazing how much obfuscated strings get](https://hashdb.openanalysis.net/#section/Using-The-API/Hash-Format) out the way when reversing Zloader. Just to show a case of what HashDB can do before and after shots of hashed values in a random function. The hashes been checked among large database of hashes with good prediction of hashing algorithms been used. ----- ----- **XORing Strings:** With API hashing out of the way. It’s important to get reversing tricks to dig into the main functions and extract configurations. There’re very limited hardcode strings in Zloader that can be clues like those. First, let’s look at Off_186010 which is an offset of an offset of a memory location **rdata:00183D80 with literal string ( #uVTN7’GQ’rxUf5Ly ). When cross referencing this offset** it’s been used 4 times in two different functions. And there’s some sort of XOR function in both subroutines which reveal this is the key literal string could be an XOR key value. ----- Cross referencing both sub_1658F0 and sub_173C90 routines would shows that over 120 times those functions has been called. Randomly checking any of the cross referencing like below ….skipped lines…….. text:001610E0 push offset unk_183E8E .text:001610E5 call sub_1658F0 ….skipped lines…….. text:0016444E push offset unk_184310 text:00164453 call sub_173C90 ….. skipped lines…… text:00165685 push offset unk_184040 text:0016568A call sub_1658F0 We noticed both subrouties been called after a push of unknow offsets Let’s use XOR key (#uVTN7’GQ’rxUf5Ly) with offset unk_184040 value. ----- Shift+E over unknow offset location Hex: 70 00 1A 00 30 00 20 00 39 00 56 00 55 00 22 00 0D 00 6A 00 1B 00 1B 00 27 00 09 00 46 00 23 00 1F 00 57 00 29 00 56 00 key: #uVTN7’GQ’rxUf5Ly Result: SuLT~7.Gh’$x.f.Lt#.VON,’`Q.r>UE5Sytu.T.7 The XORed value/result doesn’t make sense. If anything noticeable that the Hex values has zeros in sequence. Which indicate sub_1658F0 is for wide character and this makes and **sub_173C90 for normal character. let’s try again deleting all repeated zeros and XOR with** the key Hex: 701A3020395655220D6A1B1B270946231F572956 key: #uVTN7’GQ’rxUf5Ly Result: Software\Microsoft\ ----- It s not just strings that been obfuscated, some API calls been XORed too. Almost 120 offset being pushed in stack which means 120 strings are being XORed and to make it readable; _Appendix – A contains all the strings with addresses after been XORed._ **Configuration:** The other string ‘qhpacozsstaznupphhedjtuoww’ is 26 length. It’s crossed referenced twice in two separate routines. snipped assembly from sub_161E40 and sub_1673D0 routines .text:00161EE3 push offset aQhpacozsstaznu ; “qhpacozsstaznupphhedjtuoww” .text:00161EE8 push offset unk_184404 ——-skipped lines— text:001673D0 sub_1673D0 proc near ; CODE XREF: sub_171400+40↓p .text:001673D0 push ebp .text:001673D1 mov ebp, esp .text:001673D3 push edi .text:001673D4 push esi .text:001673D5 mov esi, ecx .text:001673D7 call sub_1809A0 .text:001673DC mov edi, [eax+30h] .text:001673DF mov ecx, esi .text:001673E1 call sub_1809A0 .text:001673E6 add eax, edi .text:001673E8 push 36Fh .text:001673ED push offset unk_184404 .text:001673F2 push eax .text:001673F3 call sub_171D80 .text:001673F8 add esp, 0Ch .text:001673FB mov ecx, esi .text:001673FD call sub_1809A0 ----- .text:00167402 mov edi, [eax+34h] .text:00167405 mov ecx, esi .text:00167407 call sub_1809A0 .text:0016740C add eax, edi .text:0016740E push 64h ; ‘d’ .text:00167410 push offset aQhpacozsstaznu ; “qhpacozsstaznupphhedjtuoww” In both routines notice a repeated push to an offset unk_184404. This offset contains configurations. Noticed that both offset passed into a function sub_1656B0 (name _decrypting_rc4)_ Pseudo code from sub_1656B0 routine Decrypting_rc4 function calls multiple function and those are calling other functions. What we are looking here is RC4 algorithm. ----- To have mind map where RC4 algorithm location lets Xref-from Decrypting_rc4 function where Config strings and key retrieved Xref_from sub_1656B0 (decrypting_rc4) Now let’s go back to the configuration ‘config’ offset in data block and copy its hex value to CyberChef and use RC4 algorithm to decrypt it with the key (qhpacozsstaznupphhedjtuoww) ----- Notice three things: got C2 URLs, list in Table-1, and 123 which is ID for this variant of Zloader, and at the tail there’s this value (djfsf02hf832hf03) which is another RC4 key that decrypt the registry values in \HKEY_CURRENT_USER\Software\Microsoft\bbxk and also encrypt decrypt traffic with C2 [[7].](https://www.malwarebytes.com/resources/files/2020/06/the-silent-night-zloader-zbot_final.pdf) Table-1 123 hxxp://gipc.in/post[.]php hxxp://fbhindia.com/post[.]php ----- hxxp://ecolenefiber.com/post[.]php hxxp://design.ecolenefiber.com/post[.]php hxxp://beta.marlics.ir/post[.]php hxxp://hari.pk/post[.]php hxxp://iaiskjmalang.ac.id/post[.]php hxxp://314xd.com/post[.]php hxxp://ejournal.iaiskjmalang.ac[.]id/post.php hxxp://duanvn.com/post[.]php djfsf02hf832hf03 Decrytped registry key value contains host name and the Zloader in %AppData% directory. **DGA:** ----- Zloader know for using DGA algorithm and we notice above some of the generated 32 character length URLs. To find the DGA function in this we can look for .com or post.php strings that been deobfuscatd in the previous section of XORing strings. when cross referencing .com from rdata:001849B4 location we find that it’s been called by one function and let’s name that function the_dga ----- [The_dga function has been called one by another function. Based on [8], the caller of DGA](https://bin.re/blog/the-dga-of-zloader/) routine does it math calculating values called Seed based on time and RC4 key (djfsf02hf832hf03) (second key). So the values generated are much different each day passed in used GetLocalTime and SystemTimetoFileTime APIs. Notice that the_dga function has passed value of 32 which is the same length of the URL string with Seed value which in this case makes the entire caller function to calculate Seed value. followed by _post.php and https while loop. The caller function got many obfuscated function that slows_ down analysis and it get complicated calculating generated domains manually. **Zeus Items:** Zeus uses item ID as list below which is the main one, there are more extended list based on [Zloader version [1]](https://github.com/Visgean/Zeus) [[2]](https://www.honeynet.it/wp-content/uploads/Papers/04-Titans%20revenge.pdf) [[7]. Each ID passed into a function and dissect information from victim](https://www.malwarebytes.com/resources/files/2020/06/the-silent-night-zloader-zbot_final.pdf) machine. When that information stored in attacker SQL filed it show retrieved info about the host. **Item ID** **Value** 10001 SBCID BOT ID 10002 SBCID BOTNET 10003 SBCID BOT VERSION 10005 SBCID NET LATENCY 10006 SBCID TCPPORT S1 10007 SBCID PATH SOURCE ----- **Item ID** **Value** 10008 SBCID PATH DEST 10009 SBCID TIME SYSTEM 10010 SBCID TIME TICK 10011 SBCID TIME LOCALBIAS 10012 SBCID OS INFO 10013 SBCID LANGUAGE ID 10014 SBCID PROCESS NAME 10015 SBCID PROCESS USER 10016 SBCID IPV4 ADDRESSES 10017 SBCID IPV6 ADDRESSES 10018 SBCID BOTLOG TYPE 10019 SBCID BOTLOG To get to Zeus item values and function we need to search strings in IDA to find one the common ID values since they are constant. Notice that most the calls are sub_1657B0, let’s call it z_items_main, it’s been crossed referenced 17 times List of Zeus items being found in 123 variant ----- **Item ID** **Value** 10001 SBCID BOT ID 10003 SBCID BOT VERSION 10006 SBCID_PING 10007 SBCID PATH SOURCE 11014 SBCID_GET_FILE 11015 SBCID_GET_FILE_VER 11031 SBCID_LOG_ID_EXT 11032 SBCID_LOG_ERR_CODE 11033 SBCID_LOG_MSG 10022 SBCID_DEBUG 10025 SBCID_MARKER 20001 CFGID_LAST_VERSION 20000 SBCID_BOTLOG 20005 CFG_HTTP_FILTER 20006 CFGID_HTTP_POSTDATA_FILTER 20008 CFGID_DNS_LIST Just to give an example of the level of obfuscation on every stage of Zloader. Not all the items ID values are retrieved in decimal passed to the function. Some values passed into another function and require to calculate separately like below in v29 value return from **sub_167890 .** ----- To give an example of how Zeus item works let take a look at this function sub_177110. **sub_16F780 has (20001: CFGID_LAST_VERSION) that updates Zloader version. Looking** at it in the disassembler would show so much obfuscated function, but to have an idea of what possibly this update could do let’s see the leaked source code having this similar Item [ID in similar fashion [9]](https://github.com/Visgean/Zeus/blob/c55a9fa8c8564ec196604a59111708fa8415f020/source/client/dynamicconfig.cpp) ----- The successful update would lead to update registry values in HKCU\Software\Mircosoft\bbxk\ which points to %AppData% directory of possible the new Zloader that has new C2 connections Finally, to have an idea how Zeus function being called here’s a mind map when Xref-to it. Appendix A ----- **Address** **XORed string** rdata:00183DED kernel32.dll rdata:00183DFA http rdata:00183E26 post rdata:00183E37 .63 rdata:00183E3B Wininet.dll rdata:00183DE0 Imagehlp.dll rdata:00183DB0 C:\Windows\SystemApps rdata:00183D9C Local rdata:00183D92 .exe rdata:00183D50 NtQueryVirtualMemory rdata:00183D43 Bcrypt.dll rdata:00183D38 Ftllib.dll rdata:00183D2A Samlib.dll rdata:00183D20 Post.php rdata:00183E47 Ntdll.dll rdata:00183E5C CmpMem64 rdata:00183E70 INVALID_BOT_ID rdata:00183E8E \start rdata:00183EA0 HideClass rdata:00183EB4 advapi32.dll rdata:00183ED0 ABCDEFGHIJKLMNOPQRSTUVWZabcdefghijklmnopqrstuvwz rdata:00183F21 ws2_32.dll rdata:00183F3B Shlwapi.dll rdata:00183F47 crypt32.dll rdata:00183F60 NtProtectVirtualMemory rdata:00183F77 GetMem64 ----- **Address** **XORed string** rdata:00183F90 Get rdata:00183FA0 Software\Microsoft\Windows\CurrentVersion\Run rdata:00183FFC Urlmon.dll rdata:0018400A wtsapi32.dll rdata:00184040 Software\Microsoft rdata:00184068 tmp rdata:0018407C Iphlpapi.dll rdata:0018408C Version.dll rdata:0018409E rpcrt4.dll rdata:001840AA Dll rdata:00184111 wldap32.dll rdata:00184165 ole32.dll rdata:0018416F psapi_dll rdata:00184180 NtFreeVirtualMemory rdata:001841A0 NtSetContextThread rdata:001841B3 Winsta.dll rdata:001841D0 user32.dll rdata:001841E0 Software\Microsoft\WindowsNT\CurrentVersion rdata:00184288 gdi32.dll rdata:00184292 Gdiplus.dll rdata:001842C0 regsvr32.exe rdata:001842F0 RtlCreateUserProcess rdata:00184310 NtWriteVirtualMemory rdata:00184330 InstallDate rdata:001843B0 NtReadVirtualMemory rdata:001843E0 RtlCreateProcessParameters ----- **Address** **XORed string** rdata:00184780 Connection_close rdata:00184794 Dnsapi.dll rdata:001847BC secur32.dll rdata:001847D0 kernel32.dll rdata:001847F0 NtGetContextThread rdata:00184820 Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36. rdata:00184892 NtResumeThread rdata:001848B0 SeSecurityPrivilege rdata:00184914 shell32.dll rdata:00184920 Ntdll.dll rdata:00184940 LdrGetProcedureAddress rdata:00184957 netapi32.dll rdata:00184964 Mpr.dll rdata:0018496C https:\\ rdata:00184975 X64Call rdata:00184980 NtAllocateVirtualMemory rdata:001849B4 .com rdata:001849BA Global rdata:001849CA Winscard.dll rdata:001849D7 Cabinet.dll rdata:001849E3 Userenv.dll rdata:001849EF Ncrypt.dll **References** [1] Zeus opensource, [https://github.com/Visgean/Zeus](https://github.com/Visgean/Zeus) ----- [2] Titans revenge: detecting Zeus via its own flaws, https://www.honeynet.it/wpcontent/uploads/Papers/04-Titans%20revenge.pdf [3] Hide and Seek | New Zloader Infection Chain Comes With Improved Stealth and Evasion Mechanisms, https://www.sentinelone.com/labs/hide-and-seek-new-zloader-infection-chaincomes-with-improved-stealth-and-evasion-mechanisms/ [4] The Squirrel Strikes Back: Analysis of the newly emerged cobalt-strike loader “SquirrelWaffle”, https://elis531989.medium.com/the-squirrel-strikes-back-analysis-of-thenewly-emerged-cobalt-strike-loader-squirrelwaffle-937b73dbd9f9 [5] QakBot Quick analysis, [https://twitter.com/aaqeel87/status/1443255927000424449?s=20](https://twitter.com/aaqeel87/status/1443255927000424449?s=20) [[6] HashDB project, https://hashdb.openanalysis.net/#section/Using-The-API/Hash-Format](https://hashdb.openanalysis.net/#section/Using-The-API/Hash-Format) [7] The “Silent Night” Zloader/Zbot, [https://www.malwarebytes.com/resources/files/2020/06/the-silent-night-zloader-zbot_final.pdf](https://www.malwarebytes.com/resources/files/2020/06/the-silent-night-zloader-zbot_final.pdf) [[8] The DGA of Zloader, https://bin.re/blog/the-dga-of-zloader/](https://bin.re/blog/the-dga-of-zloader/) [9] Zeus source code, https://github.com/Visgean/Zeus/blob/c55a9fa8c8564ec196604a59111708fa8415f020/source /client/dynamicconfig.cpp -----