If you’ve read our case study on Point-of-Sale insecurities, you’ll recall our high-level attack surface enumeration for POS systems.
In this case study, our research focus was application security flaws found within various POS software. Point-of-Sale applications are situated at a critical point within a cardholder’s data environment, as they often handle sensitive payment card data during transaction requests. However, the adaption of mitigating technologies such as Point-to-Point Encryption (P2PE) help to reduce the risks of insecure payment applications. While hardware-based P2PE solutions provide an acceptable degree of protection, software-based P2PE solutions remain dependent on the security of payment terminals. In part one of this blog series, we’ll turn our attention towards the black box of payment terminal security.
The proliferation of credit card skimming is evidence enough that many fraudsters’ target of choice is the payment terminal. Payment terminals are featureful Point-of-Interaction devices that may see thousands of unique transactions each day. They’ve become so commonplace that there’s rarely a thought of suspicion when strangers use these devices. As a result, it’s easy to forget that they introduce the same risks as any publicly accessible computer on a critical network. The limited capabilities provided by payment terminals may successfully defend against opportunistic attackers, but how well do these systems fare against dedicated attackers with the time and resources to understand how they work at an intimate level?
To answer this question, we decided to play the role of dedicated attackers. Our first step was to gain a better understanding of payment terminal market share. Online research suggests that the most popular vendors are Verifone, Ingenico, and PAX. In addition, we visited several local merchants and took note of which vendors were preferred. Our survey revealed that Verifone payment terminals were heavily favored by merchants in our area. Thus, we chose this vendor as our target.
At this point, we recognized the popularity of Verifone payment terminal, but our ability to distinguish one device from another was nonexistent. After a quick review of the device offerings on Verifone’s website, we quickly recognized which devices were prevalent in the field. Smaller shops and restaurants seemed to favor VX series PIN Pads while large chains seemed to favor MX series Multilane terminals. While these are not Verifone’s state-of-the-art offerings, they appear to be the most widely deployed models.
Device specifications disclose that MX series terminals run the Linux-based V/OS operating system and include 512 MB of memory. VX series PIN Pads include just 160MB of memory and run Verifone’s Verix operating system. I’d never heard of either of these operating systems prior to this research, but I did have familiarity with Linux. Naturally, attacking the unfamiliar Verix operating system seemed to be the most interesting choice. Although embedded Linux devices are fascinating, I imagine that few people have analyzed the inner workings of Verix from a security perspective.
The first step towards launching our research was to find a device for testing. We found that reputable online retail supply outlets offer VX series PIN Pad devices for $150-$300. This price point may be fair for a new device, but a used device would work just fine for our purposes. We were able to find several devices on Ebay ranging from $50-$100. Prices dropped even lower for bulk purchases or damaged devices at around $20 a piece. This was surprising, and honestly a bit scary, considering how there’s no way for a customer to validate the integrity of their transactions. As we had no plans to deploy the device in a live cardholder data environment, purchasing a used PIN Pad seemed like a good decision.
The PIN Pad device we purchased arrived in great condition. There was a slight worry that we’d be greeted with the infamous “***TAMPER***” error message, but after a successful boot, the following messages was displayed instead:
No *GO variable
At this point, we had no idea what a “*GO” variable was, how to trigger a download, or even what to download. It quickly became clear that we needed to learn a lot more about this device if we had any plans to get past this screen.
Searching Google for the term “verix os” instantly disclosed a couple of documents pertaining to the “Verix V Operating System”. Additional searches pertaining to Verix V OS devices led us to several high-level user manuals, low-level programmer’s manuals, and detailed device reference guides. While user manuals aren’t particularly helpful, reference guides provide very detailed device specific information. One of the user manuals suggested that to download an application, we must first press the “ENTER” and “7” keys simultaneously and enter a password. Pressing the keys as suggested divulged a new message:
TERMINAL MGR ENTRY
Please Enter Password
Press CANCEL to exit
The user manual suggested we consult our equipment vendor for a password, and we were unsure of any possible brute-force protection mechanisms. Thankfully, the reference guide informed us of the default, factory-set system password, which worked for our device.
From there, we were able to perform several administrative operations from the Verix Terminal Manager (VTM):
After navigating through each of the menu options, we determined “Download” to be most relevant to our immediate interests. The VTM Download Manager supports several download methods. However, the only one compatible with the hardware available to us at the time was the “USB Device” download method. The reference guide suggests that there are three software tools available from performing downloads:
While the first two tools were impossible to find, we found that “DDL.EXE” was included in several GitHub projects. The Verix programming tools reference manual includes a very detailed guide on how to use this utility. The following example is provided to demonstrate the basic usage of the direct download utility (DDL):
DDL test.out *go=test.out test.p7s
In this example, DDL will download “test.out” and “test.p7s” to the terminal and set the “*GO” variable to “test.out”. The “*GO” variable determines which file will execute when the terminal is reset, so it’s essentially a default application setting. The signature file, “test.p7s”, is required for VeriShield file authentication. After these files have been downloaded, the terminal will reset and attempt to authenticate the application. VeriShield file authentication works by verifying an application’s signature file against a Signer certificate that has been previously downloaded onto the terminal and authenticated by a Sponsor certificate. The Sponsor certificate is authenticated by the higher-level application partition certificate. If the signature file was generated using an authenticated signer private key, then the corresponding application will authenticate successfully and will be permitted to execute.
Provided this knowledge of the VeriShield file authentication security architecture, it became clear that we would need the following files in order to successfully install an application:
Although our Google queries failed to turn up anything of interest, GitHub came through once again. A quick search for “out p7s crt” exposed a few files pertaining to Verifone application projects. We noticed that “SponsorCert.crt” was recurrent, so we performed an explicit search for this filename in GitHub. This search uncovered a handful of open-source projects that contained everything necessary to successfully install an application.
After tweaking a few installation scripts, the application we chose was successfully downloaded, authenticated, and installed onto the device. When the device rebooted, our “DOWNLOAD NEEDED” message had been replaced with something new:
This message was promptly followed by the loading of a very colorful desktop environment. While elated by our success, we had no clue what VMAC was. Luckily, the VMAC programmer’s guide was on the first page of a Google search for “Verifone VMAC”. Verix Multi-app Conductor is an application manager that includes features such as application selection, multi-tasking capabilities, and inter-task communications. Apparently, the developers of the app we installed chose to bundle VMAC to launch their application. This worked well for us, as Verifone’s VMAC application seemed much more interesting than a nameless open-source project.
Verix was still relatively unfamiliar to us, but application security testing was within our domain of comfort. Despite our lack of source code for VMAC, the programmer’s guide provided us with detailed information about how the application works. It’s very likely that Verix applications suffer from the same issues as many other programs written in C with buffer overflows, format string vulnerabilities, and integer overflows. At first, it seemed as though this particular application had no way for a user to input data, but we came up with an idea.
Although we could not directly modify code due to VeriShield file authentication, we could freely modify application resources. According to the reference guide, file authentication is only enforced on executable files by default. While application developers may choose to enforce file authentication for other application resources, it is not the default behavior. In order to test our ability to hijack an application resource, we replaced an image used by an application with an image of our own. After downloading our new image and reloading the application, our suspicions were visibly confirmed. This led us to believe that we were free to modify any file unaccompanied by a signature file despite how it may be used by the application.
The files that seemed most beneficial to modify were VMAC’s configuration files. These files contain several file paths, strings, and integer values that would presumably be read by the application. Although we weren’t exactly sure how these values would be used, we were sure that unexpected input can be disastrous in C applications. After fuzzing several configuration arguments with lengthy string values, the device eventually halted and displayed an error log. Needless to say, we were excited to have finally identified a buffer overflow vulnerability in the application. The error log below depicts our control of the Program Counter register, allowing us to hijack the control of the program’s continued execution.
VERIX ERROR LOG
Type 2 OS QTB20111
Task 12 GID 1
In this post, we detailed our journey from target enumeration to code execution on a Verix PIN Pad device. Embedded devices often suffer from the same security flaws that were prevalent decades ago, and it seems that payment terminals are no exception. Furthermore, the programming tools reference manual states that “A program that jumps to a non-code memory area memory area may execute garbage for a while before crashing”. This indicates a stark lack of memory protections, which leaves these devices ripe for exploitation.
In the second part of this blog series, we’ll present a low-level overview of the Verix application space. We’ll also review our analysis of the Verix executable format and discuss how we may use known code addresses in memory to assist with exploitation.