63 Problems But Malware Ain’t One: 8ca23d7bdf520c3e7ac538c1ceb7b555 (Unpacked Sample)

Hello paranoids

Recovered from my previous post? No? Great! My overall objectives for the previous post were to:

  • Show you how to unpack a malware
  • Unpacking constructions (e.g. anti-debugging, shellcode, dynamic resolution of dependencies)

On this post, i intend to:

  • Go over some network/host tracks left by the malware
  • Malware supported commands and features

The IDA database resulting from this analysis will be added to my GitHub repository here so you can check out the comments i left there. You may find that some functions changed name when compared to the pictures i provide. However, if you understand what i am saying here, the comments and function names on the database should be clear. Every URL on this article will be defanged using [] to surround one of the dots.

Characteristics

MD5: 8ca23d7bdf520c3e7ac538c1ceb7b555
Family name: DoFoil a.k.a Smoke Loader (unpacked shellcode)
Packing algorithm: custom

Analysis Environment

Tools: OllyDbg, IDA Pro
Environment: VMware with 64-bit Windows 7

Functions

If you read the previous post, you should remember how i got the functions used by this piece of malware. The malware does load new dlls or calls standard functions in any shady way. As such, this list is accurate:

atoi
CharLowerA
CloseHandle
CoCreateInstance
CoInitialize
CoUninitialize
ConvertStringSecurityDescriptorToSecurityDescriptorA
CopyFileA
CopyFileW
CreateDirectoryW
CreateEventA
CreateFileA
CreateFileMappingA
CreateFileW
CreateMutexA
CreateProcessInternalA
CreateProcessInternalW
CreateRemoteThread
CreateThread
CreateToolhelp32Snapshot
CryptAcquireContext
CryptCreateHash
CryptDestroyHash
CryptGetHashParam
CryptHashData
CryptReleaseContent
DeleteFileA
DeleteFileW
ExitProcess
ExpandEnvironmentStringsW
FreeLibrary
GetComputerNameA
GetCurrentProcessId
GetCurrentThreadId
GetFileAttributesExA
GetFileSize
GetForeGroundWindow
GetModuleFileNameA
GetModuleFileNameW
GetModuleHandleA
GetProcAddress
GetProcessHeap
GetSystemDirectory
GetTempFileNameA
GetTempFileNameW
GetTempPathA
GetTempPathW
GetTokenInformation
GetVersion
GetVolumeInformationA
LdrGetDllHandle
LdrProcessRelocationBlock
LoadLibrary
LoadLibraryW
lstrCmpW
lstrcatA
lstrcatW
lstrcmpA
lstrlenA
lstrlenW
MapViewOfFile
MultiByteToWideChar
ObtainUserAgentString
OpenFileMappingA
OpenProcess
OpenProcessToken
OpenThread
Process32First
Process32Next
ReadFile
ReadProcessMemory
RegCloseKey
RegCreateKeyA
RegEnumKeyA
RegEnumValueW
RegNotifyChangeKeyValue
RegOpenKeyA
RegOpenKeyExA
RegQueryValueExA
RegSetValueExW
ResumeThread
RtAllocateHeap
RtReallocateHeap
RtlAddVectoredExceptionHandler
RtlComputeCrc32
RtlFreeHeap
RtlGetLastWin32Error
RtlGetVersion
RtlMoveMemory
RtlRemoveVectoredExceptionHandler
RtlZeroMemory
SHGetFolderPathW
SetFileAttributes
SetFileAttributesA
SetFileTime
SetKernelObjectSecurity
ShellExecuteW
Sleep
SuspendThread
Thread32First
Thread32Next
VirtualAlloc
VirtualFree
VirtualProtect
VirtualQuery
VirtualQueryEx
WaitForSingleObjectEx
WinHTTPCloseHandle
WinHTTPConnect
WinHTTPCrackUrl
WinHTTPGetProxyForURL
WinHTTPOpen
WinHTTPOpenRequest
WinHTTPReadData
WinHTTPReceiveResponse
WinHTTPSendRequest
WinHTTPSetOption
WinHttpGetIEProxyConfigForCurrentUser
WriteFile
WriteProcessMemory
wsprintfW
wsprintfA
ZwCreateSection
ZwMapViewOfSection
ZwQueryInformationProcess
ZwQueueAPCThread
ZwUnmapViewOfSection

According to this list, we can infer the following capabilities:

  • Networking: WinHTTPConnect, WinHTTPReadData
  • File system manipulation: DeleteFileA, WriteFile
  • Registry manipulation: RegCreateKeyA, RegOpenKeyA
  • File mappings : CreateFileMappingA, MapViewOfFile
  • Processes/Thread enumeration: CreateToolhelp32Snapshot,  Process32First, Thread32First
  • Hashing and integrity computations: CryptCreateHash, RtlComputeCrc32
  • COM: CoInitialize, CoUninitialize

