Tuesday, February 21, 2012

Deconstructing a Credit Card's Data

By Brad Antoniewicz.

Modern credit cards in the United States have three interfaces:

  1. Physical
  2. MagStripe Data
  3. RFID/NFC Data

This obviously varies from bank to bank and card manufacturer to card manufacturer. The purpose of this post is to evaluate all three interfaces of the card and see how they differ. Note that some data has been changed to protect the card holder's (my) information.

Physical Attributes

This interface is probably the most widely known and understood because its been around the longest and its the easiest to inspect. It's sort of good to understand the components of this interface because they're present in to the other interfaces (but a little different).

From a physical perspective, your card should have four main attributes:
  1. Name
  2. Expiration Date
  3. Credit Card Number
  4. Card Verification Value

Names and Expiration dates are pretty straightforward and don't need much explaining.

Credit Card Number - Also known as "Primary Account Number" (PAN). The one thing to point out is that credit card numbers have some unique properties. For instance, the first number of the card number will vary depending on the type of card.

CardStarting Number

A great article about credit card numbers is "Anatomy of Credit Card Numbers".

Another notable thing about the card number is it is actually created using a particular algorithm and thus there is a check, called the Luhn 10 check that verifies that the card number was generated in accordance with this algorithm. More info can be found here - http://www.visacemea.com/ac/ais/uploads/ais_guide_stepspcicompliant.pdf [PDF]

Card Verification Value (CVV2) - Note the version number. This is a three (MasterCard, Visa, Discover) or four (American Express, called the "CID") code printed on the card to help prevent against fraud. The idea behind it, is it proves possession of the card and is required when the card is not present. On American Express cards, this value is printed on the front, while MasterCard, Visa, and Discover cards have it printed on the back, usually in the signature box.

MagStripe Data

The magnetic stripe on the back of the card is broken up horizontally into three "tracks", the tracks often contain duplicate data and most times track 3 doesn't really contain any data.

ISO/IEC 7813 Defines the attributes of this data, and these sites describe the data available on each track in detail:
To read the data, you'll need a magstripe reader that will support reading all three tracks. Most magstripe readers emulate a HID (human input device), so its surprisingly easy to read from them - just open a text capturing program and swipe a card.

The reader I'm using is the MagTek SureSwipe 21040145.

So lets see what data we'll get from the magstripe:

Lets break down this data:

Track 1 Data
Track Data Value
% Start
B Format Code (B=Bank)
5XXXXXXXXXXXXXX2 Primary Account Number (PAN)
^ Separator
/ Name Separator
BRAD First Name
^ Separator
11 Expiration Year
03 Expiration Month
101 Service Code
000000001000000003000000 Discretionary Data
? End
Track 2 Data
; Start Track 2 Data
5XXXXXXXXXXXXXX2 Primary Account Number (PAN)
= Separator
11 Expiration Year
03 Expiration Month
101 Service Code
000000300001 Discretionary Data
? End

So you can see that Track 2 actually contains much data already present in track 1. You'll also notice that there is a difference in the discretionary data between track 1 and 2.

But where the heck is that Track 3 data? Well.. it doesn't appear that any data is written to it, or at least my reader isn't picking it up.

RFID Interface (EMV Chip)

In the last couple of years, the RFID Interface has been most talked about. Something about the idea of an attacker reading your credit card out of your pocket, seems to bother people :)

The RFID Interface specifications were designed by a group of representatives from Europay, MasterCard, and Visa (EMV) and is thus often referenced as the "EMV Chip" or just "EMV". The three things that differentiate this interface from the others are:
  1. Card Holder Name - On most cards the cardholder name is not stored within the chip, instead its replaced by something like "VALUED CUSTOMER" or "NOT SUPPLIED"
  2. Service Code - The service code that permits where the card is used (and for what) changes on the contactless interface.
  3. iCVV or Dynamic CVV - Rather then using the same CVV that is stored on the MagStripe, the smartcard capabilities allows for extended functionality, and so the designers created something called a Dynamic CVV. This CVV changes which each read of the card.
The RFID Interface is defined mostly in ISO/IEC 7816 and the EMV Specifications.

VivoPay 4500

Probably the easiest way to read the RFID interface of a credit card is to buy an equipped point of sale (POS) reader and connect it up to your computer. The VivoPay 4500 will handle all of the RFID communication and output the data on the RFID interface in plaintext over it's serial connection.

Prolific PL-2303

The Prolific PL-2303 is a USB to Serial adapter which helps when connecting to the VivoPay's Serial output. If you want to make this all work on Mac OS X 10.7.3 (like i am) you have to do a little bit of work:

First download the 64-bit open source PL2303 driver:

