Breaking Credit Card Tokenization – Part 4
This is a continuation of a series of blog posts on the topic of breaking credit card tokenization systems. I recommend reading the first three parts of the series if you have any questions about credit card tokenization terms or concepts.
Careless Transmission of Credit Cards
Remember that the main point of credit card tokenization is to keep PANs (Primary Account Numbers) out of the main application-hosting environment. Merchants accomplish this by transmitting the PAN from the customer’s browser directly to a tokenization server in a special PCI DMZ where the litany of expensive and restricted PCI controls is fully applicable. Keeping the PAN out of the hosting environment minimizes costs and restrictions on the main application’s hosting environment, which is why anyone would want to implement tokenization (ahem, cough … of course it also reduces risk, right?). However, in my experience with multiple client engagements (and admittedly even once or twice in a past life as a developer integrating e-commerce applications against payment service gateway’s tokenization APIs), subtle code flaws have allowed the PANs to accidentally get transmitted to the application server.
ASP.NET Web Forms
Almost as a routine, assessments of commerce systems written in ASP.NET Web Forms present this issue, especially if tokenization was not in its original feature set. Web Forms keeps the developer abstracted a layer or two away from the bare metal of the web (which is why Microsoft created ASP.NET MVC), and the use of “controls” to promote code reuse can result in forgotten or unexpected behavior. Requests from web control validators, partial update panels and other AJAX-ish ASP.NET controls can generate events that require round-trips to the server, like this request, for example, which I captured from an actual production commerce system (and sanitized):
POST /CreditCardPayment.aspx?c29tZXBhcnRpYWx1cGRhdGVzdHJpbmdnb2VzaGVyZS1rdWRvc3RveW91Zm9yZGVjb2Rpbmd0aGlzIQ== HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.91 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
In the above example, the developers did not realize it was happening, and the application server was not persisting the credit card numbers, but the numbers were transmitted to the application server, which technically ruins the point of tokenization. (It also exposes the application to additional attacks, as we will discuss later.) The solution is not to mix any controls that make
__doPostBack() calls on the same pages that present payment forms. In the .NET developer community, there are humorous T-shirts that sum this up quite well. Here is one example:
Card Type Prefix Fetching
Another common example of careless transmission of credit card data in web apps is the predetermination of card types on payment detail forms. For example, we observed the following request taking the
onkeypress events from a credit card text field and sending them in JSON to the server so that the card type drop down list box could be dynamically filled in:
POST /api/ccType HTTP/1.1
The first key press event generated a post similar to the above with a "
ccPrefix" of "
4" followed by "
41" then "
onkeypress generates behavior that is slightly different per browser or even browser add-ons. For example, a saved credit card number that is automatically pasted into the form by a browser’s credit card e-wallet may not even trigger the
onkeypress event at all.
Another tokenization implementation flaw that can be found during deep scrutiny is a set of
Scraping the RAM of Web Servers
It’s common knowledge that attackers breach point-of-sale (POS) systems by scraping RAM for credit card data, searching for regular expressions that match PANs and even full magnetic stripe data as a post-exploitation activity (after attackers gain an initial foothold into the systems). This is possible because of the architecture—the POS systems have to have a copy of PANs in memory for at least a brief amount of time. It’s not often remembered, but the same is true for any web server that receives a PAN as a web request—even if that request was submitted over HTTPS, encoded as
XML, etc., the server will have a plaintext copy in RAM temporarily—ripe for RAM scraping.
With a foothold into the servers hosting the commerce application, an attacker can scrape RAM to harvest credit card data that was sent to the server, whether sent erroneously or not. If the application is built in Java or .NET (or other languages with immutable strings) the persistence of these little credit card gems in memory increases considerably and would not require repeated real-time scraping. On a high-volume commerce app, if even 5-10 percent of the transactions erroneously transmitted credit card data back to the main app servers, there would be more than sufficient economic incentive for an attacker to hang out and pick up a copy of this low-hanging fruit.
Was It a DevOps Accident?
Exfiltration of PANs by a malicious member of a DevOps team is also plausible. “I saw some performance issues, so I am profiling some processes, which may generate some process dumps or debug logs on the commerce app servers.” If ever there was a possibility for a malicious insider to pull off a “salami slicing” attack, this is it. Unfortunately, penetration tests where the tester gets to pretend to be a build and release engineer are very rare.
Commerce applications that integrate with credit card tokenization systems, especially enterprise-specific systems, are not automatically immune from attacks, no matter what your PCI QSA or maybe even your payment gateway service provider says. Like anything else, the devil is in the details, so resist the binary response of, “We do tokenization, therefore, we are safe.” Mature organizations that care about managing risk will go beyond the PCI minimum required testing and bring in experts that understand these attack vectors, and carefully analyze their payment systems with a fine-tooth comb.
Stay tuned as we continue this series with some case studies of exploiting credit card tokens during penetration tests of our clients’ networks.