Research, development and trades concerning the powerful Proxmark3 device.
Remember; sharing is caring. Bring something back to the community.
"Learn the tools of the trade the hard way." +Fravia
You are not logged in.
Time changes and with it the technology
Proxmark3 @ discord
Users of this forum, please be aware that information stored on this site is not private.
Pages: 1
Hey guys,
Do you know if the PayPass / payWave (Blink) RFID standards in the US use something like MIFARE, Calypso, etc? I know they're ISO 14443 A, but that's all.
Is there any way to analyze, read, snoop, etc?
I don't have a reader besides the PM3...
Offline
hi14areader / hi14alist show nothing (well, just 0s) on my Visa payWave (Blink) card.
I'm going to have temporary access to an Omnikey 5321 but not for a month or two!
Offline
They use EMV, and you can download the standard here:
http://www.emvco.com/specifications.aspx?id=21
RFIDIOt includes a module 'ChAP.py' which will read them.
Offline
Thanks Adam!
Offline
Adam,
Using the OmniKey 5321 with RFIDIOt 0.1x (Windows) and Python 2.6, I'm getting an error in most operations of ChAP.py (with an EMV card inserted):
C:\Documents and Settings\Administrator\Desktop\RFIDIOt-Windows-0.1x>python ChAP.py -e
insert a card within 10s
Bruteforcing AIDs
Found AID: a0 00 00 00 03
6f: File Control Information (FCI) Template (30 bytes):
84: DF Name (7 bytes): a0 00 00 00 03 10 10
a5: Proprietary Information (19 bytes):
50: Application Label (11 bytes): VISA CREDIT
9f38: Processing Options Data Object List (PDOL) (3 bytes):
9f66: Card Production Life Cycle (2 bytes):
Traceback (most recent call last):
File "ChAP.py", line 815, in <module>
File "ChAP.py", line 492, in bruteforce_aids
File "ChAP.py", line 378, in decode_pse
IndexError: list index out of range
Please don't steal all my money. Oh wait, I already spent all of it on RFID hardware..
I also had to convert all the .py's from LF to CRLF *except* iso3166.py to get the tools to work on Windows (and downgrade from python 3.1 to 2.6). I run OS X, not linux, otherwise I'd try it in nix...
Offline
Ermm... OS X *is* nix! (BSD)
It's quite likely to fall over as the documentation is very hard to follow so I basically implement by fixing problems as I find them... Looks like your card has some features that the ones I've seen so far don't, but I'll take another look in case I've recently broken something...
Oh, and your money's safe with me... Trust me... I'm a hacker...
Offline
I just mean I'd try it if there were drivers available...for some reason they have drivers for OS X for many of their other devices, but nothing for 5x21.
Thanks Adam. I suppose I'll start learning a little python, I just had no idea what the issue was from looking. Damn hacker.
Offline
Adam,
What should I see normally when using an EMV card? A VISA card would be good to see if possible, but any other one would suffice.
I'm trying to get Chap.py working with my card but I don't know at what point it stopped getting correct data.
Offline
I commented out decode_pse because I was only getting 31 bytes back, but it tried to read past that. Now, will my credit card still work?
Y:\code\rfid\RFIDIOt-Windows-0.1y-beta>C:\Python26\python.exe ChAP.py
insert a card within 10s
Found AID: VISA - a0 00 00 00 03
Could not get processing options: 6984 PIN Try Limit exceeded
Application Transaction Counter: 6
Found AID: VISA Debit/Credit - a0 00 00 00 03 10 10
Could not get processing options: 6984 PIN Try Limit exceeded
Application Transaction Counter: 6
press Enter to continue
Offline
Hah! Got it!
I recovered my CC # -- I haven't deciphered the rest of the stream yet.
I sent this command: 0x00, 0xB2, 0x01, 0x0C, 0x00
It's on my VISA (Blink) from Chase. Let me know if you want the data (sans CC) to improve Chap.py. I am starting to implement it but I'm not sure if I'll be implementing it the right way without comparing to other cards since it seems the operations aren't always the same.
In fact, sending that command, I didn't expect to get the data back at that point...
Offline
Did you have to send a certain sequence of commands to the card before the "0x00, 0xB2, 0x01, 0x0C, 0x00"?
If you have a way to capture and send a trace of the communication, I can try to reproduce it using the pm3 on an Amex Blue. I've been interested in implementing this functionality for a little while on the pm3, but unfortunately I don't have access to an OmniKey.
-Ryan
Offline
As far as I know Amex cards work fine, but the only way I know of to capture the trace is by running pcscd in debug mode, so you'd need an OmniKey or some other PCSC compliant reader.
Offline
I hate to resurrect old threads like this, but I'm currently working on a similar project.... Trying to read cards with an OmniKey 5321 using RFIDOt...
I have a bunch of visa RIFD/Blink cards... Trying to read them with ChAP.py gives varying results. With an older Wells Fargo Card, I get this:
$ ./ChAP.py
insert a card within 10s
Found AID: VISA - a0 00 00 00 03
6f: File Control Information (FCI) Template (35 bytes):
84: DF Name (7 bytes): a0 00 00 00 03 10 10
a5: Proprietary Information (24 bytes):
50: Application Label (11 bytes): VISA Credit
9f38: Processing Options Data Object List (PDOL) (3 bytes):
9f66: Card Production Life Cycle (2 bytes): 5f 2d
Unrecognised TAG: 02 65 6e
Processing Options: 80: Response Message Template Format 1 (6 bytes): 00 80 08 01 01 00
SFI 01: starting record 01, ending record 01; 00 offline data authentication records
record 01: 70: Record Template (46 bytes):
57: Track 2 Equivalent Data (19 bytes): [redacted]
5f20: Cardholder Name (22 bytes): CARDHOLDER/WELLS FARGO
Application Transaction Counter: 16
Found AID: VISA Debit/Credit - a0 00 00 00 03 10 10
6f: File Control Information (FCI) Template (35 bytes):
84: DF Name (7 bytes): a0 00 00 00 03 10 10
a5: Proprietary Information (24 bytes):
50: Application Label (11 bytes): VISA Credit
9f38: Processing Options Data Object List (PDOL) (3 bytes):
9f66: Card Production Life Cycle (2 bytes): 5f 2d
Unrecognised TAG: 02 65 6e
Processing Options: 80: Response Message Template Format 1 (6 bytes): 00 80 08 01 01 00
SFI 01: starting record 01, ending record 01; 00 offline data authentication records
record 01: 70: Record Template (46 bytes):
57: Track 2 Equivalent Data (19 bytes): [redacted]
5f20: Cardholder Name (22 bytes): CARDHOLDER/WELLS FARGO
Application Transaction Counter: 17
With a newer Wells Fargo card, I get this:
$ ./ChAP.py
insert a card within 10s
Found AID: VISA - a0 00 00 00 03
6f: File Control Information (FCI) Template (35 bytes):
84: DF Name (7 bytes): a0 00 00 00 03 10 10
a5: Proprietary Information (24 bytes):
50: Application Label (11 bytes): VISA Credit
9f38: Processing Options Data Object List (PDOL) (3 bytes):
9f66: Card Production Life Cycle (2 bytes): 5f 2d
Unrecognised TAG: 02 65 6e
Could not get processing options: 6984 PIN Try Limit exceeded
Application Transaction Counter: 0
Found AID: VISA Debit/Credit - a0 00 00 00 03 10 10
6f: File Control Information (FCI) Template (35 bytes):
84: DF Name (7 bytes): a0 00 00 00 03 10 10
a5: Proprietary Information (24 bytes):
50: Application Label (11 bytes): VISA Credit
9f38: Processing Options Data Object List (PDOL) (3 bytes):
9f66: Card Production Life Cycle (2 bytes): 5f 2d
Unrecognised TAG: 02 65 6e
Could not get processing options: 6984 PIN Try Limit exceeded
A newer Chase/Blink Visa gives an error of sorts:
$ ./ChAP.py
insert a card within 10s
Found AID: VISA - a0 00 00 00 03
6f: File Control Information (FCI) Template (30 bytes):
84: DF Name (7 bytes): a0 00 00 00 03 10 10
a5: Proprietary Information (19 bytes):
50: Application Label (11 bytes): VISA CREDIT
9f38: Processing Options Data Object List (PDOL) (3 bytes):
9f66: Card Production Life Cycle (2 bytes):
Traceback (most recent call last):
File "./ChAP.py", line 836, in <module>
decode_pse(response)
File "./ChAP.py", line 379, in decode_pse
print '%02x' % data[index + taglen + offset],
IndexError: list index out of range
A Wells Fargo Debit Card gives this:
$ ./ChAP.py
insert a card within 10s
Found AID: VISA - a0 00 00 00 03
6f: File Control Information (FCI) Template (37 bytes):
84: DF Name (7 bytes): a0 00 00 00 03 10 10
a5: Proprietary Information (26 bytes):
50: Application Label (10 bytes): VISA DEBIT
87: Application Priority Indicator (1 bytes): skipping BER-TLV object!
Could not get processing options: 6984 PIN Try Limit exceeded
Application Transaction Counter: 0
Found AID: VISA Debit/Credit - a0 00 00 00 03 10 10
6f: File Control Information (FCI) Template (37 bytes):
84: DF Name (7 bytes): a0 00 00 00 03 10 10
a5: Proprietary Information (26 bytes):
50: Application Label (10 bytes): VISA DEBIT
87: Application Priority Indicator (1 bytes): skipping BER-TLV object!
Could not get processing options: 6984 PIN Try Limit exceeded
Application Transaction Counter: 0
And an older Chase/Blink card doesn't read at all (though it reads fine in HID's Diagnostic tools in windows).
Offline
Hah! Got it!
I recovered my CC # -- I haven't deciphered the rest of the stream yet.
I sent this command: 0x00, 0xB2, 0x01, 0x0C, 0x00
It's on my VISA (Blink) from Chase. Let me know if you want the data (sans CC) to improve Chap.py. I am starting to implement it but I'm not sure if I'll be implementing it the right way without comparing to other cards since it seems the operations aren't always the same.
In fact, sending that command, I didn't expect to get the data back at that point...
Samy, how did you go about sending a raw apdu command and reading its output?
Offline
Based on Samy's post, I was able to pull name and card number, but i cant figure out what is the expr date, etc..
I stripped down ChAP.py to work with a OmniKey Cardman 5321 and the Chase PayPass, here it is. If you know another command to pull other data, let me know.
cat paypass.py
#! /usr/bin/env python
"""
This is a modified ChAP.py from RFIDIOt
-Brad Antoniewicz
Script that tries to select the EMV Payment Systems Directory on all inserted cards.
Original Copyright 2008 RFIDIOt
Author: Adam Laurie, mailto:adam@algroup.co.uk
http://rfidiot.org/ChAP.py
"""
from smartcard.CardType import AnyCardType
from smartcard.CardRequest import CardRequest
from smartcard.CardConnection import CardConnection
from smartcard.CardConnectionObserver import ConsoleCardConnectionObserver
from smartcard.Exceptions import CardRequestTimeoutException
import getopt
import sys
import string
import binascii
from operator import *
# local imports
#from iso3166 import ISO3166CountryCodes
# default global options
OutputFiles= False
TryCommand= False
Debug= False
Protocol= CardConnection.T0_protocol
RawOutput= False
Verbose= False
# Global VARs for data interchange
Cdol1= ''
Cdol2= ''
CurrentAID= ''
AID = [0xa0,0x00,0x00,0x00,0x03]
GET_PROCESSING_OPTIONS = [0x80,0xa8,0x00,0x00,0x02,0x83,0x00,0x00]
# Master Data File for PSE
DF_PSE = [0x31, 0x50, 0x41, 0x59, 0x2E, 0x53, 0x59, 0x53, 0x2E, 0x44, 0x44, 0x46, 0x30, 0x31]
# define the apdus used in this script
AAC= 0
TC= 0x40
ARQC= 0x80
GENERATE_AC= [0x80,0xae]
GET_CHALLENGE= [0x00,0x84,0x00]
GET_DATA = [0x80, 0xca]
GET_PROCESSING_OPTIONS = [0x80,0xa8,0x00,0x00,0x02,0x83,0x00,0x00]
GET_RESPONSE = [0x00, 0xC0, 0x00, 0x00 ]
READ_RECORD = [0x00, 0xb2]
SELECT = [0x00, 0xA4, 0x04, 0x00]
#CMD = [0x00, 0xB2, 0x01, 0x0C, 0x00]
CMD = [0x00, 0xB2, 0x01, 0x0C, 0x00]
UNBLOCK_PIN= [0x84,0x24,0x00,0x00,0x00]
VERIFY= [0x00,0x20,0x00,0x80]
#BRUTE_AID= [0xa0,0x00,0x00,0x00]
BRUTE_AID= []
# define tags for response
BINARY= 0
TEXT= 1
BER_TLV= 2
NUMERIC= 3
MIXED= 4
TEMPLATE= 0
ITEM= 1
VALUE= 2
SFI= 0x88
CDOL1= 0x8c
CDOL2= 0x8d
# define SW1 return values
SW1_RESPONSE_BYTES= 0x61
SW1_WRONG_LENGTH= 0x6c
SW12_OK= [0x90,0x00]
SW12_NOT_SUPORTED= [0x6a,0x81]
SW12_NOT_FOUND= [0x6a,0x82]
SW12_COND_NOT_SAT= [0x69,0x85] # conditions of use not satisfied
PIN_BLOCKED= [0x69,0x83]
PIN_BLOCKED2= [0x69,0x84]
PIN_WRONG= 0x63
# define GET_DATA primitive tags
PIN_TRY_COUNTER= [0x9f,0x17]
ATC= [0x9f,0x36]
LAST_ATC= [0x9f,0x13]
LOG_FORMAT= [0x9f, 0x4f]
def printhelp():
print '\nChAP.py - Chip And PIN in Python'
print 'Ver 0.1c\n'
print 'usage:\n\n ChAP.py [options] [PIN]'
print
print 'If the optional numeric PIN argument is given, the PIN will be verified (note that this'
print 'updates the PIN Try Counter and may result in the card being PIN blocked).'
print '\nOptions:\n'
print '\t-d\t\tDebug - Show PC/SC APDU data'
print '\t-h\t\tPrint detailed help message'
print '\t-r\t\tRaw output - do not interpret EMV data'
print '\t-v\t\tVerbose on'
print
def hexprint(data):
index= 0
while index < len(data):
print '%02x' % data[index],
index += 1
print
def textprint(data):
index= 0
out= ''
while index < len(data):
if data[index] >= 0x20 and data[index] < 0x7f:
out += chr(data[index])
else:
out += '.'
index += 1
print out
def try_cmd():
le= 0x00
apdu = CMD
response, sw1, sw2 = send_apdu(apdu)
if response:
if Verbose:
print '\t[VERBOSE] Got Response!'
return response
else:
print '\t[ERROR] No Response'
return False, 0, ''
def parse_ccdata(response2):
OFFSET_HDR= 3
OFFSET_CC= 4
ENDCC= 12
OFFSET_NAMEFIELD= 23
OFFSET_NAMELEN= 26
NAMELEN= 26
NAME= 2
NAMELEN= 16
NAMEFIELD_CODE= 0x5f20
print "Response:"
print "\tHeader: ",
index=0
while index <= len(response2[:OFFSET_HDR]):
print '%02x' % response2[index],
print "(%d)" % response2[index],
index += 1
print
print "\tCard Number: ",
index=0
ccnum=""
while index < len(response2[OFFSET_CC:OFFSET_CC + 8]):
ccnum += '%02x' % response2[OFFSET_CC + index]
index +=1
print ccnum
print "\tStuff: ",
index=0
while index < len(response2[OFFSET_CC + 8:OFFSET_NAMEFIELD]):
print '%02x' % response2[OFFSET_CC + 8 + index],
print '(%d)' % response2[OFFSET_CC + 8 + index],
index +=1
print
if response2[OFFSET_NAMEFIELD] == 0x5f and response2[OFFSET_NAMEFIELD + 1] == 0x20:
if Verbose:
print "\tName Field Code Found!: %02x" % response2[OFFSET_NAMEFIELD],
print "%02x" % response2[OFFSET_NAMEFIELD + 1]
else:
print "\t[WARNING]Could not find Name Field Code!! Something might not be good"
length = '%d' % response2[OFFSET_NAMEFIELD + 2]
if Verbose:
print "\t[VERBOSE] Length:",length,"(",int(length),") %02x" % response2[OFFSET_NAMEFIELD + 2]
print "\tName:",
textprint(response2[OFFSET_NAMEFIELD+3:OFFSET_NAMEFIELD+3+int(length)])
if Verbose:
print "\t[VERBOSE] Name (Hex):",
index=0
while index < len(response2[OFFSET_NAMEFIELD+3:OFFSET_NAMEFIELD+3+int(length)]):
print '%02x' % response2[OFFSET_NAMEFIELD + 3 + index],
print '(%s)' % chr(response2[OFFSET_NAMEFIELD + 3 + index]),
index +=1
print
print "\tThe Rest: ",
index=0
while index < len(response2[OFFSET_NAMEFIELD + 3 + int(length):]):
print '%02x' % response2[OFFSET_NAMEFIELD + 3 + int(length) + index],
print '(%d)' % response2[OFFSET_NAMEFIELD + 3 + int(length) + index],
index += 1
print
def check_return(sw1,sw2):
if [sw1,sw2] == SW12_OK:
return True
return False
def send_apdu(apdu):
# send apdu and get additional data if required
response, sw1, sw2 = cardservice.connection.transmit( apdu, Protocol )
if sw1 == SW1_WRONG_LENGTH:
# command used wrong length. retry with correct length.
apdu= apdu[:len(apdu) - 1] + [sw2]
return send_apdu(apdu)
if sw1 == SW1_RESPONSE_BYTES:
# response bytes available.
apdu = GET_RESPONSE + [sw2]
response, sw1, sw2 = cardservice.connection.transmit( apdu, Protocol )
return response, sw1, sw2
def select_aid(aid):
# select an AID and return True/False plus additional data
apdu = SELECT + [len(aid)] + aid + [0x00]
#apdu = SELECT
response, sw1, sw2= send_apdu(apdu)
if check_return(sw1,sw2):
return True, response, sw1, sw2
else:
return False, [], sw1,sw2
def get_processing_options():
apdu= GET_PROCESSING_OPTIONS
response, sw1, sw2= send_apdu(apdu)
print "sent command"
if check_return(sw1,sw2):
print "Got something"
return True, response
else:
print "got nothing"
return False, "%02x%02x" % (sw1,sw2)
# main loop
try:
# 'args' will be set to remaining arguments (if any)
opts, args = getopt.getopt(sys.argv[1:],'v')
for o, a in opts:
if o == '-d':
Debug= True
if o == '-r':
RawOutput= True
if o == '-t':
Protocol= CardConnection.T1_protocol
if o == '-v':
Verbose= True
except getopt.GetoptError:
# -h will cause an exception as it doesn't exist!
printhelp()
sys.exit(True)
try:
# request any card type
cardtype = AnyCardType()
# request card insertion
print 'insert a card within 10s'
cardrequest = CardRequest( timeout=10, cardType=cardtype )
cardservice = cardrequest.waitforcard()
# attach the console tracer
if Debug:
observer=ConsoleCardConnectionObserver()
cardservice.connection.addObserver( observer )
# connect to the card
cardservice.connection.connect(Protocol)
# try to select PSE
# apdu = SELECT + [len(DF_PSE)] + DF_PSE
# response, sw1, sw2 = send_apdu( apdu )
print 'Connecting with AID: ',
hexprint(AID)
selected, response, sw1, sw2= select_aid(AID)
if selected:
print "\tSuccess!"
print "Response: \n\t",
textprint(response)
if Verbose:
print "\t[VERBOSE]: ",
hexprint(response)
print '\nRequesting Track Info: \n\t',
hexprint(CMD)
response2 = try_cmd()
if Verbose:
print "\t[VERBOSE]: ",
hexprint(response2)
print "\t[VERBOSE]: ",
textprint(response2)
parse_ccdata(response2)
#print "Get Processing Options"
#ret, response= get_processing_options()
#if ret:
# print ' Processing Options:',
except CardRequestTimeoutException:
print 'time-out: no card inserted during last 10s'
if 'win32'==sys.platform:
print 'press Enter to continue'
sys.stdin.read(1)
Offline
Iceman's fork now can be build with EMV even on 256k device:
Nonvolatile Program Memory Size: 256K bytes. Used: 222420 bytes (85%). Free: 39724 bytes (15%).
Transaction goes well
pm3 --> hf emv trans
#db# SELECT AID COMPLETED
#db# EMV TRANSACTION FINISHED
pm3 --> hf 14a list
Recorded Activity (TraceLen = 211 bytes)
Start = Start of Start Bit, End = End of last modulation. Src = Source of Transfer
iso14443a - All times are in carrier periods (1/13.56Mhz)
Start | End | Src | Data (! denotes parity error) | CRC | Annotation |
------------|------------|-----|-----------------------------------------------------------------|-----|--------------------|
0 | 992 | Rdr |52 | | WUPA
2228 | 4596 | Tag |04 00 | |
7040 | 9504 | Rdr |93 20 | | ANTICOLL
10676 | 16564 | Tag |ef 91 43 88 b5 | |
18816 | 29344 | Rdr |93 70 ef 91 43 88 b5 ca 23 | ok | SELECT_UID
30516 | 34036 | Tag |28 b4 fc | |
35584 | 40352 | Rdr |e0 80 31 73 | ok | RATS
49460 | 70324 | Tag |10 78 80 70 02 00 31 c0 64 1f 27 01 00 00 90 00 | |
| | |38 57 | ok |
74880 | 102688 | Rdr |0a 00 00 a4 04 00 0e 32 50 41 59 2e 53 59 53 2e | |
| | |44 44 46 30 31 00 b0 54 | ok |
333236 | 382836 | Tag |0a 00 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 04 10 10 87 01 01 90 00 86 5f | ok |
But unfortunately dumping EMV tag values is not working, seems that some code adjustments required as the array of card data is not filled in:
pm3 --> hf emv dump
#db# currentcard->ATQA=
#db# 00 00
#db# currentcard->UID=
#db# currentcard->SAK1=
#db# 00
#db# currentcard->SAK2=
#db# 00
#db# currentcard->ATS=
#db# currentcard->tag_4F=
....
Offline
@osys, how about you start a new thread instead of raising one from the dead (2011) ?
Offline
Sure, thanks for an advice. I've didn't find dedicated forum branch and posted here
Offline
Pages: 1