Untangling the Ripper ATM Malware
Last August , security researchers released a blog discussing a new ATM malware family called Ripper which they believe was involved in the recent ATM attacks in Thailand. Large numbers of ATMs were also temporarily shut down as a precautionary measure.
That analysis gave an overview of the techniques used by the malware, the fact that it targets three major ATM vendors, and compared Ripper to previous ATM malware families. Their analysis was based on the file with MD5 hash 15632224b7e5ca0ccb0a042daf2adc13. This file was uploaded to Virustotal by a user in Thailand on August 23.
During our analysis we noticed some additional details that where not called out, or which appear to contradict this earlier analysis. We highlight these differences in this blog post. We have also included technical indicators such as code offsets where possible for other researchers to follow on from our work.
In April of this year, Trend Micro’s Forward Looking Threat Research team and Europol EC3 collaborated on a comprehensive report on all ATM malware threats known at that point. We have been watching out for new families since then. The paper was made available to members of the Financial and Law Enforcement communities. If you are part of these industries, have not received a copy, and would like one, please contact Robert McArdle.
This analysis is based on the original malware referenced, as well as other samples that were shared by NCR (an ATM manufacturer) via a security bulletin on August 30. The primary binary analyzed was c9381c5d6f39c54aad5b57c3b1deecab6887af57 (SHA1). This was packed with UPX, and unpacked with the command: upx –d <packed_file>. The resulting unpacked binary was 5ffded28ee96493e3ad0b4c59b13484f9edc1abe (SHA1).
This malware was named Ripper because of the presence of a debug PDB string “W:\ATMRipper\Release\ATMRipper.pdb” (at file offset 0x30b80 of the unpacked binary), which indicates that the attacker’s name for the project was ATMRipper. The malware is coded in Visual C++ and the _main_ function starts at 0x4016ef (Virtual Address).
Ripper is capable of dispensing cash from the ATM in large quantities, also known as “jackpotting”. It reads data from inserted cards, both from their EMV chip and the magnetic track. This may be used as a form of authentication, identifying when an accomplice is physically located at the ATM. The malware also includes a self-destruct feature that removes all traces of itself from the infected system. This would delay the discovery and mitigation of the attack by any targeted organization.
Command Line Parameter Switches
Ripper accepts command line arguments using the format:
<malware_executable> ParentSwitch /1stSwitch /2ndSwitch
The various switches and their observed actions are as follows:
|Switch name||Parent||Switch Position||Action|
|service||Parent||Parent switch used in conjunction with 1st and 2nd switches: /autorun, /uninstall, /install, /stop, and /cleanup.|
|/autorun||service||1st||The malware is instructed to sleep for 10 minutes.|
|/uninstall||service||1st||Deletes the following autorun registry keys:
|/install||service||1st||Checks if the following target processes are running in memory (Figure 1):
If found, it renames itself to the manufacturer-specific filename. If these processes are not discovered, it’s renamed as FwLoadPm.exe, and adds the renamed binary to autorun registry keys:
|/stop||service||1st||This is effectively the “destroy everything” command.
When invoked with /stop switch, RIPPER checks if sdelete (Sysinternals tool) was dropped to the disk. It searches for the sdelete program (as sd.exe) in the <TEMP> directory. If not found, it drops the embedded sdelete program from the malware body (embedded at file offset 0x00036718 in the unpacked file). It invokes taskkill to terminate the following processes (Figure 2): aptra*, ncr*, java.exe, wrapper.exe, aiw.exe, *came*, snmp.exe, *gbr*, and ul*.exe.
It next uses sdelete to delete the following: D:\*, E:\*, F:\*, G:\*, H:\*, C:\*.log, C:\*.jrn, C:\*.brc, C:\*.xml, C:\*.zip, C:\*.bak, C:\*.err, C:\*.idx, C:\*.dat, C:\*.gsb, and C:\*.txc. RIPPER then deletes C:\* (Figure 3). It finally deletes the autorun registry keys and deletes itself after a short delay.
|/cleanup||service||2nd||Used as a second switch after /stop. When used, this switch displays the user menus, which displays the cleanup options. RIPPER performs a cleanup operation on \temp\clnup.dat, which probably contains logfiles generated by the malware.|
|install||Parent||The install option will first run the command: “taskkill /IM dbackup.exe /T /F”. It next establishes a connection to the Service Control Manager and adds \System32\dbackup.exe as a service using API CreateServiceW.|
|remove||Parent||Opens the Service Control Manager and deletes the service “DBackup Service”.|
|start||Parent||Opens the Service Control Manager and starts the service “DBackup Service”.|
|stop||Parent||Opens the Service Control Manager and closes the service “DBackup Service”.|
Figure 1. Find targeted processes for the major ATM manufacturers (Click to enlarge)
Figure 2. Taskkill existing processes and sdelete different drives and file types (Click to enlarge)
Figure 3. Sdelete all files on the C: drive (Click to enlarge)
XFS (eXtensions for Financial Services) Functions Used
RIPPER imports functions from MSXFS.dll and XFS_CONF.dll to interact with the ATM’s peripheral devices. The following table shows the functions imported and their usage:
|Function Name||Imported from DLL||Function Description||Parameters Passed|
|WFSClose||MSXFS.dll||Terminates a session between the application and the specified service.|
|WFSAsyncExecute||MSXFS.dll||Sends a service-specific command to a service provider.||WFS_CMD_PIN_GET_DATA – get user input data from PIN Pad|
|WFSFreeResult||MSXFS.dll||Notifies the XFS Manager that a memory buffer that was dynamically allocated by a service provider is to be freed.|
|WFSGetInfo||MSXFS.dll||Retrieves information from the specified service provider.|
|WFSExecute||MSXFS.dll||Sends a service-specific command to a service provider.||WFS_CMD_IDC_EJECT_CARD – eject card from ATM
WFS_CMD_CDM_DISPENSE – dispense money from ATM
WFS_CMD_IDC_READ_RAW_DATA – read raw data from bank card (magnetic stripe and EMV chip)
|WFSRegister||MSXFS.dll||Enables event monitoring for the specified service by the specified window.|
|WFSOpen||MSXFS.dll||Initiates a session between the application and the specified service.|
|WFSCancelAsyncRequest||MSXFS.dll||Cancels the specified asynchronous request being performed on the specified service before its completion.|
|WFSStartUp||MSXFS.dll||Establishes a connection between an application and the XFS Manager.|
|WFSCleanUp||MSXFS.dll||Disconnects an application from the XFS Manager.|
|WFMQueryValue||XFS_CONF.dll||Retrieves the data for the value with the specified name, within the specified open key.|
|WFMOpenKey||XFS_CONF.dll||Opens the specified key.|
|WFMEnumKey||XFS_CONF.dll||Enumerates the subkeys of the specified open key.|
|WFMCloseKey||XFS_CONF.dll||Closes the specified key.|
Three Major ATM Manufacturers Targeted
Ripper targets ATMs made by all three major vendors: Diebold, NCR, and Wincor Nixdorf. It uses the APIs imported from XFS_CONF.dll to query .DEFAULT\XFS\LOGICAL_SERVICES and find the installation specific names of the XFS services: CDM (cash dispensing module), IDC (card reader), and PIN (PIN pad). These XFS services will have different installation names on different manufacturer machines, and the correct identifier is required for the malware to operate. It adds complexity to the code, but it also allows the malware to steal from more ATM models.
The install location is specific to each vendor:
- C:\Program Files\NCR Aptra\bin\NCRPRS.exe (NCR)
- C:\Program Files\Diebold\Agilis Startup\DBackup.exe (Diebold)
- C:\Probase\cscw32\bin\FwLoadPm.exe (Wincor Nixdorf)
Ripper calls APIs WFSExecute and WFSAsyncExecute together with specific XFS parameters to read data from bank cards, dispense cash from the ATM, and read user input from the number pad.
We don’t have exact information on what data is read from the bank cards. Ripper could be reading instructions from a specially created card or could be stealing account information stored in the card. The WFS_CMD_IDC_READ_RAW_DATA command can read data from both the magnetic stripe and the EMV chip. Inserting a special card could potentially be used as an authentication mechanism, i.e. a key into the malware. The malware does compare the read data against a specific regular expression, as shown below.
Figure 4. Reading raw data from the magnetic stripe of inserted bank card
Figure 5. Parsing the read bank card data using a regex looking for Tracks 1 or 2 data
Ripper passes parameter WFS_CMD_CDM_DISPENSE to WFSExecute to dispense cash from the machine. ATMs are usually limited to dispensing up to 40 bills at a time. Multiple attempts are needed for attackers to dispense and steal all the stored cash in the ATM.
Figure 6. Print cash dispensing message
Figure 7. Uses the standard WFS_CMD_CDM_DISPENSE instruction sent via WFSExecute to dispense cash
The malware passes instruction parameter WFS_CMD_PIN_GET_DATA to WFSAsyncExecute to read user input data from the number pad. Ripper can also create and display a virtual number pad on the ATM’s screen:
Figure 8. Virtual number pad
Ripper displays two user menus for interacting with the attacker. What is highly unusual is that most of the options displayed aren’t even enabled. There are two possible reasons for this:
- The samples we analyzed were in early alpha/beta stages of development. More features have yet to be added.
- The developers decided to reduce bloat and only include the minimum features needed to dispense cash from targeted ATMs.
|“Settings Menu” Options||“Dispensing Menu” Options|
|1. Ignore cassete balance
2. CLEAN LOGS
6. UNINSTALL SERVICE
7. NETWORK: ENABLE
0. NETWORK: DISABLE
We make the following observations looking at RIPPER’s user menus:
- Many of the user menu options are already implemented via command line parameter switches.
- Ripper currently does not possess any networking functionality, nor does it import any networking APIs.
One of the interesting characteristics of RIPPER is the self-monitoring service it spawns at virtual address 0x401795:
Figure 9. Self-monitoring service (Click to enlarge)
This function calls the API WaitForSingleObject to poll hHandle. If it receives a return value of WAIT_OBJECT_0 then the state of the specified object has been signaled and the function terminates. If it receives a non-zero return value, it will go ahead with cleanup and invoke the “destroy everything” function (see Figure 3 and the write-up for /stop). The self-monitoring service can also bypass the “destroy everything” function and instead create a duplicate process of itself (via CreateProcessUserAsUserA) and start itself with the /autorun flag, effectively sleep for 10 minutes.
Our speculation is that the self-monitoring service ensures that the malware isn’t idle and is promptly removed by the attacker after completion of the cash dispensing/stealing activities. Alternately, it would delete itself and the entire operating environment to prevent the bank from discovering the malicious file.
We didn’t have access to the installer/dropper for this malware, so other components could be a part of this attack. Analysis of these would be useful for gaining a full understanding of Ripper’s operations. Currently, it is still in an early alpha/beta stage of development with basic features already in place, with other capabilities yet to be added in.
The sample we found appears to be primarily targeting Wincor Nixdorf machines, although Diebold and NCR machines are also at risk. Enabling network functionality in the future will add a new dimension to the workings of this malware family, but a variant of this threat that uses the network has yet to be found.
Here is an updated ATM malware comparison table from the one we published in our research paper, with Ripper included and a small update to GreenDispenser:
|Region/s Affected||Russia, Ukraine, other EU countrie||Mexico||Eastern Europe, South East Asia||Unknown||N/A||Mexico||Thailand|
|Manufacturer Targeted||Diebold||NCR||NCR||Diebold||Diebold, NCR (claimed)||Wincor||Diebold, NCR, Wincor|
|Installation method on ATM||Unknown||CD-ROM||CD-ROM||Unknown||N/A||Unknown||Unknown|
|Family branches to multiple variants||Yes||Yes||No||No||No||No||No|
|Programming Language||Delphi||C# compiled into .NET||C# compiled into .NET||VB||Borland C++||Visual C++||Visual C++|
|Library used to access peripherals||DbdDevAPI.dll||ncr.aptra.axfs.
|MSXFS.dll||Peripherals not accessed||MSXFS.dll||MSXFS.dll||MSXFS.dll|
|Access control implemented||Yes||Yes||Yes||Yes||No||Yes (two stage authentication)||Unconfirmed|
|User commands received via||PIN pad||Keyboard, PIN pad, SMS||PIN pad||Raw socket, files||Keyboard, Mouse||PIN pad||Keyboard, PIN pad, bank card (claimed)|
|Language Strings||Spanish||English, Spanish||English||Spanish||Russian||English||English|
|Encrypts stolen data||Yes||No||No||Yes||No||No||No|
|Time limited campaign||No||Needs activation every 24hrs||Operates only at certain times||Operates before May 21st, 2014||No||Operates Jan 1st – Aug 31st 2015||No|
|Persistent between reboots||Yes||Yes||Yes||Yes||No||No||Yes|
|Anti-Virus disabled||No||No||Yes (via other tool)||Yes||No||No||No|
|Disables ATM sensors||No||No||No||No||Yes||No||No|