From ef348a2aa01d2845a664fa14a7d985bb8a56ef1b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 12 Oct 2023 14:51:18 +0200 Subject: [PATCH] adapt a bit --- armsrc/Standalone/hf_msdsal.c | 84 +++++++++++++++++++++------- armsrc/Standalone/hf_reblay.c | 100 +++++++++++++++++++--------------- 2 files changed, 119 insertions(+), 65 deletions(-) diff --git a/armsrc/Standalone/hf_msdsal.c b/armsrc/Standalone/hf_msdsal.c index 18729cdc0..b382a9fc3 100644 --- a/armsrc/Standalone/hf_msdsal.c +++ b/armsrc/Standalone/hf_msdsal.c @@ -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,11 +192,16 @@ void RunMod(void) { // - MSD token card format - // - //Card number: 4412 3456 0578 1234 - //Expiration date: 17/11 - //Service code: 201 - //Discretionary data: 0000030000991 - //char token[19] = {0x44,0x12,0x34,0x56,0x05,0x78,0x12,0x34,0xd1,0x71,0x12,0x01,0x00,0x00,0x03,0x00,0x00,0x99,0x1f}; + // 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); diff --git a/armsrc/Standalone/hf_reblay.c b/armsrc/Standalone/hf_reblay.c index cf290fa31..497d215a3 100644 --- a/armsrc/Standalone/hf_reblay.c +++ b/armsrc/Standalone/hf_reblay.c @@ -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,46 +325,42 @@ 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 - DbpString(_YELLOW_("!!") "Reader accepted time extension!"); + DbpString(_YELLOW_("!!") " Reader accepted time extension!"); p_response = NULL; } else if ((receivedCmd[0] == 0xb2 || receivedCmd[0] == 0xb3) && len == 3) { //NACK - Request more time WTX - DbpString(_YELLOW_("!!") "NACK - time extension request?"); + DbpString(_YELLOW_("!!") " NACK - time extension request?"); if (resp == 2 && lenpacket == 0) { - DbpString(_YELLOW_("!!") "Requesting more time - WTX"); + DbpString(_YELLOW_("!!") " Requesting more time - WTX"); dynamic_response_info.response_n = 2; dynamic_response_info.response[0] = 0xf2; dynamic_response_info.response[1] = 0x0b; // Requesting the maximum amount of time } else if (lenpacket == 0) { - DbpString(_YELLOW_("!!") "NACK - ACK - Resend last command!"); // To burn some time as well + DbpString(_YELLOW_("!!") " NACK - ACK - Resend last command!"); // To burn some time as well dynamic_response_info.response[0] = 0xa3; dynamic_response_info.response_n = 1; } else { - DbpString(_YELLOW_("!!") "Avoiding request - Bluetooth data already in memory!!"); + DbpString(_YELLOW_("!!") " Avoiding request - Bluetooth data already in memory!!"); } } else { - DbpString(_GREEN_("[ ") "Card reader command" _GREEN_(" ]")); - Dbhexdump(len - 2, &receivedCmd[1], false); + 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,16 +386,17 @@ 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 { - DbpString(_YELLOW_("!!") "Avoiding unknown command - Bluetooth data already in memory!!"); + DbpString(_YELLOW_("!!") " Avoiding unknown command - Bluetooth data already in memory !!"); } } } + 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(); }