adapt a bit

This commit is contained in:
iceman1001 2023-10-12 14:51:18 +02:00
commit ef348a2aa0
2 changed files with 119 additions and 65 deletions

View file

@ -28,6 +28,7 @@
#include "iso14443a.h"
#include "protocols.h"
#include "cmd.h"
#include "commonutil.h"
void ModInfo(void) {
DbpString(" HF - Reading VISA cards & Emulating a VISA MSD Transaction(ISO14443) - (Salvador Mendoza)");
@ -152,10 +153,32 @@ void RunMod(void) {
0x59, 0x2e, 0x53, 0x59, 0x53, 0x2e, 0x44, 0x44,
0x46, 0x30, 0x31, 0x00
};
uint8_t visa[13] = {
0x00, 0xA4, 0x04, 0x00, 0x07, 0xa0, 0x00, 0x00,
0x00, 0x03, 0x10, 0x10, 0x00
uint8_t visa[] = { 0x00, 0xA4, 0x04, 0x00, 0x07, 0xa0, 0x00, 0x00, 0x00, 0x03, 0x10, 0x10, 0x00 };
/*
uint8_t select_aid_hdr[5] = { 0x00, 0xA4, 0x04, 0x00, 0x00 };
static const char* aid_list [] = {
"A00000000305076010", // VISA ELO Credit
"A0000000031010", // VISA Debit/Credit (Classic)
"A000000003101001", // VISA Credit
"A000000003101002", // VISA Debit
"A0000000032010", // VISA Electron
"A0000000032020", // VISA
"A0000000033010", // VISA Interlink
"A0000000034010", // VISA Specific
"A0000000035010", // VISA Specific
"A0000000036010", // Domestic Visa Cash Stored Value
"A0000000036020", // International Visa Cash Stored Value
"A0000000038002", // VISA Auth, VisaRemAuthen EMV-CAP (DPA)
"A0000000038010", // VISA Plus
"A0000000039010", // VISA Loyalty
"A000000003999910", // VISA Proprietary ATM
"A000000098", // Visa USA Debit Card
"A0000000980848", // Visa USA Debit Cardv
};
*/
uint8_t processing [8] = {0x80, 0xA8, 0x00, 0x00, 0x02, 0x83, 0x00, 0x00};
uint8_t sfi[5] = {0x00, 0xb2, 0x01, 0x0c, 0x00};
@ -169,10 +192,15 @@ void RunMod(void) {
// - MSD token card format -
//
//Card number: 4412 3456 0578 1234
//Expiration date: 17/11
//Service code: 201
//Discretionary data: 0000030000991
// Card number.............. 4412 3456 0578 1234
// Expiration date.......... 17/11
// Service code............. 201
// Discretionary data....... 0000030000991
// Pin verification value... 0000
// CVV / iCvv............... 030
// Trailing................. 000991
// 44 12 34 56 05 78 12 34 D 1711 2 01 00 00 03 00 00 99 1
// char token[19] = {0x44,0x12,0x34,0x56,0x05,0x78,0x12,0x34,0xd1,0x71,0x12,0x01,0x00,0x00,0x03,0x00,0x00,0x99,0x1f};
//
// It is possible to initialize directly the emulation mode, having "token" with data and set "chktoken" = true ;)
@ -185,7 +213,7 @@ void RunMod(void) {
// in case there is a read command received we shouldn't break
uint8_t data[PM3_CMD_DATA_SIZE] = {0x00};
uint8_t visauid[7] = {0x04, 0x02, 0x03, 0x04};
uint8_t visauid[7] = {0xE9, 0x66, 0x5D, 0x20};
memcpy(data, visauid, 4);
// to initialize the emulation
@ -275,6 +303,10 @@ void RunMod(void) {
chktoken = false;
LED_C_OFF();
LED_B_ON();
// add loop visa
// for (int i = 0; i < ARRAYLEN(AIDlist); i ++) {
// hexstr_to_byte_array("a0da02631a440a44000000a012ad10a00e800200048108", sam_apdu, &sam_len);
uint8_t apdulen = iso14_apdu(apdus[i], (uint16_t) apduslen[i], false, apdubuffer, NULL);
if (apdulen > 0) {
@ -289,8 +321,10 @@ void RunMod(void) {
// check for PDOL
if (apdubuffer[u] == 0x9F && apdubuffer[u + 1] == 0x38) {
for (uint8_t e = 0; e <= apdubuffer[u + 2]; e++)
for (uint8_t e = 0; e <= apdubuffer[u + 2]; e++) {
pdol[e] = apdubuffer[u + e + 2];
}
// generate a challenge
plen = treatPDOL(pdol);
@ -425,12 +459,16 @@ void RunMod(void) {
// depending on card reader commands, the Proxmark will answer to fool the reader
// respond with PPSE
if (receivedCmd[2] == 0xA4 && receivedCmd[6] == 0x32 && prevCmd == 0) {
// need to adapt lengths..
uint8_t ppsea[39] = {
// 0x23 = 35, skip two first bytes then the message - SW 2 is 35 = 0x23
0x6F, 0x23, 0x84, 0x0E, 0x32, 0x50, 0x41, 0x59,
0x2E, 0x53, 0x59, 0x53, 0x2E, 0x44, 0x44, 0x46,
0x30, 0x31, 0xA5, 0x11, 0xBF, 0x0C, 0x0E, 0x61,
0x0C, 0x4F, 0x07, 0xA0, 0x00, 0x00, 0x00, 0x03,
0x10, 0x10, 0x87, 0x01, 0x01, 0x90, 0x00
0x0C, 0x4F,
// len aid0 aid1 aid2...
0x07, 0xA0, 0x00, 0x00, 0x00, 0x03, 0x10, 0x10,
0x87, 0x01, 0x01, 0x90, 0x00
};
memcpy(&dynamic_response_info.response[1], ppsea, sizeof(ppsea));
dynamic_response_info.response_n = sizeof(ppsea) + 1;
@ -439,10 +477,14 @@ void RunMod(void) {
// respond Visa AID
} else if (receivedCmd[2] == 0xA4 && receivedCmd[10] == 0x03 && receivedCmd[11] == 0x10 && prevCmd == 1) {
uint8_t visauid_long[34] = {
0x6F, 0x1E, 0x84, 0x07, 0xA0, 0x00, 0x00, 0x00,
0x03, 0x10, 0x10, 0xA5, 0x13, 0x50, 0x0B, 0x56,
0x49, 0x53, 0x41, 0x20, 0x43, 0x52, 0x45, 0x44,
0x49, 0x54, 0x9F, 0x38, 0x03, 0x9F, 0x66, 0x02,
// 0x1E = 30, skip two first bytes then the message - SW 2 is 30 = 0x1E
0x6F, 0x1E, 0x84,
// len aid0 aid1 aid2....
0x07, 0xA0, 0x00, 0x00, 0x00, 0x03, 0x10, 0x10,
0xA5, 0x13, 0x50,
// len V I S A C R E D I T
0x0B, 0x56, 0x49, 0x53, 0x41, 0x20, 0x43, 0x52, 0x45, 0x44, 0x49, 0x54,
0x9F, 0x38, 0x03, 0x9F, 0x66, 0x02,
0x90, 0x00
};
memcpy(&dynamic_response_info.response[1], visauid_long, sizeof(visauid_long));
@ -461,16 +503,18 @@ void RunMod(void) {
uint8_t card[25] = {
0x70, 0x15, 0x57, 0x13, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90,
0x00
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x90, 0x00
};
// add token array == Track 2 found before
memcpy(&card[4], token, sizeof(token));
memcpy(&dynamic_response_info.response[1], card, sizeof(card));
dynamic_response_info.response_n = sizeof(card) + 1;
prevCmd++;
} else {
uint8_t finished[2] = {0x6f, 0x00};
uint8_t finished[2] = {0x6F, 0x00};
memcpy(&dynamic_response_info.response[1], finished, sizeof(finished));
dynamic_response_info.response_n = sizeof(finished) + 1;
if (prevCmd == 5) {
@ -509,8 +553,8 @@ void RunMod(void) {
EmSendPrecompiledCmd(p_response);
}
}
switch_off();
switch_off();
set_tracing(false);
BigBuf_free_keep_EM();
reply_ng(CMD_HF_MIFARE_SIMULATE, retval, NULL, 0);

View file

@ -73,29 +73,25 @@ void ModInfo(void) {
void RunMod() {
StandAloneMode();
Dbprintf(_YELLOW_(">>") "Relaying ISO/14443A data over Bluetooth a.k.a. reblay Started<<");
DbpString("");
Dbprintf(_YELLOW_(">>> ") " Relaying ISO/14443A data over Bluetooth a.k.a. reblay Started " _YELLOW_("<<<"));
DbpString("");
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
// Allocate 512 bytes for the dynamic modulation, created when the reader queries for it
// Such a response is less time critical, so we can prepare them on the fly
#define DYNAMIC_RESPONSE_BUFFER_SIZE 512
#define DYNAMIC_MODULATION_BUFFER_SIZE 1024
uint8_t flags = FLAG_4B_UID_IN_DATA; //UID 4 bytes(could be 7 bytes if needed it)
uint8_t data[PM3_CMD_DATA_SIZE] = {0x00}; // in case there is a read command received we shouldn't break
uint8_t visauid[7] = {0x01, 0x02, 0x03, 0x04};
// UID 4 bytes(could be 7 bytes if needed it)
uint8_t flags = FLAG_4B_UID_IN_DATA;
// in case there is a read command received we shouldn't break
uint8_t data[PM3_CMD_DATA_SIZE] = {0x00};
uint8_t visauid[7] = {0xE9, 0x66, 0x5D, 0x20};
memcpy(data, visauid, 4);
// to initialize the emulation
uint8_t tagType = 4; // 4 = ISO/IEC 14443-4 - javacard (JCOP)
tag_response_info_t *responses;
uint32_t cuid = 0;
uint32_t counters[3] = { 0x00, 0x00, 0x00 };
uint8_t tearings[3] = { 0xbd, 0xbd, 0xbd };
uint8_t pages = 0;
// For received Bluetooth package
uint8_t rpacket[MAX_FRAME_SIZE] = { 0x00 };
@ -126,6 +122,12 @@ void RunMod() {
uint8_t receivedCmd[MAX_FRAME_SIZE] = { 0x00 };
uint8_t receivedCmdPar[MAX_PARITY_SIZE] = { 0x00 };
// Allocate 512 bytes for the dynamic modulation, created when the reader queries for it
// Such a response is less time critical, so we can prepare them on the fly
#define DYNAMIC_RESPONSE_BUFFER_SIZE 512
#define DYNAMIC_MODULATION_BUFFER_SIZE 1024
uint8_t dynamic_response_buffer[DYNAMIC_RESPONSE_BUFFER_SIZE] = {0};
uint8_t dynamic_modulation_buffer[DYNAMIC_MODULATION_BUFFER_SIZE] = {0};
@ -143,9 +145,9 @@ void RunMod() {
uint8_t state = STATE_READ;
if (state == STATE_READ) {
DbpString(_YELLOW_("[ ") "In reading mode" _YELLOW_(" ]"));
DbpString("Initialized [ " _YELLOW_("reading mode") " ]");
} else {
DbpString(_YELLOW_("[ ") "In emulation mode" _YELLOW_(" ]"));
DbpString("Initialized [ " _BLUE_("emulation mode") " ]");
}
for (;;) {
@ -162,10 +164,10 @@ void RunMod() {
else if (button_pressed == BUTTON_SINGLE_CLICK) { // Pressing one time change between reading & emulation
if (state == STATE_READ) {
state = STATE_EMU;
DbpString(_YELLOW_("[ ") "In emulation mode" _YELLOW_(" ]"));
DbpString("[ " _BLUE_("Emulation mode") " ]");
} else {
state = STATE_READ;
DbpString(_YELLOW_("[ ") "In reading mode" _YELLOW_(" ]"));
DbpString("[ " _YELLOW_("Reading mode") " ]");
}
}
@ -178,6 +180,7 @@ void RunMod() {
iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
if (iso14443a_select_card(NULL, &card_a_info, NULL, true, 0, false)) {
LED_B_ON();
// Get data to send a ping with UID + ATQA + SAK
@ -208,7 +211,9 @@ void RunMod() {
Dbhexdump(uidlen + 4, rdata, false);
DbpString(_YELLOW_("[ ") "Sending ping" _YELLOW_(" ]"));
if (usart_writebuffer_sync(rdata, uidlen + 4) == PM3_SUCCESS) {
DbpString(_YELLOW_("[ ") "Sent!" _YELLOW_(" ]"));
for (;;) {
@ -261,26 +266,31 @@ void RunMod() {
// free eventually allocated BigBuf memory but keep Emulator Memory
BigBuf_free_keep_EM();
if (SimulateIso14443aInit(tagType, flags, data, &responses, &cuid, counters, tearings, &pages) == false) {
// 4 = ISO/IEC 14443-4 - javacard (JCOP)
if (SimulateIso14443aInit(4, flags, data, &responses, &cuid, NULL, NULL, NULL) == false) {
BigBuf_free_keep_EM();
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
DbpString(_YELLOW_("!!") "Error initializing the emulation process!");
DbpString(_RED_("Error initializing the emulation process!"));
SpinDelay(500);
state = STATE_READ;
DbpString(_YELLOW_("[ ") "Initialized reading mode" _YELLOW_(" ]"));
DbpString("Initialized [ "_YELLOW_("reading mode") " ]");
continue;
}
// We need to listen to the high-frequency, peak-detected path.
iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN);
int len = 0; // Command length
int retval = PM3_SUCCESS; // Check emulation status
// Command length
int len = 0;
// Check emulation status
int retval = PM3_SUCCESS;
uint8_t resp = 0; // Bluetooth response
// Bluetooth response
uint8_t resp = 0;
lenpacket = 0;
uint8_t prevcmd = 0x00; // Keep track of last terminal type command
// Keep track of last terminal type command
uint8_t prevcmd = 0x00;
clear_trace();
set_tracing(true);
@ -288,11 +298,12 @@ void RunMod() {
for (;;) {
LED_B_OFF();
// Clean receive command buffer
if (!GetIso14443aCommandFromReader(receivedCmd, receivedCmdPar, &len)) {
DbpString(_YELLOW_("!!") "Emulator stopped");
if (GetIso14443aCommandFromReader(receivedCmd, receivedCmdPar, &len) == false) {
DbpString("Emulator stopped");
retval = PM3_EOPABORTED;
break;
}
tag_response_info_t *p_response = NULL;
LED_B_ON();
@ -314,24 +325,18 @@ void RunMod() {
}
}
if (receivedCmd[0] == ISO14443A_CMD_REQA && len == 1) { // Received a REQUEST
// DbpString(_YELLOW_("+") "REQUEST Received");
p_response = &responses[RESP_INDEX_ATQA];
} else if (receivedCmd[0] == ISO14443A_CMD_HALT && len == 4) { // Received a HALT
// DbpString(_YELLOW_("+") "Received a HALT");
p_response = NULL;
resp = 0;
} else if (receivedCmd[0] == ISO14443A_CMD_WUPA && len == 1) { // Received a WAKEUP
// DbpString(_YELLOW_("+") "WAKEUP Received");
p_response = &responses[RESP_INDEX_ATQA];
resp = 0;
} else if (receivedCmd[1] == 0x20 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT && len == 2) { // Received request for UID (cascade 1)
// DbpString(_YELLOW_("+") "Request for UID C1");
p_response = &responses[RESP_INDEX_UIDC1];
} else if (receivedCmd[1] == 0x70 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT && len == 9) { // Received a SELECT (cascade 1)
// DbpString(_YELLOW_("+") "Request for SELECT S1");
p_response = &responses[RESP_INDEX_SAKC1];
} else if (receivedCmd[0] == ISO14443A_CMD_RATS && len == 4) { // Received a RATS request
// DbpString(_YELLOW_("+") "Request for RATS");
p_response = &responses[RESP_INDEX_RATS];
resp = 1;
} else if (receivedCmd[0] == 0xf2 && len == 4) { // ACKed - Time extension
@ -352,8 +357,10 @@ void RunMod() {
DbpString(_YELLOW_("!!") " Avoiding request - Bluetooth data already in memory!!");
}
} else {
DbpString(_GREEN_("[ ") "Card reader command" _GREEN_(" ]"));
if (g_dbglevel == DBG_DEBUG ) {
DbpString("[ "_YELLOW_("Card reader command") " ]");
Dbhexdump(len - 2, &receivedCmd[1], false);
}
if ((receivedCmd[0] == 0x02 || receivedCmd[0] == 0x03) && len > 3) { // Process reader commands
@ -379,7 +386,7 @@ void RunMod() {
} else {
if (lenpacket == 0) {
DbpString(_YELLOW_("!!") "Received unknown command!");
DbpString(_RED_("Received unknown command!"));
memcpy(dynamic_response_info.response, receivedCmd, len);
dynamic_response_info.response_n = len;
} else {
@ -387,8 +394,9 @@ void RunMod() {
}
}
}
if (dynamic_response_info.response_n > 0) {
DbpString(_GREEN_("[ ") "Proxmark3 answer" _GREEN_(" ]"));
DbpString("[ " _GREEN_("Proxmark3 answer") " ]");
Dbhexdump(dynamic_response_info.response_n, dynamic_response_info.response, false);
DbpString("----");
if (lenpacket > 0) {
@ -402,7 +410,7 @@ void RunMod() {
if (prepare_tag_modulation(&dynamic_response_info, DYNAMIC_MODULATION_BUFFER_SIZE) == false) {
Dbprintf(_YELLOW_("[ ") "Buffer size: %d "_YELLOW_(" ]"), dynamic_response_info.response_n);
SpinDelay(500);
DbpString(_YELLOW_("!!") "Error preparing Proxmark to answer!");
DbpString(_RED_("Error preparing Proxmark to answer!"));
continue;
}
p_response = &dynamic_response_info;
@ -412,13 +420,15 @@ void RunMod() {
EmSendPrecompiledCmd(p_response);
}
}
switch_off();
switch_off();
set_tracing(false);
BigBuf_free_keep_EM();
reply_ng(CMD_HF_MIFARE_SIMULATE, retval, NULL, 0);
}
}
DbpString(_YELLOW_("[=]") "exiting");
DbpString("Exit standalone mode!");
DbpString("");
SpinErr(15, 200, 3);
LEDsoff();
}