Then decompress and install:
 unzip osx-pl2303.kext.zip  
 sudo cp -R osx-pl2303.kext /System/Library/Extensions/  
 cd /System/Library/Extensions/  
 sudo kextload osx-pl2303.kext  

Insert your USB adapter then check to make sure the driver created a device interface (your interface might be named differently):
 system:Extensions user$ ls /dev/tty.PL*  


pwnpass.py is a python script created by Eric Johnson (and others) which allows you to interact with VivoPay Devices. To use it, you may have to first install py-serial to get it running. I'm using mac ports to manage all of the python packages.
 sudo port install python26 py26-serial

Next edit line 103 of pwnpass.py so that your device is appropriately defined. The default timeout for the open source driver is 1 second, I've changed it to 0.3 which seems to work better.
return serial.Serial('/dev/tty.PL2303-000011FD', 19200, timeout=0.3)

So if we run it on the same card we used before, we see the following raw data:

OmniKey CardMan 5321 Config

If you want to be a little more conventional, you can use a standard, off the shelf RFID reader, like the OmniKey CardMan 5321.

BackTrack Setup

In BackTrack 5, you'll have to manually install the drivers to make it all work. I explained the process here but the post needs a little updating:

  1. As of today, you can download the HID driver from http://www.hidglobal.com/drivers/omnikey/ifdokrfid_lnx_i686-2.9.1.tar.gz. If they ever update it again, you'll have to go here and select the appropriate drop downs.
  2. It looks like the script in the post got a little messed up by the code formatter i used. I made it directly downloadable from http://www.opensecurityresearch.com/files/cardman_fix.sh

Mac OSX 10.7.3 Setup

Making it all work on Mac OS X 10.7.3 can be a bit of a pain to figure out, but I should have most of the difficulties worked out here. First off, you'll need to install Python 2.6, and the Crypto modules.
 sudo port install python26 py26-crypto  
Next select and download the Mac OSX drivers from HID. Initially, the driver version that was available to download was ifdokrfid_mac_10.6_i386-, which didn't work with 10.7.3. I had to modify the installer so that it worked for 10.7:
 vi ifdokrfid_mac_10.6_i386-   
and change line 31 from this:
 if [ ${MACOS_VER_MAJOR} -ne 10 -o ${MACOS_VER_MINOR} -ne 6 ]; then   
to this:
 if [ ${MACOS_VER_MAJOR} -ne 10 -o ${MACOS_VER_MINOR} -ne 7 ]; then  
then everything should install fine.

