mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
adapt a bit
This commit is contained in:
parent
3a1a09ef63
commit
ef348a2aa0
2 changed files with 119 additions and 65 deletions
|
@ -28,6 +28,7 @@
|
||||||
#include "iso14443a.h"
|
#include "iso14443a.h"
|
||||||
#include "protocols.h"
|
#include "protocols.h"
|
||||||
#include "cmd.h"
|
#include "cmd.h"
|
||||||
|
#include "commonutil.h"
|
||||||
|
|
||||||
void ModInfo(void) {
|
void ModInfo(void) {
|
||||||
DbpString(" HF - Reading VISA cards & Emulating a VISA MSD Transaction(ISO14443) - (Salvador Mendoza)");
|
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,
|
0x59, 0x2e, 0x53, 0x59, 0x53, 0x2e, 0x44, 0x44,
|
||||||
0x46, 0x30, 0x31, 0x00
|
0x46, 0x30, 0x31, 0x00
|
||||||
};
|
};
|
||||||
uint8_t visa[13] = {
|
|
||||||
0x00, 0xA4, 0x04, 0x00, 0x07, 0xa0, 0x00, 0x00,
|
uint8_t visa[] = { 0x00, 0xA4, 0x04, 0x00, 0x07, 0xa0, 0x00, 0x00, 0x00, 0x03, 0x10, 0x10, 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 processing [8] = {0x80, 0xA8, 0x00, 0x00, 0x02, 0x83, 0x00, 0x00};
|
||||||
uint8_t sfi[5] = {0x00, 0xb2, 0x01, 0x0c, 0x00};
|
uint8_t sfi[5] = {0x00, 0xb2, 0x01, 0x0c, 0x00};
|
||||||
|
@ -169,11 +192,16 @@ void RunMod(void) {
|
||||||
|
|
||||||
// - MSD token card format -
|
// - MSD token card format -
|
||||||
//
|
//
|
||||||
//Card number: 4412 3456 0578 1234
|
// Card number.............. 4412 3456 0578 1234
|
||||||
//Expiration date: 17/11
|
// Expiration date.......... 17/11
|
||||||
//Service code: 201
|
// Service code............. 201
|
||||||
//Discretionary data: 0000030000991
|
// 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};
|
// 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 ;)
|
// 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
|
// in case there is a read command received we shouldn't break
|
||||||
uint8_t data[PM3_CMD_DATA_SIZE] = {0x00};
|
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);
|
memcpy(data, visauid, 4);
|
||||||
|
|
||||||
// to initialize the emulation
|
// to initialize the emulation
|
||||||
|
@ -275,6 +303,10 @@ void RunMod(void) {
|
||||||
chktoken = false;
|
chktoken = false;
|
||||||
LED_C_OFF();
|
LED_C_OFF();
|
||||||
LED_B_ON();
|
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);
|
uint8_t apdulen = iso14_apdu(apdus[i], (uint16_t) apduslen[i], false, apdubuffer, NULL);
|
||||||
|
|
||||||
if (apdulen > 0) {
|
if (apdulen > 0) {
|
||||||
|
@ -289,8 +321,10 @@ void RunMod(void) {
|
||||||
|
|
||||||
// check for PDOL
|
// check for PDOL
|
||||||
if (apdubuffer[u] == 0x9F && apdubuffer[u + 1] == 0x38) {
|
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];
|
pdol[e] = apdubuffer[u + e + 2];
|
||||||
|
}
|
||||||
|
|
||||||
// generate a challenge
|
// generate a challenge
|
||||||
plen = treatPDOL(pdol);
|
plen = treatPDOL(pdol);
|
||||||
|
@ -425,12 +459,16 @@ void RunMod(void) {
|
||||||
// depending on card reader commands, the Proxmark will answer to fool the reader
|
// depending on card reader commands, the Proxmark will answer to fool the reader
|
||||||
// respond with PPSE
|
// respond with PPSE
|
||||||
if (receivedCmd[2] == 0xA4 && receivedCmd[6] == 0x32 && prevCmd == 0) {
|
if (receivedCmd[2] == 0xA4 && receivedCmd[6] == 0x32 && prevCmd == 0) {
|
||||||
|
// need to adapt lengths..
|
||||||
uint8_t ppsea[39] = {
|
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,
|
0x6F, 0x23, 0x84, 0x0E, 0x32, 0x50, 0x41, 0x59,
|
||||||
0x2E, 0x53, 0x59, 0x53, 0x2E, 0x44, 0x44, 0x46,
|
0x2E, 0x53, 0x59, 0x53, 0x2E, 0x44, 0x44, 0x46,
|
||||||
0x30, 0x31, 0xA5, 0x11, 0xBF, 0x0C, 0x0E, 0x61,
|
0x30, 0x31, 0xA5, 0x11, 0xBF, 0x0C, 0x0E, 0x61,
|
||||||
0x0C, 0x4F, 0x07, 0xA0, 0x00, 0x00, 0x00, 0x03,
|
0x0C, 0x4F,
|
||||||
0x10, 0x10, 0x87, 0x01, 0x01, 0x90, 0x00
|
// 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));
|
memcpy(&dynamic_response_info.response[1], ppsea, sizeof(ppsea));
|
||||||
dynamic_response_info.response_n = sizeof(ppsea) + 1;
|
dynamic_response_info.response_n = sizeof(ppsea) + 1;
|
||||||
|
@ -439,10 +477,14 @@ void RunMod(void) {
|
||||||
// respond Visa AID
|
// respond Visa AID
|
||||||
} else if (receivedCmd[2] == 0xA4 && receivedCmd[10] == 0x03 && receivedCmd[11] == 0x10 && prevCmd == 1) {
|
} else if (receivedCmd[2] == 0xA4 && receivedCmd[10] == 0x03 && receivedCmd[11] == 0x10 && prevCmd == 1) {
|
||||||
uint8_t visauid_long[34] = {
|
uint8_t visauid_long[34] = {
|
||||||
0x6F, 0x1E, 0x84, 0x07, 0xA0, 0x00, 0x00, 0x00,
|
// 0x1E = 30, skip two first bytes then the message - SW 2 is 30 = 0x1E
|
||||||
0x03, 0x10, 0x10, 0xA5, 0x13, 0x50, 0x0B, 0x56,
|
0x6F, 0x1E, 0x84,
|
||||||
0x49, 0x53, 0x41, 0x20, 0x43, 0x52, 0x45, 0x44,
|
// len aid0 aid1 aid2....
|
||||||
0x49, 0x54, 0x9F, 0x38, 0x03, 0x9F, 0x66, 0x02,
|
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
|
0x90, 0x00
|
||||||
};
|
};
|
||||||
memcpy(&dynamic_response_info.response[1], visauid_long, sizeof(visauid_long));
|
memcpy(&dynamic_response_info.response[1], visauid_long, sizeof(visauid_long));
|
||||||
|
@ -461,16 +503,18 @@ void RunMod(void) {
|
||||||
uint8_t card[25] = {
|
uint8_t card[25] = {
|
||||||
0x70, 0x15, 0x57, 0x13, 0x00, 0x00, 0x00, 0x00,
|
0x70, 0x15, 0x57, 0x13, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 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(&card[4], token, sizeof(token));
|
||||||
|
|
||||||
memcpy(&dynamic_response_info.response[1], card, sizeof(card));
|
memcpy(&dynamic_response_info.response[1], card, sizeof(card));
|
||||||
dynamic_response_info.response_n = sizeof(card) + 1;
|
dynamic_response_info.response_n = sizeof(card) + 1;
|
||||||
prevCmd++;
|
prevCmd++;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
uint8_t finished[2] = {0x6f, 0x00};
|
uint8_t finished[2] = {0x6F, 0x00};
|
||||||
memcpy(&dynamic_response_info.response[1], finished, sizeof(finished));
|
memcpy(&dynamic_response_info.response[1], finished, sizeof(finished));
|
||||||
dynamic_response_info.response_n = sizeof(finished) + 1;
|
dynamic_response_info.response_n = sizeof(finished) + 1;
|
||||||
if (prevCmd == 5) {
|
if (prevCmd == 5) {
|
||||||
|
@ -509,8 +553,8 @@ void RunMod(void) {
|
||||||
EmSendPrecompiledCmd(p_response);
|
EmSendPrecompiledCmd(p_response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch_off();
|
|
||||||
|
|
||||||
|
switch_off();
|
||||||
set_tracing(false);
|
set_tracing(false);
|
||||||
BigBuf_free_keep_EM();
|
BigBuf_free_keep_EM();
|
||||||
reply_ng(CMD_HF_MIFARE_SIMULATE, retval, NULL, 0);
|
reply_ng(CMD_HF_MIFARE_SIMULATE, retval, NULL, 0);
|
||||||
|
|
|
@ -73,29 +73,25 @@ void ModInfo(void) {
|
||||||
|
|
||||||
void RunMod() {
|
void RunMod() {
|
||||||
StandAloneMode();
|
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);
|
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);
|
memcpy(data, visauid, 4);
|
||||||
|
|
||||||
// to initialize the emulation
|
// to initialize the emulation
|
||||||
uint8_t tagType = 4; // 4 = ISO/IEC 14443-4 - javacard (JCOP)
|
|
||||||
tag_response_info_t *responses;
|
tag_response_info_t *responses;
|
||||||
|
|
||||||
uint32_t cuid = 0;
|
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
|
// For received Bluetooth package
|
||||||
uint8_t rpacket[MAX_FRAME_SIZE] = { 0x00 };
|
uint8_t rpacket[MAX_FRAME_SIZE] = { 0x00 };
|
||||||
|
@ -126,6 +122,12 @@ void RunMod() {
|
||||||
uint8_t receivedCmd[MAX_FRAME_SIZE] = { 0x00 };
|
uint8_t receivedCmd[MAX_FRAME_SIZE] = { 0x00 };
|
||||||
uint8_t receivedCmdPar[MAX_PARITY_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_response_buffer[DYNAMIC_RESPONSE_BUFFER_SIZE] = {0};
|
||||||
uint8_t dynamic_modulation_buffer[DYNAMIC_MODULATION_BUFFER_SIZE] = {0};
|
uint8_t dynamic_modulation_buffer[DYNAMIC_MODULATION_BUFFER_SIZE] = {0};
|
||||||
|
|
||||||
|
@ -143,9 +145,9 @@ void RunMod() {
|
||||||
uint8_t state = STATE_READ;
|
uint8_t state = STATE_READ;
|
||||||
|
|
||||||
if (state == STATE_READ) {
|
if (state == STATE_READ) {
|
||||||
DbpString(_YELLOW_("[ ") "In reading mode" _YELLOW_(" ]"));
|
DbpString("Initialized [ " _YELLOW_("reading mode") " ]");
|
||||||
} else {
|
} else {
|
||||||
DbpString(_YELLOW_("[ ") "In emulation mode" _YELLOW_(" ]"));
|
DbpString("Initialized [ " _BLUE_("emulation mode") " ]");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
@ -162,10 +164,10 @@ void RunMod() {
|
||||||
else if (button_pressed == BUTTON_SINGLE_CLICK) { // Pressing one time change between reading & emulation
|
else if (button_pressed == BUTTON_SINGLE_CLICK) { // Pressing one time change between reading & emulation
|
||||||
if (state == STATE_READ) {
|
if (state == STATE_READ) {
|
||||||
state = STATE_EMU;
|
state = STATE_EMU;
|
||||||
DbpString(_YELLOW_("[ ") "In emulation mode" _YELLOW_(" ]"));
|
DbpString("[ " _BLUE_("Emulation mode") " ]");
|
||||||
} else {
|
} else {
|
||||||
state = STATE_READ;
|
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);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
|
||||||
if (iso14443a_select_card(NULL, &card_a_info, NULL, true, 0, false)) {
|
if (iso14443a_select_card(NULL, &card_a_info, NULL, true, 0, false)) {
|
||||||
|
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
|
|
||||||
// Get data to send a ping with UID + ATQA + SAK
|
// Get data to send a ping with UID + ATQA + SAK
|
||||||
|
@ -208,7 +211,9 @@ void RunMod() {
|
||||||
Dbhexdump(uidlen + 4, rdata, false);
|
Dbhexdump(uidlen + 4, rdata, false);
|
||||||
|
|
||||||
DbpString(_YELLOW_("[ ") "Sending ping" _YELLOW_(" ]"));
|
DbpString(_YELLOW_("[ ") "Sending ping" _YELLOW_(" ]"));
|
||||||
|
|
||||||
if (usart_writebuffer_sync(rdata, uidlen + 4) == PM3_SUCCESS) {
|
if (usart_writebuffer_sync(rdata, uidlen + 4) == PM3_SUCCESS) {
|
||||||
|
|
||||||
DbpString(_YELLOW_("[ ") "Sent!" _YELLOW_(" ]"));
|
DbpString(_YELLOW_("[ ") "Sent!" _YELLOW_(" ]"));
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
@ -261,26 +266,31 @@ void RunMod() {
|
||||||
// free eventually allocated BigBuf memory but keep Emulator Memory
|
// free eventually allocated BigBuf memory but keep Emulator Memory
|
||||||
BigBuf_free_keep_EM();
|
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();
|
BigBuf_free_keep_EM();
|
||||||
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
|
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);
|
SpinDelay(500);
|
||||||
state = STATE_READ;
|
state = STATE_READ;
|
||||||
DbpString(_YELLOW_("[ ") "Initialized reading mode" _YELLOW_(" ]"));
|
DbpString("Initialized [ "_YELLOW_("reading mode") " ]");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need to listen to the high-frequency, peak-detected path.
|
// We need to listen to the high-frequency, peak-detected path.
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN);
|
||||||
|
|
||||||
int len = 0; // Command length
|
// Command length
|
||||||
int retval = PM3_SUCCESS; // Check emulation status
|
int len = 0;
|
||||||
|
// Check emulation status
|
||||||
|
int retval = PM3_SUCCESS;
|
||||||
|
|
||||||
uint8_t resp = 0; // Bluetooth response
|
// Bluetooth response
|
||||||
|
uint8_t resp = 0;
|
||||||
lenpacket = 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();
|
clear_trace();
|
||||||
set_tracing(true);
|
set_tracing(true);
|
||||||
|
@ -288,11 +298,12 @@ void RunMod() {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
// Clean receive command buffer
|
// Clean receive command buffer
|
||||||
if (!GetIso14443aCommandFromReader(receivedCmd, receivedCmdPar, &len)) {
|
if (GetIso14443aCommandFromReader(receivedCmd, receivedCmdPar, &len) == false) {
|
||||||
DbpString(_YELLOW_("!!") "Emulator stopped");
|
DbpString("Emulator stopped");
|
||||||
retval = PM3_EOPABORTED;
|
retval = PM3_EOPABORTED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
tag_response_info_t *p_response = NULL;
|
tag_response_info_t *p_response = NULL;
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
|
|
||||||
|
@ -314,46 +325,42 @@ void RunMod() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (receivedCmd[0] == ISO14443A_CMD_REQA && len == 1) { // Received a REQUEST
|
if (receivedCmd[0] == ISO14443A_CMD_REQA && len == 1) { // Received a REQUEST
|
||||||
// DbpString(_YELLOW_("+") "REQUEST Received");
|
|
||||||
p_response = &responses[RESP_INDEX_ATQA];
|
p_response = &responses[RESP_INDEX_ATQA];
|
||||||
} else if (receivedCmd[0] == ISO14443A_CMD_HALT && len == 4) { // Received a HALT
|
} else if (receivedCmd[0] == ISO14443A_CMD_HALT && len == 4) { // Received a HALT
|
||||||
// DbpString(_YELLOW_("+") "Received a HALT");
|
|
||||||
p_response = NULL;
|
p_response = NULL;
|
||||||
resp = 0;
|
resp = 0;
|
||||||
} else if (receivedCmd[0] == ISO14443A_CMD_WUPA && len == 1) { // Received a WAKEUP
|
} else if (receivedCmd[0] == ISO14443A_CMD_WUPA && len == 1) { // Received a WAKEUP
|
||||||
// DbpString(_YELLOW_("+") "WAKEUP Received");
|
|
||||||
p_response = &responses[RESP_INDEX_ATQA];
|
p_response = &responses[RESP_INDEX_ATQA];
|
||||||
resp = 0;
|
resp = 0;
|
||||||
} else if (receivedCmd[1] == 0x20 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT && len == 2) { // Received request for UID (cascade 1)
|
} 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];
|
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)
|
} 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];
|
p_response = &responses[RESP_INDEX_SAKC1];
|
||||||
} else if (receivedCmd[0] == ISO14443A_CMD_RATS && len == 4) { // Received a RATS request
|
} else if (receivedCmd[0] == ISO14443A_CMD_RATS && len == 4) { // Received a RATS request
|
||||||
// DbpString(_YELLOW_("+") "Request for RATS");
|
|
||||||
p_response = &responses[RESP_INDEX_RATS];
|
p_response = &responses[RESP_INDEX_RATS];
|
||||||
resp = 1;
|
resp = 1;
|
||||||
} else if (receivedCmd[0] == 0xf2 && len == 4) { // ACKed - Time extension
|
} 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;
|
p_response = NULL;
|
||||||
} else if ((receivedCmd[0] == 0xb2 || receivedCmd[0] == 0xb3) && len == 3) { //NACK - Request more time WTX
|
} 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) {
|
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_n = 2;
|
||||||
dynamic_response_info.response[0] = 0xf2;
|
dynamic_response_info.response[0] = 0xf2;
|
||||||
dynamic_response_info.response[1] = 0x0b; // Requesting the maximum amount of time
|
dynamic_response_info.response[1] = 0x0b; // Requesting the maximum amount of time
|
||||||
} else if (lenpacket == 0) {
|
} 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[0] = 0xa3;
|
||||||
dynamic_response_info.response_n = 1;
|
dynamic_response_info.response_n = 1;
|
||||||
} else {
|
} else {
|
||||||
DbpString(_YELLOW_("!!") "Avoiding request - Bluetooth data already in memory!!");
|
DbpString(_YELLOW_("!!") " Avoiding request - Bluetooth data already in memory!!");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DbpString(_GREEN_("[ ") "Card reader command" _GREEN_(" ]"));
|
if (g_dbglevel == DBG_DEBUG ) {
|
||||||
|
DbpString("[ "_YELLOW_("Card reader command") " ]");
|
||||||
Dbhexdump(len - 2, &receivedCmd[1], false);
|
Dbhexdump(len - 2, &receivedCmd[1], false);
|
||||||
|
}
|
||||||
|
|
||||||
if ((receivedCmd[0] == 0x02 || receivedCmd[0] == 0x03) && len > 3) { // Process reader commands
|
if ((receivedCmd[0] == 0x02 || receivedCmd[0] == 0x03) && len > 3) { // Process reader commands
|
||||||
|
|
||||||
|
@ -379,16 +386,17 @@ void RunMod() {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (lenpacket == 0) {
|
if (lenpacket == 0) {
|
||||||
DbpString(_YELLOW_("!!") "Received unknown command!");
|
DbpString(_RED_("Received unknown command!"));
|
||||||
memcpy(dynamic_response_info.response, receivedCmd, len);
|
memcpy(dynamic_response_info.response, receivedCmd, len);
|
||||||
dynamic_response_info.response_n = len;
|
dynamic_response_info.response_n = len;
|
||||||
} else {
|
} 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) {
|
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);
|
Dbhexdump(dynamic_response_info.response_n, dynamic_response_info.response, false);
|
||||||
DbpString("----");
|
DbpString("----");
|
||||||
if (lenpacket > 0) {
|
if (lenpacket > 0) {
|
||||||
|
@ -402,7 +410,7 @@ void RunMod() {
|
||||||
if (prepare_tag_modulation(&dynamic_response_info, DYNAMIC_MODULATION_BUFFER_SIZE) == false) {
|
if (prepare_tag_modulation(&dynamic_response_info, DYNAMIC_MODULATION_BUFFER_SIZE) == false) {
|
||||||
Dbprintf(_YELLOW_("[ ") "Buffer size: %d "_YELLOW_(" ]"), dynamic_response_info.response_n);
|
Dbprintf(_YELLOW_("[ ") "Buffer size: %d "_YELLOW_(" ]"), dynamic_response_info.response_n);
|
||||||
SpinDelay(500);
|
SpinDelay(500);
|
||||||
DbpString(_YELLOW_("!!") "Error preparing Proxmark to answer!");
|
DbpString(_RED_("Error preparing Proxmark to answer!"));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
p_response = &dynamic_response_info;
|
p_response = &dynamic_response_info;
|
||||||
|
@ -412,13 +420,15 @@ void RunMod() {
|
||||||
EmSendPrecompiledCmd(p_response);
|
EmSendPrecompiledCmd(p_response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch_off();
|
|
||||||
|
|
||||||
|
switch_off();
|
||||||
set_tracing(false);
|
set_tracing(false);
|
||||||
BigBuf_free_keep_EM();
|
BigBuf_free_keep_EM();
|
||||||
reply_ng(CMD_HF_MIFARE_SIMULATE, retval, NULL, 0);
|
reply_ng(CMD_HF_MIFARE_SIMULATE, retval, NULL, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DbpString(_YELLOW_("[=]") "exiting");
|
DbpString("Exit standalone mode!");
|
||||||
|
DbpString("");
|
||||||
|
SpinErr(15, 200, 3);
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue