Low-level hacking of NCR ATMs

Tomcat

Professional
Messages
2,656
Reputation
10
Reaction score
647
Points
113
There are systems that mere mortals do not have access to by default. And the developers of such systems naively believe that they are protected from penetration and the watchful eyes of researchers.

Take, for example, automated teller machines (ATMs). There are often cases when unknown people approach an ATM, 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 underexplored ones.

Beginning of the research

There is an opinion that the only way to steal money from an ATM is to arrive in a dump truck, hook onto the ATM with a hook and rip it out, and then use an angle grinder, a crowbar and a gas welding machine. But there is another method.

After a short search on Ebay, I found the NCR USB S1 Dispenser with firmware on my desk. The goals were:
  • find a bypass for encrypting commands that the computer sends 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 (jerking the cassette) to generate encryption keys for the commands from the previous paragraph.

nkqwri4xymfedse_tdd_mfqkwc8.png


Firmware

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

zyn201rwrhyrwet6lawdgkcjmpm.png


There are two main sections of interest in an ELF file: .text and .data:
  • One of them contains a code that runs all the time (let’s call it the main firmware) when the dispenser is connected to the system unit at the top of the ATM.
  • The second contains bootloader code packaged 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 symbols left uncut in the file - take it and look for something interesting.

Internal structure of the main firmware

If you divide the code into its main components, you will get the following diagram (in order of subordination):
1. A thread that receives USB packets and distributes them among services.
2. Services are the main execution units, each of them has its own role and each has its own tasks (classes).
3. Classes - here these are tasks that can be performed by a particular service using controllers.
4. Controllers - actually “workers” (workers), who are engaged in validating tasks sent to them, executing them, and also generating response packets.

bbx9dsyvocknltgx3sr8kubghv0.png


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

As a result, I found the following services that should do exactly what I was looking for:

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

z4j948foksgqipdtpkpd4txwe2m.png


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

akwiq2yyefxr1l_3d2iepme-qdo.png


Subsequently, another service caught my eye: UsbDownloadService. Its task is to connect the dispenser to the computer and the dispenser firmware version does not match the one stored on the ATM computer, go to the bootloader in order to upload the firmware with which the OS should work (located in the folder with the vendor’s software on the computer). This service can also provide information about the firmware version.

26kcycxcpiehexunrdlmpq4gjus.png


Physical authentication

Physical authentication is implemented at the highest level and protects ATM from simply sending issuing commands via USB without authorization. In this case, it consists in the fact that only when the safe with money is open, you need to perform one of the following actions:
  • remove and insert the bottom cassette,
  • switch the toggle switch on the back wall of the dispenser stand.

wrvgjn2ondfz-ar9eqratwm8fuy.png


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

Vulnerability

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

yjypn4wot4lpkggp6xunjrgr2va.png


As it turned out, UsbDownloadService accepts commands that do not require encryption. Sounds tempting. But what if everything else is protected, and the name Secure Bootloader justifies itself? It won't justify!

We need to go deeper

As already mentioned, the .data section contains packaged 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.

rdbfztrajma7yrnq6kmrr7o5jcc.png


While the presence of a bootloader was a secret, the question remained open: how does software on a computer upload firmware? After all, nothing like this could be found in the main firmware.

tbb0uy2d1bzgxpfbf1ies02kapg.png


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

No problem: compare the main firmware with the bootloader code, read the controller datasheet - and a certain picture begins to emerge.

e-xdvvhfkqldjbfbjrqybgdwua4.png


It turned out that uploading the firmware, although it looks secure, is not so. All you need to know is how to fill it correctly.

Quite a lot of effort and time has been spent on fully understanding this process (you can learn more about this in the report “Blackbox is dead—Long live Blackbox!” at the Black Hat 2018 conference in Las Vegas). What does it cost to resolder the NVRAM memory, upload a backup to it in order to “unbrick” the entire controller... Thanks to my colleague Alexey for his patience!

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

1) Generate a pair of RSA keys and upload the public key to the controller.

6gy41hu5hu_ivzg6lazlc5qbaaw.png


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

jjyj3t71ptne_l7r4cpouwbi6iq.png


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

kr9oldlexmlcav4iyl9hnxrs844.png


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

54e8dl0gwyv3i0pxaqw-udgbmbu.png


After which, if everything is calculated and recorded successfully, the main firmware will be loaded.

It turned out that when writing firmware there is only one limitation: the firmware version must be no lower than the current one. But no one is stopping us from replacing the firmware version in its data itself.

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

By this point, the main firmware code had been well studied, and commands for issuing banknotes had been found. Now they can be sent unencrypted, and the dispenser will happily honor them.

gubkm1l2g0mdd_dfepxjy2n50sa.png


Delivery

After everything we experienced during the research (for example, a “bricked” real ATM), the result was so pleasant and compensating for the effort that I wanted to repeat the algorithm with another major vendor.

ytk1wxlqy9dotiuoqvwlvsc2g0o.png



The most real ATM began to hum strainedly and willingly shared with us fresh, crisp banknotes (in this case, vendor-made “candy wrappers”). No magic was used: just a laptop, a brain and a USB cord.

Conclusions

We have once again become convinced that, guided by the principle of security through obscurity, it is impossible to provide adequate protection. The proprietary nature of the code or firmware does not mean at all that an attacker will not one day gain access to it and take advantage of the vulnerabilities found. You can acquire everything necessary to realize selfish goals if you have a certain amount of money.

Developers should deal with the code, and security people 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 specific case.

PS The vendor confirmed the vulnerability (the flaw was also found in another model - S2), which was announced as fixed in the February 2018 fix.

CVE List:

CVE-2017-17668 (NCR S1 Dispenser) https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-17668

CVE-2018-5717 (NCR S2 Dispenser) https: //cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-5717
 
Top