DorkBot: An Investigation
Research By: Mark Lechtik
DorkBot is a known malware that dates back to 2012. It is thought to be distributed via links on social media, instant messaging applications or infected removable media. Although it is a veteran among the notorious malware families, we believe that more networks have been infected with Dorkbot than previously expected, with the most affected countries being Sri Lanka, India and Russia.
General geographic distribution of the Dorkbot infections
The malware essentially serves as a general purpose downloader and launcher of other binary components, mostly modules for conducting DDoS attacks or stealing passwords. The analysis in this case was based on the sample that was observed in multiple infections in the wild in the past month.
The DorkBot malware comes packed within a simple dropper, in which the payload is embedded as an RC4 encrypted blob. This blob can be found at the resource section of the binary, encoded with Base64.
Figure 2: Structure of the decoded resource
The dropper decodes the Base64 payload and decrypts the result, which consists of a PE loading shellcode and the raw binary of the malware. Right after decryption, control is passed to the shellcode which locates the raw binary, loads it and then passes execution to its entry point.
Figure 3: Decryption and execution of the payload embedded within the resource
The malware’s dropper can be identified by a peculiar loop which invokes a message box to an undefined handle with the value 0xFFFFA481 and the text “Will exec“.
The payload consists of the following actions taking place consecutively:
- Argument check: If a filename is passed as an argument, it will be looked up in the current directory and executed with ShellExecuteW. However, if the argument ends with “\” it will be assumed to be a directory name. In the latter case, it will be opened in a new window by spawning “explorer.exe” using ShellExecuteW, with the directory path appended to the current directory as an argument. This feature exists for the purpose of running other processes under the malware, and is leveraged to replace all shortcuts to run the malware first and then use it to spawn the actual shortcut path, thereby achieving persistence in the system.
- Self-copy: The malware creates a copy of itself in %appdata%.
- AntiVM Check: Uses SetupDiGetDeviceRegistryPropertyA to obtain a string with the device name of the hard drive, and checks whether it contains one of the following as substrings: “vbox“, “qemu“, “vmware“, “virtual hd“. In case it does, the malware infers it runs in a VM and terminates.
- Start-up process termination: Enumerates all the following registry keys in order to shut down all non-malware related start-up processes:
Figure 4: Enumeration and termination of start-up process,
according to paths from registry run keys.
- Computer ID calculation: Each infected machine gets an ID of the format “<computer_name>#<calculated_md5>“, where the 2nd parameter is the MD5 hash of a system info buffer with the following structure:
- GUID calculation: Most of the objects in the malware (events, mutexes, file-names etc.) are given a name based on a generated GUID, which is built the following way (based on the system info struct explained earlier, SID of the current process owner and a key passed to the GUID generation function as an argument):
DWORD Data1: MD5(sysinfo)[0..3] xor key
DWORD Data2|Data3: MD5(sysinfo)[4..7] xor key
DWORD Data4[0..3]: MD5(sysinfo)[8..11] xor CRC32(user_SID)
DWORD Data4[4..7]: MD5(sysinfo)[12..15] xor CRC32(user_SID)
- APC injection: Creates a suspended exe process, writes the contents of the malware’s mapped image to it, queues the main worker thread control function (described next) as an APC and resumes its main thread. Consequently, the aforementioned function starts to run in the context of the initiated svchost.exe process.
- Worker thread control function: This routine contains the major bulk of the malware’s functionality, and invokes its various features as threads. It is expected that this function will run under svchost.exe as a result of the injection described earlier, and in case this fails will run in the context of the current process. However, the latter will not happen in reality due to a bug in the code, where the handle of the initiated svchost.exe main thread is closed right after the process handle is closed. This causes the process to crash, avoiding any further malicious activity to occur.
The flow of the actions taken by the function itself is:
- PE loading actions, namely applying relocations and resolving imports for the malware’s mapped executable.
- Creation of a hidden scheduled task (with the use of the ITask COM class) which is set to start upon the current user’s logon.
- Creation of a registry runkey under HKCM\Software\Microsoft\Windows\CurrentVersion\Run. The key’s name is a GUID generated beforehand and the path is set to the file copied to %appdata%.
- Deletion of the original malware file in a separate thread (only if the malware runs from a non-removable drive, and successfully injected to svchost.exe).
If the malware is executed from removable media, it will register a designated class for it under HCKU\Software\Classes\CLSID, with the classes name being a calculated GUID with the key 0xDEADBEEF.
Figure 6: Registration of a class for the malware
File modification watchdog: A thread that constantly calculates the CRC32 of the copied malware binary in %appdata% and compares it with the original file’s CRC32. In case this changes, the copied file is deleted and rewritten it with the contents of the original one.
Figure 7: File modification watchdog code
- Shortcut replacement thread: Iterates through all mounted drives (obtained with GetLogicalDriveStringsW) and enumerates all files in order to find those with “.lnk” extension. In case such a file is found, it’s target path is modified (using the IPersistFile COM class) to execute cmd.exe with an argument consisting of:
- Path generated by the malware, containing the malware’s copy.
- The enumerated file’s path, which will be invoked through the execution of the malware itself.
Injection of process watchdog code: The malware will enumerate all running processes and will exclude 64 bit processes, the current process and ones which run an image with the names “teamviewer.exe“\”tv_w32.exe”
Figure 8: Exclusion of TeamViewer from targeted processes for injection
All other processes (as well as a malware created notepad.exe process) will get injected with the following piece of code:
Figure 9: Injected process watchdog code
where the pointers 0x11111111, 0x22222222, 0x33333333 and 0x44444444 will be replaced by the injecting function prior to writing the code, as can be seen below:
Figure 10: Replacement of invalid pointers in the process watchdog
payloads to actual function pointers.
The injected code itself will wait indefinitely on an event, which will be signaled when the original malware process is terminated. In case this happens the malware is spawned again.
Communication: All C2 domains are resident within the binary as AES256-CBC encrypted blobs, ordered in a pointer table that can be found in offset 16 of the .data section.
Figure 11: Encrypted CnC domain table
Figure 12: Decryption routine for the CnC domains
The following types of communication can be observed in the malware:
- HTTP GET request to obtain a file from one of the sample’s CnCs. The CnC is contacted through a subdomain of the format “v%d“, where the numeric value is obtained from a global variable set during run-time. If a file is returned from the server, it is being written with a random 10 character name under %appdata% and initiated with CreateProcessW.
Note: other variants of the malware may use different subdomains, e.g. “up%d“.
- A raw protocol over TCP, used to obtain new CnC addresses from which files can be downloaded. The protocol request message is a buffer that consists of 170 bytes, and has the following structure:
Figure 13: Structure of a raw protocol request to the CnC
The response consists of 517 bytes and has the following structure:
Figure 14: Response packet from the CnC
153a3104fe52062844fed64c7a033d8378f7977f – Dropper 0cf0f00b7c78d68365b4c890c76941051e244e6f – Unpacked payload
We have 9 active Anti-Bot signatures for DorkBot family: