Some time ago, Kaspersky discovered and reported a new type of malicious program called Tyupkin, which targets ATM machines by moving beyond targeting consumers with card skimmers that steal debit card numbers to directly getting cash from an ATM without the need for a counterfeit or stolen card.
At the heart of the Tyupkin exploitation of ATMs is the simple fact that it requires physical access to an ATM. The attacker would need a bootable CD to install the malware in the ATM. Because of this, physical security elements should be seriously taken into consideration.
According to Kaspersky, this malware was active on more than 50 ATMs in Eastern Europe, but from VirtualTotal submissions, we consider that this malware has spread to several other countries, including the US, India and China.
Here are the basic steps of how this malware performs its attack:
It is only active at specific times of the night on certain days of the week, between Sunday and Monday 1:00 to 5:00.
There is a hidden window running the malware in the background. When the user enters the right key in the keypad, it displays the program interface, then it generates a key based on a random seed. Of course, the algorithm responsible for this operation is known only by the authors of the malware to prevent anyone from interacting with the ATM.
When the correct key is entered, it leads to the process to take money off the net.
First and foremost, let me give you a brief overview of what’s related to banking technology.
Historically, hardware vendors have taken a proprietary approach, with products and protocols designed purely for their own machines. This has promulgated the usual problems of closed systems: loss of hardware independence, inability to have a mixed vendor implementation, high cost of change, etc.
Now, industry-wide standards are being introduced – a move which is creating an open environment and which will have wide-ranging ramifications for the self-service industry.
Most prominent amongst these standards is WOSA, which has been developed by Microsoft, and is comprised of many of the main integrators and hardware vendors. They have taken Microsoft’s Windows Open Service Architecture and added Extensions for Financial Services (the XFS part) in order to meet the special requirements of financial applications for access to services and devices.
The essence of WOSA is that allows the seamless integration of Windows applications with services and enterprise capabilities needed by users and developers. It is a family of interfaces which shield users and developers from system complexities and which offer, for instance, standard database access (ODBC) and standard access to messaging services and communication support, including SNA, RPC and Sockets. Each of the elements of WOSA includes a set of Application Program Interfaces (API) and Service Provider Interfaces (SPIs) with associated supporting software.
The WOSA XFS incorporates the definition of a further API and corresponding set of SPIs. The specification defines a standard set of interfaces such that, for example, an application that uses the API set to communication with a particular service provider can work, without need for enhancement, with another vendor’s service provider as long as that vendor is WOSA XFS compliant.
Although the WOSA XFS defines a general architecture for access to service providers from Windows based applications, the initial focus has been on providing access to peripheral devices that are unique to financial institutions, such as ATMs. Since these devices are often complex, difficult to manage, and proprietary, the development of a standardized interface to them offers financial institutions immediate gains in productivity and flexibility.
WOSA XFS changed its name to simply XFS when the standard was adopted by the international CEN/ISSS standards body. However, it is most commonly called CEN/XFS by the industry participants.
As we have seen previously, Payment Systems and Electronic Funds Transfer is a black art due to everything being proprietary. You need to work as an employee of a big vendor (like NCR, Diebold, etc.) or at a financial institution or a bank in order to understand the end to end picture. You’ll not find enough information by just looking for freely available documents and code on the Internet – just because these standards are not open at all!
Coming back to Tyupkin, this malware uses the WOSA/XFS or CEN/XFS which different hardware vendors comply with. As far as we are concerned, they get their hands on some manual references that contain detailed information on how to interact with the ATM. We have found XFS specification papers released by CEN which we will use along this analysis to understand the XFS architecture. We have seen also some leaks on Baidu search engine published by F-Secure, but we are not sure that it was the ones used by cybercriminals.
The architecture of the Extensions for Financial Services (XFS) system is shown below:
The applications communicate with service providers via the Extensions for Financial Services Manager using the API set.
The XFS Manager provides overall management of the XFS subsystem. The XFS Manager is responsible for mapping the API (WFS…) functions to SPI (WFP…) functions, and calling the appropriate vendor-specific service providers. Note that the calls are always to a local service provider.
Each XFS service for each vendor is accessed via a service-specific module called a service provider. For example, vendor A’s journal printer is accessed via vendor A’s journal printer service provider, and vendor B’s receipt printer is accessed via vendor B’s receipt printer service provider.
We are going to use these tools to perform the analysis:
DotNet Reflector / RDG Packer Detector / PEBear
This sample has been compiled with C# Dot NET language:
By looking at the imports/exports:
As you can see, MSXFS.DLL is our dll from Microsoft which contains the function calls to the API and SPI.
After the sample run, it sleeps for 10 minutes to evade anti-malware tools:
Then, it will call InitializeComponent () which is responsible for setting the right names for labels, fonts, and colors for the different objects of the Form including the main window. Afterwards, it calls SHGetFolderPath two times to get the System directory as well as the startup directory.
Persistence to reboot in the registry key:
Make a copy of itself in C:\WINDOWS\system32\ulssm.exe, I am not totally sure about this, strings are obfuscated and I could not decrypt them manually, I tried de4net but it failed.
Next, it calls prepareXFSManagerAndOpenServiceProvider. Basically, before an application is allowed to utilize any of the services managed by the XFS subsystem, it must first identify itself to the subsystem. This is accomplished using the WFSStartUp function. An application is only required to perform this function once, regardless of the number of XFS services it utilizes, so this function would typically be called during application initialization. Similarly, the complementary function, WFSCleanUp, is typically called during application shutdown. If an application exits or is shut down without issuing the WFSCleanUp function, the XFS Manager does the cleanup automatically, including the closing of any sessions with service providers the application has left open.
Once a connection between an application and the XFS Manager has successfully been negotiated via WFSStartUp, the application establishes a virtual session with a service provider by issuing a WFSOpen request. Opens are directed towards “logical services” as defined in the XFS configuration.
A service handle (hService) is assigned to the session, and is used in all the calls to the service in the lifetime of the session. Finally, when an application no longer requires the use of a particular service, it issues a WFSClose.
After successfully preparing the XFS service manager, the malware start two threads, and if it fails it just deletes the bin silently and exits.
TimeInterval thread will determine whether the current system time is Sunday or Monday, between 1:00 to 5:00 AM. If the condition is met, it will be marked as a PIN_PAD_ACTIVE_TIME. The second thread MainLoop checks for this Boolean field. If true, if the condition is satisfied, it calls waitForMasterKey, which is self-explained. Inside this function, it calls WFSExecute with WFS_CMD_PIN_GET_DATA attribute (0x198).
WFSExecute sends a service-specific command to a service provider, here is the prototype that corresponds to this API:
HRESULT WFSExecute (hService, dwCommand, lpCmdData, dwTimeOut, lppResult)
hService is the handle to the service as returned by WFSOpen, and WFS_CMD_PIN_GET_DATA is the command which is used to return keystrokes entered by the user. It will automatically set the PIN pad to echo characters on the display if there is a display. For each keystroke, an execute notification event is sent in order to allow an application to perform the appropriate display action. The third argument is interesting, it is a pointer to a command data structure to be passed to the service provider, and this data structure is defined as follows:
usMaxLen Specifies the maximum number of digits which can be returned to the application in the output parameter, which is in our case is equal to 10.
If bAutoEnd is set to true, the service provider terminates the command when the maximum number of digits is entered. Otherwise, as our case, the input is terminated by the user using one of the termination keys. When usMaxLen is reached, the service provider will disable all numeric keys.
The third and fourth parameters are not important for us. uTerminateFDKs Specifies those FDKs which must terminate the execution of the command. In our case, this value is equal to 0x400, which is the ENTER key: #define
Then, it tests whether WFSExecute returned the right value, which is 0, otherwise when there is an error, it calls again the prepareXFSManagerAndOpenServiceProvider and WFSExecute API.
Finally, it calls the function scenario (), and depending on which key sequence has been taped on the PINP AD, Tyupkin does the following:
MKEY_CLOSE_AND_ERASE_APP: the corresponding key sequence (333333)
Close and delete the program.
MKEY_HIDE_APP: the corresponding key sequence (111111)
Hide the application’s main screen.
MKEY_EXTEND_TIME: the corresponding key sequence (555555)
Modify the time period of the activation of the malware, and display time was extended, then sleep 2 seconds and return -1.
MKEY_SHOW_APP: the corresponding key sequence (22222)
Display the main screen of the application, then it calls PrintCode () which generates randomly 8 digits and wait for the equivalent session key to be entered according to some algorithm.
When the right code is entered, DISPENSE_SESSIOM_ACTIVE is equal to True.
After the user enters the cassette number and presses enter, it calls getDecimalNumberFromPINFKDigit to convert the number entered to an integer, then it verifies if it is bigger than 1 and smaller than the total number of cassettes and calls executeDispense, which in turn calls WFSExecute with WFS_CMD_CDM_DISPENSE, then calls getCashUnitInfo/getCashUnitInfo which calls WFSGetInfo (retrieves information from the specified service provider) to get information related to each cassette and how much income there is on it.
Conclusion and IOC
As far as I am concerned, we are going to see more cases related to ATM malwares, because this is where the money is. Targeting financial institutions directly is better for cybercriminals than doing skimming or running RAM scrappers or doing web injects and ATS stuff.
Ploutus malware has been shown to be before, and Tyupkin is now a concrete weakness in the ATM infrastructure. Also the fact that many ATMs run unsupported OS like Windows XP and the absence of security solutions is another problem that needs to be addressed urgently. My recommendation for the banks is to review the physical security of their ATMs and their employers (insiders?).
Indicators of compromise:
Check the ATM equipment for the following files:
C: \ Documents and Settings \ All Users \ Start Menu \ Programs \ Startup \ AptraDebug.lnk
C: \ WINDOWS \ system32 \ ulssm.exe
Check the following registry key:
HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Run \ AptraDebug