Tyupkin ATM Malware: Take The Money Now Or Never!
A Sandbox is a dynamic file analysis system that allows a researcher to analyze the behavior of potentially malicious code in a virtualized environment without damaging a real host system. In some cases, a sandbox has to analyze an attack without seeing the full chain (for example when it analyzes a dropped file without the corresponding dropper component) or must work with limited information about the target environment (for example when an attack targets a particular operating system or runtime). In the worst-case scenario, these missing pieces can completely hinder the sandbox’s ability to successfully run an application.
In today’s blog post, we are going to dive deep into one such example and show how the Lastline sandbox can still classify malware despite an incomplete environment, and even how a security researcher or incident responder can still be able to elicit behavior from a malware sample. This can be done via the so-called application bundles. These bundles allow the user to extend, customize, and tailor the analysis environment to the needs of the particular attack and allow us to analyze and dissect an application requiring non-existent Windows DLLs, file path or registry values.
For today’s case study, we use a Tyupkin malware sample, a .Net application for bank automated teller machines (ATM) running on the Microsoft Windows operating system. Tyupkin’s aim is to steal cash by sending a specific command to the cash dispenser of the compromised ATM. During the analysis, our sandbox will trick the malware into believing that our analysis environment is an ATM itself. We will achieve this by submitting our sample bundled with a few specific DLLs that provide programmer’s interfaces to a Windows-based ATM, Extensions for Financial Services (XFS).
Interestingly, this malware family seems to be delivered to the ATM manually. In other words, to install the malware, the attacker requires physical access to an ATM via an exposed USB port or other input/output bus. Note that this is not usually necessary as some attackers have been known to install ATM malware as part of an internal software update processes.
As with many malware families, ATM malware actively tries to hinder incident response and evade dynamic analysis systems by using well-known, off-the-shelf code protectors and packers, such as .NET Reactor, .Net Confuser, VMProtect, and Themida. This is a common self-defense mechanism. For example, one of the previously seen ATM infectors packed with the Themida packer makes use of several anti-debug and anti-sandbox tricks (as shown below in the analysis overview of the sample SHA1: 3022e60790e17303def03761c8fa7e7393a0ad26): IsDebuggerPresent, CheckRemoteDebuggerPresent, RDTSC timing evasions, and Windows class names to name a few.
Some other families, such as ATMii, are known to perform the remote code injection hiding the malicious code in a specific ATM process.
The piece of ATM malware that is the subject of this article is known as Tyupkin (SHA1: 0c3e6c1d4873416dec94c16e97163746d580603d). The entry point has the following code:
The first sandbox evasion we see is an execution delay of 10 minutes. Considering that many automated malware analysis systems to allocate only 4-5 minutes to analyze application behaviors, it is not a surprise to see such a simple yet potentially effective evasion attempt.
Let’s now step into the Form1 class, and further, into the InitializeComponent method. The purpose of this method is to register a specific event handler Form1_Shown.
Below a fragment of “Form1_Shown” code:
It first retrieves a path to the system directory through the SHGetFolderPath function and verifies whether it already infected the underlying system. Then it hides the main window by calling ShowWindow API with SW_HIDE parameter, and adds itself to the autorun to make sure it will run after reboot:
Next, it checks whether the connection to the XFS Manager was successfully established and if not, it deletes itself by using the following command:
del /F /S /Q C:\WINDOWS\system32\ulssm.exe
If the connection is successful, the program runs two threads: the first checks the current system time which then allows the second thread to execute only on Sunday and Monday nights, and only at specific time intervals. This is done by calling a combination of _time64 and _localtime64 functions, and then parsing the time_t structure. We can see a snippet of such code in the fragment below:
The second thread contains the main functionality of the malware. Tyupkin supports several operations, or activation codes, known only by the criminals, which prevents unauthorized access (or black-box analysis approach). Given a proper activation code (entered using the ATM PIN pad) the malware can delete itself or hide/show its main window. It can also programmatically disable the network interfaces through the NcFreeNetconProperties API (netshell.dll) every time the cash is dispensed (probably to foil any attempt to communicate with the infected machine):
The malware is also able to extend the timeout interval (probably for those sleepyheads criminals who don’t want to withdraw money just during the first hours of the day, as mandated by the checks performed by the first thread), and, most importantly, to withdraw money, which is after all its main purpose. This is achieved by calling WFSExecute API when the dwCommand parameter is equal to WFS_CMD_CDM_DISPENSE (0x12E). To get the current balance of the cash units, the malware calls WFSGetInfo API with dwCategory parameter set to WFS_INF_CDM_CASH_UNIT_INFO (0x303). If successful, the following text will appear on the ATM’s screen: “Take the money now!” prompting the user to enter a cassette number and press enter:
Below is the complete workflow of the Tyupkin ATM malware:
Automatic Analysis for Detection
As we can see in the analysis above, this Tyupkin malware family requires a very specific environment to exhibit its behavior. Even if the malware successfully loads (which is not a given) entire functionalities are still not triggered if a specific library is not installed.
As we discussed in earlier blog posts, the Lastline analysis engine is able to dynamically adjust the environment to meet the attackers’ goals, to alter the system information at runtime, or detect malicious behaviors even in program sections that are not fully executed.
Another approach to detect this type of targeted attack is by using the environment sensitivity of the program against the attacker itself. The main idea is to flag a sample as suspicious whenever the analyzed code is deemed too dependent on a specific environment, for example when some ATM components are required for execution.
Manual Analysis via Lastline Application Bundles
Detecting such malware is important, but sometimes a malware analyst needs to go further and see more details of the behavior by manually adjusting the analysis environment to meet the attacker requirements. This can include invoking the executable with a specific command line, altering the registry or file-system, or loading code in the context of a particular process.
The Lastline analysis sandbox allows doing exactly this via a concept we call Lastline application bundles. These bundles, called llappbundles, allow the analyst to specify exactly how the environment is to be “prepared” and how the analysis will be performed by the sandbox (both Windows or Mac OS sandboxes are supported).
For example, sometimes an executable requires additional command line launch parameters—must be run from a particular folder or with a specific file name—or it should run a specific export function (in case of DLL), or run a file imports APIs from a DLL that is not present in the guest OS. All these issues are addressed by llappbundles. Below we can see a screenshot of a successful (i.e., complete with behaviors) execution of the Typkin malware after loading an application bundle with both sample and required libraries.
In order to create an application bundle we used the create_appbundle function:
tyupkin_appbundle = llappbundle.helper.create_appbundle(
r"ulssm.exe": open("myfiles/tyupkin.exe_", "rb"),
r"msxfs.dll": open("myfiles/msxfs.dll", "rb"),
r"xfs_supp.dll": open("myfiles/xfs_supp.dll", "rb"),
r"xfs_conf.dll": open("myfiles/xfs_conf.dll", "rb")
with open('myfiles/tyupkin.app','wb') as output_stream:
Another approach is to create an archive with all the DLLs and the main executable file—the Lastline analysis engine is smart enough to generate an application bundle from it.
In this article, we showed how a security researcher or incident response organization can analyze applications, such as ATM malware, that require non-default Windows libraries. By submitting programs as application bundles (llappbundles), it is possible to perform dynamic customization of the guest analysis environment. This easily allows incident responders to investigate evasion and persistence mechanisms as well as analyze packers and protectors that are normally used to hinder analysis. Further, it is possible to improve detection of samples targeting specific environments, a behavior commonly found in advanced persistent threats.
Latest posts by Alexander Sevtsov (see all)
- I Hash You: A Simple But Effective Trick to Evade Dynamic Analysis - April 10, 2018
- Olympic Destroyer: A new Candidate in South Korea - February 21, 2018
- Smoke Loader Campaign: When Defense Becomes a Numbers Game - February 1, 2018