Some of the functions referred previously were not used by the sample i had so, an analysis based on hardcoded addresses for standard functions is not enough.

String Decoding

URLs, HTTP parameters, registry keys, file names, folder names and so on are kept encoded internally. The strings are decoded by three functions:

URLs (decoded by “url_encoder_decoder”):

  • http[:]//hsbc-auth-2[.]ru/smk/index.php
  • http[:]//wasduherwasgu[.]net/smk/index.php
  • http[:]//tanenzwut-tan[.]su/smk/index.php
  • http[:]//libersmicshliber[.]com/smk/index.php

Beacon format strings, registry related data (decoded “string_encoder_decoder_1”):

  • “%d#%s#%s#%d.%d#%d#%d#%d#%d#%d”
  • “%d#%s#%s#%d.%d#%d#%d#%d#%d#%s”
  • “http[:]//www.microsoft[.]com/”
  • “Software\Microsoft\Internet Explorer”
  • “Software”
  • “Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run”
  • “Software\Microsoft\Windows\CurrentVersion\Run”
  • “Microsoft One Drive”
  • “Software\Microsoft\Windows\CurrentVersion\Uninstall”
  • “sample”
  • “System\CurrentControlSet\Services\Disk\Enum”
  • “advapi32.dll”
  • “Location:”
  • 2015
  • “plugin_size”
  • “explorer.exe”
  • “%s%08X%08X”
  • “%08X”
  • “Work”
  • “user32”
  • “shell32”
  • “advapi32”
  • “urlmon”
  • “ole32”
  • “winhttp”
  • “HelpLink”
  • “URLInfoAbout”
  • “sbiedll”
  • “dbghelp”
  • “qemu”
  • “virtual”
  • vmware”
  • “xen”
  • “ffffcce24”
  • “svcVersion”
  • “Version”
  • “Version”

Path format string, paths, shell commands and HTTP parameters (decoded by “string_encoder_decoder_2”):

  • “%s\%s”
  • “%s%s”
  • “regsvr32 /s %s”
  • “%s\%s.lnk”
  • “%APPDATA%\Microsoft”
  • “%TEMP%”
  • “%CompSpec%”
  • “.exe”
  • “.dll”
  • “/c start %s && exit”
  • “:Zone.Identifier”
  • “GET”
  • “POST”
  • “Content-Type: application/x-www-form-urlencoded”
  • “runas”
  • String Decoding

Both “string_decoder_1” and “string_decoder_2” call “encodes_decodes_string_using_rc4” with different four bytes keys. It is a redundancy to say that the last two sets of strings are internally encoded using RC4.

Preamble and Process Hollowing

The malware starts by resolving the dependencies i have referred previously on this article and then proceeds to check the Windows version. If the operating system is Windows Vista or above, the malware leverages the Windows Integrity Mechanism. You can find lots of resources online explaining this mechanism. The Windows Integrity Mechanism is similar to SELinux Mandatory Access Control where an object of lower integrity can’t interfere with an object of higher integrity. The notion of separation between non-privileged users and privileged users (e.g. administrators) has existed in Windows versions previous to Vista (e.g. user process cannot read/write files from administrator). However, starting on Windows vista, even when you have an account with administrative privileges, you get a prompt (our beloved UAC) every time you attempt to execute a binary. This is the mechanism in action, which attributes a default medium integrity to the applications launched by authenticated users.

The malware checks the level of integrity it runs at and then sets creates an empty DACL with the SE_DACL_PROTECTED attribute enabled. This prevents any inheritance of security descriptor information from the parent process.

After the Sleep loop we have an if that checks whether the second argument for the main function is zero. If you remember from the previous post this argument is an address (250000h in my case):

main4

The reason for this check is only understood once you look at the left branch of the function. On the left branch we have:

Anti-analysis:

The method “checks_file_name_volume_loaded_modules_and_registry” (see picture below):

  • Checks whether the file name contains the word “sample”
  • Checks whether the volume serial is 0CD1A40h or 70144646h (volume serials for sandboxes)
  • Checks if sbiedll.dll (sandboxie) or dbghelp.dll (Windows DbgHelp library) have been loaded in memory
  • Queries “System\CurrentControlSet\Services\Disk\Enum\0” for the name of the primary volume and checks if the name contains: “qemu”, “virtual”, “vmware” or “xen”

If any of the above conditions is met, the malware enters an everlasting sleep.

Privilege elevation:

The malware then tries to elevate privileges (shell_execute) using a trick that involves ShellExecuteEx with a verb “runas”. The user will be prompted with the typical UAC box to authorise the elevation. This will only occur if the integrity of the process is below medium.

On “spawns_new_process_and_replaces_it_with_this”, the malware spawns explorer.exe and the malicious code from this malware is loaded into it. This technique is typically called “Process Hollowing” where a non-malicious process is spawned in suspended state and its content is overwritten with malicious code that is then executed when it is set to active. The current process then exists. I am sure you will never look at your explorer.exe process the same way.

The last point should make the right branch more clear. The right branch is executed by the newly spawned process. The picture below depicts the last chunk peace of the main function.

Analysing the right branch

Due to the complexity of this malware, i will focus on points that i consider essential and describe the overall operation of the binary. Once the process hollowing is finished, the malicious code (now executing inside explorer.exe) runs the code on the right side of the branch. The malware beacons http[:]//www.microsoft[.]com/ to check for network connectivity and if the number of bytes read is less than ten or the connection and subsequent request fail, the malware sleeps and then retries later. Once connectivity is confirmed, the malware creates a mutex named as (padded_volume_serial = volume_serial_padded_with_zeroes_to_eight_digits) with the following structure:

[MD5([computer_name]45386319[padded_volume_serial])][padded_volume_serial]

If the malware cannot create the mutex because it already exists (host already infected), the malware posts (before existing):

2015#[mutex_name]#22222#[windows_major_version].[windows_minor_version]#[service_pack_major_version]#[integrity_level]#10001#13#0

to the remote URL:

http[:]//hsbc-auth-2[.]ru/smk/index.php

integrity_level is 1 if integrity is below medium or 0 otherwise.

The malware then exits. If, on the other hand it proceeds (mutex is successfully created), it tries to achieve persistence.

Persistence Mechanism

It attempts to resolve the string “%APPDATA%\Microsoft” and then “%TEMP%” ExpandEnvironmentStringsW failed for the former. The chosen folder will host a copy of the binary with a name resembling the following structure:

[a-z]{8}.exe

The [a-z] is generated from the first 8 bytes of the mutex name and by another encoding function which maps the bytes to a limited set of characters (a-z). The malware then checks the following keys:

  • HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run
  • HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run

In order to understand this step, i am going to provide an example. Let us say the host has a software X installed which must be executed on startup. This can be done by putting the main software binary on Windows startup folder or by creating a subkey under one or both of the previous registry keys. As an example:

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run\X

This subkey would contain as one of the values the path for the binary belonging to X software (e.g. X.exe). Malware typically leverages the first and/or second keys to achieve persistence across host boots. This malware attempts to create a subkey under the first key. If this attempt was not successful, the malware attempts to create a subkey under the second key.

In order to be more stealth, it picks the name of a subkey of an already persistent application and uses it (by checking any of the Run keys). If the malware fails to get any name from the Run keys, it picks an application name from:

“HKEY_CURRENT_USER\Software\”

This would still be stealth since this key contains the name of software installed on the machine. If the malware fails to get a name from this last key it uses the name “Microsoft One Drive” (who is going to suspect Microsoft?).

If the malware fails to set any of the Run keys, it creates a .lnk file on Windows startup folder for the binary that, as previously referred will be either on “%APPDATA%\Microsoft” or “%TEMP%”. The malware then copies itself to one of these directories and spawns a thread that keeps the malware persistent (i have seen this behaviour before when analysed an Andromeda downloader). The malware then spawns a thread to beacon the server and deal with commands from the latter. As a curiosity, the file copy timestamps (MACE) are changed to the ones of “advapi32.dll”. This mechanism of timestamps tampering is called timestomping and it is used to confuse analysts which don’t expect MACE timestamps to be as old as the ones belonging to standard files such as Windows dlls.

Client-Server Interactions

The function responsible for this part is depicted below:

I am going to start with “beacons_server_and_processes_requests” which is the core function used to interact with the remote server. The function “load_dll_in_memory_and_call_export” will be described later.

beacons_server_and_processes_requests

If you remember what i referred previously, the malware beacons one URL before exiting if there is an ongoing infection. Once the malware is executing properly, it cycles across URLs using the URL generator below (“generates_beacon_url” on IDA database):

domain_generator

The malware stores the URLs encoded. The data stored on 295020h is used as an index to choose the encoded URL.”encoder_decoder” is the function used to decode urls (called “url_encoder_decoder” on IDA database). A search for the address 295020h on IDA gives us:

domain_generator_seed

The address is firstly accessed on “executed_by_spawned_process” where it is initialised. Besides “generates_beacon_domain”, only “beacons_server_and_processes_command” accesses the address (at least using the address directly). The variable stored on this address is changed and (consequently) the URLs are cycled by this last function under certain conditions (more about this later).

Then we have the function “opens_file_and_decodes_it”:

