[Editor’s Note: Here is a super useful how-to guide for penetration testing payment terminals by Miika Turkia. Given recent breach news headlines, payment terminals are getting much more security scrutiny. Bad guys are exploiting and undermining them, so we as penetration testers need skills to be able to properly evaluate the security stance of these payment devices. Miika delivers by providing step-by-step instructions for evaluating the security of payment terminals. And, furthermore, his suggestions and insights go beyond payment terminals as well, revealing some strategies and tactics we can use in all kinds of penetration testing. Well done, Miika! –Ed.]
By: Miika Turkia
There is plentitude of payment terminals out there and the design principles vary quite a bit. The ones I have run into in Finland appear to be tightly secured with no attack surface. At first glance, that is. These generally open only outbound connections and use SSL encryption to protect the traffic. Here, I explain why testing a simple, tightly secured payment terminal is not as simple as one might think.
The payment terminals we are talking about are tamper proof. They usually have Ethernet connectivity, and a serial line. The interface open to normal user is the card slot and PIN pad, and in some occasions contactless reader. The actual configuration does vary between models and vendors, but the basic idea is that the terminal initiates all the connections and doesn’t listen to anything incoming.
Don’t forget the basics
When starting a pen test against this kind of a mute payment terminal, I do the basic port and vulnerability scanning first. Even when the vendor states that there is no services listening, I have discovered production terminals with telnet open, and free login as root. This obviously means pretty much the end of the game, or actually gives me more options to play with the terminal, for example, the possibility to MITM properly validated SSL connections. We have also had etherleak on some terminals leaking interesting information. One should remember that when dealing with credit card numbers, a tiny bit of data might be enough to leak a whole card number to anyone listening.
Serial line is occasionally used by cash registers to talk to the payment terminal, mainly to instruct it the amount of the payment. Fuzzing the used protocol over the serial line is somewhat lucrative. It usually causes quite a few crashes. The trouble with pen testing production terminals is that one has no information about the internals or what actually occurs inside the payment terminal on crashes. The only thing I know is that the terminal either reboots or goes to an otherwise inoperable state. Whether the vulnerability is actually exploitable usually remains a mystery.
I have used Perl or Python to talk to the terminals over the serial link or the other interfaces. Since the protocol is usually “compressed”, it is pretty much giving the hex codes for the commands and the values in binary form. Also, a CRC check sum is calculated (you need to know, guess, or brute the initial value). Nonetheless, unknown commands, strange command combinations, and unexpected values do cause enough problems on the terminals. Be creative with your Sulley scripts.
To detect malfunctions, one should implement instrumentation. What I do is run a NOP command every other instruction that I am sending to the payment terminal. The NOP could be e.g. status query, or heartbeat, or whatever the terminal implements. This method does sometimes give you the exact input that caused the problem, but often not. You might get the crash with a delay, or the terminal might go to some sort of error state and respond to ping properly, even though you cannot do any transactions with it. This will naturally invalidate all the further testing before the terminal is reset. One should also do visual inspection on the terminal as there might be something interesting on the screen, or you can get a better idea on the instruction that caused the trouble if you spot the terminal booting before instrumentation notices it.
There are also reportedly badly implemented terminals that leak error information or even contents of the memory on the terminal’s small screen . One should probably install a camera with motion detection to grab a “screenshot” when something changes on the terminal screen.
Acting as a controller
Since payment terminals usually support control from a cash register or a slot machine, one can use the protocol to e.g. instruct the terminal to return money to the card. A simple serial protocol usually means that you can just send simple commands to the terminal such as messages to display on the screen, or how much to charge. More complex protocols e.g. (usually over Ethernet) typically require one to write a server side emulator to act as a cash register or a slot machine. The handshakes must be right, along with all the standard pings and other queries.
My approach has been to implement a multi-threaded application that performs the keep-alive functionality and answers to any standard queries automatically. My server also listens on a master socket for any incoming commands that I might want to inject into the stream. This allows me to test different states, and also with modifying the server side, I can fuzz any of the automated states of the protocol.
As you can imagine, it is quite time consuming to test these more complex protocols especially when they don’t recover well from unexpected input. Power cycling the payment terminal is often needed. Even with its limitations, this approach has allowed me to return the paid amount to the card, or even a considerably larger sum. And naturally the fuzzing has caused countless reboots and error states. With some customers, the fraud detection should catch the incorrect returns to the card, but I highly doubt that all merchants have such processes implemented.
Pretending to be the payment mediation server
If one assumes that SSL protected traffic from payment terminal to the payment mediation server is secure, once again you might be quite wrong. It is surprising how often a MITM attack succeeds as the server certificate is not validated at all, or is poorly validated. A long certificate trust chain just might fool the payment terminal. Also, the client side ciphers supported often include very poor choices, starting from NULL cipher to anonymous Diffie-Hellman. Getting to this MITM position gets you the credit card numbers from the terminal immediately with no additional effort. On some occasions, it is enough to just listen on a port that gets the payment terminals requests and log the card numbers, no need to talk back. If you are less lucky with the SSL configurations, then downgrade attacks might fit the case.
This is something where I have no experience. So far I have trusted when I was told the payment terminals were tamper proof. I know this is misplaced trust as experience has shown that one has to test everything, since the implementations often have flaws in them. At least on software side, there have been so many mistakes even in rather simple implementations. But if the engagement does not allow me to physically tamper with the device, all the bets are off.
The only interfaces a normal end user has to payment terminals is usually the PIN pad and card interface. Surprisingly often, you can find a maintenance menu when being creative with the keyboard, or resetting the terminal. When protections are missing, you might be able to reconfigure the payment terminal any way you can imagine, however, I have not seen this flaw in a few years.
The card interfaces include magnetic stripe, contact and contactless readers. Magnetic stripes are quite easy to “forge” with cheap hardware that easily writes you new magnetic stripes. Then the testing process is to write a card and swipe it. And repeat after repeat always inspecting the results manually/visually.
EMV contact interface is more interesting since it is much more complex protocol. The payment terminal actually discusses with the card instead of just reading the data out. A programmable smart card is the way to go in this area. Or you might be able to grab a development board that you can hook up to your computer and control the contact interfaces more easily. It takes quite a bit of learning to write a fuzzer on a smart card, and especially quite a bit of time.
The contactless interface can also be tested with these programmable smart cards. However, a Proxmark or Chameleon might be better suited for contactless testing than the programmable smart card. Since programming these devices is easier than re-flashing the smart card, the fuzzer implementation should be easier and faster, especially when testing.
This is an area where we are lacking the options for testing. I am not aware of any fuzzer that would be publicly available and so far, I have not had time to implement this myself. This is a real shame as I am quite confident that the contactless interface fuzzing will bring a lot of new vulnerabilities into light from the payment terminals. This is also an interface that can readily be used to attack the payment terminals on any store. The contactless interface even allows longer term attacks to be performed from afar utilizing a directional antenna.
The payment terminals I have been testing check for updates once in a while, e.g. every 5 boots. This tends to be totally insecure, allowing me to replace the firmware on payment terminals, or receive quite a bit of internal information by just eavesdropping the traffic. Even when the firmware installation validates the package properly, I have been able to force the installation of an older version of the firmware with some weaknesses in it (e.g. open telnet service). If the terminal cannot be downgraded, it might still be possible to install another customer’s newer firmware on it. (Sadly, this route has bricked the terminals for me so far, as they start to communicate to different mediation and payment servers that are not reachable from the network that I have been testing on.)
Gaining access to the internal interfaces
Obviously, I have done most of my gigs so that access to the payment terminal has been arranged. However, if you are doing it over the network, the serial line might still be reachable. Almost all the master PCs, cash registers or gas pumps I have tested so far have been easy to compromise. Unpatched Windows XP is not uncommon to be talking to the payment terminal over a serial connection or some application level protocol over an Ethernet interface. Once you compromise the machine that is instructing the payment terminal to charge customers, you do most likely gain access to these interfaces as well.
One should also remember that some of the payment terminals talk over a WiFi connection and might thus be susceptible to standard WiFi attacks or eavesdropping. Even if you cannot hack yourself into joining the WiFi you can still do fuzzing on the WiFi protocol stack of the payment terminals.
What’s missing from the picture
Proper ways to debug and see what is going on inside the payment terminals has so far been out of my reach. Even if some of the crashes caused by fuzzing would be exploitable, I do not know, and cannot even do, proper analysis being blind to the internal operations.
Good tools to test the EMV protocol along with contactless (NFC) interface are not generally available, or are extremely difficult to setup. Charlie Miller’s paper “Exploring the NFC Attack Surface” describes the NFC fuzzing part and should be a good base to start fuzzing the EMV layer. But any input and tools to help in this area are appreciated.
I hope this write-up is a good starting point with new ideas about how to improve the testing of payment terminals and provides a comprehensive list of things to check when testing payment terminals or similar embedded devices (and the tools and methods to accomplish that).
Even though a payment terminal is locked down pretty well on the surface, there is still a lot of work to be done to properly test different attack vectors. Plenty of different attacks have worked before and new methods must be developed or discovered as the holes are being plugged. Currently this means custom code for all the different environments and terminals – quite a time consuming effort.
When everything else is tight and secure, the master PC, cash register or gas pump PC are probably still an easy targets to give you more leverage and the possibility to talk legitimately to the payment terminal.