Background

ATM Hacking isn’t new, there are plenty of known issues with ATMs including skimmers and (very) outdated software. When you ask someone about ATMs (especially in security) the response is often “ATMs aren’t secure!” but how do you educate people about ATMs and how do you inspire students to look into physical hardware and security? As part of the Collegiate Pentesting Competition (CPTC for short) jrwr and I were tasked with figuring out how to make the ATMs operational, and it was one of the most positive experiences I had working on a project. I am grateful for the chance to have worked with him and hope to work with him again soon! Our task was to figure out how these ATMs worked, reverse engineer them, and get them working for the CPTC competition less than two months away. In no way do we condone hacking real ATMs, and all the ATMs in this project were purchased for the competition and never connected to real payment processing networks!

A herd of ATMs roaming into their temporary habitat

Our task was to make “payment” processing possible on the ATMs using their existing hardware with as few modifications as possible. During this process we evaluated many different possible designs on how to implement the payment processor. All of this could (and has been) run off the Raspberry Pi, however in an effort to provide the greatest learning experience for competitors, we elected to implement a relay system. Our final result needed only some slight reconfiguration — dial-in number and encryption keys.

Data Flow for Processing

Only the ATMs and the Raspberry Pi made use of Dial-Up, the rest was done over a combination of UDP and HTTP traffic to simulate the payment processing system. Getting there however, was quite an adventure…

Getting Started

These 1500 Series ATMs are still in use in many places, however they have upgraded modules — either an external payment processing device (what we were simulating) or an upgraded head unit which replaces the core components and supports ethernet (using an upgraded but very similar version of the protocol)

(Localized) External Payment Processor device (ATM Dialup to Ethernet)

Knowing very little about these ATMs, except they had at least one RJ-11 connection and their operator password and encryption keys, the first task was to connect everything up. jrwr ‘s previous experience with appliances and some payment networks, we went ahead and configured the ATMs using as many 0’s or spaces (0x30 and 0x20 respectively) to attempt to track the protocol. Although dial-up protocols are straightforward in composition, they aren’t really used (or documented) day to day anymore. Working with Google, we found many older commands and protocols, some of which were useful, but many of which were not. Eventually, we were able to find enough AT commands to make it possible to dial a Raspberry Pi and communicate over the line. Making use of the PBX systems, we were able to communicate between the Raspberry Pis and ATMs without any external interfaces or phone infrastructure.

Dial-Up isn’t exactly the most complicated protocol but it is also not a protocol people generally use day to day anymore. After consulting Google, we were able to find enough AT commands to make it possible to dial out (in?) to the Raspberry Pi.

If you are curious what AT commands are supported by most modems, this is one of the most centralized guides I was able to find was from none other then USRobotics’s (USR) old user manuals!

Interacting with the modem is best done via minicom or screen when directly interfacing with it however that poses a problem since we need to also interact with it and not have screen doing anything we don’t expect. After quite a bit of searching we found a tool called interceptty, a tool almost as old as the ATMs themselves. The sole purpose of interceptty was to allow us to see what messages were being exchanged between the ATMs/Modems and our software. This tool is probably one of the most indispensable tools for dealing with serial data since we can easily replay or monitor transactions.

First step, getting the modem to answer incoming calls. This was a bit tricker because it required the modem and the ATM to automatically dial/redial. It turned out the ATM has quite a few settings available for modem configuration including redial times and a bunch of other options. Sadly all these options are behind an operator code which makes it a bit impractical

for an easy attack. However, since many of these ATMs use dial-up, it is possible to sit on the line and answer messages.

Getting the Modem To Auto Answer via screen:

+++

ATS0=2

\r



Example to run: interceptty -o /tmp/debug.log /dev/ttyACM0 /tmp/debug0 Then just use /tmp/debug0 instead of the raw device to monitor the connection.

Getting data byte by byte and the true and proven asdfasdfasjlfdasdfasdfadsfsdf for responsiveness testing

The result? Data! Sort of…

0D0A52494E470D0A0D0A52494E470D0A0D0A52494E470D0A0D0A52494E470D0A0D0A434F4E4E45435420393630300D0AFFFFFFFFFFBBD7C08477777777777777

0D0A4E4F20434152524945520D0A0D0A52494E470D0A0D0A52494E470D0A0D0A52494E470D0A0D0A52494E470D0A0D0A434F4E4E45435420393630300D0AFFFFFFFFF6EA32A1777777777777

0D0A4E4F20434152524945520D0A0D0A52494E470D0A0D0A52494E470D0A0D0A52494E470D0A0D0A52494E470D0A0D0A434F4E4E45435420393630300D0AFFFFFFFFFF25978477777777777777

0D0A4E4F20434152524945520D0A0D0A52494E470D0A0D0A52494E470D0A0D0A52494E470D0A0D0A52494E470D0A0D0A434F4E4E45435420393630300D0AFFFFFFFFFF87AB25DD777777777777

The first thing we noticed was the data essentially repeated, and that there was some non-ascii characters in the messages. However, many online decoders (xlate) won’t decode all the data. As much as we tried to figure out how to get the ATM to respond, it simply just wouldn’t budge. However, if you’re very good at picking out ASCII in the message you’ll notice repeating messages.

RING RING RING RING CONNECT 9600

<something unprintable>

NO CARRIER RING RING RING RING CONNECT 9600

Which makes it clear what is happening — we’re getting the modem in most of our dumps and unprintable data is very likely the ATM trying to connect.

Looking into that data:

FF FF FF FF 96 E0 40 77 77 77 77 77 77 77

This message kept repeating meaning it was some form of data coming in. Whether it was from the modem or the ATM we didn’t know. But many protocols (including wireless) make use of preambles which allow a computer or data processor a way to differentiate the data from the noise efficiently and without wasting too much processing time. My theory was that either the 0xFF’s or the 0x77’s were a preamble/handshake and the machine would respond back with its data if given the proper handshake.

To make more sense of this, its easier to visualize the way the signal looks:

Visualization of the data coming from the serial data of the modem

The final 0 and 1 are “real” data in this example. As you can see, with a pattern such as 0x77 or 0xFF we can easily see where the handshake or start message is. Without it, we aren’t very sure. So I tested this.

The first attempt was to send back what we were given in an attempt to see

if the ATM responded to a specific protocol message. If it is sending a specific message at least sending something wrong but in the same format should trigger it to respond (hopefully) with an error. At least that was the thought. Initial testing showed no differences in the responses.

Unable to find a solution around this, we started searching having hit a roadblock on processing. While documentation is not posted on the Hyosung website, the Tranax ATM documentation is very plentiful online, and after some searching we had a breakthrough. We discovered the provisional protocol guide, which gave us a clearer picture on how to make the ATMs speak. Once again, these ATMs are not the most modern. In fact on reseller sites they point out the fact these ATMs support up to 3DES encryption and in the high end models even support Windows XP!