Contactless Bank Card Attacks





Posted by: cuamckuu



Retrieving map contents and working with EMV teams can be interesting not only for research purposes. There are several types of attacks on contactless bank cards, the implementation of which will be discussed under the cut.



Introduction



This year I got an internship in Summer of Hack 2019 at Digital Security and worked on the topic of research on contactless EMV cards. During the internship, it turned out to be better to learn how bank cards work, and to create a new utility for working with contactless cards. A demonstration of the data reading mode can be found here .



Types of Attacks



The card and the terminal communicate using the EMV standard (Europay + MasterCard + VISA), which was developed to increase the security of payments. In this regard, there are not many attack vectors on contactless cards. The article will focus on the following:





Such attacks are possible when interacting with the card according to the EMV standard. Many cards allow you to easily read the user's private information, in particular PAN, expiration date and holder’s name. The read data is enough to map the card in some online stores, for example, Amazon. And the received private data can be used for more personalized phishing or when sending spam.



In a similar way, a DoS attack is implemented. Calling the necessary EMV-commands allows you to overflow the internal transaction counter or simulate incorrect PIN-code entry, which leads to card blocking.



Why reinvent the wheel?



Before starting the development, it was decided to study the existing solutions. In particular, they considered: RFIDIOt / ChAP.py , Jaccal , nfcmillionaire , Conference PoC , “Ruby” script , Android apps / libs .



Most of the programs reviewed try to simulate the operation of a POS terminal and use dictionaries with identifiers of supported cards, so often such solutions will work only with Visa and MasterCard.



Another problem is reading a small part of the data instead of dumping a full dump. Almost all programs try to parse as many EMV as possible on the fly and make parsing errors.



If any of the problems is absent or not so pronounced, then most likely we are talking about an application / library for Android, and you will need a phone with an NFC reader, which not everyone has.



The described problems can be solved, for this it is necessary:





Retrieving data from the map



There are already articles on Habré describing in detail the process of interaction between the card and the terminal ( one , two , three ), so I’ll try not to repeat myself and focus on the practical part.



To communicate with the card, we will use the PN532 reader because of the pleasant price and the libnfc library. Seamlessly get down to business. The data on the map is organized as follows:

Environment -> Applications -> Files -> Records.



The purpose of reading is to get data from all records, for this you need to go through a complete chain, and the choice of environment and application occurs only once at the beginning of communication.

The same process in terms of EMV commands:





Consider the example of the formation of one of the teams. The first command to select a contactless environment is always the same and looks like this:



