From 33c795d0bd0ba50616072a806fd5b38e1e2ccaef Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sun, 14 Feb 2016 11:07:16 -0500 Subject: [PATCH 01/16] add check to fread call --- client/cmdhficlass.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 6c85e1c1..59b0ddc3 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -1046,7 +1046,11 @@ int CmdHFiClassCloneTag(const char *Cmd) { // else we have to create a share memory int i; fseek(f,startblock*8,SEEK_SET); - fread(tag_data,sizeof(iclass_block_t),endblock - startblock + 1,f); + if ( fread(tag_data,sizeof(iclass_block_t),endblock - startblock + 1,f) == 0 ) { + PrintAndLog("File reading error."); + fclose(f); + return 2; + } uint8_t MAC[4]={0x00,0x00,0x00,0x00}; uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; From fd9172d5c2bca6370fe98f719e2267ac14159c4f Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sun, 14 Feb 2016 11:26:00 -0500 Subject: [PATCH 02/16] @iceman1001 s coverity fixes resource leak in hf mf sniff possible overflow in hf 14a raw - add check to fix --- client/cmdhf14a.c | 179 ++++++++++++++++++++++++------------------- client/cmdhfmf.c | 191 ++++++++++++++++++++++++---------------------- 2 files changed, 203 insertions(+), 167 deletions(-) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 81716db3..330fbec0 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -352,16 +352,16 @@ int CmdHF14AReader(const char *Cmd) PrintAndLog(" x0 -> <1 kByte"); break; case 0x01: - PrintAndLog(" x1 -> 1 kByte"); + PrintAndLog(" x0 -> 1 kByte"); break; case 0x02: - PrintAndLog(" x2 -> 2 kByte"); + PrintAndLog(" x0 -> 2 kByte"); break; case 0x03: - PrintAndLog(" x3 -> 4 kByte"); + PrintAndLog(" x0 -> 4 kByte"); break; case 0x04: - PrintAndLog(" x4 -> 8 kByte"); + PrintAndLog(" x0 -> 8 kByte"); break; } switch (card.ats[pos + 3] & 0xf0) { @@ -458,86 +458,110 @@ int CmdHF14ACUIDs(const char *Cmd) return 1; } +int usage_hf_14a_sim(void) { + PrintAndLog("\n Emulating ISO/IEC 14443 type A tag with 4 or 7 byte UID\n"); + PrintAndLog("Usage: hf 14a sim t u x"); + PrintAndLog(" Options : "); + PrintAndLog(" h : this help"); + PrintAndLog(" t : 1 = MIFARE Classic"); + PrintAndLog(" 2 = MIFARE Ultralight"); + PrintAndLog(" 3 = MIFARE Desfire"); + PrintAndLog(" 4 = ISO/IEC 14443-4"); + PrintAndLog(" 5 = MIFARE Tnp3xxx"); + PrintAndLog(" 6 = MIFARE Mini"); + PrintAndLog(" 7 = NTAG 215 from emu mem"); + PrintAndLog(" u : 4 or 7 byte UID"); + PrintAndLog(" x : (Optional) performs the 'reader attack', nr/ar attack against a legitimate reader"); + PrintAndLog("\n sample : hf 14a sim t 1 u 1122344"); + PrintAndLog(" : hf 14a sim t 1 u 1122344 x\n"); + return 0; +} // ## 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(" 5 = MIFARE Tnp3xxx"); - 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); + bool errors = FALSE; + uint8_t flags = 0; + uint8_t tagtype = 1; + uint64_t uid = 0; + uint8_t cmdp = 0; - // Are we handling the (optional) second part uid? - if (long_uid > 0xffffffff) { - PrintAndLog("Emulating ISO/IEC 14443 type A tag with 7 byte UID (%014"llx")",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; + while(param_getchar(Cmd, cmdp) != 0x00) + { + switch(param_getchar(Cmd, cmdp)) + { + case 'h': + case 'H': + return usage_hf_14a_sim(); + case 't': + case 'T': + // Retrieve the tag type + tagtype = param_get8ex(Cmd, cmdp+1, 0, 10); + if (tagtype == 0) + errors = true; + cmdp += 2; + break; + case 'u': + case 'U': + // Retrieve the full 4 or 7 byte long uid + uid = param_get64ex(Cmd, cmdp+1, 0, 16); + if (uid == 0 ) + errors = TRUE; + + if (uid > 0xffffffff) { + PrintAndLog("Emulating ISO/IEC 14443 type A tag with 7 byte UID (%014"llx")",uid); + flags |= FLAG_7B_UID_IN_DATA; + } else { + PrintAndLog("Emulating ISO/IEC 14443 type A tag with 4 byte UID (%08x)",uid); + flags |= FLAG_4B_UID_IN_DATA; + } + cmdp += 2; + break; + case 'x': + case 'X': + flags |= FLAG_NR_AR_ATTACK; + cmdp++; + break; + default: + PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + if(errors) break; } -/* - // 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]); + //Validations + if (errors) return usage_hf_14a_sim(); + + PrintAndLog("Press pm3-button to abort simulation"); + + UsbCommand c = {CMD_SIMULATE_TAG_ISO_14443a,{ tagtype, flags, 0 }}; + + num_to_bytes(uid, 7, c.d.asBytes); + clearCommandBuffer(); + SendCommand(&c); + + //uint8_t data[40]; + //uint8_t key[6]; + UsbCommand resp; + while(!ukbhit()){ + if ( WaitForResponseTimeout(CMD_ACK,&resp,1500)) { + if ( (resp.arg[0] & 0xffff) == CMD_SIMULATE_MIFARE_CARD ){ + // attempt to get key: + // TODO: + + //memset(data, 0x00, sizeof(data)); + //memset(key, 0x00, sizeof(key)); + //int len = (resp.arg[1] > sizeof(data)) ? sizeof(data) : resp.arg[1]; + //memcpy(data, resp.d.asBytes, len); + //tryMfk32(uid, data, key); + //tryMfk32_moebius(uid, data, key); + //tryMfk64(uid, data, key); + //PrintAndLog("--"); + } + } } - - 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); - } -*/ -// 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; + return 0; } int CmdHF14ASnoop(const char *Cmd) { @@ -705,7 +729,8 @@ int CmdHF14ACmdRaw(const char *cmd) { if(topazmode) c.arg[0] |= ISO14A_TOPAZMODE; - // Max buffer is USB_CMD_DATA_SIZE + // Max buffer is USB_CMD_DATA_SIZE + datalen = (datalen > USB_CMD_DATA_SIZE) ? USB_CMD_DATA_SIZE : datalen; c.arg[1] = (datalen & 0xFFFF) | (numbits << 16); memcpy(c.d.asBytes,data,datalen); diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 48e78b1c..21c0cde2 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -121,10 +121,11 @@ int CmdHF14AMfWrBl(const char *Cmd) PrintAndLog("--block no:%d, key type:%c, key:%s", blockNo, keyType?'B':'A', sprint_hex(key, 6)); PrintAndLog("--data: %s", sprint_hex(bldata, 16)); - UsbCommand c = {CMD_MIFARE_WRITEBL, {blockNo, keyType, 0}}; + UsbCommand c = {CMD_MIFARE_WRITEBL, {blockNo, keyType, 0}}; memcpy(c.d.asBytes, key, 6); memcpy(c.d.asBytes + 10, bldata, 16); - SendCommand(&c); + clearCommandBuffer(); + SendCommand(&c); UsbCommand resp; if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { @@ -142,7 +143,7 @@ int CmdHF14AMfRdBl(const char *Cmd) uint8_t blockNo = 0; uint8_t keyType = 0; uint8_t key[6] = {0, 0, 0, 0, 0, 0}; - + char cmdp = 0x00; @@ -150,8 +151,8 @@ int CmdHF14AMfRdBl(const char *Cmd) PrintAndLog("Usage: hf mf rdbl "); PrintAndLog(" sample: hf mf rdbl 0 A FFFFFFFFFFFF "); return 0; - } - + } + blockNo = param_get8(Cmd, 0); cmdp = param_getchar(Cmd, 1); if (cmdp == 0x00) { @@ -164,10 +165,11 @@ int CmdHF14AMfRdBl(const char *Cmd) return 1; } PrintAndLog("--block no:%d, key type:%c, key:%s ", blockNo, keyType?'B':'A', sprint_hex(key, 6)); - - UsbCommand c = {CMD_MIFARE_READBL, {blockNo, keyType, 0}}; + + UsbCommand c = {CMD_MIFARE_READBL, {blockNo, keyType, 0}}; memcpy(c.d.asBytes, key, 6); - SendCommand(&c); + clearCommandBuffer(); + SendCommand(&c); UsbCommand resp; if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { @@ -217,9 +219,10 @@ int CmdHF14AMfRdSc(const char *Cmd) return 1; } PrintAndLog("--sector no:%d key type:%c key:%s ", sectorNo, keyType?'B':'A', sprint_hex(key, 6)); - + UsbCommand c = {CMD_MIFARE_READSC, {sectorNo, keyType, 0}}; memcpy(c.d.asBytes, key, 6); + clearCommandBuffer(); SendCommand(&c); PrintAndLog(" "); @@ -239,7 +242,7 @@ int CmdHF14AMfRdSc(const char *Cmd) PrintAndLog("Command execute timeout"); } - return 0; + return 0; } uint8_t FirstBlockOfSector(uint8_t sectorNo) @@ -263,7 +266,7 @@ uint8_t NumBlocksPerSector(uint8_t sectorNo) int CmdHF14AMfDump(const char *Cmd) { uint8_t sectorNo, blockNo; - + uint8_t keyA[40][6]; uint8_t keyB[40][6]; uint8_t rights[40][4]; @@ -316,16 +319,17 @@ int CmdHF14AMfDump(const char *Cmd) return 2; } } - + fclose(fin); PrintAndLog("|-----------------------------------------|"); PrintAndLog("|------ Reading sector access bits...-----|"); PrintAndLog("|-----------------------------------------|"); - + for (sectorNo = 0; sectorNo < numSectors; sectorNo++) { UsbCommand c = {CMD_MIFARE_READBL, {FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 0, 0}}; memcpy(c.d.asBytes, keyA[sectorNo], 6); + clearCommandBuffer(); SendCommand(&c); if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { @@ -347,11 +351,11 @@ int CmdHF14AMfDump(const char *Cmd) rights[sectorNo][3] = 0x01; } } - + PrintAndLog("|-----------------------------------------|"); PrintAndLog("|----- Dumping all blocks to file... -----|"); PrintAndLog("|-----------------------------------------|"); - + bool isOK = true; for (sectorNo = 0; isOK && sectorNo < numSectors; sectorNo++) { for (blockNo = 0; isOK && blockNo < NumBlocksPerSector(sectorNo); blockNo++) { @@ -360,6 +364,7 @@ int CmdHF14AMfDump(const char *Cmd) if (blockNo == NumBlocksPerSector(sectorNo) - 1) { // sector trailer. At least the Access Conditions can always be read with key A. UsbCommand c = {CMD_MIFARE_READBL, {FirstBlockOfSector(sectorNo) + blockNo, 0, 0}}; memcpy(c.d.asBytes, keyA[sectorNo], 6); + clearCommandBuffer(); SendCommand(&c); received = WaitForResponseTimeout(CMD_ACK,&resp,1500); } else { // data block. Check if it can be read with key A or key B @@ -367,6 +372,7 @@ int CmdHF14AMfDump(const char *Cmd) if ((rights[sectorNo][data_area] == 0x03) || (rights[sectorNo][data_area] == 0x05)) { // only key B would work UsbCommand c = {CMD_MIFARE_READBL, {FirstBlockOfSector(sectorNo) + blockNo, 1, 0}}; memcpy(c.d.asBytes, keyB[sectorNo], 6); + clearCommandBuffer(); SendCommand(&c); received = WaitForResponseTimeout(CMD_ACK,&resp,1500); } else if (rights[sectorNo][data_area] == 0x07) { // no key would work @@ -375,6 +381,7 @@ int CmdHF14AMfDump(const char *Cmd) } else { // key A would work UsbCommand c = {CMD_MIFARE_READBL, {FirstBlockOfSector(sectorNo) + blockNo, 0, 0}}; memcpy(c.d.asBytes, keyA[sectorNo], 6); + clearCommandBuffer(); SendCommand(&c); received = WaitForResponseTimeout(CMD_ACK,&resp,1500); } @@ -518,6 +525,7 @@ int CmdHF14AMfRestore(const char *Cmd) PrintAndLog("Writing to block %3d: %s", FirstBlockOfSector(sectorNo) + blockNo, sprint_hex(bldata, 16)); memcpy(c.d.asBytes + 10, bldata, 16); + clearCommandBuffer(); SendCommand(&c); UsbCommand resp; @@ -1069,6 +1077,7 @@ int CmdHF14AMf1kSim(const char *Cmd) UsbCommand c = {CMD_SIMULATE_MIFARE_CARD, {flags, exitAfterNReads,0}}; memcpy(c.d.asBytes, uid, sizeof(uid)); + clearCommandBuffer(); SendCommand(&c); if(flags & FLAG_INTERACTIVE) @@ -1077,7 +1086,7 @@ int CmdHF14AMf1kSim(const char *Cmd) PrintAndLog("Press pm3-button to abort simulation"); while(! WaitForResponseTimeout(CMD_ACK,&resp,1500)) { //We're waiting only 1.5 s at a time, otherwise we get the - // annoying message about "Waiting for a response... " + //annoying message about "Waiting for a response... " } } @@ -1144,7 +1153,6 @@ int CmdHF14AMfEClear(const char *Cmd) return 0; } - int CmdHF14AMfESet(const char *Cmd) { uint8_t memBlock[16]; @@ -1172,7 +1180,6 @@ int CmdHF14AMfESet(const char *Cmd) return 0; } - int CmdHF14AMfELoad(const char *Cmd) { FILE * f; @@ -1182,13 +1189,13 @@ int CmdHF14AMfELoad(const char *Cmd) uint8_t buf8[64] = {0x00}; int i, len, blockNum, numBlocks; int nameParamNo = 1; - + uint8_t blockWidth = 32; char ctmp = param_getchar(Cmd, 0); if ( ctmp == 'h' || ctmp == 0x00) { PrintAndLog("It loads emul dump from the file `filename.eml`"); - PrintAndLog("Usage: hf mf eload [card memory] "); - PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K"); + PrintAndLog("Usage: hf mf eload [card memory] [numblocks]"); + PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K, u = UL"); PrintAndLog(""); PrintAndLog(" sample: hf mf eload filename"); PrintAndLog(" hf mf eload 4 filename"); @@ -1201,14 +1208,17 @@ int CmdHF14AMfELoad(const char *Cmd) case '\0': numBlocks = 16*4; break; case '2' : numBlocks = 32*4; break; case '4' : numBlocks = 256; break; + case 'U' : // fall through + case 'u' : numBlocks = 255; blockWidth = 8; break; default: { numBlocks = 16*4; nameParamNo = 0; } } + uint32_t numblk2 = param_get32ex(Cmd,2,0,10); + if (numblk2 > 0) numBlocks = numblk2; len = param_getstr(Cmd,nameParamNo,filename); - if (len > FILE_PATH_SIZE - 4) len = FILE_PATH_SIZE - 4; fnameptr += len; @@ -1235,19 +1245,18 @@ int CmdHF14AMfELoad(const char *Cmd) return 2; } - if (strlen(buf) < 32){ + if (strlen(buf) < blockWidth){ if(strlen(buf) && feof(f)) break; - PrintAndLog("File content error. Block data must include 32 HEX symbols"); + PrintAndLog("File content error. Block data must include %d HEX symbols", blockWidth); fclose(f); return 2; } - for (i = 0; i < 32; i += 2) { + for (i = 0; i < blockWidth; i += 2) { sscanf(&buf[i], "%02x", (unsigned int *)&buf8[i / 2]); - } - - if (mfEmlSetMem(buf8, blockNum, 1)) { + } + if (mfEmlSetMem_xt(buf8, blockNum, 1, blockWidth/2)) { PrintAndLog("Cant set emul block: %3d", blockNum); fclose(f); return 3; @@ -1268,7 +1277,6 @@ int CmdHF14AMfELoad(const char *Cmd) return 0; } - int CmdHF14AMfESave(const char *Cmd) { FILE * f; @@ -1354,7 +1362,6 @@ int CmdHF14AMfESave(const char *Cmd) return 0; } - int CmdHF14AMfECFill(const char *Cmd) { uint8_t keyType = 0; @@ -1394,7 +1401,6 @@ int CmdHF14AMfECFill(const char *Cmd) return 0; } - int CmdHF14AMfEKeyPrn(const char *Cmd) { int i; @@ -1402,7 +1408,9 @@ int CmdHF14AMfEKeyPrn(const char *Cmd) uint8_t data[16]; uint64_t keyA, keyB; - if (param_getchar(Cmd, 0) == 'h') { + char cmdp = param_getchar(Cmd, 0); + + if ( cmdp == 'h' || cmdp == 'H') { PrintAndLog("It prints the keys loaded in the emulator memory"); PrintAndLog("Usage: hf mf ekeyprn [card memory]"); PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K"); @@ -1411,8 +1419,6 @@ int CmdHF14AMfEKeyPrn(const char *Cmd) return 0; } - char cmdp = param_getchar(Cmd, 0); - switch (cmdp) { case '0' : numSectors = 5; break; case '1' : @@ -1439,7 +1445,6 @@ int CmdHF14AMfEKeyPrn(const char *Cmd) return 0; } - int CmdHF14AMfCSetUID(const char *Cmd) { uint8_t wipeCard = 0; @@ -1513,7 +1518,7 @@ int CmdHF14AMfCSetBlk(const char *Cmd) { uint8_t memBlock[16] = {0x00}; uint8_t blockNo = 0; - bool wipeCard = FALSE; + uint8_t params = MAGIC_SINGLE; int res; if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') { @@ -1532,10 +1537,12 @@ int CmdHF14AMfCSetBlk(const char *Cmd) } char ctmp = param_getchar(Cmd, 2); - wipeCard = (ctmp == 'w' || ctmp == 'W'); + if (ctmp == 'w' || ctmp == 'W') + params |= MAGIC_WIPE; + PrintAndLog("--block number:%2d data:%s", blockNo, sprint_hex(memBlock, 16)); - res = mfCSetBlock(blockNo, memBlock, NULL, wipeCard, CSETBLOCK_SINGLE_OPER); + res = mfCSetBlock(blockNo, memBlock, NULL, params); if (res) { PrintAndLog("Can't write block. error=%d", res); return 1; @@ -1543,18 +1550,21 @@ int CmdHF14AMfCSetBlk(const char *Cmd) return 0; } - int CmdHF14AMfCLoad(const char *Cmd) { FILE * f; - char filename[FILE_PATH_SIZE] = {0x00}; + char filename[FILE_PATH_SIZE]; char * fnameptr = filename; char buf[64] = {0x00}; uint8_t buf8[64] = {0x00}; uint8_t fillFromEmulator = 0; int i, len, blockNum, flags=0; - if (param_getchar(Cmd, 0) == 'h' || param_getchar(Cmd, 0)== 0x00) { + memset(filename, 0, sizeof(filename)); + + char ctmp = param_getchar(Cmd, 0); + + if (ctmp == 'h' || ctmp == 'H' || ctmp == 0x00) { PrintAndLog("It loads magic Chinese card from the file `filename.eml`"); PrintAndLog("or from emulator memory (option `e`)"); PrintAndLog("Usage: hf mf cload "); @@ -1563,7 +1573,6 @@ int CmdHF14AMfCLoad(const char *Cmd) return 0; } - char ctmp = param_getchar(Cmd, 0); if (ctmp == 'e' || ctmp == 'E') fillFromEmulator = 1; if (fillFromEmulator) { @@ -1572,11 +1581,11 @@ int CmdHF14AMfCLoad(const char *Cmd) PrintAndLog("Cant get block: %d", blockNum); return 2; } - if (blockNum == 0) flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC; // switch on field and send magic sequence + if (blockNum == 0) flags = MAGIC_INIT + MAGIC_WUPC; // switch on field and send magic sequence if (blockNum == 1) flags = 0; // just write - if (blockNum == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD; // Done. Magic Halt and switch off field. + if (blockNum == 16 * 4 - 1) flags = MAGIC_HALT + MAGIC_OFF; // Done. Magic Halt and switch off field. - if (mfCSetBlock(blockNum, buf8, NULL, 0, flags)) { + if (mfCSetBlock(blockNum, buf8, NULL, flags)) { PrintAndLog("Cant set magic card block: %d", blockNum); return 3; } @@ -1619,11 +1628,11 @@ int CmdHF14AMfCLoad(const char *Cmd) for (i = 0; i < 32; i += 2) sscanf(&buf[i], "%02x", (unsigned int *)&buf8[i / 2]); - if (blockNum == 0) flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC; // switch on field and send magic sequence + if (blockNum == 0) flags = MAGIC_INIT + MAGIC_WUPC; // switch on field and send magic sequence if (blockNum == 1) flags = 0; // just write - if (blockNum == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD; // Done. Switch off field. + if (blockNum == 16 * 4 - 1) flags = MAGIC_HALT + MAGIC_OFF; // Done. Switch off field. - if (mfCSetBlock(blockNum, buf8, NULL, 0, flags)) { + if (mfCSetBlock(blockNum, buf8, NULL, flags)) { PrintAndLog("Can't set magic card block: %d", blockNum); return 3; } @@ -1644,12 +1653,13 @@ int CmdHF14AMfCLoad(const char *Cmd) } int CmdHF14AMfCGetBlk(const char *Cmd) { - uint8_t memBlock[16]; + uint8_t data[16]; uint8_t blockNo = 0; int res; - memset(memBlock, 0x00, sizeof(memBlock)); + memset(data, 0x00, sizeof(data)); + char ctmp = param_getchar(Cmd, 0); - if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') { + if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') { PrintAndLog("Usage: hf mf cgetblk "); PrintAndLog("sample: hf mf cgetblk 1"); PrintAndLog("Get block data from magic Chinese card (only works with such cards)\n"); @@ -1660,28 +1670,29 @@ int CmdHF14AMfCGetBlk(const char *Cmd) { PrintAndLog("--block number:%2d ", blockNo); - res = mfCGetBlock(blockNo, memBlock, CSETBLOCK_SINGLE_OPER); + res = mfCGetBlock(blockNo, data, MAGIC_SINGLE); if (res) { PrintAndLog("Can't read block. error=%d", res); return 1; } - PrintAndLog("block data:%s", sprint_hex(memBlock, 16)); + PrintAndLog("block data:%s", sprint_hex(data, sizeof(data))); return 0; } - int CmdHF14AMfCGetSc(const char *Cmd) { - uint8_t memBlock[16] = {0x00}; + uint8_t data[16]; uint8_t sectorNo = 0; int i, res, flags; + memset(data, 0x00, sizeof(data)); + char ctmp = param_getchar(Cmd, 0); - if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') { + if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') { PrintAndLog("Usage: hf mf cgetsc "); PrintAndLog("sample: hf mf cgetsc 0"); PrintAndLog("Get sector data from magic Chinese card (only works with such cards)\n"); return 0; - } + } sectorNo = param_get8(Cmd, 0); if (sectorNo > 15) { @@ -1690,37 +1701,37 @@ int CmdHF14AMfCGetSc(const char *Cmd) { } PrintAndLog("--sector number:%d ", sectorNo); + PrintAndLog("block | data"); - flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC; + flags = MAGIC_INIT + MAGIC_WUPC; for (i = 0; i < 4; i++) { if (i == 1) flags = 0; - if (i == 3) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD; + if (i == 3) flags = MAGIC_HALT + MAGIC_OFF; - res = mfCGetBlock(sectorNo * 4 + i, memBlock, flags); + res = mfCGetBlock(sectorNo * 4 + i, data, flags); if (res) { PrintAndLog("Can't read block. %d error=%d", sectorNo * 4 + i, res); return 1; } - - PrintAndLog("block %3d data:%s", sectorNo * 4 + i, sprint_hex(memBlock, 16)); + PrintAndLog(" %3d | %s", sectorNo * 4 + i, sprint_hex(data, sizeof(data))); } return 0; } - int CmdHF14AMfCSave(const char *Cmd) { FILE * f; - char filename[FILE_PATH_SIZE] = {0x00}; + char filename[FILE_PATH_SIZE]; char * fnameptr = filename; uint8_t fillFromEmulator = 0; - uint8_t buf[64] = {0x00}; + uint8_t buf[64]; int i, j, len, flags; - - // memset(filename, 0, sizeof(filename)); - // memset(buf, 0, sizeof(buf)); - if (param_getchar(Cmd, 0) == 'h') { + memset(filename, 0, sizeof(filename)); + memset(buf, 0, sizeof(buf)); + char ctmp = param_getchar(Cmd, 0); + + if ( ctmp == 'h' || ctmp == 'H' ) { PrintAndLog("It saves `magic Chinese` card dump into the file `filename.eml` or `cardID.eml`"); PrintAndLog("or into emulator memory (option `e`)"); PrintAndLog("Usage: hf mf esave [file name w/o `.eml`][e]"); @@ -1728,23 +1739,21 @@ int CmdHF14AMfCSave(const char *Cmd) { PrintAndLog(" hf mf esave filename"); PrintAndLog(" hf mf esave e \n"); return 0; - } - - char ctmp = param_getchar(Cmd, 0); + } if (ctmp == 'e' || ctmp == 'E') fillFromEmulator = 1; if (fillFromEmulator) { // put into emulator - flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC; + flags = MAGIC_INIT + MAGIC_WUPC; for (i = 0; i < 16 * 4; i++) { if (i == 1) flags = 0; - if (i == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD; - + if (i == 16 * 4 - 1) flags = MAGIC_HALT + MAGIC_OFF; + if (mfCGetBlock(i, buf, flags)) { PrintAndLog("Cant get block: %d", i); break; } - + if (mfEmlSetMem(buf, i, 1)) { PrintAndLog("Cant set emul block: %d", i); return 3; @@ -1754,15 +1763,15 @@ int CmdHF14AMfCSave(const char *Cmd) { } else { len = strlen(Cmd); if (len > FILE_PATH_SIZE - 4) len = FILE_PATH_SIZE - 4; - + + // get filename based on UID if (len < 1) { - // get filename - if (mfCGetBlock(0, buf, CSETBLOCK_SINGLE_OPER)) { + + if (mfCGetBlock(0, buf, MAGIC_SINGLE)) { PrintAndLog("Cant get block: %d", 0); len = sprintf(fnameptr, "dump"); fnameptr += len; - } - else { + } else { for (j = 0; j < 7; j++, fnameptr += 2) sprintf(fnameptr, "%02x", buf[j]); } @@ -1771,8 +1780,9 @@ int CmdHF14AMfCSave(const char *Cmd) { fnameptr += len; } + // add .eml extension sprintf(fnameptr, ".eml"); - + // open file f = fopen(filename, "w+"); @@ -1782,10 +1792,10 @@ int CmdHF14AMfCSave(const char *Cmd) { } // put hex - flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC; + flags = MAGIC_INIT + MAGIC_WUPC; for (i = 0; i < 16 * 4; i++) { if (i == 1) flags = 0; - if (i == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD; + if (i == 16 * 4 - 1) flags = MAGIC_HALT + MAGIC_OFF; if (mfCGetBlock(i, buf, flags)) { PrintAndLog("Cant get block: %d", i); @@ -1795,15 +1805,13 @@ int CmdHF14AMfCSave(const char *Cmd) { fprintf(f, "%02x", buf[j]); fprintf(f,"\n"); } + fflush(f); fclose(f); - PrintAndLog("Saved to file: %s", filename); - return 0; } } - int CmdHF14AMfSniff(const char *Cmd){ bool wantLogToFile = 0; @@ -1873,7 +1881,10 @@ int CmdHF14AMfSniff(const char *Cmd){ uint16_t traceLen = resp.arg[1]; len = resp.arg[2]; - if (res == 0) return 0; // we are done + if (res == 0) { + free(buf); + return 0; // we are done + } if (res == 1) { // there is (more) data to be transferred if (pckNum == 0) { // first packet, (re)allocate necessary buffer @@ -1952,7 +1963,7 @@ int CmdHF14AMfSniff(const char *Cmd){ } //needs nt, ar, at, Data to decrypt -int CmdDecryptTraceCmds(const char *Cmd){ +int CmdHf14MfDecryptBytes(const char *Cmd){ uint8_t data[50]; int len = 0; param_gethex_ex(Cmd,3,data,&len); @@ -1986,7 +1997,7 @@ static command_t CommandTable[] = {"cgetsc", CmdHF14AMfCGetSc, 0, "Read sector - Magic Chinese card"}, {"cload", CmdHF14AMfCLoad, 0, "Load dump into magic Chinese card"}, {"csave", CmdHF14AMfCSave, 0, "Save dump from magic Chinese card into file or emulator"}, - {"decrypt", CmdDecryptTraceCmds,1, "[nt] [ar_enc] [at_enc] [data] - to decrypt snoop or trace"}, + {"decrypt", CmdHf14MfDecryptBytes,1, "[nt] [ar_enc] [at_enc] [data] - to decrypt snoop or trace"}, {NULL, NULL, 0, NULL} }; From 3d4982ddbfebc7eca00daf644ac6dee937488d61 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sun, 14 Feb 2016 11:42:34 -0500 Subject: [PATCH 03/16] =?UTF-8?q?FIX:=20Coverity,=20unintended=20sign=20ex?= =?UTF-8?q?tention,=20CID=20#121363,=20(numbits=20<<=2016=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …) becomes int, then uint64_t. But the signness might set all upper bits to 1 in the process. from @iceman1001 . --- client/cmdhf14a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 330fbec0..b369d187 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -731,7 +731,7 @@ int CmdHF14ACmdRaw(const char *cmd) { // Max buffer is USB_CMD_DATA_SIZE datalen = (datalen > USB_CMD_DATA_SIZE) ? USB_CMD_DATA_SIZE : datalen; - c.arg[1] = (datalen & 0xFFFF) | (numbits << 16); + c.arg[1] = (datalen & 0xFFFF) | ( (uint32_t)(numbits) << 16); memcpy(c.d.asBytes,data,datalen); SendCommand(&c); From 7a616c0d70d3018c6bf81095f7432543a38ad3c9 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sun, 14 Feb 2016 12:06:29 -0500 Subject: [PATCH 04/16] =?UTF-8?q?FIX,=20Coverity,=20Argument=20can't=20be?= =?UTF-8?q?=20negative.=20CID#=20212322,=20ftell(f)=20can=20=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …be negative. Not allowed in malloc... from @iceman1001 --- client/cmdhficlass.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 59b0ddc3..a169e827 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -283,8 +283,12 @@ int CmdHFiClassELoad(const char *Cmd) { long fsize = ftell(f); fseek(f, 0, SEEK_SET); - uint8_t *dump = malloc(fsize); + if (fsize < 0) { + PrintAndLog("Error, when getting filesize"); + return 1; + } + uint8_t *dump = malloc(fsize); size_t bytes_read = fread(dump, 1, fsize, f); fclose(f); From eb5b63b4a6b07fb9d7034c11d99408033613b1d5 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sun, 14 Feb 2016 12:13:22 -0500 Subject: [PATCH 05/16] =?UTF-8?q?FIX,=20Coverity,=20Argument=20can't=20be?= =?UTF-8?q?=20negative.=20CID#=20212322,=20ftell(f)=20can=20=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …be negative. Not allowed in malloc... from iceman1001 --- client/cmdhficlass.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index a169e827..67bcbe76 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -285,6 +285,7 @@ int CmdHFiClassELoad(const char *Cmd) { if (fsize < 0) { PrintAndLog("Error, when getting filesize"); + fclose(f); return 1; } @@ -1506,6 +1507,12 @@ static int loadKeys(char *filename) { long fsize = ftell(f); fseek(f, 0, SEEK_SET); + if ( fsize < 0 ) { + PrintAndLog("Error, when getting filesize"); + fclose(f); + return 1; + } + uint8_t *dump = malloc(fsize); size_t bytes_read = fread(dump, 1, fsize, f); From b0c68b72d361f43be0639dbf66aca0ec1b7599d9 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sun, 14 Feb 2016 12:26:03 -0500 Subject: [PATCH 06/16] fix keyNbr entry error checking coverity scan by iceman1001 found. --- client/cmdhficlass.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 67bcbe76..54b780c7 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -596,7 +596,7 @@ int CmdHFiClassReader_Dump(const char *Cmd) { errors = param_gethex(tempStr, 0, CreditKEY, dataLen); } else if (dataLen == 1) { keyNbr = param_get8(Cmd, cmdp+1); - if (keyNbr <= ICLASS_KEYS_MAX) { + if (keyNbr < ICLASS_KEYS_MAX) { memcpy(CreditKEY, iClass_Key_Table[keyNbr], 8); } else { PrintAndLog("\nERROR: Credit KeyNbr is invalid\n"); @@ -630,7 +630,7 @@ int CmdHFiClassReader_Dump(const char *Cmd) { errors = param_gethex(tempStr, 0, KEY, dataLen); } else if (dataLen == 1) { keyNbr = param_get8(Cmd, cmdp+1); - if (keyNbr <= ICLASS_KEYS_MAX) { + if (keyNbr < ICLASS_KEYS_MAX) { memcpy(KEY, iClass_Key_Table[keyNbr], 8); } else { PrintAndLog("\nERROR: Credit KeyNbr is invalid\n"); @@ -889,7 +889,7 @@ int CmdHFiClass_WriteBlock(const char *Cmd) { errors = param_gethex(tempStr, 0, KEY, dataLen); } else if (dataLen == 1) { keyNbr = param_get8(Cmd, cmdp+1); - if (keyNbr <= ICLASS_KEYS_MAX) { + if (keyNbr < ICLASS_KEYS_MAX) { memcpy(KEY, iClass_Key_Table[keyNbr], 8); } else { PrintAndLog("\nERROR: Credit KeyNbr is invalid\n"); @@ -992,7 +992,7 @@ int CmdHFiClassCloneTag(const char *Cmd) { errors = param_gethex(tempStr, 0, KEY, dataLen); } else if (dataLen == 1) { keyNbr = param_get8(Cmd, cmdp+1); - if (keyNbr <= ICLASS_KEYS_MAX) { + if (keyNbr < ICLASS_KEYS_MAX) { memcpy(KEY, iClass_Key_Table[keyNbr], 8); } else { PrintAndLog("\nERROR: Credit KeyNbr is invalid\n"); @@ -1177,7 +1177,7 @@ int CmdHFiClass_ReadBlock(const char *Cmd) { errors = param_gethex(tempStr, 0, KEY, dataLen); } else if (dataLen == 1) { keyNbr = param_get8(Cmd, cmdp+1); - if (keyNbr <= ICLASS_KEYS_MAX) { + if (keyNbr < ICLASS_KEYS_MAX) { memcpy(KEY, iClass_Key_Table[keyNbr], 8); } else { PrintAndLog("\nERROR: Credit KeyNbr is invalid\n"); @@ -1314,8 +1314,13 @@ int CmdHFiClassReadTagFile(const char *Cmd) { long fsize = ftell(f); fseek(f, 0, SEEK_SET); - uint8_t *dump = malloc(fsize); + if ( fsize < 0 ) { + PrintAndLog("Error, when getting filesize"); + fclose(f); + return 1; + } + uint8_t *dump = malloc(fsize); size_t bytes_read = fread(dump, 1, fsize, f); fclose(f); @@ -1440,7 +1445,7 @@ int CmdHFiClassCalcNewKey(const char *Cmd) { errors = param_gethex(tempStr, 0, NEWKEY, dataLen); } else if (dataLen == 1) { keyNbr = param_get8(Cmd, cmdp+1); - if (keyNbr <= ICLASS_KEYS_MAX) { + if (keyNbr < ICLASS_KEYS_MAX) { memcpy(NEWKEY, iClass_Key_Table[keyNbr], 8); } else { PrintAndLog("\nERROR: NewKey Nbr is invalid\n"); @@ -1459,7 +1464,7 @@ int CmdHFiClassCalcNewKey(const char *Cmd) { errors = param_gethex(tempStr, 0, OLDKEY, dataLen); } else if (dataLen == 1) { keyNbr = param_get8(Cmd, cmdp+1); - if (keyNbr <= ICLASS_KEYS_MAX) { + if (keyNbr < ICLASS_KEYS_MAX) { memcpy(OLDKEY, iClass_Key_Table[keyNbr], 8); } else { PrintAndLog("\nERROR: Credit KeyNbr is invalid\n"); @@ -1605,8 +1610,8 @@ int CmdHFiClassManageKeys(const char *Cmd) { case 'n': case 'N': keyNbr = param_get8(Cmd, cmdp+1); - if (keyNbr < 0) { - PrintAndLog("Wrong block number"); + if (keyNbr >= ICLASS_KEYS_MAX) { + PrintAndLog("Invalid block number"); errors = true; } cmdp += 2; From 165e0775b1660a4dfc1f95338585bcb663b6b5e7 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sun, 14 Feb 2016 12:33:07 -0500 Subject: [PATCH 07/16] fix possible null if no file found also initialize filename variable so not null found by iceman1001 --- client/cmdhficlass.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 54b780c7..4cf9d3ea 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -373,10 +373,13 @@ int CmdHFiClassDecrypt(const char *Cmd) { //Open the tagdump-file FILE *f; char filename[FILE_PATH_SIZE]; - if(opt == 'f' && param_getstr(Cmd, 1, filename) > 0) - { + if(opt == 'f' && param_getstr(Cmd, 1, filename) > 0) { f = fopen(filename, "rb"); - }else{ + if ( f == NULL ) { + PrintAndLog("Could not find file %s", filename); + return 1; + } + } else { return usage_hf_iclass_decrypt(); } @@ -938,7 +941,7 @@ int usage_hf_iclass_clone(void) { } int CmdHFiClassCloneTag(const char *Cmd) { - char filename[FILE_PATH_SIZE]; + char filename[FILE_PATH_SIZE] = {0}; char tempStr[50]={0}; uint8_t KEY[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; uint8_t keyNbr = 0; @@ -1043,6 +1046,7 @@ int CmdHFiClassCloneTag(const char *Cmd) { if (startblock<5) { PrintAndLog("You cannot write key blocks this way. yet... make your start block > 4"); + fclose(f); return 0; } // now read data from the file from block 6 --- 19 From 568377946c910e27a319f39e4f81e6f3fd72ee92 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sun, 14 Feb 2016 12:36:55 -0500 Subject: [PATCH 08/16] FIX: Coverity, Out-of-bounds. In the loop, variable i, can... ...be as much as 1051, overflowing the databuf with size 1024. --- client/cmdhflegic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index 7ee601b2..4e52c35c 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -58,7 +58,7 @@ int CmdLegicDecode(const char *Cmd) int crc = 0; int wrp = 0; int wrc = 0; - uint8_t data_buf[1024]; // receiver buffer + uint8_t data_buf[1052]; // receiver buffer char out_string[3076]; // just use big buffer - bad practice char token_type[4]; From 8ea5706047cb0f6e7bd9f04306249d6a349c2239 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sun, 14 Feb 2016 13:24:03 -0500 Subject: [PATCH 09/16] additional memory leaks, overflow and unchecked ... return values fixed thanks to iceman1001 --- client/cmdhfmf.c | 15 +++++++++++---- client/util.c | 7 ++++--- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 21c0cde2..d306ac65 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -875,6 +875,7 @@ int CmdHF14AMfChk(const char *Cmd) break; default: PrintAndLog("Key type must be A , B or ?"); + free(keyBlock); return 1; }; @@ -926,6 +927,7 @@ int CmdHF14AMfChk(const char *Cmd) if (!p) { PrintAndLog("Cannot allocate memory for defKeys"); free(keyBlock); + fclose(f); return 2; } keyBlock = p; @@ -1219,7 +1221,7 @@ int CmdHF14AMfELoad(const char *Cmd) if (numblk2 > 0) numBlocks = numblk2; len = param_getstr(Cmd,nameParamNo,filename); - if (len > FILE_PATH_SIZE - 4) len = FILE_PATH_SIZE - 4; + if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5; fnameptr += len; @@ -1316,7 +1318,7 @@ int CmdHF14AMfESave(const char *Cmd) len = param_getstr(Cmd,nameParamNo,filename); - if (len > FILE_PATH_SIZE - 4) len = FILE_PATH_SIZE - 4; + if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5; // user supplied filename? if (len < 1) { @@ -1593,7 +1595,7 @@ int CmdHF14AMfCLoad(const char *Cmd) return 0; } else { len = strlen(Cmd); - if (len > FILE_PATH_SIZE - 4) len = FILE_PATH_SIZE - 4; + if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5; memcpy(filename, Cmd, len); fnameptr += len; @@ -1762,7 +1764,7 @@ int CmdHF14AMfCSave(const char *Cmd) { return 0; } else { len = strlen(Cmd); - if (len > FILE_PATH_SIZE - 4) len = FILE_PATH_SIZE - 4; + if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5; // get filename based on UID if (len < 1) { @@ -1906,6 +1908,11 @@ int CmdHF14AMfSniff(const char *Cmd){ bufsize = traceLen; memset(buf, 0x00, traceLen); } + if (bufPtr == NULL) { + PrintAndLog("Cannot allocate memory for trace"); + free(buf); + return 2; + } memcpy(bufPtr, resp.d.asBytes, len); bufPtr += len; pckNum++; diff --git a/client/util.c b/client/util.c index c4f7d200..e5cbc4aa 100644 --- a/client/util.c +++ b/client/util.c @@ -23,7 +23,7 @@ int ukbhit(void) static struct termios Otty, Ntty; - tcgetattr( 0, &Otty); + if ( tcgetattr( 0, &Otty) == -1 ) return -1; Ntty = Otty; Ntty.c_iflag = 0; /* input mode */ @@ -140,8 +140,9 @@ char *sprint_bin_break(const uint8_t *data, const size_t len, const uint8_t brea size_t in_index = 0; // loop through the out_index to make sure we don't go too far for (size_t out_index=0; out_index < max_len; out_index++) { - // set character - sprintf(tmp++, "%u", data[in_index]); + // set character - (should be binary but verify it isn't more than 1 digit) + if (data[in_index]<10) + sprintf(tmp++, "%u", data[in_index]); // check if a line break is needed and we have room to print it in our array if ( (breaks > 0) && !((in_index+1) % breaks) && (out_index+1 != max_len) ) { // increment and print line break From 735136e6a33e4851127b45d373ea58f1710bd1f4 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sun, 14 Feb 2016 13:37:05 -0500 Subject: [PATCH 10/16] lf t55 bruteforce lots of resource leaks... plus strlen(Cmd) can never be less than 0 iceman1001 fixes... --- client/cmdlft55xx.c | 31 +++++++++++++++++++++++-------- client/cmdlfviking.c | 8 ++++---- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 348cb229..5d797edc 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -1371,11 +1371,9 @@ int CmdT55xxBruteForce(const char *Cmd) { char buf[9]; char filename[FILE_PATH_SIZE]={0}; int keycnt = 0; + int ch; uint8_t stKeyBlock = 20; - uint8_t *keyBlock = NULL, *p; - keyBlock = calloc(stKeyBlock, 6); - if (keyBlock == NULL) return 1; - + uint8_t *keyBlock = NULL, *p = NULL; uint32_t start_password = 0x00000000; //start password uint32_t end_password = 0xFFFFFFFF; //end password bool found = false; @@ -1383,6 +1381,9 @@ int CmdT55xxBruteForce(const char *Cmd) { char cmdp = param_getchar(Cmd, 0); if (cmdp == 'h' || cmdp == 'H') return usage_t55xx_bruteforce(); + keyBlock = calloc(stKeyBlock, 6); + if (keyBlock == NULL) return 1; + if (cmdp == 'i' || cmdp == 'I') { int len = strlen(Cmd+2); @@ -1417,6 +1418,7 @@ int CmdT55xxBruteForce(const char *Cmd) { if (!p) { PrintAndLog("Cannot allocate memory for defaultKeys"); free(keyBlock); + fclose(f); return 2; } keyBlock = p; @@ -1431,6 +1433,7 @@ int CmdT55xxBruteForce(const char *Cmd) { if (keycnt == 0) { PrintAndLog("No keys found in file"); + free(keyBlock); return 1; } PrintAndLog("Loaded %d keys", keycnt); @@ -1440,8 +1443,10 @@ int CmdT55xxBruteForce(const char *Cmd) { for (uint16_t c = 0; c < keycnt; ++c ) { if (ukbhit()) { - getchar(); + ch = getchar(); + (void)ch; printf("\naborted via keyboard!\n"); + free(keyBlock); return 0; } @@ -1451,6 +1456,7 @@ int CmdT55xxBruteForce(const char *Cmd) { if ( !AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, TRUE, testpwd)) { PrintAndLog("Aquireing data from device failed. Quitting"); + free(keyBlock); return 0; } @@ -1458,10 +1464,12 @@ int CmdT55xxBruteForce(const char *Cmd) { if ( found ) { PrintAndLog("Found valid password: [%08X]", testpwd); + free(keyBlock); return 0; } } PrintAndLog("Password NOT found."); + free(keyBlock); return 0; } @@ -1471,8 +1479,10 @@ int CmdT55xxBruteForce(const char *Cmd) { start_password = param_get32ex(Cmd, 0, 0, 16); end_password = param_get32ex(Cmd, 1, 0, 16); - if ( start_password >= end_password ) return usage_t55xx_bruteforce(); - + if ( start_password >= end_password ) { + free(keyBlock); + return usage_t55xx_bruteforce(); + } PrintAndLog("Search password range [%08X -> %08X]", start_password, end_password); uint32_t i = start_password; @@ -1482,13 +1492,16 @@ int CmdT55xxBruteForce(const char *Cmd) { printf("."); fflush(stdout); if (ukbhit()) { - getchar(); + ch = getchar(); + (void)ch; printf("\naborted via keyboard!\n"); + free(keyBlock); return 0; } if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, TRUE, i)) { PrintAndLog("Aquireing data from device failed. Quitting"); + free(keyBlock); return 0; } found = tryDetectModulation(); @@ -1503,6 +1516,8 @@ int CmdT55xxBruteForce(const char *Cmd) { PrintAndLog("Found valid password: [%08x]", i); else PrintAndLog("Password NOT found. Last tried: [%08x]", --i); + + free(keyBlock); return 0; } diff --git a/client/cmdlfviking.c b/client/cmdlfviking.c index 8c0656d2..5c0e590c 100644 --- a/client/cmdlfviking.c +++ b/client/cmdlfviking.c @@ -66,7 +66,7 @@ int CmdVikingClone(const char *Cmd) { uint64_t rawID = 0; bool Q5 = false; char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) < 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_viking_clone(); + if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_viking_clone(); id = param_get32ex(Cmd, 0, 0, 16); if (id == 0) return usage_lf_viking_clone(); @@ -74,8 +74,8 @@ int CmdVikingClone(const char *Cmd) { Q5 = true; rawID = getVikingBits(id); - PrintAndLog("Cloning - ID: %08X, Raw: %08X%08X",id,(uint32_t)(rawID >> 32),(uint32_t) (rawID & 0xFFFFFFFF)); - UsbCommand c = {CMD_VIKING_CLONE_TAG,{rawID >> 32, rawID & 0xFFFFFFFF, Q5}}; + + UsbCommand c = {CMD_VIKING_CLONE_TAG,{rawID >> 32, rawID & 0xFFFF, Q5}}; clearCommandBuffer(); SendCommand(&c); //check for ACK @@ -89,7 +89,7 @@ int CmdVikingSim(const char *Cmd) { uint8_t clk = 32, encoding = 1, separator = 0, invert = 0; char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) < 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_viking_sim(); + if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_viking_sim(); id = param_get32ex(Cmd, 0, 0, 16); if (id == 0) return usage_lf_viking_sim(); From d23411ef619c87b488fddff87cff3c1ffde1ac12 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sun, 14 Feb 2016 13:41:25 -0500 Subject: [PATCH 11/16] resource leak and malloc(x) cannot be negative thanks iceman1001 --- client/loclass/elite_crack.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/client/loclass/elite_crack.c b/client/loclass/elite_crack.c index c824eaa1..5dd8bf6d 100644 --- a/client/loclass/elite_crack.c +++ b/client/loclass/elite_crack.c @@ -563,15 +563,23 @@ int bruteforceFile(const char *filename, uint16_t keytable[]) long fsize = ftell(f); fseek(f, 0, SEEK_SET); + if (fsize < 0) { + prnlog("Error, when getting fsize"); + fclose(f); + return 1; + } + uint8_t *dump = malloc(fsize); size_t bytes_read = fread(dump, 1, fsize, f); fclose(f); - if (bytes_read < fsize) - { - prnlog("Error, could only read %d bytes (should be %d)",bytes_read, fsize ); - } - return bruteforceDump(dump,fsize,keytable); + if (bytes_read < fsize) { + prnlog("Error, could only read %d bytes (should be %d)",bytes_read, fsize ); + } + + uint8_t res = bruteforceDump(dump,fsize,keytable); + free(dump); + return res; } /** * From 38d618baa9cb563ff86bda46fcabd992255afadd Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sun, 14 Feb 2016 14:43:19 -0500 Subject: [PATCH 12/16] remove redundant llx prix64 defines remove unused commented out #includes coverity indicates compressed_fpga_stream.opaque needs to be initialized to Z_NULL fgetc returns int define llu --- client/cmdhficlass.c | 4 +--- client/cmdlfem4x.c | 4 +--- client/cmdlft55xx.c | 3 --- client/fpga_compress.c | 8 +++++--- client/loclass/elite_crack.c | 4 ++-- client/proxmark3.h | 1 + 6 files changed, 10 insertions(+), 14 deletions(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 4cf9d3ea..134ca21e 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -33,8 +33,6 @@ #include "usb_cmd.h" #include "cmdhfmfu.h" -#define llX PRIx64 - static int CmdHelp(const char *Cmd); #define ICLASS_KEYS_MAX 8 @@ -1350,7 +1348,7 @@ uint64_t hexarray_to_uint64(uint8_t *key) { for (int i = 0;i < 8;i++) sprintf(&temp[(i *2)],"%02X",key[i]); temp[16] = '\0'; - if (sscanf(temp,"%016"llX,&uint_key) < 1) + if (sscanf(temp,"%016"llx,&uint_key) < 1) return 0; return uint_key; } diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index 7ff8037b..aa0fc856 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -21,8 +21,6 @@ #include "cmdlfem4x.h" #include "lfdemod.h" -#define llx PRIx64 - char *global_em410xId; static int CmdHelp(const char *Cmd); @@ -58,7 +56,7 @@ int CmdEM410xRead(const char *Cmd) return 0; } char id[12] = {0x00}; - sprintf(id, "%010llx",lo); + sprintf(id, "%010"PRIx64,lo); global_em410xId = id; return 1; diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 5d797edc..dfee9aa6 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -10,7 +10,6 @@ #include #include #include -//#include //not used - marshmellow #include "proxmark3.h" #include "ui.h" #include "graph.h" @@ -22,8 +21,6 @@ #include "util.h" #include "data.h" #include "lfdemod.h" -//#include "../common/crc.h" //not used - marshmellow -//#include "../common/iso14443crc.h" //not used - marshmellow #include "cmdhf14a.h" //for getTagInfo #define T55x7_CONFIGURATION_BLOCK 0x00 diff --git a/client/fpga_compress.c b/client/fpga_compress.c index 2779e835..0c40f22f 100644 --- a/client/fpga_compress.c +++ b/client/fpga_compress.c @@ -91,6 +91,7 @@ int zlib_compress(FILE *infile[], uint8_t num_infiles, FILE *outfile) for(uint16_t j = 0; j < num_infiles; j++) { fclose(infile[j]); } + free(fpga_config); return(EXIT_FAILURE); } @@ -112,7 +113,7 @@ int zlib_compress(FILE *infile[], uint8_t num_infiles, FILE *outfile) compressed_fpga_stream.avail_in = i; compressed_fpga_stream.zalloc = fpga_deflate_malloc; compressed_fpga_stream.zfree = fpga_deflate_free; - + compressed_fpga_stream.opaque = Z_NULL; ret = deflateInit2(&compressed_fpga_stream, COMPRESS_LEVEL, Z_DEFLATED, @@ -187,6 +188,7 @@ int zlib_decompress(FILE *infile, FILE *outfile) compressed_fpga_stream.avail_out = DECOMPRESS_BUF_SIZE; compressed_fpga_stream.zalloc = fpga_deflate_malloc; compressed_fpga_stream.zfree = fpga_deflate_free; + compressed_fpga_stream.opaque = Z_NULL; ret = inflateInit2(&compressed_fpga_stream, 0); @@ -195,9 +197,9 @@ int zlib_decompress(FILE *infile, FILE *outfile) compressed_fpga_stream.next_in = inbuf; uint16_t i = 0; do { - uint8_t c = fgetc(infile); + int c = fgetc(infile); if (!feof(infile)) { - inbuf[i++] = c; + inbuf[i++] = c & 0xFF; compressed_fpga_stream.avail_in++; } else { break; diff --git a/client/loclass/elite_crack.c b/client/loclass/elite_crack.c index 5dd8bf6d..e9814e95 100644 --- a/client/loclass/elite_crack.c +++ b/client/loclass/elite_crack.c @@ -522,8 +522,8 @@ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[]) errors += bruteforceItem(*attack, keytable); } free(attack); - clock_t t2 = clock(); - float diff = (((float)t2 - (float)t1) / CLOCKS_PER_SEC ); + t1 = clock() - t1; + float diff = ((float)t1 / CLOCKS_PER_SEC ); prnlog("\nPerformed full crack in %f seconds",diff); // Pick out the first 16 bytes of the keytable. diff --git a/client/proxmark3.h b/client/proxmark3.h index 8236bfe7..616d9c70 100644 --- a/client/proxmark3.h +++ b/client/proxmark3.h @@ -16,6 +16,7 @@ #include #define llx PRIx64 #define lli PRIi64 +#define llu PRIu64 #define hhu PRIu8 #include "usb_cmd.h" From 776f7e61601a67f1613126cb133bd5bbf94a64c4 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sun, 14 Feb 2016 17:00:20 -0500 Subject: [PATCH 13/16] put back viking clone bug fix forgot i added this on a different computer recently - forgot to merge it in... --- client/cmdlfviking.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdlfviking.c b/client/cmdlfviking.c index 5c0e590c..45e4b1d5 100644 --- a/client/cmdlfviking.c +++ b/client/cmdlfviking.c @@ -74,8 +74,8 @@ int CmdVikingClone(const char *Cmd) { Q5 = true; rawID = getVikingBits(id); - - UsbCommand c = {CMD_VIKING_CLONE_TAG,{rawID >> 32, rawID & 0xFFFF, Q5}}; + PrintAndLog("Cloning - ID: %08X, Raw: %08X%08X",id,(uint32_t)(rawID >> 32),(uint32_t) (rawID & 0xFFFFFFFF)); + UsbCommand c = {CMD_VIKING_CLONE_TAG,{rawID >> 32, rawID & 0xFFFFFFFF, Q5}}; clearCommandBuffer(); SendCommand(&c); //check for ACK From e7707cdb1713b6f0b20e47867f6675de848331e6 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sun, 14 Feb 2016 17:41:16 -0500 Subject: [PATCH 14/16] verify wait isn't null --- armsrc/iclass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 4e4854ca..f99d0eca 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -1447,7 +1447,7 @@ static void TransmitIClassCommand(const uint8_t *cmd, int len, int *samples, int } WDT_HIT(); } - if (samples) *samples = (c + *wait) << 3; + if (samples && wait) *samples = (c + *wait) << 3; } From d0168f2f4919562e94b22215a182622bca2e2785 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sun, 14 Feb 2016 18:08:14 -0500 Subject: [PATCH 15/16] clear array before assigning --- client/cmdmain.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/cmdmain.c b/client/cmdmain.c index 7bba80f4..c1d730ee 100644 --- a/client/cmdmain.c +++ b/client/cmdmain.c @@ -177,10 +177,11 @@ void UsbCommandReceived(UsbCommand *UC) switch(UC->cmd) { // First check if we are handling a debug message case CMD_DEBUG_PRINT_STRING: { - char s[USB_CMD_DATA_SIZE+1] = {0x00}; + char s[USB_CMD_DATA_SIZE+1]; + memset(s, 0x00, sizeof(s)); size_t len = MIN(UC->arg[0],USB_CMD_DATA_SIZE); memcpy(s,UC->d.asBytes,len); - PrintAndLog("#db# %s ", s); + PrintAndLog("#db# %s", s); return; } break; From 7c5e0ebe7aeef010999ec6c6809f8a0faab016ae Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sun, 14 Feb 2016 18:37:09 -0500 Subject: [PATCH 16/16] undo adjustments to cmdhf14a.c and cmdhfmf.c as these will be adjusted with the magic command adjustments --- client/cmdhf14a.c | 183 ++++++++++++++++++---------------------- client/cmdhfmf.c | 206 +++++++++++++++++++++------------------------- 2 files changed, 173 insertions(+), 216 deletions(-) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index b369d187..81716db3 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -352,16 +352,16 @@ int CmdHF14AReader(const char *Cmd) PrintAndLog(" x0 -> <1 kByte"); break; case 0x01: - PrintAndLog(" x0 -> 1 kByte"); + PrintAndLog(" x1 -> 1 kByte"); break; case 0x02: - PrintAndLog(" x0 -> 2 kByte"); + PrintAndLog(" x2 -> 2 kByte"); break; case 0x03: - PrintAndLog(" x0 -> 4 kByte"); + PrintAndLog(" x3 -> 4 kByte"); break; case 0x04: - PrintAndLog(" x0 -> 8 kByte"); + PrintAndLog(" x4 -> 8 kByte"); break; } switch (card.ats[pos + 3] & 0xf0) { @@ -458,110 +458,86 @@ int CmdHF14ACUIDs(const char *Cmd) return 1; } -int usage_hf_14a_sim(void) { - PrintAndLog("\n Emulating ISO/IEC 14443 type A tag with 4 or 7 byte UID\n"); - PrintAndLog("Usage: hf 14a sim t u x"); - PrintAndLog(" Options : "); - PrintAndLog(" h : this help"); - PrintAndLog(" t : 1 = MIFARE Classic"); - PrintAndLog(" 2 = MIFARE Ultralight"); - PrintAndLog(" 3 = MIFARE Desfire"); - PrintAndLog(" 4 = ISO/IEC 14443-4"); - PrintAndLog(" 5 = MIFARE Tnp3xxx"); - PrintAndLog(" 6 = MIFARE Mini"); - PrintAndLog(" 7 = NTAG 215 from emu mem"); - PrintAndLog(" u : 4 or 7 byte UID"); - PrintAndLog(" x : (Optional) performs the 'reader attack', nr/ar attack against a legitimate reader"); - PrintAndLog("\n sample : hf 14a sim t 1 u 1122344"); - PrintAndLog(" : hf 14a sim t 1 u 1122344 x\n"); - return 0; -} // ## simulate iso14443a tag // ## greg - added ability to specify tag UID int CmdHF14ASim(const char *Cmd) { - bool errors = FALSE; - uint8_t flags = 0; - uint8_t tagtype = 1; - uint64_t uid = 0; - uint8_t cmdp = 0; - - while(param_getchar(Cmd, cmdp) != 0x00) - { - switch(param_getchar(Cmd, cmdp)) - { - case 'h': - case 'H': - return usage_hf_14a_sim(); - case 't': - case 'T': - // Retrieve the tag type - tagtype = param_get8ex(Cmd, cmdp+1, 0, 10); - if (tagtype == 0) - errors = true; - cmdp += 2; - break; - case 'u': - case 'U': - // Retrieve the full 4 or 7 byte long uid - uid = param_get64ex(Cmd, cmdp+1, 0, 16); - if (uid == 0 ) - errors = TRUE; - - if (uid > 0xffffffff) { - PrintAndLog("Emulating ISO/IEC 14443 type A tag with 7 byte UID (%014"llx")",uid); - flags |= FLAG_7B_UID_IN_DATA; - } else { - PrintAndLog("Emulating ISO/IEC 14443 type A tag with 4 byte UID (%08x)",uid); - flags |= FLAG_4B_UID_IN_DATA; - } - cmdp += 2; - break; - case 'x': - case 'X': - flags |= FLAG_NR_AR_ATTACK; - cmdp++; - break; - default: - PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); - errors = true; - break; - } - if(errors) break; + 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(" 5 = MIFARE Tnp3xxx"); + 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); - //Validations - if (errors) return usage_hf_14a_sim(); - - PrintAndLog("Press pm3-button to abort simulation"); - - UsbCommand c = {CMD_SIMULATE_TAG_ISO_14443a,{ tagtype, flags, 0 }}; - - num_to_bytes(uid, 7, c.d.asBytes); - clearCommandBuffer(); - SendCommand(&c); - - //uint8_t data[40]; - //uint8_t key[6]; - UsbCommand resp; - while(!ukbhit()){ - if ( WaitForResponseTimeout(CMD_ACK,&resp,1500)) { - if ( (resp.arg[0] & 0xffff) == CMD_SIMULATE_MIFARE_CARD ){ - // attempt to get key: - // TODO: - - //memset(data, 0x00, sizeof(data)); - //memset(key, 0x00, sizeof(key)); - //int len = (resp.arg[1] > sizeof(data)) ? sizeof(data) : resp.arg[1]; - //memcpy(data, resp.d.asBytes, len); - //tryMfk32(uid, data, key); - //tryMfk32_moebius(uid, data, key); - //tryMfk64(uid, data, key); - //PrintAndLog("--"); - } - } + // Are we handling the (optional) second part uid? + if (long_uid > 0xffffffff) { + PrintAndLog("Emulating ISO/IEC 14443 type A tag with 7 byte UID (%014"llx")",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; } - return 0; +/* + // 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); + } +*/ +// 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) { @@ -729,9 +705,8 @@ int CmdHF14ACmdRaw(const char *cmd) { if(topazmode) c.arg[0] |= ISO14A_TOPAZMODE; - // Max buffer is USB_CMD_DATA_SIZE - datalen = (datalen > USB_CMD_DATA_SIZE) ? USB_CMD_DATA_SIZE : datalen; - c.arg[1] = (datalen & 0xFFFF) | ( (uint32_t)(numbits) << 16); + // Max buffer is USB_CMD_DATA_SIZE + c.arg[1] = (datalen & 0xFFFF) | (numbits << 16); memcpy(c.d.asBytes,data,datalen); SendCommand(&c); diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index d306ac65..48e78b1c 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -121,11 +121,10 @@ int CmdHF14AMfWrBl(const char *Cmd) PrintAndLog("--block no:%d, key type:%c, key:%s", blockNo, keyType?'B':'A', sprint_hex(key, 6)); PrintAndLog("--data: %s", sprint_hex(bldata, 16)); - UsbCommand c = {CMD_MIFARE_WRITEBL, {blockNo, keyType, 0}}; + UsbCommand c = {CMD_MIFARE_WRITEBL, {blockNo, keyType, 0}}; memcpy(c.d.asBytes, key, 6); memcpy(c.d.asBytes + 10, bldata, 16); - clearCommandBuffer(); - SendCommand(&c); + SendCommand(&c); UsbCommand resp; if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { @@ -143,7 +142,7 @@ int CmdHF14AMfRdBl(const char *Cmd) uint8_t blockNo = 0; uint8_t keyType = 0; uint8_t key[6] = {0, 0, 0, 0, 0, 0}; - + char cmdp = 0x00; @@ -151,8 +150,8 @@ int CmdHF14AMfRdBl(const char *Cmd) PrintAndLog("Usage: hf mf rdbl "); PrintAndLog(" sample: hf mf rdbl 0 A FFFFFFFFFFFF "); return 0; - } - + } + blockNo = param_get8(Cmd, 0); cmdp = param_getchar(Cmd, 1); if (cmdp == 0x00) { @@ -165,11 +164,10 @@ int CmdHF14AMfRdBl(const char *Cmd) return 1; } PrintAndLog("--block no:%d, key type:%c, key:%s ", blockNo, keyType?'B':'A', sprint_hex(key, 6)); - - UsbCommand c = {CMD_MIFARE_READBL, {blockNo, keyType, 0}}; + + UsbCommand c = {CMD_MIFARE_READBL, {blockNo, keyType, 0}}; memcpy(c.d.asBytes, key, 6); - clearCommandBuffer(); - SendCommand(&c); + SendCommand(&c); UsbCommand resp; if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { @@ -219,10 +217,9 @@ int CmdHF14AMfRdSc(const char *Cmd) return 1; } PrintAndLog("--sector no:%d key type:%c key:%s ", sectorNo, keyType?'B':'A', sprint_hex(key, 6)); - + UsbCommand c = {CMD_MIFARE_READSC, {sectorNo, keyType, 0}}; memcpy(c.d.asBytes, key, 6); - clearCommandBuffer(); SendCommand(&c); PrintAndLog(" "); @@ -242,7 +239,7 @@ int CmdHF14AMfRdSc(const char *Cmd) PrintAndLog("Command execute timeout"); } - return 0; + return 0; } uint8_t FirstBlockOfSector(uint8_t sectorNo) @@ -266,7 +263,7 @@ uint8_t NumBlocksPerSector(uint8_t sectorNo) int CmdHF14AMfDump(const char *Cmd) { uint8_t sectorNo, blockNo; - + uint8_t keyA[40][6]; uint8_t keyB[40][6]; uint8_t rights[40][4]; @@ -319,17 +316,16 @@ int CmdHF14AMfDump(const char *Cmd) return 2; } } - + fclose(fin); PrintAndLog("|-----------------------------------------|"); PrintAndLog("|------ Reading sector access bits...-----|"); PrintAndLog("|-----------------------------------------|"); - + for (sectorNo = 0; sectorNo < numSectors; sectorNo++) { UsbCommand c = {CMD_MIFARE_READBL, {FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 0, 0}}; memcpy(c.d.asBytes, keyA[sectorNo], 6); - clearCommandBuffer(); SendCommand(&c); if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { @@ -351,11 +347,11 @@ int CmdHF14AMfDump(const char *Cmd) rights[sectorNo][3] = 0x01; } } - + PrintAndLog("|-----------------------------------------|"); PrintAndLog("|----- Dumping all blocks to file... -----|"); PrintAndLog("|-----------------------------------------|"); - + bool isOK = true; for (sectorNo = 0; isOK && sectorNo < numSectors; sectorNo++) { for (blockNo = 0; isOK && blockNo < NumBlocksPerSector(sectorNo); blockNo++) { @@ -364,7 +360,6 @@ int CmdHF14AMfDump(const char *Cmd) if (blockNo == NumBlocksPerSector(sectorNo) - 1) { // sector trailer. At least the Access Conditions can always be read with key A. UsbCommand c = {CMD_MIFARE_READBL, {FirstBlockOfSector(sectorNo) + blockNo, 0, 0}}; memcpy(c.d.asBytes, keyA[sectorNo], 6); - clearCommandBuffer(); SendCommand(&c); received = WaitForResponseTimeout(CMD_ACK,&resp,1500); } else { // data block. Check if it can be read with key A or key B @@ -372,7 +367,6 @@ int CmdHF14AMfDump(const char *Cmd) if ((rights[sectorNo][data_area] == 0x03) || (rights[sectorNo][data_area] == 0x05)) { // only key B would work UsbCommand c = {CMD_MIFARE_READBL, {FirstBlockOfSector(sectorNo) + blockNo, 1, 0}}; memcpy(c.d.asBytes, keyB[sectorNo], 6); - clearCommandBuffer(); SendCommand(&c); received = WaitForResponseTimeout(CMD_ACK,&resp,1500); } else if (rights[sectorNo][data_area] == 0x07) { // no key would work @@ -381,7 +375,6 @@ int CmdHF14AMfDump(const char *Cmd) } else { // key A would work UsbCommand c = {CMD_MIFARE_READBL, {FirstBlockOfSector(sectorNo) + blockNo, 0, 0}}; memcpy(c.d.asBytes, keyA[sectorNo], 6); - clearCommandBuffer(); SendCommand(&c); received = WaitForResponseTimeout(CMD_ACK,&resp,1500); } @@ -525,7 +518,6 @@ int CmdHF14AMfRestore(const char *Cmd) PrintAndLog("Writing to block %3d: %s", FirstBlockOfSector(sectorNo) + blockNo, sprint_hex(bldata, 16)); memcpy(c.d.asBytes + 10, bldata, 16); - clearCommandBuffer(); SendCommand(&c); UsbCommand resp; @@ -875,7 +867,6 @@ int CmdHF14AMfChk(const char *Cmd) break; default: PrintAndLog("Key type must be A , B or ?"); - free(keyBlock); return 1; }; @@ -927,7 +918,6 @@ int CmdHF14AMfChk(const char *Cmd) if (!p) { PrintAndLog("Cannot allocate memory for defKeys"); free(keyBlock); - fclose(f); return 2; } keyBlock = p; @@ -1079,7 +1069,6 @@ int CmdHF14AMf1kSim(const char *Cmd) UsbCommand c = {CMD_SIMULATE_MIFARE_CARD, {flags, exitAfterNReads,0}}; memcpy(c.d.asBytes, uid, sizeof(uid)); - clearCommandBuffer(); SendCommand(&c); if(flags & FLAG_INTERACTIVE) @@ -1088,7 +1077,7 @@ int CmdHF14AMf1kSim(const char *Cmd) PrintAndLog("Press pm3-button to abort simulation"); while(! WaitForResponseTimeout(CMD_ACK,&resp,1500)) { //We're waiting only 1.5 s at a time, otherwise we get the - //annoying message about "Waiting for a response... " + // annoying message about "Waiting for a response... " } } @@ -1155,6 +1144,7 @@ int CmdHF14AMfEClear(const char *Cmd) return 0; } + int CmdHF14AMfESet(const char *Cmd) { uint8_t memBlock[16]; @@ -1182,6 +1172,7 @@ int CmdHF14AMfESet(const char *Cmd) return 0; } + int CmdHF14AMfELoad(const char *Cmd) { FILE * f; @@ -1191,13 +1182,13 @@ int CmdHF14AMfELoad(const char *Cmd) uint8_t buf8[64] = {0x00}; int i, len, blockNum, numBlocks; int nameParamNo = 1; - uint8_t blockWidth = 32; + char ctmp = param_getchar(Cmd, 0); if ( ctmp == 'h' || ctmp == 0x00) { PrintAndLog("It loads emul dump from the file `filename.eml`"); - PrintAndLog("Usage: hf mf eload [card memory] [numblocks]"); - PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K, u = UL"); + PrintAndLog("Usage: hf mf eload [card memory] "); + PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K"); PrintAndLog(""); PrintAndLog(" sample: hf mf eload filename"); PrintAndLog(" hf mf eload 4 filename"); @@ -1210,18 +1201,15 @@ int CmdHF14AMfELoad(const char *Cmd) case '\0': numBlocks = 16*4; break; case '2' : numBlocks = 32*4; break; case '4' : numBlocks = 256; break; - case 'U' : // fall through - case 'u' : numBlocks = 255; blockWidth = 8; break; default: { numBlocks = 16*4; nameParamNo = 0; } } - uint32_t numblk2 = param_get32ex(Cmd,2,0,10); - if (numblk2 > 0) numBlocks = numblk2; len = param_getstr(Cmd,nameParamNo,filename); - if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5; + + if (len > FILE_PATH_SIZE - 4) len = FILE_PATH_SIZE - 4; fnameptr += len; @@ -1247,18 +1235,19 @@ int CmdHF14AMfELoad(const char *Cmd) return 2; } - if (strlen(buf) < blockWidth){ + if (strlen(buf) < 32){ if(strlen(buf) && feof(f)) break; - PrintAndLog("File content error. Block data must include %d HEX symbols", blockWidth); + PrintAndLog("File content error. Block data must include 32 HEX symbols"); fclose(f); return 2; } - for (i = 0; i < blockWidth; i += 2) { + for (i = 0; i < 32; i += 2) { sscanf(&buf[i], "%02x", (unsigned int *)&buf8[i / 2]); - } - if (mfEmlSetMem_xt(buf8, blockNum, 1, blockWidth/2)) { + } + + if (mfEmlSetMem(buf8, blockNum, 1)) { PrintAndLog("Cant set emul block: %3d", blockNum); fclose(f); return 3; @@ -1279,6 +1268,7 @@ int CmdHF14AMfELoad(const char *Cmd) return 0; } + int CmdHF14AMfESave(const char *Cmd) { FILE * f; @@ -1318,7 +1308,7 @@ int CmdHF14AMfESave(const char *Cmd) len = param_getstr(Cmd,nameParamNo,filename); - if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5; + if (len > FILE_PATH_SIZE - 4) len = FILE_PATH_SIZE - 4; // user supplied filename? if (len < 1) { @@ -1364,6 +1354,7 @@ int CmdHF14AMfESave(const char *Cmd) return 0; } + int CmdHF14AMfECFill(const char *Cmd) { uint8_t keyType = 0; @@ -1403,6 +1394,7 @@ int CmdHF14AMfECFill(const char *Cmd) return 0; } + int CmdHF14AMfEKeyPrn(const char *Cmd) { int i; @@ -1410,9 +1402,7 @@ int CmdHF14AMfEKeyPrn(const char *Cmd) uint8_t data[16]; uint64_t keyA, keyB; - char cmdp = param_getchar(Cmd, 0); - - if ( cmdp == 'h' || cmdp == 'H') { + if (param_getchar(Cmd, 0) == 'h') { PrintAndLog("It prints the keys loaded in the emulator memory"); PrintAndLog("Usage: hf mf ekeyprn [card memory]"); PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K"); @@ -1421,6 +1411,8 @@ int CmdHF14AMfEKeyPrn(const char *Cmd) return 0; } + char cmdp = param_getchar(Cmd, 0); + switch (cmdp) { case '0' : numSectors = 5; break; case '1' : @@ -1447,6 +1439,7 @@ int CmdHF14AMfEKeyPrn(const char *Cmd) return 0; } + int CmdHF14AMfCSetUID(const char *Cmd) { uint8_t wipeCard = 0; @@ -1520,7 +1513,7 @@ int CmdHF14AMfCSetBlk(const char *Cmd) { uint8_t memBlock[16] = {0x00}; uint8_t blockNo = 0; - uint8_t params = MAGIC_SINGLE; + bool wipeCard = FALSE; int res; if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') { @@ -1539,12 +1532,10 @@ int CmdHF14AMfCSetBlk(const char *Cmd) } char ctmp = param_getchar(Cmd, 2); - if (ctmp == 'w' || ctmp == 'W') - params |= MAGIC_WIPE; - + wipeCard = (ctmp == 'w' || ctmp == 'W'); PrintAndLog("--block number:%2d data:%s", blockNo, sprint_hex(memBlock, 16)); - res = mfCSetBlock(blockNo, memBlock, NULL, params); + res = mfCSetBlock(blockNo, memBlock, NULL, wipeCard, CSETBLOCK_SINGLE_OPER); if (res) { PrintAndLog("Can't write block. error=%d", res); return 1; @@ -1552,21 +1543,18 @@ int CmdHF14AMfCSetBlk(const char *Cmd) return 0; } + int CmdHF14AMfCLoad(const char *Cmd) { FILE * f; - char filename[FILE_PATH_SIZE]; + char filename[FILE_PATH_SIZE] = {0x00}; char * fnameptr = filename; char buf[64] = {0x00}; uint8_t buf8[64] = {0x00}; uint8_t fillFromEmulator = 0; int i, len, blockNum, flags=0; - memset(filename, 0, sizeof(filename)); - - char ctmp = param_getchar(Cmd, 0); - - if (ctmp == 'h' || ctmp == 'H' || ctmp == 0x00) { + if (param_getchar(Cmd, 0) == 'h' || param_getchar(Cmd, 0)== 0x00) { PrintAndLog("It loads magic Chinese card from the file `filename.eml`"); PrintAndLog("or from emulator memory (option `e`)"); PrintAndLog("Usage: hf mf cload "); @@ -1575,6 +1563,7 @@ int CmdHF14AMfCLoad(const char *Cmd) return 0; } + char ctmp = param_getchar(Cmd, 0); if (ctmp == 'e' || ctmp == 'E') fillFromEmulator = 1; if (fillFromEmulator) { @@ -1583,11 +1572,11 @@ int CmdHF14AMfCLoad(const char *Cmd) PrintAndLog("Cant get block: %d", blockNum); return 2; } - if (blockNum == 0) flags = MAGIC_INIT + MAGIC_WUPC; // switch on field and send magic sequence + if (blockNum == 0) flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC; // switch on field and send magic sequence if (blockNum == 1) flags = 0; // just write - if (blockNum == 16 * 4 - 1) flags = MAGIC_HALT + MAGIC_OFF; // Done. Magic Halt and switch off field. + if (blockNum == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD; // Done. Magic Halt and switch off field. - if (mfCSetBlock(blockNum, buf8, NULL, flags)) { + if (mfCSetBlock(blockNum, buf8, NULL, 0, flags)) { PrintAndLog("Cant set magic card block: %d", blockNum); return 3; } @@ -1595,7 +1584,7 @@ int CmdHF14AMfCLoad(const char *Cmd) return 0; } else { len = strlen(Cmd); - if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5; + if (len > FILE_PATH_SIZE - 4) len = FILE_PATH_SIZE - 4; memcpy(filename, Cmd, len); fnameptr += len; @@ -1630,11 +1619,11 @@ int CmdHF14AMfCLoad(const char *Cmd) for (i = 0; i < 32; i += 2) sscanf(&buf[i], "%02x", (unsigned int *)&buf8[i / 2]); - if (blockNum == 0) flags = MAGIC_INIT + MAGIC_WUPC; // switch on field and send magic sequence + if (blockNum == 0) flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC; // switch on field and send magic sequence if (blockNum == 1) flags = 0; // just write - if (blockNum == 16 * 4 - 1) flags = MAGIC_HALT + MAGIC_OFF; // Done. Switch off field. + if (blockNum == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD; // Done. Switch off field. - if (mfCSetBlock(blockNum, buf8, NULL, flags)) { + if (mfCSetBlock(blockNum, buf8, NULL, 0, flags)) { PrintAndLog("Can't set magic card block: %d", blockNum); return 3; } @@ -1655,13 +1644,12 @@ int CmdHF14AMfCLoad(const char *Cmd) } int CmdHF14AMfCGetBlk(const char *Cmd) { - uint8_t data[16]; + uint8_t memBlock[16]; uint8_t blockNo = 0; int res; - memset(data, 0x00, sizeof(data)); - char ctmp = param_getchar(Cmd, 0); + memset(memBlock, 0x00, sizeof(memBlock)); - if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') { + if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') { PrintAndLog("Usage: hf mf cgetblk "); PrintAndLog("sample: hf mf cgetblk 1"); PrintAndLog("Get block data from magic Chinese card (only works with such cards)\n"); @@ -1672,29 +1660,28 @@ int CmdHF14AMfCGetBlk(const char *Cmd) { PrintAndLog("--block number:%2d ", blockNo); - res = mfCGetBlock(blockNo, data, MAGIC_SINGLE); + res = mfCGetBlock(blockNo, memBlock, CSETBLOCK_SINGLE_OPER); if (res) { PrintAndLog("Can't read block. error=%d", res); return 1; } - PrintAndLog("block data:%s", sprint_hex(data, sizeof(data))); + PrintAndLog("block data:%s", sprint_hex(memBlock, 16)); return 0; } + int CmdHF14AMfCGetSc(const char *Cmd) { - uint8_t data[16]; + uint8_t memBlock[16] = {0x00}; uint8_t sectorNo = 0; int i, res, flags; - memset(data, 0x00, sizeof(data)); - char ctmp = param_getchar(Cmd, 0); - if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') { + if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') { PrintAndLog("Usage: hf mf cgetsc "); PrintAndLog("sample: hf mf cgetsc 0"); PrintAndLog("Get sector data from magic Chinese card (only works with such cards)\n"); return 0; - } + } sectorNo = param_get8(Cmd, 0); if (sectorNo > 15) { @@ -1703,37 +1690,37 @@ int CmdHF14AMfCGetSc(const char *Cmd) { } PrintAndLog("--sector number:%d ", sectorNo); - PrintAndLog("block | data"); - flags = MAGIC_INIT + MAGIC_WUPC; + flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC; for (i = 0; i < 4; i++) { if (i == 1) flags = 0; - if (i == 3) flags = MAGIC_HALT + MAGIC_OFF; + if (i == 3) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD; - res = mfCGetBlock(sectorNo * 4 + i, data, flags); + res = mfCGetBlock(sectorNo * 4 + i, memBlock, flags); if (res) { PrintAndLog("Can't read block. %d error=%d", sectorNo * 4 + i, res); return 1; } - PrintAndLog(" %3d | %s", sectorNo * 4 + i, sprint_hex(data, sizeof(data))); + + PrintAndLog("block %3d data:%s", sectorNo * 4 + i, sprint_hex(memBlock, 16)); } return 0; } + int CmdHF14AMfCSave(const char *Cmd) { FILE * f; - char filename[FILE_PATH_SIZE]; + char filename[FILE_PATH_SIZE] = {0x00}; char * fnameptr = filename; uint8_t fillFromEmulator = 0; - uint8_t buf[64]; + uint8_t buf[64] = {0x00}; int i, j, len, flags; + + // memset(filename, 0, sizeof(filename)); + // memset(buf, 0, sizeof(buf)); - memset(filename, 0, sizeof(filename)); - memset(buf, 0, sizeof(buf)); - char ctmp = param_getchar(Cmd, 0); - - if ( ctmp == 'h' || ctmp == 'H' ) { + if (param_getchar(Cmd, 0) == 'h') { PrintAndLog("It saves `magic Chinese` card dump into the file `filename.eml` or `cardID.eml`"); PrintAndLog("or into emulator memory (option `e`)"); PrintAndLog("Usage: hf mf esave [file name w/o `.eml`][e]"); @@ -1741,21 +1728,23 @@ int CmdHF14AMfCSave(const char *Cmd) { PrintAndLog(" hf mf esave filename"); PrintAndLog(" hf mf esave e \n"); return 0; - } + } + + char ctmp = param_getchar(Cmd, 0); if (ctmp == 'e' || ctmp == 'E') fillFromEmulator = 1; if (fillFromEmulator) { // put into emulator - flags = MAGIC_INIT + MAGIC_WUPC; + flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC; for (i = 0; i < 16 * 4; i++) { if (i == 1) flags = 0; - if (i == 16 * 4 - 1) flags = MAGIC_HALT + MAGIC_OFF; - + if (i == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD; + if (mfCGetBlock(i, buf, flags)) { PrintAndLog("Cant get block: %d", i); break; } - + if (mfEmlSetMem(buf, i, 1)) { PrintAndLog("Cant set emul block: %d", i); return 3; @@ -1764,16 +1753,16 @@ int CmdHF14AMfCSave(const char *Cmd) { return 0; } else { len = strlen(Cmd); - if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5; - - // get filename based on UID + if (len > FILE_PATH_SIZE - 4) len = FILE_PATH_SIZE - 4; + if (len < 1) { - - if (mfCGetBlock(0, buf, MAGIC_SINGLE)) { + // get filename + if (mfCGetBlock(0, buf, CSETBLOCK_SINGLE_OPER)) { PrintAndLog("Cant get block: %d", 0); len = sprintf(fnameptr, "dump"); fnameptr += len; - } else { + } + else { for (j = 0; j < 7; j++, fnameptr += 2) sprintf(fnameptr, "%02x", buf[j]); } @@ -1782,9 +1771,8 @@ int CmdHF14AMfCSave(const char *Cmd) { fnameptr += len; } - // add .eml extension sprintf(fnameptr, ".eml"); - + // open file f = fopen(filename, "w+"); @@ -1794,10 +1782,10 @@ int CmdHF14AMfCSave(const char *Cmd) { } // put hex - flags = MAGIC_INIT + MAGIC_WUPC; + flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC; for (i = 0; i < 16 * 4; i++) { if (i == 1) flags = 0; - if (i == 16 * 4 - 1) flags = MAGIC_HALT + MAGIC_OFF; + if (i == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD; if (mfCGetBlock(i, buf, flags)) { PrintAndLog("Cant get block: %d", i); @@ -1807,13 +1795,15 @@ int CmdHF14AMfCSave(const char *Cmd) { fprintf(f, "%02x", buf[j]); fprintf(f,"\n"); } - fflush(f); fclose(f); + PrintAndLog("Saved to file: %s", filename); + return 0; } } + int CmdHF14AMfSniff(const char *Cmd){ bool wantLogToFile = 0; @@ -1883,10 +1873,7 @@ int CmdHF14AMfSniff(const char *Cmd){ uint16_t traceLen = resp.arg[1]; len = resp.arg[2]; - if (res == 0) { - free(buf); - return 0; // we are done - } + if (res == 0) return 0; // we are done if (res == 1) { // there is (more) data to be transferred if (pckNum == 0) { // first packet, (re)allocate necessary buffer @@ -1908,11 +1895,6 @@ int CmdHF14AMfSniff(const char *Cmd){ bufsize = traceLen; memset(buf, 0x00, traceLen); } - if (bufPtr == NULL) { - PrintAndLog("Cannot allocate memory for trace"); - free(buf); - return 2; - } memcpy(bufPtr, resp.d.asBytes, len); bufPtr += len; pckNum++; @@ -1970,7 +1952,7 @@ int CmdHF14AMfSniff(const char *Cmd){ } //needs nt, ar, at, Data to decrypt -int CmdHf14MfDecryptBytes(const char *Cmd){ +int CmdDecryptTraceCmds(const char *Cmd){ uint8_t data[50]; int len = 0; param_gethex_ex(Cmd,3,data,&len); @@ -2004,7 +1986,7 @@ static command_t CommandTable[] = {"cgetsc", CmdHF14AMfCGetSc, 0, "Read sector - Magic Chinese card"}, {"cload", CmdHF14AMfCLoad, 0, "Load dump into magic Chinese card"}, {"csave", CmdHF14AMfCSave, 0, "Save dump from magic Chinese card into file or emulator"}, - {"decrypt", CmdHf14MfDecryptBytes,1, "[nt] [ar_enc] [at_enc] [data] - to decrypt snoop or trace"}, + {"decrypt", CmdDecryptTraceCmds,1, "[nt] [ar_enc] [at_enc] [data] - to decrypt snoop or trace"}, {NULL, NULL, 0, NULL} };