X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/50193c1e3eb7f904bdc4be84618b1b045539597b..14006804dd8e68db2a877e0ee588f10a1b178caf:/client/cmdhf14a.c diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 46cfbebe..5937fcad 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include "util.h" #include "iso14443crc.h" #include "data.h" @@ -22,8 +22,6 @@ #include "cmdhf14a.h" #include "common.h" #include "cmdmain.h" -#include "nonce2key/nonce2key.h" -#include "nonce2key/crapto1.h" static int CmdHelp(const char *Cmd); @@ -159,449 +157,13 @@ void iso14a_set_timeout(uint32_t timeout) { SendCommand(&c); } -int CmdHF14AMifare(const char *Cmd) -{ - uint32_t uid = 0; - uint32_t nt = 0; - uint64_t par_list = 0, ks_list = 0, r_key = 0; - uint8_t isOK = 0; - - UsbCommand c = {CMD_READER_MIFARE, {strtol(Cmd, NULL, 0), 0, 0}}; - SendCommand(&c); - - //flush queue - while (kbhit()) getchar(); - while (WaitForResponseTimeout(CMD_ACK, 500) != NULL) ; - - // message - printf("-------------------------------------------------------------------------\n"); - printf("Executing command. It may take up to 30 min.\n"); - printf("Press the key on proxmark3 device to abort proxmark3.\n"); - printf("Press the key on the proxmark3 device to abort both proxmark3 and client.\n"); - printf("-------------------------------------------------------------------------\n"); - - // wait cycle - while (true) { - printf("."); - if (kbhit()) { - getchar(); - printf("\naborted via keyboard!\n"); - break; - } - - UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 2000); - if (resp != NULL) { - isOK = resp->arg[0] & 0xff; - - uid = (uint32_t)bytes_to_num(resp->d.asBytes + 0, 4); - nt = (uint32_t)bytes_to_num(resp->d.asBytes + 4, 4); - par_list = bytes_to_num(resp->d.asBytes + 8, 8); - ks_list = bytes_to_num(resp->d.asBytes + 16, 8); - - printf("\n\n"); - PrintAndLog("isOk:%02x", isOK); - if (!isOK) PrintAndLog("Proxmark can't get statistic info. Execution aborted.\n"); - break; - } - } - printf("\n"); - - // error - if (isOK != 1) return 1; - - // execute original function from util nonce2key - if (nonce2key(uid, nt, par_list, ks_list, &r_key)) return 2; - printf("-------------------------------------------------------------------------\n"); - PrintAndLog("Key found:%012llx \n", r_key); - - return 0; -} - -int CmdHF14AMfWrBl(const char *Cmd) -{ - int i, temp; - uint8_t blockNo = 0; - uint8_t keyType = 0; - uint8_t key[6] = {0, 0, 0, 0, 0, 0}; - uint8_t bldata[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - - const char *cmdp = Cmd; - const char *cmdpe = Cmd; - - if (strlen(Cmd)<3) { - PrintAndLog("Usage: hf 14 mfwrbl "); - PrintAndLog(" sample: hf 14a mfwrbl 0 A FFFFFFFFFFFF 000102030405060708090A0B0C0D0E0F"); - return 0; - } - PrintAndLog("l: %s", Cmd); - - // skip spaces - while (*cmdp==' ' || *cmdp=='\t') cmdp++; - blockNo = strtol(cmdp, NULL, 0) & 0xff; - - // next value - while (*cmdp!=' ' && *cmdp!='\t') cmdp++; - while (*cmdp==' ' || *cmdp=='\t') cmdp++; - if (*cmdp != 'A' && *cmdp != 'a') { - keyType = 1; - } - - // next value - while (*cmdp!=' ' && *cmdp!='\t') cmdp++; - while (*cmdp==' ' || *cmdp=='\t') cmdp++; - - // next value here:cmdpe - cmdpe = cmdp; - while (*cmdpe!=' ' && *cmdpe!='\t') cmdpe++; - while (*cmdpe==' ' || *cmdpe=='\t') cmdpe++; - - if ((int)cmdpe - (int)cmdp != 13) { - PrintAndLog("Length of key must be 12 hex symbols"); - return 0; - } - - for(i = 0; i < 6; i++) { - sscanf((char[]){cmdp[0],cmdp[1],0},"%X",&temp); - key[i] = temp & 0xff; - cmdp++; - cmdp++; - } - - // next value - while (*cmdp!=' ' && *cmdp!='\t') cmdp++; - while (*cmdp==' ' || *cmdp=='\t') cmdp++; - - if (strlen(cmdp) != 32) { - PrintAndLog("Length of block data must be 32 hex symbols"); - return 0; - } - - for(i = 0; i < 16; i++) { - sscanf((char[]){cmdp[0],cmdp[1],0},"%X",&temp); - bldata[i] = temp & 0xff; - cmdp++; - cmdp++; - } - PrintAndLog(" block no:%02x key type:%02x key:%s", blockNo, keyType, sprint_hex(key, 6)); - PrintAndLog(" data: %s", sprint_hex(bldata, 16)); - - UsbCommand c = {CMD_MIFARE_WRITEBL, {blockNo, keyType, 0}}; - memcpy(c.d.asBytes, key, 6); - memcpy(c.d.asBytes + 10, bldata, 16); - SendCommand(&c); - UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500); - - if (resp != NULL) { - uint8_t isOK = resp->arg[0] & 0xff; - - PrintAndLog("isOk:%02x", isOK); - } else { - PrintAndLog("Command execute timeout"); - } - - return 0; -} - -int CmdHF14AMfRdBl(const char *Cmd) -{ - int i, temp; - uint8_t blockNo = 0; - uint8_t keyType = 0; - uint8_t key[6] = {0, 0, 0, 0, 0, 0}; - - const char *cmdp = Cmd; - - - if (strlen(Cmd)<3) { - PrintAndLog("Usage: hf 14 mfrdbl "); - PrintAndLog(" sample: hf 14a mfrdbl 0 A FFFFFFFFFFFF "); - return 0; - } - - // skip spaces - while (*cmdp==' ' || *cmdp=='\t') cmdp++; - blockNo = strtol(cmdp, NULL, 0) & 0xff; - - // next value - while (*cmdp!=' ' && *cmdp!='\t') cmdp++; - while (*cmdp==' ' || *cmdp=='\t') cmdp++; - if (*cmdp != 'A' && *cmdp != 'a') { - keyType = 1; - } - - // next value - while (*cmdp!=' ' && *cmdp!='\t') cmdp++; - while (*cmdp==' ' || *cmdp=='\t') cmdp++; - - if (strlen(cmdp) != 12) { - PrintAndLog("Length of key must be 12 hex symbols"); - return 0; - } - - for(i = 0; i < 6; i++) { - sscanf((char[]){cmdp[0],cmdp[1],0},"%X",&temp); - key[i] = temp & 0xff; - cmdp++; - cmdp++; - } - PrintAndLog(" block no:%02x key type:%02x key:%s ", blockNo, keyType, sprint_hex(key, 6)); - - UsbCommand c = {CMD_MIFARE_READBL, {blockNo, keyType, 0}}; - memcpy(c.d.asBytes, key, 6); - SendCommand(&c); - UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500); - - if (resp != NULL) { - uint8_t isOK = resp->arg[0] & 0xff; - uint8_t * data = resp->d.asBytes; - - PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 16)); - } else { - PrintAndLog("Command execute timeout"); - } - - return 0; -} - -int CmdHF14AMfRdSc(const char *Cmd) -{ - int i, temp; - uint8_t sectorNo = 0; - uint8_t keyType = 0; - uint8_t key[6] = {0, 0, 0, 0, 0, 0}; - - const char *cmdp = Cmd; - - - if (strlen(Cmd)<3) { - PrintAndLog("Usage: hf 14 mfrdsc "); - PrintAndLog(" sample: hf 14a mfrdsc 0 A FFFFFFFFFFFF "); - return 0; - } - - // skip spaces - while (*cmdp==' ' || *cmdp=='\t') cmdp++; - sectorNo = strtol(cmdp, NULL, 0) & 0xff; - - // next value - while (*cmdp!=' ' && *cmdp!='\t') cmdp++; - while (*cmdp==' ' || *cmdp=='\t') cmdp++; - if (*cmdp != 'A' && *cmdp != 'a') { - keyType = 1; - } - - // next value - while (*cmdp!=' ' && *cmdp!='\t') cmdp++; - while (*cmdp==' ' || *cmdp=='\t') cmdp++; - - if (strlen(cmdp) != 12) { - PrintAndLog("Length of key must be 12 hex symbols"); - return 0; - } - - for(i = 0; i < 6; i++) { - sscanf((char[]){cmdp[0],cmdp[1],0},"%X",&temp); - key[i] = temp & 0xff; - cmdp++; - cmdp++; - } - PrintAndLog(" sector no:%02x key type:%02x key:%s ", sectorNo, keyType, sprint_hex(key, 6)); - - UsbCommand c = {CMD_MIFARE_READSC, {sectorNo, keyType, 0}}; - memcpy(c.d.asBytes, key, 6); - SendCommand(&c); - UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500); - PrintAndLog(" "); - - if (resp != NULL) { - uint8_t isOK = resp->arg[0] & 0xff; - uint8_t * data = resp->d.asBytes; - - PrintAndLog("isOk:%02x", isOK); - for (i = 0; i < 2; i++) { - PrintAndLog("data:%s", sprint_hex(data + i * 16, 16)); - } - } else { - PrintAndLog("Command1 execute timeout"); - } - - // response2 - resp = WaitForResponseTimeout(CMD_ACK, 500); - PrintAndLog(" "); - - if (resp != NULL) { - uint8_t * data = resp->d.asBytes; - - for (i = 0; i < 2; i++) { - PrintAndLog("data:%s", sprint_hex(data + i * 16, 16)); - } - } else { - PrintAndLog("Command2 execute timeout"); - } - - return 0; -} - -int CmdHF14AMfNested(const char *Cmd) -{ - int i, temp, len; - uint8_t sectorNo = 0; - uint8_t keyType = 0; - uint8_t key[6] = {0, 0, 0, 0, 0, 0}; - uint8_t isEOF; - uint8_t * data; - uint32_t uid; - fnVector * vector = NULL; - int lenVector = 0; - UsbCommand * resp = NULL; - - const char *cmdp = Cmd; - - if (strlen(Cmd)<3) { - PrintAndLog("Usage: hf 14a nested "); - PrintAndLog(" sample: hf 14a nested 0 A FFFFFFFFFFFF "); - return 0; - } - - // skip spaces - while (*cmdp==' ' || *cmdp=='\t') cmdp++; - sectorNo = strtol(cmdp, NULL, 0) & 0xff; - - // next value - while (*cmdp!=' ' && *cmdp!='\t') cmdp++; - while (*cmdp==' ' || *cmdp=='\t') cmdp++; - if (*cmdp != 'A' && *cmdp != 'a') { - keyType = 1; - } - - // next value - while (*cmdp!=' ' && *cmdp!='\t') cmdp++; - while (*cmdp==' ' || *cmdp=='\t') cmdp++; - - if (strlen(cmdp) != 12) { - PrintAndLog("Length of key must be 12 hex symbols"); - return 0; - } - - for(i = 0; i < 6; i++) { - sscanf((char[]){cmdp[0],cmdp[1],0},"%X",&temp); - key[i] = temp & 0xff; - cmdp++; - cmdp++; - } - PrintAndLog(" sector no:%02x key type:%02x key:%s ", sectorNo, keyType, sprint_hex(key, 6)); - - // flush queue - while (WaitForResponseTimeout(CMD_ACK, 500) != NULL) ; - - UsbCommand c = {CMD_MIFARE_NESTED, {sectorNo, keyType, 0}}; - memcpy(c.d.asBytes, key, 6); - SendCommand(&c); - - PrintAndLog("\n"); - printf("-------------------------------------------------------------------------\n"); - - // wait cycle - while (true) { - printf("."); - if (kbhit()) { - getchar(); - printf("\naborted via keyboard!\n"); - break; - } - - resp = WaitForResponseTimeout(CMD_ACK, 1500); - - if (resp != NULL) { - isEOF = resp->arg[0] & 0xff; - data = resp->d.asBytes; - - PrintAndLog("isEOF:%02x", isEOF); - for (i = 0; i < 2; i++) { - PrintAndLog("data:%s", sprint_hex(data + i * 16, 16)); - } - if (isEOF) break; - - len = resp->arg[1] & 0xff; - if (len == 0) continue; - - memcpy(&uid, resp->d.asBytes, 4); - PrintAndLog("uid:%08x len=%d trgbl=%d trgkey=%d", uid, len, resp->arg[2] & 0xff, (resp->arg[2] >> 8) & 0xff); - - vector = (fnVector *) realloc((void *)vector, (lenVector + len) * sizeof(fnVector) + 200); - if (vector == NULL) { - PrintAndLog("Memory allocation error for fnVector. len: %d bytes: %d", lenVector + len, (lenVector + len) * sizeof(fnVector)); - break; - } - - for (i = 0; i < len; i++) { - vector[lenVector + i].blockNo = resp->arg[2] & 0xff; - vector[lenVector + i].keyType = (resp->arg[2] >> 8) & 0xff; - vector[lenVector + i].uid = uid; - - memcpy(&vector[lenVector + i].nt, (void *)(resp->d.asBytes + 8 + i * 8 + 0), 4); - memcpy(&vector[lenVector + i].ks1, (void *)(resp->d.asBytes + 8 + i * 8 + 4), 4); - - PrintAndLog("i=%d nt:%08x ks1:%08x", i, vector[lenVector + i].nt, vector[lenVector + i].ks1); - } - - lenVector += len; - } - } - - - - // finalize - free(vector); - - return 0; -} - -int CmdHF14AMf1kSim(const char *Cmd) -{ - int i, temp; - uint8_t uid[4] = {0, 0, 0, 0}; - - const char *cmdp = Cmd; - - - if (strlen(Cmd)<3) { - PrintAndLog("Usage: hf 14a mfsim "); - PrintAndLog(" sample: hf 14a mfsim 0a0a0a0a "); - return 0; - } - - // skip spaces - while (*cmdp==' ' || *cmdp=='\t') cmdp++; - - if (strlen(cmdp) != 8) { - PrintAndLog("Length of UID must be 8 hex symbols"); - return 0; - } - - for(i = 0; i < 4; i++) { - sscanf((char[]){cmdp[0],cmdp[1],0},"%X",&temp); - uid[i] = temp & 0xff; - cmdp++; - cmdp++; - } - PrintAndLog(" uid:%s ", sprint_hex(uid, 4)); - - UsbCommand c = {CMD_SIMULATE_MIFARE_CARD, {0, 0, 0}}; - memcpy(c.d.asBytes, uid, 6); - SendCommand(&c); - - return 0; -} - - int CmdHF14AReader(const char *Cmd) { UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT, 0, 0}}; SendCommand(&c); UsbCommand * resp = WaitForResponse(CMD_ACK); uint8_t * uid = resp->d.asBytes; - iso14a_card_select_t * card = uid + 12; + iso14a_card_select_t * card = (iso14a_card_select_t *)(uid + 12); if(resp->arg[0] == 0) { PrintAndLog("iso14443a card select failed"); @@ -611,6 +173,24 @@ int CmdHF14AReader(const char *Cmd) PrintAndLog("ATQA : %02x %02x", card->atqa[0], card->atqa[1]); PrintAndLog(" UID : %s", sprint_hex(uid, 12)); PrintAndLog(" SAK : %02x [%d]", card->sak, resp->arg[0]); + + switch (card->sak) { + case 0x00: PrintAndLog(" SAK : NXP MIFARE Ultralight | Ultralight C"); break; + case 0x04: PrintAndLog(" SAK : NXP MIFARE (various !DESFire !DESFire EV1)"); break; + + case 0x08: PrintAndLog(" SAK : NXP MIFARE CLASSIC 1k | Plus 2k"); break; + case 0x09: PrintAndLog(" SAK : NXP MIFARE Mini 0.3k"); break; + case 0x10: PrintAndLog(" SAK : NXP MIFARE Plus 2k"); break; + case 0x11: PrintAndLog(" SAK : NXP MIFARE Plus 4k"); break; + case 0x18: PrintAndLog(" SAK : NXP MIFARE Classic 4k | Plus 4k"); break; + case 0x20: PrintAndLog(" SAK : NXP MIFARE DESFire 4k | DESFire EV1 2k/4k/8k | Plus 2k/4k | JCOP 31/41"); break; + case 0x24: PrintAndLog(" SAK : NXP MIFARE DESFire | DESFire EV1"); break; + case 0x28: PrintAndLog(" SAK : JCOP31 or JCOP41 v2.3.1"); break; + case 0x38: PrintAndLog(" SAK : Nokia 6212 or 6131 MIFARE CLASSIC 4K"); break; + case 0x88: PrintAndLog(" SAK : Infineon MIFARE CLASSIC 1K"); break; + case 0x98: PrintAndLog(" SAK : Gemplus MPCOS"); break; + default: ; + } if(resp->arg[0] == 1) PrintAndLog(" ATS : %s", sprint_hex(card->ats, card->ats_len)); else @@ -622,25 +202,108 @@ int CmdHF14AReader(const char *Cmd) // ## simulate iso14443a tag // ## greg - added ability to specify tag UID int CmdHF14ASim(const char *Cmd) -{ +{ + UsbCommand c = {CMD_SIMULATE_TAG_ISO_14443a,{0,0,0}}; + + // Retrieve the tag type + uint8_t tagtype = param_get8ex(Cmd,0,0,10); + + // When no argument was given, just print help message + if (tagtype == 0) { + PrintAndLog(""); + PrintAndLog(" Emulating ISO/IEC 14443 type A tag with 4 or 7 byte UID"); + PrintAndLog(""); + PrintAndLog(" syntax: hf 14a sim "); + PrintAndLog(" types: 1 = MIFARE Classic"); + PrintAndLog(" 2 = MIFARE Ultralight"); + PrintAndLog(" 3 = MIFARE DESFIRE"); + PrintAndLog(" 4 = ISO/IEC 14443-4"); + PrintAndLog(""); + return 1; + } + + // Store the tag type + c.arg[0] = tagtype; + + // Retrieve the full 4 or 7 byte long uid + uint64_t long_uid = param_get64ex(Cmd,1,0,16); + + // Are we handling the (optional) second part uid? + if (long_uid > 0xffffffff) { + PrintAndLog("Emulating ISO/IEC 14443 type A tag with 7 byte UID (%014llx)",long_uid); + // Store the second part + c.arg[2] = (long_uid & 0xffffffff); + long_uid >>= 32; + // Store the first part, ignore the first byte, it is replaced by cascade byte (0x88) + c.arg[1] = (long_uid & 0xffffff); + } else { + PrintAndLog("Emulating ISO/IEC 14443 type A tag with 4 byte UID (%08x)",long_uid); + // Only store the first part + c.arg[1] = long_uid & 0xffffffff; + } +/* + // At lease save the mandatory first part of the UID + c.arg[0] = long_uid & 0xffffffff; + + // At lease save the mandatory first part of the UID + c.arg[0] = long_uid & 0xffffffff; + + if (c.arg[1] == 0) { + PrintAndLog("Emulating ISO/IEC 14443 type A tag with UID %01d %08x %08x",c.arg[0],c.arg[1],c.arg[2]); + } + + switch (c.arg[0]) { + case 1: { + PrintAndLog("Emulating ISO/IEC 14443-3 type A tag with 4 byte UID"); + UsbCommand c = {CMD_SIMULATE_TAG_ISO_14443a,param_get32ex(Cmd,0,0,10),param_get32ex(Cmd,1,0,16),param_get32ex(Cmd,2,0,16)}; + } break; + case 2: { + PrintAndLog("Emulating ISO/IEC 14443-4 type A tag with 7 byte UID"); + } break; + default: { + PrintAndLog("Error: unkown tag type (%d)",c.arg[0]); + PrintAndLog("syntax: hf 14a sim ",c.arg[0]); + PrintAndLog(" type1: 4 ",c.arg[0]); + + return 1; + } break; + } +*/ +/* unsigned int hi = 0, lo = 0; int n = 0, i = 0; while (sscanf(&Cmd[i++], "%1x", &n ) == 1) { hi= (hi << 4) | (lo >> 28); lo= (lo << 4) | (n & 0xf); } - - // c.arg should be set to *Cmd or convert *Cmd to the correct format for a uid - UsbCommand c = {CMD_SIMULATE_TAG_ISO_14443a, {hi, lo, 0}}; - PrintAndLog("Emulating 14443A TAG with UID %x%16x", hi, lo); +*/ +// UsbCommand c = {CMD_SIMULATE_TAG_ISO_14443a,param_get32ex(Cmd,0,0,10),param_get32ex(Cmd,1,0,16),param_get32ex(Cmd,2,0,16)}; +// PrintAndLog("Emulating ISO/IEC 14443 type A tag with UID %01d %08x %08x",c.arg[0],c.arg[1],c.arg[2]); SendCommand(&c); return 0; } -int CmdHF14ASnoop(const char *Cmd) -{ - UsbCommand c = {CMD_SNOOP_ISO_14443a}; +int CmdHF14ASnoop(const char *Cmd) { + int param = 0; + + if (param_getchar(Cmd, 0) == 'h') { + PrintAndLog("It get data from the field and saves it into command buffer."); + PrintAndLog("Buffer accessible from command hf 14a list."); + PrintAndLog("Usage: hf 14a snoop [c][r]"); + PrintAndLog("c - triggered by first data from card"); + PrintAndLog("r - triggered by first 7-bit request from reader (REQ,WUP,...)"); + PrintAndLog("sample: hf 14a snoop c r"); + return 0; + } + + for (int i = 0; i < 2; i++) { + char ctmp = param_getchar(Cmd, i); + if (ctmp == 'c' || ctmp == 'C') param |= 0x01; + if (ctmp == 'r' || ctmp == 'R') param |= 0x02; + } + + UsbCommand c = {CMD_SNOOP_ISO_14443a, {param, 0, 0}}; SendCommand(&c); return 0; } @@ -649,12 +312,6 @@ static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, {"list", CmdHF14AList, 0, "List ISO 14443a history"}, - {"mifare", CmdHF14AMifare, 0, "Read out sector 0 parity error messages. param - "}, - {"mfrdbl", CmdHF14AMfRdBl, 0, "Read MIFARE classic block"}, - {"mfrdsc", CmdHF14AMfRdSc, 0, "Read MIFARE classic sector"}, - {"mfwrbl", CmdHF14AMfWrBl, 0, "Write MIFARE classic block"}, - {"nested", CmdHF14AMfNested, 0, "Test nested authentication"}, - {"mfsim", CmdHF14AMf1kSim, 0, "Simulate MIFARE 1k card - NOT WORKING!!!"}, {"reader", CmdHF14AReader, 0, "Act like an ISO14443 Type A reader"}, {"sim", CmdHF14ASim, 0, " -- Fake ISO 14443a tag"}, {"snoop", CmdHF14ASnoop, 0, "Eavesdrop ISO 14443 Type A"}, @@ -663,6 +320,10 @@ static command_t CommandTable[] = int CmdHF14A(const char *Cmd) { + // flush + while (WaitForResponseTimeout(CMD_ACK, 500) != NULL) ; + + // parse CmdsParse(CommandTable, Cmd); return 0; }