byte_t const command[] = { 0x40, 0x01, // Pn532 InDataExchange 0x00, 0xA4, // SELECT ppse 0x04, 0x00, // P1:By name, P2:_ 0x0e, // Lc: Data length 0x32, 0x50, 0x41, 0x59, 0x2e, 0x53, 0x59, // Data string: 0x53, 0x2e, 0x44, 0x44, 0x46, 0x30, 0x31, // 2PAY.SYS.DDF01 (PPSE) 0x00 // Le };
      
      





Response example: 6F 23 84 0E 32 50 41 59 2E 53 59 53 2E 44 44 46 30 31 A5 11 BF 0C 0E 61 0C 4F 07 A0 00 00 00 03 10 10 87 01 01 90 00



To call the next command, we need to parse the response of the previous command.







We are interested in the application identifier AID. We memorize it and form a new SELECT query, but this time we pass the received AID to the SELECT command, and not the PPSE, as in the first command.



Example: 00 A4 04 00 07 A0 00 00 00 03 10 10 00



As mentioned earlier, it is important to get AID dynamically, rather than using a prepared dictionary, then your application is likely to be able to read different types of cards, for example, MIR cards.



After the application is selected, we can read the necessary records using the READ RECORD command and passing in the file number and record number as parameters.



An example of team formation: (more about this can be found in the standard. EMV Book1. 11.2 READ RECORD)



  byte_t const sfi_param = (sfi << 3) | (1 << 2); byte_t const command[] = { 0x40, 0x01, // Pn532 InDataExchange 0x00, 0xB2, // READ RECORD record_number, sfi_param, // P1:record_number and P2:SFI 0x00 // Le };
      
      





Call example: 00 B2 02 14 00



Note that not a complete byte is allocated to the file number, respectively, there may be 31 (2 ^ 5 - 1) files in total, and 255 entries. Files from the 1st to the 10th are allocated for storage of internal data, and the remaining ones are allocated for storage transaction log if the card supports logging.



Now using two nested loops, we can get the data of all the map records by calling the READ RECORD command for each pair. The search process can be significantly accelerated if you pay attention to the status word returned by the card (the last two bytes of the response). Status can tell us that the file does not exist (SW = 0x6A82) or that there are no further entries in this file (SW = 0x6A83).



In practice, it turned out that it makes sense to consider only the case of a non-existent file, since sometimes there are cards that incorrectly use the status code for missing entries. After reading the data, you can send it to one of the online parsers, I liked this one .



Fragment of data extracted from map records:







The read data is enough to map the card in some online stores (mainly in foreign ones), and the information obtained can be used for a more personalized attack using social engineering.



We organize contactless DoS



We proceed to the next type of attack. There are at least 2 implementation methods for DoS-a.



Slow way



To implement the slow method (the attack will take about 4 minutes), it is necessary to overfill the internal card transaction counter (ATC). To do this, call:





Consider the steps in more detail. The choice of contactless environment and application is similar to the item with data extraction, the only difference is that this time we need to process the response of the SELECT APPLICATION command.







We are interested in the PDOL field, since it will be needed for the subsequent call of the GET PROCESSING OPTIONS command, which will increase the transaction counter for each call.

In PDOL, the card asks for information about the terminal and payment from us.



In the example above, the map asks us:





Since we implement DoS, not a real payment, we can not worry about the correctness of the values ​​and just use the pre-prepared values ​​that the card will accept. Read more about the required values ​​in the standard. (EMV Book 3. Annex A Data Elements Dictionary).



For the convenience of practical use, I quote the table:

Tag (Hex) Description Valid Value (Hex)
9F59 Terminal transaction information C8 80 00
9F5A Terminal transaction type 00
9F58 Merchant type indicator 01
9F66 Terminal Transaction Qualifiers 79 00 40 80
9F02 Amount (authorized) 00 00 00 10 00 00
9F03 Amount (Other) 00 00 00 00 00 00
9F1A Terminal country code 01 24
5F2A Transaction Currency Code 01 24
95 Terminal Verification Results 00 00 00 00 00
9A Transaction date 19 01 01
9C Transaction type 00
9F37 Unpredictable number 82 3D DE 7A


Having formed the data requested by the card, we are ready to call the GPO.



Example: 80 A8 00 00 12 83 10 79 00 40 80 00 00 00 10 00 00 82 3D DE 7A 01 24 00



Answer: 77 4F 82 02 20 00 94 0C 10 02 03 00 18 01 01 00 10 04 04 00 57 13 42 76 55 00 66 83 25 13 D2 00 52 01 14 89 36 20 00 00 1F 5F 20 02 20 2F 9F 10 07 06 01 11 03 80 20 00 9F 6C 02 30 00 9F 26 08 33 33 89 D5 70 A3 DF 37 9F 27 01 00 9F 36 02 02 48 48 90 00



Repeat the GPO call 65,536 times, and the card is blocked. You can reduce the number of calls required by first reading the current ATC value using GET DATA.



Quick way



The quick method is much more convenient (and more dangerous), since it will take about 2 seconds to lock the card, so a detailed analysis of implementation details will remain behind the scenes.



The method is similar to the previous one, but this time it will be necessary to lower the counter of attempts to enter the PIN code, instead of increasing the transaction counter. The PIN value of Try Counter can also be obtained through GET DATA, but in this case there will be no significant increase in speed.



Required Operations:





Summary



During the internship, it was possible to create a new tool for working with contactless bank cards and solve several problems that are present in existing solutions, and using a cheap reader significantly reduces the cost of a research kit and can help attract new people to research the security of contactless bank cards. The source code for the program is available on Github .



All Articles