mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 05:43:48 -07:00
rework simaid & rename few vars
This commit is contained in:
parent
0560d74b01
commit
1acc030fd4
8 changed files with 137 additions and 121 deletions
|
@ -445,7 +445,7 @@ void RunMod(void) {
|
|||
// received a RATS request
|
||||
} else if (receivedCmd[0] == ISO14443A_CMD_RATS && len == 4) {
|
||||
prevCmd = 0;
|
||||
p_response = &responses[RESP_INDEX_RATS];
|
||||
p_response = &responses[RESP_INDEX_ATS];
|
||||
|
||||
} else {
|
||||
if (g_dbglevel == DBG_DEBUG) {
|
||||
|
|
|
@ -338,7 +338,7 @@ void RunMod() {
|
|||
} else if (receivedCmd[1] == 0x70 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT && len == 9) { // Received a SELECT (cascade 1)
|
||||
p_response = &responses[RESP_INDEX_SAKC1];
|
||||
} else if (receivedCmd[0] == ISO14443A_CMD_RATS && len == 4) { // Received a RATS request
|
||||
p_response = &responses[RESP_INDEX_RATS];
|
||||
p_response = &responses[RESP_INDEX_ATS];
|
||||
resp = 1;
|
||||
} else if (receivedCmd[0] == 0xf2 && len == 4) { // ACKed - Time extension
|
||||
DbpString(_YELLOW_("!!") " Reader accepted time extension!");
|
||||
|
|
|
@ -247,7 +247,7 @@ void RunMod(void) {
|
|||
} else if (receivedCmd[1] == 0x70 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2 && len == 9) { // Received a SELECT (cascade 2)
|
||||
p_response = &responses[RESP_INDEX_SAKC2];
|
||||
} else if (receivedCmd[0] == ISO14443A_CMD_RATS && len == 4) { // Received a RATS request
|
||||
p_response = &responses[RESP_INDEX_RATS];
|
||||
p_response = &responses[RESP_INDEX_ATS];
|
||||
} else if (receivedCmd[0] == ISO14443A_CMD_PPS) {
|
||||
p_response = &responses[RESP_INDEX_PPS];
|
||||
} else {
|
||||
|
@ -425,7 +425,7 @@ void RunMod(void) {
|
|||
} else if (receivedCmd[1] == 0x70 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2 && len == 9) { // Received a SELECT (cascade 2)
|
||||
p_response = &responses[RESP_INDEX_SAKC2];
|
||||
} else if (receivedCmd[0] == ISO14443A_CMD_RATS && len == 4) { // Received a RATS request
|
||||
p_response = &responses[RESP_INDEX_RATS];
|
||||
p_response = &responses[RESP_INDEX_ATS];
|
||||
} else if (receivedCmd[0] == ISO14443A_CMD_PPS) {
|
||||
p_response = &responses[RESP_INDEX_PPS];
|
||||
} else {
|
||||
|
|
|
@ -1696,20 +1696,21 @@ static void PacketReceived(PacketCommandNG *packet) {
|
|||
uint8_t tagtype;
|
||||
uint16_t flags;
|
||||
uint8_t uid[10];
|
||||
uint8_t rats[20];
|
||||
uint8_t ats[20];
|
||||
uint8_t aid[30];
|
||||
uint8_t response[100];
|
||||
uint8_t apdu[100];
|
||||
int aid_len;
|
||||
int respond_len;
|
||||
int apdu_len;
|
||||
bool enumerate;
|
||||
uint8_t selectaid_response[100];
|
||||
uint8_t getdata_response[100];
|
||||
uint32_t ats_len;
|
||||
uint32_t aid_len;
|
||||
uint32_t selectaid_response_len;
|
||||
uint32_t getdata_response_len;
|
||||
} PACKED;
|
||||
struct p *payload = (struct p *) packet->data.asBytes;
|
||||
// ## Simulate iso14443a tag - pass tag type, UID, ATS, AID, responses
|
||||
SimulateIso14443aTagAID(payload->tagtype, payload->flags, payload->uid,
|
||||
payload->rats, sizeof(payload->rats), payload->aid, payload->response,
|
||||
payload->apdu, payload->aid_len, payload->respond_len,
|
||||
payload->apdu_len, payload->enumerate); // ## Simulate iso14443a tag - pass tag type, UID, rats, aid, resp, apdu
|
||||
payload->ats, payload->ats_len, payload->aid, payload->aid_len,
|
||||
payload->selectaid_response, payload->selectaid_response_len,
|
||||
payload->getdata_response, payload->getdata_response_len);
|
||||
break;
|
||||
}
|
||||
case CMD_HF_ISO14443A_ANTIFUZZ: {
|
||||
|
|
|
@ -1108,7 +1108,7 @@ bool prepare_allocated_tag_modulation(tag_response_info_t *response_info, uint8_
|
|||
}
|
||||
|
||||
bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data,
|
||||
uint8_t *iRATs, size_t irats_len, tag_response_info_t **responses,
|
||||
uint8_t *ats, size_t ats_len, tag_response_info_t **responses,
|
||||
uint32_t *cuid, uint32_t counters[3], uint8_t tearings[3], uint8_t *pages) {
|
||||
uint8_t sak = 0;
|
||||
// The first response contains the ATQA (note: bytes are transmitted in reverse order).
|
||||
|
@ -1130,9 +1130,9 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data,
|
|||
// TA(1) = 0x80: different divisors not supported, DR = 1, DS = 1
|
||||
// TB(1) = not present. Defaults: FWI = 4 (FWT = 256 * 16 * 2^4 * 1/fc = 4833us), SFGI = 0 (SFG = 256 * 16 * 2^0 * 1/fc = 302us)
|
||||
// TC(1) = 0x02: CID supported, NAD not supported
|
||||
// static uint8_t rRATS[] = { 0x04, 0x58, 0x80, 0x02, 0x00, 0x00 };
|
||||
static uint8_t rRATS[40] = { 0x05, 0x75, 0x80, 0x60, 0x02, 0x00, 0x00, 0x00 };
|
||||
uint8_t rRATS_len = 8;
|
||||
// static uint8_t rATS[] = { 0x04, 0x58, 0x80, 0x02, 0x00, 0x00 };
|
||||
static uint8_t rATS[40] = { 0x05, 0x75, 0x80, 0x60, 0x02, 0x00, 0x00, 0x00 };
|
||||
uint8_t rATS_len = 8;
|
||||
|
||||
// GET_VERSION response for EV1/NTAG
|
||||
static uint8_t rVERSION[10] = { 0x00 };
|
||||
|
@ -1184,8 +1184,8 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data,
|
|||
rATQA[0] = 0x44;
|
||||
rATQA[1] = 0x03;
|
||||
sak = 0x20;
|
||||
memcpy(rRATS, "\x06\x75\x77\x81\x02\x80\x00\x00", 8);
|
||||
rRATS_len = 8; // including CRC
|
||||
memcpy(rATS, "\x06\x75\x77\x81\x02\x80\x00\x00", 8);
|
||||
rATS_len = 8; // including CRC
|
||||
break;
|
||||
}
|
||||
case 4: { // ISO/IEC 14443-4 - javacard (JCOP)
|
||||
|
@ -1254,8 +1254,8 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data,
|
|||
}
|
||||
case 11: { // ISO/IEC 14443-4 - javacard (JCOP) / EMV
|
||||
|
||||
memcpy(rRATS, "\x13\x78\x80\x72\x02\x80\x31\x80\x66\xb1\x84\x0c\x01\x6e\x01\x83\x00\x90\x00\x00\x00", 21);
|
||||
rRATS_len = 21; // including CRC
|
||||
memcpy(rATS, "\x13\x78\x80\x72\x02\x80\x31\x80\x66\xb1\x84\x0c\x01\x6e\x01\x83\x00\x90\x00\x00\x00", 21);
|
||||
rATS_len = 21; // including CRC
|
||||
rATQA[0] = 0x04;
|
||||
sak = 0x20;
|
||||
break;
|
||||
|
@ -1271,17 +1271,17 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data,
|
|||
}
|
||||
}
|
||||
|
||||
// copy the iRATs if supplied.
|
||||
// iRATs is a pointer to 20 byte array
|
||||
// rRATS is a 40 byte array
|
||||
if ((flags & FLAG_RATS_IN_DATA) == FLAG_RATS_IN_DATA) {
|
||||
memcpy(rRATS, iRATs, irats_len);
|
||||
// copy the ats if supplied.
|
||||
// ats is a pointer to 20 byte array
|
||||
// rATS is a 40 byte array
|
||||
if ((flags & FLAG_ATS_IN_DATA) == FLAG_ATS_IN_DATA) {
|
||||
memcpy(rATS, ats, ats_len);
|
||||
// rats len is dictated by the first char of the string, add 2 crc bytes
|
||||
rRATS_len = (iRATs[0] + 2);
|
||||
rATS_len = (ats[0] + 2);
|
||||
// Since its Varible length we can send value > 40 and overflow our array.
|
||||
// Even if RATS protocol defined as max 40 bytes doesn't mean people try stuff
|
||||
if (rRATS_len > sizeof(rRATS)) {
|
||||
if (g_dbglevel >= DBG_ERROR) Dbprintf("[-] ERROR: iRATS overflow. Max %zu, got %zu", sizeof(rRATS), rRATS_len);
|
||||
if (rATS_len > sizeof(rATS)) {
|
||||
if (g_dbglevel >= DBG_ERROR) Dbprintf("[-] ERROR: ATS overflow. Max %zu, got %zu", sizeof(rATS), rATS_len);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1379,7 +1379,7 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data,
|
|||
return false;
|
||||
}
|
||||
|
||||
AddCrc14A(rRATS, rRATS_len - 2);
|
||||
AddCrc14A(rATS, rATS_len - 2);
|
||||
|
||||
AddCrc14A(rPPS, sizeof(rPPS) - 2);
|
||||
|
||||
|
@ -1407,7 +1407,7 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data,
|
|||
{ .response = rSAKc1, .response_n = sizeof(rSAKc1) }, // Acknowledge select - cascade 1
|
||||
{ .response = rSAKc2, .response_n = sizeof(rSAKc2) }, // Acknowledge select - cascade 2
|
||||
{ .response = rSAKc3, .response_n = sizeof(rSAKc3) }, // Acknowledge select - cascade 3
|
||||
{ .response = rRATS, .response_n = sizeof(rRATS) }, // dummy ATS (pseudo-ATR), answer to RATS
|
||||
{ .response = rATS, .response_n = sizeof(rATS) }, // dummy ATS (pseudo-ATR), answer to RATS
|
||||
{ .response = rVERSION, .response_n = sizeof(rVERSION) }, // EV1/NTAG GET_VERSION response
|
||||
{ .response = rSIGN, .response_n = sizeof(rSIGN) }, // EV1/NTAG READ_SIG response
|
||||
{ .response = rPPS, .response_n = sizeof(rPPS) }, // PPS response
|
||||
|
@ -1415,7 +1415,7 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data,
|
|||
};
|
||||
|
||||
// since rats len is variable now.
|
||||
responses_init[RESP_INDEX_RATS].response_n = rRATS_len;
|
||||
responses_init[RESP_INDEX_ATS].response_n = rATS_len;
|
||||
|
||||
// "precompiled" responses.
|
||||
// These exist for speed reasons. There are no time in the anti collision phase to calculate responses.
|
||||
|
@ -1428,7 +1428,7 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data,
|
|||
// 85 bytes normally (rats = 8 bytes)
|
||||
// 77 bytes + ratslen,
|
||||
|
||||
#define ALLOCATED_TAG_MODULATION_BUFFER_SIZE ( ((77 + rRATS_len) * 8) + 77 + rRATS_len + 12 + 12 + 12)
|
||||
#define ALLOCATED_TAG_MODULATION_BUFFER_SIZE ( ((77 + rATS_len) * 8) + 77 + rATS_len + 12 + 12 + 12)
|
||||
|
||||
uint8_t *free_buffer = BigBuf_calloc(ALLOCATED_TAG_MODULATION_BUFFER_SIZE);
|
||||
// modulation buffer pointer and current buffer free space size
|
||||
|
@ -1455,7 +1455,7 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data,
|
|||
// 'hf 14a sim'
|
||||
//-----------------------------------------------------------------------------
|
||||
void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *data, uint8_t exitAfterNReads,
|
||||
uint8_t *iRATs, size_t irats_len) {
|
||||
uint8_t *ats, size_t ats_len) {
|
||||
|
||||
#define ATTACK_KEY_COUNT 16
|
||||
|
||||
|
@ -1497,7 +1497,7 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *data, uint8_
|
|||
.modulation_n = 0
|
||||
};
|
||||
|
||||
if (SimulateIso14443aInit(tagType, flags, data, iRATs, irats_len, &responses, &cuid, counters, tearings, &pages) == false) {
|
||||
if (SimulateIso14443aInit(tagType, flags, data, ats, ats_len, &responses, &cuid, counters, tearings, &pages) == false) {
|
||||
BigBuf_free_keep_EM();
|
||||
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
|
||||
return;
|
||||
|
@ -1820,7 +1820,7 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *data, uint8_
|
|||
EmSend4bit(CARD_NACK_NA);
|
||||
p_response = NULL;
|
||||
} else {
|
||||
p_response = &responses[RESP_INDEX_RATS];
|
||||
p_response = &responses[RESP_INDEX_ATS];
|
||||
}
|
||||
} else if (receivedCmd[0] == MIFARE_ULC_AUTH_1) { // ULC authentication, or Desfire Authentication
|
||||
LogTrace(receivedCmd, Uart.len, Uart.startTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
|
||||
|
@ -3941,9 +3941,10 @@ It can also continue after the AID has been selected, and respond to other reque
|
|||
This was forked from the original function to allow for more flexibility in the future, and to increase the processing speed of the original function.
|
||||
/// */
|
||||
|
||||
void SimulateIso14443aTagAID(uint8_t tagType, uint16_t flags, uint8_t *data,
|
||||
uint8_t *iRATs, size_t irats_len, uint8_t *aid, uint8_t *resp,
|
||||
uint8_t *apdu, int aidLen, int respondLen, int apduLen, bool enumerate) {
|
||||
void SimulateIso14443aTagAID(uint8_t tagType, uint16_t flags, uint8_t *uid,
|
||||
uint8_t *ats, size_t ats_len, uint8_t *aid, size_t aid_len,
|
||||
uint8_t *selectaid_response, size_t selectaid_response_len,
|
||||
uint8_t *getdata_response, size_t getdata_response_len) {
|
||||
tag_response_info_t *responses;
|
||||
uint32_t cuid = 0;
|
||||
uint32_t counters[3] = { 0x00, 0x00, 0x00 };
|
||||
|
@ -3954,6 +3955,12 @@ void SimulateIso14443aTagAID(uint8_t tagType, uint16_t flags, uint8_t *data,
|
|||
uint8_t receivedCmd[MAX_FRAME_SIZE] = { 0x00 };
|
||||
uint8_t receivedCmdPar[MAX_PARITY_SIZE] = { 0x00 };
|
||||
|
||||
// Buffers must be provided by the caller, even if lengths are 0
|
||||
// Copy the AID, AID Response, and the GetData APDU response into our variables
|
||||
if ((aid == NULL) || (selectaid_response == NULL) || (getdata_response == NULL)) {
|
||||
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINVARG, NULL, 0);
|
||||
}
|
||||
|
||||
// free eventually allocated BigBuf memory but keep Emulator Memory
|
||||
BigBuf_free_keep_EM();
|
||||
|
||||
|
@ -3970,7 +3977,7 @@ void SimulateIso14443aTagAID(uint8_t tagType, uint16_t flags, uint8_t *data,
|
|||
.modulation_n = 0
|
||||
};
|
||||
|
||||
if (SimulateIso14443aInit(tagType, flags, data, iRATs, irats_len, &responses, &cuid, counters, tearings, &pages) == false) {
|
||||
if (SimulateIso14443aInit(tagType, flags, uid, ats, ats_len, &responses, &cuid, counters, tearings, &pages) == false) {
|
||||
BigBuf_free_keep_EM();
|
||||
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
|
||||
return;
|
||||
|
@ -3990,23 +3997,6 @@ void SimulateIso14443aTagAID(uint8_t tagType, uint16_t flags, uint8_t *data,
|
|||
set_tracing(true);
|
||||
LED_A_ON();
|
||||
|
||||
// Filters for when this comes through
|
||||
static uint8_t aidFilter[30] = { 0x00 }; // Default AID Value
|
||||
static uint8_t aidResponse[100] = { 0x00 }; // Default AID Response
|
||||
static uint8_t apduCommand [100] = { 0x00 }; // Default APDU GetData Response
|
||||
|
||||
// Copy the AID, AID Response, and the GetData APDU response into our variables
|
||||
if (aid != 0) {
|
||||
memcpy(aidFilter, aid, aidLen);
|
||||
}
|
||||
if (resp != 0) {
|
||||
memcpy(aidResponse, resp, respondLen);
|
||||
}
|
||||
if (apdu != 0) {
|
||||
memcpy(apduCommand, apdu, apduLen);
|
||||
}
|
||||
|
||||
|
||||
// main loop
|
||||
bool finished = false;
|
||||
bool got_rats = false;
|
||||
|
@ -4051,7 +4041,7 @@ void SimulateIso14443aTagAID(uint8_t tagType, uint16_t flags, uint8_t *data,
|
|||
finished = true;
|
||||
}
|
||||
} else if (receivedCmd[0] == ISO14443A_CMD_RATS && len == 4) { // Received a RATS request
|
||||
p_response = &responses[RESP_INDEX_RATS];
|
||||
p_response = &responses[RESP_INDEX_ATS];
|
||||
got_rats = true;
|
||||
} else {
|
||||
// clear old dynamic responses
|
||||
|
@ -4081,19 +4071,19 @@ void SimulateIso14443aTagAID(uint8_t tagType, uint16_t flags, uint8_t *data,
|
|||
// xx in this case is len of the AID value in hex
|
||||
|
||||
// aid len is found as a hex value in receivedCmd[6] (Index Starts at 0)
|
||||
int aid_len = receivedCmd[5+offset];
|
||||
int received_aid_len = receivedCmd[5+offset];
|
||||
uint8_t *received_aid = &receivedCmd[6+offset];
|
||||
|
||||
// aid enumeration flag
|
||||
if (enumerate == true) {
|
||||
Dbprintf("Received AID (%d):", aid_len);
|
||||
Dbhexdump(aid_len, received_aid, false);
|
||||
if ((flags & FLAG_ENUMERATE_AID) == FLAG_ENUMERATE_AID) {
|
||||
Dbprintf("Received AID (%d):", received_aid_len);
|
||||
Dbhexdump(received_aid_len, received_aid, false);
|
||||
}
|
||||
|
||||
if (memcmp(aidFilter, received_aid, aid_len) == 0) { // Evaluate the AID sent by the Reader to the AID supplied
|
||||
if ((received_aid_len == aid_len) && (memcmp(aid, received_aid, aid_len) == 0)) { // Evaluate the AID sent by the Reader to the AID supplied
|
||||
// AID Response will be parsed here
|
||||
memcpy(dynamic_response_info.response + 1 + offset, aidResponse, respondLen + 1 + offset);
|
||||
dynamic_response_info.response_n = respondLen + 2;
|
||||
memcpy(dynamic_response_info.response + 1 + offset, selectaid_response, selectaid_response_len + 1 + offset);
|
||||
dynamic_response_info.response_n = selectaid_response_len + 2;
|
||||
} else { // Any other SELECT FILE command will return with a Not Found
|
||||
dynamic_response_info.response[1 + offset] = 0x6A;
|
||||
dynamic_response_info.response[2 + offset] = 0x82;
|
||||
|
@ -4113,8 +4103,8 @@ void SimulateIso14443aTagAID(uint8_t tagType, uint16_t flags, uint8_t *data,
|
|||
case 0xCA: { // GET DATA
|
||||
if (sentCount == 0) {
|
||||
// APDU Command will just be parsed here
|
||||
memcpy(dynamic_response_info.response + 1 + offset, apduCommand, apduLen + 2);
|
||||
dynamic_response_info.response_n = respondLen + 1 + offset;
|
||||
memcpy(dynamic_response_info.response + 1 + offset, getdata_response, getdata_response_len + 2);
|
||||
dynamic_response_info.response_n = selectaid_response_len + 1 + offset;
|
||||
} else {
|
||||
finished = true;
|
||||
break;
|
||||
|
|
|
@ -105,7 +105,7 @@ typedef enum {
|
|||
RESP_INDEX_SAKC1,
|
||||
RESP_INDEX_SAKC2,
|
||||
RESP_INDEX_SAKC3,
|
||||
RESP_INDEX_RATS,
|
||||
RESP_INDEX_ATS,
|
||||
RESP_INDEX_VERSION,
|
||||
RESP_INDEX_SIGNATURE,
|
||||
RESP_INDEX_PPS,
|
||||
|
@ -145,9 +145,10 @@ void RAMFUNC SniffIso14443a(uint8_t param);
|
|||
void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *data, uint8_t exitAfterNReads,
|
||||
uint8_t *iRATs, size_t irats_len);
|
||||
|
||||
void SimulateIso14443aTagAID(uint8_t tagType, uint16_t flags, uint8_t *data,
|
||||
uint8_t *iRATs, size_t irats_len, uint8_t *aid, uint8_t *resp,
|
||||
uint8_t *apdu, int aid_len, int respond_len, int apdu_len, bool enumerate);
|
||||
void SimulateIso14443aTagAID(uint8_t tagType, uint16_t flags, uint8_t *uid,
|
||||
uint8_t *ats, size_t ats_len, uint8_t *aid, size_t aid_len,
|
||||
uint8_t *selectaid_response, size_t selectaid_response_len,
|
||||
uint8_t *getdata_response, size_t getdata_response_len);
|
||||
|
||||
bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data,
|
||||
uint8_t *iRATs, size_t irats_len, tag_response_info_t **responses,
|
||||
|
|
|
@ -3715,58 +3715,61 @@ int CmdHF14AAIDSim(const char *Cmd) {
|
|||
CLIParserInit(&ctx, "hf 14a simaid",
|
||||
"Simulate ISO/IEC 14443 type A tag with 4,7 or 10 byte UID, and filter for AID Values\n"
|
||||
"These AID Values can be responded to and include extra APDU commands on GetData after response\n",
|
||||
"hf 14a simaid -t 3 -> MIFARE Desfire\n"
|
||||
"hf 14a simaid -t 4 -> ISO/IEC 14443-4\n"
|
||||
"hf 14a simaid -t 11 -> Javacard (JCOP)\n"
|
||||
"hf 14a simaid -t 3 --aid a000000000000000000000 --response 9000 --apdu 9000 -> AID, Response and APDU\n"
|
||||
"hf 14a simaid -t 3 --rats 05788172220101 --response 01009000 --apdu 86009000 -> Custom RATS Added\n"
|
||||
"hf 14a simaid -t 3 --rats 05788172220101 -x -> Enumerate AID Values\n"
|
||||
"hf 14a simaid -t 3 -> MIFARE Desfire\n"
|
||||
"hf 14a simaid -t 4 -> ISO/IEC 14443-4\n"
|
||||
"hf 14a simaid -t 11 -> Javacard (JCOP)\n"
|
||||
"hf 14a simaid -t 3 --aid a000000000000000000000 --selectaid_response 9000 --getdata_response 9000 -> Custom AID and responses\n"
|
||||
"hf 14a simaid -t 3 --ats 05788172220101 --selectaid_response 01009000 --getdata_response 86009000 -> Custom ATS and responses\n"
|
||||
"hf 14a simaid -t 3 --ats 05788172220101 -x -> Enumerate AID Values\n"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_int1("t", "type", "<1-12> ", "Simulation type to use"),
|
||||
arg_str0("u", "uid", "<hex>", "<4|7|10> hex bytes UID"),
|
||||
arg_str0("r", "rats", "<hex>", "<0-20> hex bytes RATS"),
|
||||
arg_str0("a", "aid", "<hex>", "<0-100> hex bytes for AID to respond to (Default: A000000000000000000000)"),
|
||||
arg_str0("e", "response", "<hex>", "<0-100> hex bytes for APDU Response to AID Select (Default: 9000)"),
|
||||
arg_str0("p", "apdu", "<hex>", "<0-100> hex bytes for APDU Response to Get Data request after AID (Default: 9000)"),
|
||||
arg_str0("r", "ats", "<hex>", "<0-20> hex bytes ATS"),
|
||||
arg_str0("a", "aid", "<hex>", "<0-30> hex bytes for AID to respond to (Default: A000000000000000000000)"),
|
||||
arg_str0("e", "selectaid_response", "<hex>", "<0-100> hex bytes for APDU Response to AID Select (Default: 9000)"),
|
||||
arg_str0("p", "getdata_response", "<hex>", "<0-100> hex bytes for APDU Response to Get Data request after AID (Default: 9000)"),
|
||||
arg_lit0("x", "enumerate", "Enumerate all AID values via returning Not Found and print them to console "),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
int tagtype = arg_get_int_def(ctx, 1, 1);
|
||||
|
||||
bool enumerate = arg_get_lit(ctx, 7);
|
||||
|
||||
int uid_len = 0;
|
||||
int rats_len = 0;
|
||||
int ats_len = 0;
|
||||
int aid_len = 0;
|
||||
int respond_len = 0;
|
||||
int apdu_len = 0;
|
||||
int selectaid_response_len = 0;
|
||||
int getdata_response_len = 0;
|
||||
|
||||
uint8_t uid[10] = {0};
|
||||
uint8_t rats[20] = {0};
|
||||
uint8_t aid[30] = {0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
uint8_t response[100] = {0x90, 0x00};
|
||||
uint8_t apdu[100] = {0x90, 0x00};
|
||||
uint8_t ats[20] = {0};
|
||||
uint8_t aid[30] = {0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
uint8_t default_aid_len = 11;
|
||||
uint8_t selectaid_response[100] = {0x90, 0x00};
|
||||
uint8_t default_selectaid_response_len = 2;
|
||||
uint8_t getdata_response[100] = {0x90, 0x00};
|
||||
uint8_t default_getdata_response_len = 2;
|
||||
|
||||
int tagtype = arg_get_int_def(ctx, 1, 1);
|
||||
CLIGetHexWithReturn(ctx, 2, uid, &uid_len);
|
||||
CLIGetHexWithReturn(ctx, 3, rats, &rats_len);
|
||||
CLIGetHexWithReturn(ctx, 3, ats, &ats_len);
|
||||
CLIGetHexWithReturn(ctx, 4, aid, &aid_len);
|
||||
CLIGetHexWithReturn(ctx, 5, response, &respond_len);
|
||||
CLIGetHexWithReturn(ctx, 6, apdu, &apdu_len);
|
||||
CLIGetHexWithReturn(ctx, 5, selectaid_response, &selectaid_response_len);
|
||||
CLIGetHexWithReturn(ctx, 6, getdata_response, &getdata_response_len);
|
||||
bool enumerate = arg_get_lit(ctx, 7);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
// default value fill for the AID, response, and apdu
|
||||
// default value fill for the AID, selectaid_response, and getdata_response
|
||||
if (aid_len == 0) {
|
||||
aid_len = 11;
|
||||
aid_len = default_aid_len;
|
||||
}
|
||||
if (respond_len == 0) {
|
||||
respond_len = 2;
|
||||
|
||||
if (selectaid_response_len == 0) {
|
||||
selectaid_response_len = default_selectaid_response_len;
|
||||
}
|
||||
if (apdu_len == 0) {
|
||||
apdu_len = 2;
|
||||
if (getdata_response_len == 0) {
|
||||
getdata_response_len = default_getdata_response_len;
|
||||
}
|
||||
|
||||
uint16_t flags = 0;
|
||||
|
@ -3776,19 +3779,39 @@ int CmdHF14AAIDSim(const char *Cmd) {
|
|||
FLAG_SET_UID_IN_DATA(flags, uid_len);
|
||||
if (IS_FLAG_UID_IN_EMUL(flags)) {
|
||||
PrintAndLogEx(ERR, "Please specify a 4, 7, or 10 byte UID");
|
||||
CLIParserFree(ctx);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
PrintAndLogEx(SUCCESS, "Emulating " _YELLOW_("ISO/IEC 14443 type A tag")" with " _GREEN_("%d byte UID (%s)"), uid_len, sprint_hex(uid, uid_len));
|
||||
useUIDfromEML = false;
|
||||
}
|
||||
|
||||
if (rats_len > 0) {
|
||||
flags |= FLAG_RATS_IN_DATA;
|
||||
if (ats_len > sizeof(ats)) {
|
||||
PrintAndLogEx(ERR, "Provided ATS too long");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
if (aid_len > sizeof(aid)) {
|
||||
PrintAndLogEx(ERR, "Provided AID too long");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
CLIParserFree(ctx);
|
||||
if (selectaid_response_len > sizeof(selectaid_response)) {
|
||||
PrintAndLogEx(ERR, "Provided SelectAID response too long");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
if (getdata_response_len > sizeof(getdata_response)) {
|
||||
PrintAndLogEx(ERR, "Provided GetData response too long");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
if (ats_len > 0) {
|
||||
flags |= FLAG_ATS_IN_DATA;
|
||||
}
|
||||
|
||||
if (enumerate) {
|
||||
flags |= FLAG_ENUMERATE_AID;
|
||||
}
|
||||
|
||||
if (tagtype > 12) {
|
||||
PrintAndLogEx(ERR, "Undefined tag %d", tagtype);
|
||||
|
@ -3803,31 +3826,31 @@ int CmdHF14AAIDSim(const char *Cmd) {
|
|||
uint8_t tagtype;
|
||||
uint16_t flags;
|
||||
uint8_t uid[10];
|
||||
uint8_t rats[20];
|
||||
uint8_t ats[20];
|
||||
uint8_t aid[30];
|
||||
uint8_t response[100];
|
||||
uint8_t apdu[100];
|
||||
int aid_len;
|
||||
int respond_len;
|
||||
int apdu_len;
|
||||
bool enumerate;
|
||||
uint8_t selectaid_response[100];
|
||||
uint8_t getdata_response[100];
|
||||
uint32_t ats_len;
|
||||
uint32_t aid_len;
|
||||
uint32_t selectaid_response_len;
|
||||
uint32_t getdata_response_len;
|
||||
} PACKED payload;
|
||||
|
||||
payload.tagtype = tagtype;
|
||||
payload.flags = flags;
|
||||
payload.enumerate = enumerate;
|
||||
|
||||
// Copy data to payload
|
||||
memcpy(payload.uid, uid, uid_len);
|
||||
memcpy(payload.rats, rats, rats_len);
|
||||
memcpy(payload.ats, ats, ats_len);
|
||||
memcpy(payload.aid, aid, aid_len);
|
||||
memcpy(payload.response, response, respond_len);
|
||||
memcpy(payload.apdu, apdu, apdu_len);
|
||||
memcpy(payload.selectaid_response, selectaid_response, selectaid_response_len);
|
||||
memcpy(payload.getdata_response, getdata_response, getdata_response_len);
|
||||
|
||||
// copy the lengths data to the payload
|
||||
memcpy(&payload.aid_len, &aid_len, sizeof(aid_len));
|
||||
memcpy(&payload.respond_len, &respond_len, sizeof(respond_len));
|
||||
memcpy(&payload.apdu_len, &apdu_len, sizeof(apdu_len));
|
||||
payload.ats_len = ats_len;
|
||||
payload.aid_len = aid_len;
|
||||
payload.selectaid_response_len = selectaid_response_len;
|
||||
payload.getdata_response_len = getdata_response_len;
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommandNG(CMD_HF_ISO14443A_SIM_AID, (uint8_t *)&payload, sizeof(payload));
|
||||
|
|
|
@ -772,7 +772,8 @@ typedef struct {
|
|||
#define FLAG_INTERACTIVE 0x0001
|
||||
#define FLAG_ATQA_IN_DATA 0x0002
|
||||
#define FLAG_SAK_IN_DATA 0x0004
|
||||
#define FLAG_RATS_IN_DATA 0x0008
|
||||
#define FLAG_ATS_IN_DATA 0x0008
|
||||
#define FLAG_ENUMERATE_AID 0x0010
|
||||
|
||||
// internal constants, use the function macros instead
|
||||
#define FLAG_MASK_UID 0x0030
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue