2015-11-02
Abstract
The banking trojan Shifu appears to inherit some of its features from several other well-known banking trojans. Floser Bacurio and Wayne Low decided to take a close look at one of its droppers.
Copyright © 2015 Virus Bulletin
Following takedown operations against various notorious banking trojans, including Zeus, Dridex and Gozi, a freshly brewed banking trojan, Shifu, has recently made the news; we believe it inherits some features from the earlier well-known banking trojans. We decided to dive deeper into one of its droppers (MD5: E60F72FFA76386079F2645BE2ED84E53; SHA1: 963BFC778F94FE190FDD1DD66284E9BC9DD2BED6). A number of features caught our eye when looking at its underlying code.
On our first look at the dropper, we observed that the dropper code is not heavily obfuscated, although most of the strings are encoded; it turns out that the strings can easily be decoded using a simple XOR operation.
At the entry point, we can immediately tell that Shifu attempts to exploit a local privilege escalation vulnerability. The vulnerability was assigned the CVE number CVE-2015-0003 in February 2015 and can be used to elevate the privilege of a process to system privilege on Windows 7 and above. The exploit code can easily be found on the Internet, so it is not surprising that the malware attempts to exploit this (patched) vulnerability. This means that the malware may not execute properly without sufficient privileges and also serves as a reminder that Windows users should always install the latest Windows updates.
After performing the local privilege escalation routine, we arrive at the code where the malware will extract the payloads embedded in its binary. The payloads consist of two aPLib compressed blobs for 32-bit and 64-bit platforms, which is a very common technique used by malware nowadays. The use of the aPLib compressor suggests that Shifu might have adopted some of the techniques used by malware like Zeus (aka Zbot) or Rovnix (and thus Carberp), for which the source code has been leaked.
One of the most notable things observed in the code injection routine is an attempt to obfuscate the MZPE header by overwriting random bytes in it. This action does not affect the execution of the payload since the payload code will be injected into the memory of the remote process and will be executed directly in the context of the remote process via an asynchronous thread. The purpose of overwriting bytes in the MZPE header is to defeat behavioural analysis systems and HIPS technology – with a corrupted MZPE header, the sample does not look like a legitimate binary file and could thus bypass some trivial PE signature checks.
Analysing the decompressed buffer directly might result in an incorrect AddressOfEntryPoint as Shifu’s author has intentionally obfuscated the entry point address by XORing with a widely used XOR key, 0x31337, throughout the program regardless of the dropper or payload. Shifu will first try injecting the payload code into explorer.exe. When the code injection into explorer.exe fails, to play it safe, Shifu’s author implements an additional routine which will create or spawn a random Windows process found in C:\Windows\system32, or in C:\Windows\syswow64 if it is a 64-bit platform. Under normal circumstances, most Windows executable files (for instance svchost.exe) can be executed, but will quit immediately when called by non-Windows services. In order to circumvent this behaviour, Shifu first creates a suspended Windows process and then injects an infinite sleep, Sleep(-1), routine and executes it in the memory of the suspended process. After that, the suspended process will be resumed and continue execution, but it will not quit immediately unless it is forced to exit explicitly. Once the targeted process has been determined, Shifu will carry out another code injection routine to execute the payload via CreateRemoteThread or RtlCreateUserThread (Figure 2).
There are many anti-sandbox and anti-VM detection techniques in the dropper, as is common in mal-ware nowadays. Some of these checks have been documented in a McAfee blog post [1], so Table 1 lists some of the process names, as well as their hashes (computed by checking well-known process names using the Windows API function RtlComputeCrc32) that are ‘blacklisted’ by Shifu. Shifu checks a list of active processes running on the machine, as well as the sample’s file name, against hard-coded CRC32 hashes in order to avoid the malware being analysed by a sandbox or by virtual machines that are built to perform dynamic analysis of malware samples.
Process name | CRC32 hash |
---|---|
vmwareuser.exe | 0x99DD4432 |
vmwaretray.exe | 0x1F413C1F |
vboxservice.exe | 0x64340DCE |
vboxtray.exe | 0x63C54474 |
wireshark.exe | 0x77AE10F7 |
procmon.exe | 0x5BA9B1FE |
procexp.exe | 0x3CE2BEF3 |
fortitracer.exe | 0x332FD095 |
ollydbg.exe | 0xAF2015F2 |
python.exe | 0xD2EFC6C4 |
sysanalyzer.exe | 0x4231F0AD |
sniff_hit.exe | 0xD20981E0 |
joeboxserver.exe | 0x2AAA273B |
joeboxcontrol.exe | 0x777BE06C |
Table 1. Process names that are ‘blacklisted’ by Shifu.
It also employs a check against the file names shown in Table 2.
On analysing the decompressed payload using a disassembler, it turns out that we have landed at an invalid code entry point, as mentioned in the previous section, and the disassembler will complain that the import address table is corrupted. The payload cannot be analysed in a disassembler directly without first ‘fixing’ the file. We later realized that, besides the code entry point obfuscation, Shifu’s author has also deployed some other trivial tricks to the payload to mislead analysts:
Obfuscating the import table address – the original import table address can be restored by XORing with the key 0x31337.
Obfuscating import function names (Figure 3 and Figure 4) – the function names are encoded using the static XOR key 0xFF. (In the Appendix, we provide a simple IDAPython script to fix the function names under IDA Pro.)
(Click here to view a larger version of Figure 4.)
Shifu’s author also utilized multi-threading to add complexity to the malware and make dynamic analysis more challenging. On the other hand, from a static analysis perspective, the malware’s encoding/encryption routine is insignificant and most of the strings in the binary can trivially be decoded and fixed within IDA Pro with a few lines of code (Figure 5). However, some of the strings, such as the command-and-control server name, are encrypted using RC4.
(Click here to view a larger version of Figure 5.)
Before Shifu is able to carry out its wide range of information-stealing activities, it needs to make sure its payload code will be injected into the relevant processes. When the payload is injected by the dropper, the very first thing it will do is traverse the running processes and transfer its code into any process that does not already contain it. In other words, all the active processes apart from the system processes will contain a copy of the payload code whenever the machine is infected.
Afterwards, a named pipe will be created in order to allow communication between the payloads in different processes.
Looking into Shifu’s data theft features, we could see that the malware is equipped with some of the keylogging features found in traditional keyloggers, as well as having the ability to steal numerous banking credentials from the victim. Shifu also uses the Windows API-hooking technique in order to steal other credentials. Table 3 shows a short summary of the hooked Windows APIs along with their respective purposes.
Hooked Windows API | Purpose |
---|---|
User32!GetClipboardData | Captures the ASCII and UNICODE text currently saved in the clipboard window |
User32!TranslateMessage | Captures the keyboard’s keystrokes |
User32!GetMessageA/User32!GetMessageW | The hook’s handler performs the same thing as the user32!TranslateMessage hook’s handler |
Table 3. Hooked Windows APIs and their purposes.
Under normal circumstances, these Windows API hooks should be able to capture the keystrokes on an infected machine. However, Shifu also tries to capture virtual keyboards, which are commonly used in Internet banking, by taking screenshots of the infected machine whenever the malware detects a mouse click. It is also noteworthy that the virtual keyboard screen will only be grabbed when the malware detects an opened screen with one of the following titles, all of which are used by Italian Internet banking websites:
Password
Telemaco
Scelta e Login dispositivo
TLQ Web
db Corporate Banking Web
SecureStoreCSP - enter PIN
Shifu manipulates Windows API hooks in order to intercept the certificate password when a certificate is being imported to the certificate store. All the certificate blob data and passwords found in the Crypt32!PFXImportCertStore API will be intercepted, unless the process contains the string ‘torrent’.
The imported public keys on the infected machine will also be captured. This is possible, using the Windows Crypt32!CertEnumSystemStore API, without having access to the private key.
These hooks may be useful to the attackers when the victim imports certificates using a Windows PGP client like Gpg4win; the hook handlers could intercept the private key and certificate and save it to Shifu’s specified log directory as ‘randomhexavalue_cert.pfx’. Furthermore, it could be useful if the attackers want to access the cryptocurrency wallet downloaded from the victim machine, which is encrypted using an RSA key pair.
Shifu’s author and its operators will be able to abuse the stolen certificates for nefarious purposes.
In line with the current cryptocurrency hype, Shifu also targets Bitcoin and Litecoin wallet files found on the victim’s machine. Shifu tries to steal VPN and VNC login credentials by checking the command line of running executables. If a remote desktop protocol (RDP or VNC) or VPN process is found with the configuration file name specified in the command line, Shifu attempts to save a copy of the configuration file.
It appears that this trojan steals far more information than a typical banking trojan would: from keylogging, screenshot capture, certificate capture and cryptocurrency wallet grabbing, to FTP and POP3 credentials grabbing. The malware also appears to target point-of-sale terminals for payment card data as well as some financial institutions themselves. It scans the machines if one of the following strings is found in the path of the executable file of the current process:
tellerplus
bancline
fidelity
micrsolv
bankman
vanity
episys
jack henry
cruisenet
gplusmain
silverlake
v48d0250s1
When a potential POS machine is found, the malware will send a flag, ‘ETC’, back to its C&C server. Based on the malware code, there is no immediate action after the machine has been recognized as a POS system; perhaps a memory-scrapping module will be deployed by the botnet operators to this machine at a later time.
When analysing Shifu’s Windows API-hooking mechanisms, we also discovered that the malware tries to remain hidden from the victim. The malware conceals its presence from the running processes by hijacking the Windows ntdll!ZwQuerySystemInformation API, which is called whenever a user-mode program attempts to enumerate a list of active processes using one of various process enumeration APIs. However, this is a well-known technique and is defeated by all modern security tools. Apparently, the purpose of this trick is to remain concealed from non-tech-savvy users, however what confused us is that the malware also hijacks Windows API calls used for DNS resolution, such as ws2_32!gethostbyname, ws2_32!getaddrinfo and ws2_32!GetAddrInfoExW, to redirect URLs that contain the pattern ‘secure\..*\.moz\..*’ to ‘google.com’. Essentially, this seems to dismiss the idea of the malware being stealthy, as hijacking a website is often a clear sign of infection.
When a new machine is infected, the malware will report the new victim to the command-and-control (C&C) server by connecting to a domain that is hard-coded in the code, using the path ‘/news/userlogin.php’. The following is the information on the machine that will be stored in the botnet’s control panel (also see Figure 6):
botid – username and computer name
ver – botnet version
up – uptime of the infected machine
os – operating system identifier of the infected machine
ltime – local timestamp of the infected machine
token – existence of smart card information
cn – unknown
av – name of the security solution installed
dmn – domain name of the workstation
All the data sent and received is obfuscated to prevent direct exposure by a packet sniffer program. The data is encoded and decoded using the RC4 algorithm with the key ‘a7zoSTHljZylEx4o3mJ2eqIdsEguKC15KnyQdfx4RTc5sjH’.
When information is collected on the machine, it is immediately sent back to the C&C server via the path ‘/news/userpanel.php’. A fake HTTP referrer, ‘www1.google.com’, is used throughout the C&C communications.
When there is a need to generate a random domain name via a domain generation algorithm (DGA), the malware contacts the master C&C server first to retrieve some configuration data via the path ‘/news/users.php’.
In the payload of the most recently distributed Shifu, with a compilation date of 06 Oct 2015, we have noticed a subtle update: it no longer connects to the C&C server on machines that are found to have Man-in-the-Middle (MitM) interception for HTTPS connections. It makes this check by comparing the certificate’s MD5 fingerprint with those of some well-known websites (see Figure 7):
microsoft.com
dropbox.com
twitter.com
sendspace.com
etrade.com
facebook.com
instagram.com
github.com
icloud.com
python.org
The purpose for this update is believed to be to avoid the malware’s SSL traffic being intercepted and analysed by researchers and by intrusion detection systems that typically have SSL traffic inspection capabilities.
It seems that Shifu’s author feels nostalgic about the PhishWall anti-phishing solution from SecureBrain. All third-party browser plug-ins will be disabled immediately via a single registry value, ‘Enable Browser Extensions’, located in HKCU\Software\Microsoft\Internet Explorer\Main, if PhishWall is found to be installed as an Internet Explorer plug-in. This makes sense, given that Shifu was first found to be actively spread in Japan, as SecureBrain is a Japanese security provider. Moreover, it appears that Shifu’s author is cautious with the SecureBrain solution and does not want to create obvious noise – for example by disabling all browser plug-ins – that could easily alert non-tech-savvy victims.
In addition to disabling third-party IE plug-ins, it also disables the pop-up blocker in IE through a registry key:
HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3 "1406" = 0
Last but not least, Shifu also allows the botnet operator to download and execute additional modules, hence it supports a limited set of commands. The following is a list of commands currently supported by the malware:
Webinjection to the targeted Internet banking sites is carried out through a local Apache server installed silently by Shifu. In the underlying code, we realized that the botnet operators issue mitm_mod and mitm_script commands to download a copy of the Apache web server software as well as the webinjection script and its associated configuration file, config.xml. When these files are in place on the infected machine, the malware will first modify and make sure the Apache server is properly configured by setting the server’s address to localhost (127.0.0.1) using a random port for both HTTP and HTTPS. After the server’s configuration file is set, the server’s process will be started and its status will be monitored periodically through an asynchronous thread every second to make sure it keeps running.
Webinjection through the local HTTP server won’t work without setting up a hook on the browser process. However, the hook implementation is simpler than that of traditional banking trojans. Table 4 shows a summary of the hooks on the Winsock API. Besides hooking the Winsock API, it also hijacks the SSL verification API used by the browser process so that the verification is always successful regardless of whether the presented SSL certificates are valid.
Hook Windows API | Purpose |
---|---|
ws2_32!connect ws2_32!connectEx | Redirect all the HTTP/HTTPS traffic to a local HTTP server to carry out man-in-the-middle operation |
crypt32!CertVerifyCertificateChainPolicy nss3.dll!SSL_AuthCertificateHook nspr4.dll!SSL_AuthCertificateHook | Always return success when the browser’s SSL verification process takes place |
Table 4. Hooks on the Winsock API.
It is assumed that Shifu is mainly distributed via Flash-based exploit kits. This module allows the botherder to make the botnet clean up Flash cookies found in the %APPDATA%\Macromedia folder to cover the presence of the exploited Flash files.
Like most software, the botnet also supports automatic updates. As the malware uses a trivial protection method to prevent the removal of the malware file – through an opened file handle – it must first close the file handle before being able to replace the new binary file.
The real reason why the botnet supports the self-destruction feature (which destroys both the malware and the operating system) is still a mystery to us. But based on the nature of the botnet – it copies lots of ideas and codes from different notorious malware – and the fact that it tries to evade analysis by both auto-analysis systems and manual analysis, we can safely assume that the self-destruction routine will be executed when it is found to be executing on an unwilling platform.
The self-destruction routine (see Figure 8) is pretty straightforward:
Remove all the files attached to removable drives, for instance thumb drives.
Corrupt the filesystem (e.g. NTFS/FAT) by overwriting its boot sector.
Shut down the machine.
In case the shutdown operation is not successful, it terminates itself.
In conclusion, Shifu is an enhanced or improved piece of banking malware that has borrowed a lot of techniques from its predecessors; it rectified and refined the weaknesses possibly found in other renowned competitors. The author clearly has a good understanding of how to deal with thread synchronization in multi-threaded applications – which could indicate that he/she is an experienced programmer. However, the use of some old-school techniques in Shifu can be easily spotted and blocked by many security products.
[1] Japanese Banking Trojan Shifu Combines Malware Tools. https://blogs.mcafee.com/mcafee-labs/japanese-banking-trojan-shifu-combines-malware-tools/.
[2] Shifu: ‘Masterful’ New Banking Trojan Is Attacking 14 Japanese Banks. https://securityintelligence.com/shifu-masterful-new-banking-trojan-is-attacking-14-japanese-banks/.
Table A1 shows the sample SHA1 used in the analysis.
Compilation timestamp | Dropper’s SHA1 | X86 Payload’s SHA1 |
---|---|---|
18 August 2015 | 963BFC778F94FE190FDD1DD66284E9BC9DD2BED6 | 16E4476146511F6B9D8DDF4B232D896D7EC91F50 |
06 October 2015 | B4ED692D6E8C35F3C611084E6785972CCAE8DCDC | 8FC58220FD84F3A59F20D52F4A07F07657474467 |
Table 5. Sample SHA1 used in the analysis.
shifu_fix_iat.py import idaapi import idautils # Global variables IMG_BASE = idaapi.get_imagebase() list_seg = [] for seg in idautils.Segments(): list_seg.append(seg) IMG_END = idc.SegEnd(list_seg[len(list_seg)-1]) def decrypt(ea, key): # Virtual address to IMAGE_IMPORT_DESCRIPTOR->FirstThunk va_iat = 0 # Virtual address to IMAGE_IMPORT_DESCRIPTOR->OriginalFirstThunk va_int = 0 tmp_ea = ea # Back-tracing to locate the IMAGE_IMPORT_DESCRIPTOR from import address table passed from the callback for xref in idautils.XrefsTo(ea, 0): if XrefTypeName(xref.type) == ‘Data_Offset’: va_iat = xref.frm - 0x10 if va_iat != 0: print “Import Name Table->%08x” % (idaapi.get_long(va_iat) + IMG_BASE) va_int = idaapi.get_long(va_iat) + IMG_BASE else: return if va_int != 0: va_itd = idaapi.get_long(va_int) # Enumerate array of IMAGE_THUNK_DATA while va_itd != 0: va_itd = va_itd + IMG_BASE if va_itd > IMG_BASE and va_itd <= IMG_END: print «Image thunk data->%08x» % va_itd va_ibn = va_itd + 2 ch = idaapi.get_byte(va_ibn) str = ‘’ while ch != 0 and ch != 255: str += chr(ch ^ key) va_ibn += 1 ch = idaapi.get_byte(va_ibn) # Save the decoded import name print «IMAGE_IMPORT_BY_NAME->Name (%08x): %s» % (va_itd+2, str) idc.MakeName(tmp_ea, str) tmp_ea += 4 # Next IMAGE_THUNK_DATA va_int += 4 va_itd = idaapi.get_long(va_int) else: return def imp_cb(ea, name, ord): if not name: print «%08x: ord#%d» % (ea, ord) else: print «%08x: %s (ord#%d)» % (ea, name, ord) # The decrypt function will be responsible to enumerate IMPORT_DESCRIPTOR_TABLE to decode all the function name decrypt(ea, 0xFF) # We only want to callback once for every imported DLL return False # Main nimps = idaapi.get_import_module_qty() for i in xrange(0, nimps): name = idaapi.get_import_module_name(i) if not name: print «Failed to get import module name for #%d» % i continue print «Walking-> %s» % name idaapi.enum_import_names(i, imp_cb) print «All done...»