This function attempts to open the file “[a-z]{8}[a-z]{8}” which is present on either “%TEMP%\” or “%APPDATA%\Microsoft\” according to where the binary was copied to. As you can see the binary reads 15 bytes starting at a non-zero offset inside the file.  This function returns (on eax) either zero (no file) or a pointer to an hex array containing the 15 bytes read from it. This 15 bytes will be part of the beacon sent to the remote server to get a command. I assume this is a means to identify the victim. Another option would be this array as a means to authenticate the malware. However, this would represent a weak authentication since on the first interaction the malware would have no means to authenticate itself (the file does not exists).

“beacons_server_and_processes_command” is then called. This function is the biggest on the whole malware and, as such, i will not post pictures of  it. I will go through the parts that i consider important. As said on the previous paragraph, the malware request a command by beaconing the server. The structure of the beacon is the following:

2015#[mutex_name]#22222#[windows_major_version].[windows_minor_version]#[service_pack_major_version]#[integrity_level]#10001#0#[15_bytes_hex_array]

Once the command is received, we have the typical if-else construction to process the command. The server response may contain a dll which is stored on either “%TEMP%\” or “%APPDATA%\Microsoft\” with the name “[a-z]{8}[a-z]{8}” (sounds familiar?). In Dofoil terminology this is called a plugin which will be later loaded when the function “load_dll_in_memory_and_call_export” is called. This function simply maps the dll in memory, decodes it and calls one of its exported functions (called “Work”). The MACE timestamps for the new file are also tampered to be the same as the ones belonging to “advapi32.dll”.

As for the supported features, besides the typical ExitProcess (server orders the malware to terminate process) and the deletion of the malicious binary (used together in this case), as well as the plugin functionality, the malware supports four features which are related to the file type embedded on the server response (yes, there is another binary).  If the server embeds an executable, the malware will (depending on another response field) take one of the following actions:

  • Write the executable to disk and execute it using CreateProcessInternal
  • Map the binary to an allocated region of memory and call its entrypoint

If on the other hand, the embedded file is a dll, the malware will perform one of the following actions:

  • Write the dll to disk and load it using LoadLibrary
  • Write the dll to disk and register the former as a global dll using the command “regsvr32 /s”
  • Copy the dll into an allocated region of memory and call its entrypoint

Files that are written to disk are written using the following procedure:

  1. Use GetTempPathW and GetTempFileNameW to create a temporary file.
  2. Delete the created file
  3. Use the fullpath of the temporary folder, append “.exe” or “.dll” according to the embedded file and create a new file.
  4. Write the binary (.dll or .exe) to the file.

I have also noticed that the server may send some flags to the binary to be used after the process launching feature is used. One of the flags tells the malware to exit while the other tells the malware to delete the file written to disk (the downloaded binary). I assume these mechanisms are used to update the malware using an approach similar to the following:

  1. New version is downloaded to Temp folder
  2. New version is spawned by the current active malware.
  3. Active malware either exits or just deletes file on temporary folder.

Between the two options, my guess is that it is a matter of leaving traces or not. When the system boots, the old malware will not be spawned again and the new sample is executed instead.

URL Cycling

Looking at the disassembled function “beacons_server_and_processes_command”, the address 295020h (dictates the beaconed URL) is incremented when:

  • The  creation of the first beacon (used to get the command) fails on wsprintf (number of bytes written is zero).
  • If the first character on the server response is ‘<‘
  • If the value of the first dword on server’s response has a value greater than the size of the data sent on the beacon (the formatted string i have referred on 1.). Mind that when ii refer the “size of the data sent on the beacon” i mean the number of bytes outputted by the function wsprintf which is used to create the beacon. I assume this first dword tells the malware the number of bytes received by the server. If the server receives less bytes than the ones sent, this represents an erratic behaviour. The URL is changed and the routine returns.
  • If the CRC computed on the downloaded data fails. I did not refer this CRC feature but the malware seems to use the current URL string as a means to check the integrity of the response using RtlComputeCrc32.

Final thoughts

Dofoil/Smoke Loader is a nasty piece of malware. While the host related activity is relatively simple to analyse, the structure  of the requests and responses is cumbersome. This makes sense since Dofoil is not a complete malware but simply a modular vessel capable of deploying new malware, inject into processes and map malicious binaries into memory (binaries sent by the server). The nasty functionality comes from downloaded binaries and/or plugins.

I have relied heavily on static analysis and selective execution of malware sections of code. My objective was to extract strings and determine the overall behaviour of the malware (e.g. modified registry keys, created files, beacon structures). The malware had lots of runtime checks and complex constructions. As such, selective execution of code is desired to avoid waiting for breakpoints to be hit. Signing out!

Stay safe 😉

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s