Zharkbot Strings
Extracting strings from this downloader
Overview
ZharkBot is a loader which boasts multiple anti-analysis and anti-sandbox features. We have observed it being dropped by Amadey, with a potential connection between the Amadey developers and the developers of ZharkBot. According to LIA...
- Amadey downloading Zharkbot: https://loaderinsight.agency/?p=task_view&f=amadey&task=0bQf8Q4C0JS9, the payload host is seen on both Zharkbot and Amadey.
- Amadey downloads Zharkbot: https://loaderinsight.agency/?p=payload_view&hash=1aa0622a744ec4d28a561bac60ec5e907476587efbadfde546d2b145be4b8109. Different host, just an observation that the same Amadey botnet was downloading ZB.
- The same tasking seen on from both ZB and Amadey: https://loaderinsight.agency/?p=task_view&f=zharkbot&task=0bUW9w8K3PM3
References
- Delivered in a rust packer oalabs
- https://x.com/0xperator/status/1750153123581083699
- https://x.com/ViriBack/status/1749184882822029564?s=20
- https://github.com/RussianPanda95/Yara-Rules/blob/main/ZharkBot/zharkbot.yar
- StackStack IDA plugin
- Zharkbot Ad on Github
Sample
1aa0622a744ec4d28a561bac60ec5e907476587efbadfde546d2b145be4b8109
UnpacMe
Analysis
Zharkbot is written in C++ and makes liberal use of in-line string encryption which makes static analysis difficult. The string encryption is interspersed with API calls which also makes pure emulation difficult so we are going to use a mix of static and dynamic analysis.
Due to the use of C++ and specifically C++ strings the decrypted string data needs to be converted into a string before it can be used. This requires calling std::string::assign
or the constructor std::string::string
for each string. We can take advantage of this to dynamically dump the decrypted strings with a breakpoint on each function. Then use a simple IDA Python script to copy the strings back into IDA for static analysis.
The first strings dump we obtained follows.
Sandbox Detection
From the strings we can see multiple usernames that are used to detect commercial sandbox offerings; Paul Jones, george, Harry Johnson, azure, USER-PC, vtc, abby, Linky, Horst, WALKER, Anna, Administrator, Anna.
There are also detections for common hypervisors like QEMU, VBOX, and emulators like BOCHS.
Installation and Persistence
We can also see that malware makes a copy of itself in the TEMP
directory with a generated folder name and the file name explert.exe
. The malware also sets up persistence via the RUNONCE registry key.
If the malware is not launched from the TEMP
directory it will simply make a copy then run the copy via a scheduled task. We re-ran the debugger with the copied binary and dumped the following new strings.
IDA Scripts
The following script can be used to populate IDA with the strings dumped from the debugger. Note that the binary in IDA need to be rebased to the same address as the binary in the debugger.
import idaapi, idc, idautils
def set_hexrays_comment(address, text):
'''
set comment in decompiled code
'''
cfunc = idaapi.decompile(address)
tl = idaapi.treeloc_t()
tl.ea = address
tl.itp = idaapi.ITP_SEMI
cfunc.set_user_cmt(tl, text)
cfunc.save_user_cmts()
def set_comment(address, text):
## Set in dissassembly
idc.set_cmt(address, text,0)
## Set in decompiled data
set_hexrays_comment(address, text)
strings = [(0xA46119, "C:\\Users\\admin\\Documents\\Outlook Files\\honey@pot.com.pst"),(0xA44905, "admin"),(0xA4630C, "Paul Jones"),(0xA44905, "admin"),(0xA46453, "george"),(0xA44905, "admin"),(0xA466C4, "Harry Johnson"),(0xA44905, "admin"),(0xA467E7, "azure"),(0xA44905, "admin"),(0xA46A87, "admin"),(0xA44785, "RELAB10"),(0xA46C6C, "USER-PC"),(0xA44905, "admin"),(0xA44905, "admin"),(0xA44905, "admin"),(0xA47466, "abby"),(0xA44905, "admin"),(0xA477C9, "Linky"),(0xA44905, "admin"),(0xA479F9, "Horst"),(0xA44905, "admin"),(0xA47C40, "WALKER"),(0xA44905, "admin"),(0xA47E51, "Anna"),(0xA44905, "admin"),(0xA482A4, "Administrator"),(0xA44905, "admin"),(0xA4847C, "Anna"),(0xA44785, "RELAB10"),(0xA44785, "RELAB10"),(0xA44785, "RELAB10"),(0xA489ED, "SystemBiosVersion"),(0xA48BF1, "HARDWARE\\DESCRIPTION\\SYSTEM"),(0xA39EA8, "INTEL - 6040000"),(0xA48C9F, "FTNT1"),(0xA48F7D, "SystemBiosVersion"),(0xA49181, "HARDWARE\\DESCRIPTION\\SYSTEM"),(0xA39EA8, "INTEL - 6040000"),(0xA4936C, "INTEL-604000"),(0xA4960C, "SystemBiosVersion"),(0xA34775, "SystemBiosVersion"),(0xA497EC, "HARDWARE\\DESCRIPTION\\SYSTEM"),(0xA34775, "HARDWARE\\DESCRIPTION\\SYSTEM"),(0xA39EA8, "INTEL - 6040000"),(0xA49865, "SMCI"),(0xA34775, "SMCI"),(0xA49A6E, "SystemBiosVersion"),(0xA34775, "SystemBiosVersion"),(0xA49C4C, "HARDWARE\\DESCRIPTION\\SYSTEM"),(0xA34775, "HARDWARE\\DESCRIPTION\\SYSTEM"),(0xA39EA8, "INTEL - 6040000"),(0xA49CC3, "QEMU"),(0xA34775, "QEMU"),(0xA49ECC, "SystemBiosVersion"),(0xA34775, "SystemBiosVersion"),(0xA4A0AC, "HARDWARE\\DESCRIPTION\\SYSTEM"),(0xA34775, "HARDWARE\\DESCRIPTION\\SYSTEM"),(0xA39EA8, "INTEL - 6040000"),(0xA4A123, "VBOX"),(0xA34775, "VBOX"),(0xA4A32C, "SystemBiosVersion"),(0xA34775, "SystemBiosVersion"),(0xA4A50C, "HARDWARE\\DESCRIPTION\\SYSTEM"),(0xA34775, "HARDWARE\\DESCRIPTION\\SYSTEM"),(0xA39EA8, "INTEL - 6040000"),(0xA4A589, "BOCHS"),(0xA34775, "BOCHS"),(0xA4A79C, "SystemBiosVersion"),(0xA34775, "SystemBiosVersion"),(0xA4A97C, "HARDWARE\\DESCRIPTION\\SYSTEM"),(0xA34775, "HARDWARE\\DESCRIPTION\\SYSTEM"),(0xA39EA8, "INTEL - 6040000"),(0xA4AA92, "AMI"),(0xA34775, "AMI"),(0xA4AC9C, "SystemBiosVersion"),(0xA34775, "SystemBiosVersion"),(0xA4AE7C, "HARDWARE\\DESCRIPTION\\SYSTEM"),(0xA34775, "HARDWARE\\DESCRIPTION\\SYSTEM"),(0xA39EA8, "INTEL - 6040000"),(0xA4AEF3, "SONI"),(0xA34775, "SONI"),(0xA4B0FC, "SystemBiosVersion"),(0xA34775, "SystemBiosVersion"),(0xA4B2DC, "Software\\Microsoft\\Windows\\CurrentVersion"),(0xA34775, "Software\\Microsoft\\Windows\\CurrentVersion"),(0xA4B4A3, "55274-640-2673064-23950"),(0xA34775, "55274-640-2673064-23950"),(0xA4B6AD, "SystemBiosVersion"),(0xA34775, "SystemBiosVersion"),(0xA4B88C, "Software\\Microsoft\\Windows\\CurrentVersion"),(0xA34775, "Software\\Microsoft\\Windows\\CurrentVersion"),(0xA4BA56, "76487-644-3177037-23510"),(0xA34775, "76487-644-3177037-23510"),(0xA4BC70, "SystemBiosVersion"),(0xA34775, "SystemBiosVersion"),(0xA4BE50, "Software\\Microsoft\\Windows\\CurrentVersion"),(0xA34775, "Software\\Microsoft\\Windows\\CurrentVersion"),(0xA4C023, "76487-337-8429955-22614"),(0xA34775, "76487-337-8429955-22614"),(0xA4C84D, "uexrjzoshxhefvpksdnoodeaygzzzmgcrsshzsringklulrobfcnkpszq"),(0xA34775, "uexrjzoshxhefvpksdnoodeaygzzzmgcrsshzsringklulrobfcnkpszq"),(0xA4CA30, "zoopoimmwwgyfchdhjubqggfxglcttjmdoptvjvvxyfgytdolchycbyhqmrootts"),(0xA34775, "zoopoimmwwgyfchdhjubqggfxglcttjmdoptvjvvxyfgytdolchycbyhqmrootts"),(0xA4CBF9, "chbxkdkitnebyugurzzt"),(0xA34775, "chbxkdkitnebyugurzzt"),(0xA367AE, "23495762359867"),(0xA36A36, "23495762359867"),(0xA36A6D, "C:\\Users\\admin\\AppData\\Local\\Temp"),(0xA36D3A, "explert.exe"),(0xA370C9, "explert.exe"),(0xA3724D, " /TR \""),(0xA373EB, "explert.exe"),(0xA375D3, "C:\\Windows\\System32\\schtasks.exe /Create /SC MINUTE /MO 1 /TN "),(0xA37AC9, "Startup"),(0xA37CE3, "SOFTWARE\\MICROSOFT\\WINDOWS\\CURRENTVERSION\\EXPLORER\\USER SHELL FOLDERS"),(0xA37F39, "explert.exe"),(0xA381BD, "explert.exe"),(0xA383B3, "SOFTWARE\\MICROSOFT\\WINDOWS\\CURRENTVERSION\\RUNONCE"),(0xA38590, "C:\\Users\\admin\\AppData\\Local\\Temp\\23495762359867\\explert.exe"),(0xA38729, "explert.exe"),(0xA38E1E, "23495762359867"),(0xA38E59, "C:\\Users\\admin\\AppData\\Local\\Temp"),(0xA390F6, "Startup"),(0xA3954A, "explert.exe"),(0xA397CD, "explert.exe"),(0xA399B1, "SOFTWARE\\MICROSOFT\\WINDOWS\\CURRENTVERSION\\RUNONCE"),(0xA3EA06, "DRIVESERIAL:VMWARE NVME_0000|PROCESSORID:1F8BFBFF00050657|MOTHERBOARDID:NONE"),(0xA44905, "admin"),(0xA44785, "RELAB10"),(0xA4CDFA, "ProductName"),(0xA34775, "ProductName"),(0xA4CFE0, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"),(0xA34775, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"),(0xA39EA8, "Windows 10 Enterprise"),(0xA4D1A9, "root:1.2.5B"),(0xA34775, "root:1.2.5B"),(0xA4D213, "0x0531353"),(0xA34775, "0x0531353"),(0xA4D299, "&bld="),(0xA34775, "&bld="),(0xA4D30D, "0x0531353"),(0xA34775, "0x0531353"),(0xA4D398, "&os="),(0xA34775, "&os="),(0xA4D40C, "0x0531353"),(0xA34775, "0x0531353"),(0xA4D498, "&mn="),(0xA34775, "&mn="),(0xA4D50C, "0x0531353"),(0xA34775, "0x0531353"),(0xA4D585, "&us="),(0xA34775, "&us="),(0xA4D5F9, "0x0531353"),(0xA34775, "0x0531353"),(0xA4D672, "?id="),(0xA34775, "?id="),(0xA4DA94, "https://solutionhub.cc:443/socket/"),(0xA361A5, "Couldnt open url!"),(0xA34775, "Couldnt open url!"),(0xA4DA94, "https://solutionhub.cc:443/socket/"),(0xA361A5, "Couldnt open url!"),(0xA34775, "Couldnt open url!"),(0xA390F6, "Startup"),(0xA39309, "SOFTWARE\\MICROSOFT\\WINDOWS\\CURRENTVERSION\\EXPLORER\\USER SHELL FOLDERS"),(0xA3954A, "explert.exe"),(0xA397CD, "explert.exe"),(0xA399B1, "SOFTWARE\\MICROSOFT\\WINDOWS\\CURRENTVERSION\\RUNONCE"),(0xA4DA94, "https://solutionhub.cc:443/socket/"),(0xA361A5, "Couldnt open url!"),(0xA34775, "Couldnt open url!"),(0xA4DA94, "https://solutionhub.cc:443/socket/"),(0xA361A5, "Couldnt open url!"),(0xA34775, "Couldnt open url!"),(0xA390F6, "Startup"),(0xA39309, "SOFTWARE\\MICROSOFT\\WINDOWS\\CURRENTVERSION\\EXPLORER\\USER SHELL FOLDERS"),(0xA3954A, "explert.exe"),(0xA397CD, "explert.exe"),(0xA399B1, "SOFTWARE\\MICROSOFT\\WINDOWS\\CURRENTVERSION\\RUNONCE"),(0xA4DA94, "https://solutionhub.cc:443/socket/"),(0xA361A5, "Couldnt open url!"),(0xA34775, "Couldnt open url!")]
for s in strings:
print(f"{hex(s[0]-5)}: {s[1]}")
try:
set_comment(s[0]-5, s[1])
except:
pass
BONUS: Rolf SSE Removal Script
Rolf dropped by the stream and noticed that the messy XMM string decryption operations depend on SSE2 being available and wrote an IDA script to set it as unavailable forcing hex-rays to remove the XMM code. The non XMM string decryption remains as there are two versions of the decryption per string, but it makes it much easier to read. In his words...
basically there's a global variable that records the SSE version, and the SSE code executes if it is 2 or greater. so I wrote a microcode plugin to patch that global variable to the value 0, there's a macro called
_M_IX86_FP
and all of the string decryption checks it to make sure SSE2 is available
The script can be found on pastebin here:ReplaceGlobalOperands.py