As it turns out, HID has since released a newer version of the driver that "just works" (ifdokrfid_mac_universal- I did notice some problems with connecting the reader before running pcscd, so keep that in mind.

You can just launch pcscd from the command line:
 sudo pcscd  
If something isn't working, you can enable debugging and tell it to run in the foreground with:
 sudo pcscd -f -d
With the driver installed, pcscd running, and the reader connected, you can use RFIDiot to check if the reader was properly detected:
 RFIDIOt-1.0a user$ python2.6 cardselect.py -L  
 PCSC devices:  
 No: 0 OMNIKEY CardMan 5x21 00 00  
 No: 1 OMNIKEY CardMan 5x21 00 01  

TouchaTag (ACR122U) Reader Config

The Touchatag reader is another commercial off the shelf reader like the Omnikey Cardman 5321. It's popular because of its libNFC support, however with the tasks we're doing using RFIDiot, it doesn't really matter. I'm providing configuration information here for diversity. Once you connect the reader to your system, you'll likely notice its light seems to blink rather then staying lit. To fix this, it will require a quick little driver configuration change:
 sudo vi /usr/libexec/SmartCardServices/drivers/ifd-acsccid.bundle/Contents/Info.plist  
On line 53 (under ifdDriverOptions) change
to this:
Then to make sure its working properly:
 ~ user$ nfc-list   
 nfc-list use libnfc 1.4.0 (r833)  
 Connected to NFC device: ACS ACR38U-CCID 00 00 / ACR122U102 - PN532 v1.4 (0x07)  
Once that's all set up, just start pcscd if its not already running:
 sudo pcscd  
and then check RFIDiot's cardselect.py:
 RFIDIOt-1.0a user$ python2.6 cardselect.py -L  
 PCSC devices:  
   No: 0          ACS ACR38U-CCID 00 00  

Using RFIDiot to Read Card Data

In most situations, RFIDiot's ChAP.py should be able to query the card's data. On an RFID level, the card is first queried with a generic "tell me your file structure" method, and if the card doesn't respond, the reader sends requests for specific application ID's (AIDs) that are known structures for different vendors (Mastercard, Visa, etc...). In the rare case that ChAP.py doesn't work well, you may have to define your own specific AID in ChAP.py or write your own parser like I did for the Chase Visa PayPass cards.

By default ChAP.py will attempt to parse the data from the card and translate it so we can make sense out of each byte. Instead, I'll tell ChAP.py not do that and just display the raw data (-r).
 RFIDIOt-1.0a user$ python2.6 ChAP.py -r  
 insert a card within 10s  
  Found AID: MASTERCARD - a0 00 00 00 04 10 10  
 6f 17 84 07 a0 00 00 00 04 10 10 a5 0c 50 0a 4d 61 73 74 65 72 43 61 72 64  
  Processing Options: 77 0a 82 02 00 00 94 04 08 01 01 00  
   SFI 01: starting record 01, ending record 01; 00 offline data authentication records  
    record 01: 70 81 90 9f 6c 02 00 01 9f 62 06 00 00 00 00 01 c0 9f 63 06 00 00 00 00 00 3c 56 3e 42 35 34 36 35 30 33 32 30 36 38 39 39 38 30 31 32 5e 53 55 50 50 4c 49 45 44 2f 4e 4f 54 5e 31 31 30 33 35 30 32 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 9f 64 01 03 9f 65 02 00 e0 9f 66 02 00 1e 9f 6b 13 5X XX XX XX XX XX X2 d1 10 35 02 00 00 00 00 00 00 0f 9f 67 01 03 9f 68 0e 00 00 00 00 00 00 00 00 5e 03 42 03 1f 03  
 p...l....b........c......<V>B5XXXXXXXXXXXXXX2^SUPPLIED/NOT^1103502000000001000000000000000.d...e....f....k.Te. h.....5.........g...h.........^.B...  
An important thing to note here is the ChAP.py isn't pulling the track two data by default.

RFID vs MagStripe

Lets look at the differences between the raw data obtained from the RFID interface with the VivoPay and that from the MagStripe. Here's the VivoPay data:

The following table breaks out the raw data from the magstripe and RFID interface to make it a little easier when comparing the two.

Track 1 Data
MagStripeRFID Value
% %Start
B BFormat Code (B=Bank)
^ ^Separator
/ /Name Separator
BRADNOT First Name
^ ^Separator
11 11 Expiration Year
03 03Expiration Month
101 502 Service Code
000000001000000003000000 000000001000000637291901 Discretionary Data
? ? End
Track 2 Data
; ;Start Track 2 Data
= =Separator
11 11Expiration Year
03 03Expiration Month
101 502 Service Code
000000300001 0000072029191 Discretionary Data
? ? End
N/A I Trailing Data (Unknown)

Service Code - One interesting thing to note is the Service code differs. According to ISO/IEC 7813:2006(E), page 6, the service codes break down to:

  • 101 - Can be used internationally with normal authorization, for any goods, with no PIN requirements
  • 502 - Can be used nationally with normal authorization, for goods and services with no PIN requirements

So there are clearly some restrictions for where and how you can use the card.

You'll notice that the discretionary data on both track 1 and track 2 differ from that of the magstripe. Although the contents of the data stored within the discretionary data field are particular to the card manufacturer, we know that in here is where the CVV is stored. On the magstripe, CVV1 is used, while the RFID interface uses iCVV or Dynamic CVV.

Look what happens if we query the RFID interface a couple more times:
You'll notice that the discretionary data changes on both tracks. That's the "dynamic" part of dynamic CVV.

Kristen Paget just gave a talk a Shmoocon and said that "check digits" (I believe the dynamic CVV is the only check that this applies to) can only be used once and if it is used a second time, the card is immediately frozen and the RFID chip can no longer be used.

Overall, there isn't much explanation of exactly how the iCVV or the dynamic CVV is actually generated, so if feel free to use the comments below to let me know what you know!

Here are some more useful links about the different CVVs and how they're generated:


  1. So, if the dynamic CVV is in fact used by the card issuers to validate the presence of a card when used for NFC payment, the risks of someone using data collected by terminal data interception, or pocket surfing is minimal. Would this be a correct assumption?

  2. You stated that, in the RFID data the service code was:

    502 - Can be used nationally with normal authorization, for goods and services and requires a PIN

    I'm looking at the chart you posted:
    and I find myself confused. It would appear that a "2" in position 3 corresponds to:
    Goods and Services only, with no PIN requirement listed (a dash). Am I misreading the chart, or was this a typo?

  3. Thanks Anonymous! Corrected!

    RykE - overall i'd say the risks associated with pocket surfing are somewhat minimal. There are a lot of backend processes that reduce exactly how much money someone can charge to your card. For clarification, it's worth to point out that if you never use the RFID interface, then the dynamic CVV doesnt increment, and you cannot invalidate the CVV that was sniffed from you. That gives the attacker one transaction. However, as Kristen Paget pointed out, an attacker could just perform multiple reads to increase the number of transactions they can make.

  4. Just a minor correction but its not Eric Johnson, pwnpass.py was written by: 3ric Johanson

  5. Hi, OSR. I really like this article, however I have a little something about the track 3 data.
    According to ISO/IEC 4909 "Identification cards — Financial transaction cards — Magnetic stripe data content for track 3" (preview link: http://webstore.iec.ch/preview/info_isoiec4909%7Bed1.0%7Den.pdf)
    (store link: http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=43309)
    Track 3 does in fact contain data, I think that it was just your scanner that was not picking up the data. Hope this clears some stuff up, and I thought it might do well as a correction to that particular line.

  6. Hi there Brad, I just bought a ACR122U and trying to run in windows to test paypass cards. Big problem tho, When i try to run ChAP.py,pwnpass.py and even rfidiot the python shell shows error


    Any help you can give me would be so deeply appreciated, Maybe even slightly compensated :P

    if you have the time affliate-solutions-sydney at hot mail dot com

  7. Do you happen to have a pinout for the VivoPay 4500? Mine has an 8P8C port, and I need to adapt it to RS232.

  8. This might help - http://opensecurityresearch.com/files/datacable.pdf - If it does, you can thank kristin paget :)

  9. That did work! Thanks Kristin. At least pwnpass.py recognizes it, but it won't scan any cards. I'm assuming my reader's defective. Oh well. Thanks for the pdf!

  10. Hey, how's it goin? You touched briefly on the subject of differences betweeen Track 1 and track 2 data. Could you maybe inform me as to what and how exactly the data could be converted (track 1 to track 2 )

  11. Jordan, did you get any farther? I've been doing some RFID security research lately with the Proxmark3 and HID cards. I recently received a Vivopay 4500 in the mail and ran into the same problem. I'm going to build that datacable in the upcoming days and see what I can find out.

  12. hi all any body have data for chip or how i can write it ... thanks

  13. I knew nothing abut the tech you are talking about here. But I have a credtit card EMV chip that was accidentally dropped by burglars at our house. I would like to know what info I can get from the chip that can help us to locate the criminal, and how. Thanks! MM

  14. I believed I had everything setup properly: Vivopay 4500, serial cable with Prolific adapter, Python 2.7, pyserial, edited pwnpass to ID the adapter (shows up as TTYUSB0 in Backtrack5), but when I run pwnpass, all I get is a spinning pipe symbol and the phrase "om nom nom..." Nothing else ever happens. This in in both Win7 and BT5.

    This seems to refer to some lines in the pwnpass code:
    elif len(result) == 0:
    sys.stdout.write("\b\r" + outchar[iter] + " om nom nom...
    Any ideas or suggestions? Thank you so much for your help!!

    1. If you did happen to figure this out, can you please post some insight. I'm having the same issue on windows, don't have a mac

  15. Is there anyway you could go through the pwnpass steps for Windows.
    Mainly how to set the correct path for the serial port. I'm not great with python, so the more info the better... Thanks in advance

  16. I need a soft wear to make track 1 to track 2

  17. Just to clarify, the PAN you got was the actual complete PAN, and not full of Xs right? You just put the Xs to stop someone from going on a shopping spree? Sorry if I sound dumb.

  18. how can u generate track 2 when u only got track one or just the card details?

  19. Hi there, Just want to say thanks for this blog post. After watching Kristins conference talk I found your site.

    I have a vivopay 4500 and followed your article and it definitely works with no problem - I am using Mac OS 10.6.8

    Next I am going to get a Arc122u for my experiments.

    Ps - if anybody is wondering when the pwnpass script is working it should say 'Feed me Seymour' and when your serial port isn't what it is expecting it will say 'om nom nom'. When it is successful the will say pwnzered! and spit out the 2 track data.

    1. What do you mean by "serial port isn't what it is expecting" exactly?

    2. What exactly do you mean by isnt what it is expecting and how can I fix this?

  20. Hi everyone - I have discovered that pwnpass is pointless when you own a vivopay 4500. Just use 'Serial Tools' for mac - the setting is 19200/8-N-1 RAW

    1. Hey, I doubt you'll see this, but I have a Vivopay 4500 that was not getting to 'Feed me Seymour' with pwnpass and tried it with Serial Tools and those settings, but I'm getting a bunch of Hex values in <>'s any help?

  21. What is the start sentinal of Track 3 for a Financial card (Credit, Debit)?

    1. Credit/Debit cards have a blank Track 3

  22. If I have ccn+exp+ccv can I write track 2?

  23. Is there anyway you could go through the pwnpass steps for Windows. 
    Mainly how to set the correct path for the serial port. I'm not great with python, so the more info the better..... Anyone have any info? Would be a great hep

  24. Do you have any tips for finding unknown AID's? should I ttry bruteforcing it.