Low Level Hacking NCR ATMs

    Image: Sascha Kohlmann , CC BY-SA 2.0

    There are systems for which mere mortals do not have access by default. And the developers of such systems naively believe that they are protected from penetration and the keen eyes of researchers.

    Take at least ATMs (ATM). It is not uncommon for unknown people to approach ATMs, connect a laptop, take money and leave without leaving any logs in the system. And recent stories with “ cutlets ” (malware called Cutlet Maker ) even more confirm that there are no invulnerable systems - there are under-researched ones.

    Begin research

    There is an opinion that the only way to steal money from an ATM is to arrive at a dump truck, pick up an ATM with a hook and tear it out with giblets, and then use the grinder, scrap and gas welding machine. But there is another method.

    After a brief search on Ebay , I had on my desk a NCR USB S1 Dispenser dispenser handkerchief with firmware. The goals were:

    • find a bypass of encryption of commands sent by the computer via USB to the dispenser itself, in particular for issuing banknotes
    • learn how to bypass the need for physical access to the safe for authentication (juggling the cassette) to generate command encryption keys from the previous paragraph.


    The firmware is an ELF file for the NXP ColdFire processor ( Motorola 68040 , my favorite processor), running on VxWorks v5.5.1 .

    In the ELF file of interest are two main sections - .text and .data :

    • One of them contains a code that turns all the main time (let's call it the main firmware) when the dispenser is connected to the system unit at the top of the ATM.
    • In the second, the bootloader code is packed using zlib (its local name is USB Secure Bootloader ), which is responsible for uploading the firmware and running the main code.

    And the best part is that there are uncut characters in the file - take it and look for something interesting.

    Internal device of the main firmware

    If you divide the code into the main components, you get the following scheme (in the order of submission):

    1. A stream that deals with receiving USB packages and distributing them among services.
    2. Services are the basic performing units, each of them has its own role and each has its own tasks (classes).
    3. Classes - here these are tasks that a service can perform with the help of controllers.
    4. The controllers are actually “ workers ” ( workers ) who are engaged in the validation of the tasks sent to them, their execution, and the formation of response packets.

    Since there is a lot of code in the firmware, it was decided to start by searching for all possible services, and then look where the tasks are being transferred.

    As a result, the following services were found that just have to do what I’m looking for:

    1) DispTranService (Dispenser Transaction Service) : working with encrypted commands, generating bundles of banknotes, authentication. You can say the most interesting - here.

    2) securityService : after authentication on the side of the dispenser, a session key is generated, which is sent to the computer in encrypted form upon computer request. With this key all important commands will be encrypted - issuing, forming a stack of banknotes.

    Subsequently, another service caught my eye: UsbDownloadService. Its task is to connect the dispenser to the computer and the version of the dispenser’s firmware version that is stored on the ATM computer, to go to the bootloader in order to upload the firmware the OS should work with (it is in the folder with the vendor software on the computer). This service is also able to give information about the firmware version.

    Physical authentication

    Physical authentication is implemented at the highest level and protects the ATM from simply sending USB commands to issue without authorization. In this case, it lies in the fact that only with an open safe with money you need to perform one of the following actions:

    • remove and insert the lower cassette,
    • switch the toggle switch on the back of the rack with the dispenser.

    But all this is required only if the access level is set to the maximum, that is, physical. There are three of them: USB (0), logical (1) and physical (2). The remaining two are used by service providers and developers for debugging and testing firmware. Well, the physical one is highly recommended by the vendor for use by default.


    The following describes a critical vulnerability (already fixed by the vendor at the time of publication of the article), which, if there is access to the service area, but without access to the safe (for example, through a hole made in the ATM front panel), execute any commands of the dispenser, including cash.

    As it turned out, UsbDownloadService accepts commands that do not require encryption. It sounds tempting. But then everything is protected further, and the name Secure Bootloader will justify itself?

    (Spoiler: not justify!)

    We need to go deeper

    As already mentioned, in the .data section there is a packed bootloader code, which for a long time did not arouse my interest, and my colleagues, when they examined the firmware, did not pay attention to it.

    While the presence of the bootloader was secret, the question remained open: how did the software on the computer fill up the firmware? After all, nothing was found in the main firmware.

    So, the bootloader is unpacked, loaded into IDA at offset 0x100000 - now you can explore ... Only no characters!

    It doesn't matter: comparing the main firmware with the bootloader code, reading the datasheet of the controller - and a certain picture begins to emerge.

    It turned out that the firmware upload, although it seems to be protected, is actually not. Just need to know how to fill it correctly.

    Quite a lot of effort and time was spent on a full understanding of this process (for more details, see the report “ Blackbox is dead — Long live Blackbox!"At the Black Hat 2018 conference in Las Vegas). What is the cost of soldering NVRAM's memory, uploading a backup to it in order to “sprinkle” the entire controller ... Thanks to a colleague Alexey for his patience!

    The result was the following algorithm for uploading the firmware to the dispenser:

    1) Generate a pair of RSA keys and pour the public key into the controller.

    2) Write successively the .data and .text sections from the ELF to their physical addresses from the section headers.

    3) Calculate SHA-1 from the recorded data, encrypt the hash with a private key, send to the controller.

    4) Count and send the sum of all recorded firmware words.

    After that, if everything is calculated and recorded successfully, the main firmware will be downloaded.

    It turned out that when writing firmware there is only one limitation: the firmware version should be no lower than the current one. But after all, no one bothers us to replace the firmware version in its data itself.

    As a result, my special firmware with antisecurity -fixes was flooded and successfully launched!

    At this point, the code of the main firmware was well studied, commands for issuing banknotes were found. Now they can be sent unencrypted, and the dispenser will happily execute them.


    After all that was experienced during the research (for example, a real ATM zakirpicheny ), the result was so pleasant and compensating for the efforts that the algorithm wanted to repeat with another major vendor.

    The real ATM began to whir and willingly shared with us fresh crisp notes (in this case vendor “candy wrappers”). No magic was applied: only a laptop, a brain and a USB-cord.


    Once again we were convinced that, guided by the principle of security through obscurity , it is impossible to provide adequate protection. The propriety of a code or firmware does not mean at all that an attacker will not have access to it at one point and will not take advantage of the vulnerabilities found. All necessary for the implementation of selfish goals can be acquired in the presence of a certain amount of money.

    Developers should deal with the code, and security specialists should protect it. That is why the most productive approach seems to be cooperation with information security companies with sufficient experience in ensuring the security of various systems that will help build adequate protection in each particular case.

    PS Vendor confirmed the vulnerability (the breach was also found in another model - S2), which was declared as amended in the February fix of the 2018th year.

    CVE list:


    Before me, my colleagues, Dima Sklyarov and Misha Tsvetkov , were already working on the firmware (though without a dispenser board) . Their achievements helped me a lot in the study, for which I thank them so much! On the part of "iron" Alexey Stennikov helped me a lot .

    Also popular now: