X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/d08faa4e026f0eb4a9ecaf8bdda2091b4ab99565..774560e39ef23cc168daf85c0620653385a85cbc:/client/cmdhfmf.c?ds=inline diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 0a24f6da..ba8295ec 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -20,8 +20,18 @@ int CmdHF14AMifare(const char *Cmd) uint32_t nt = 0, nr = 0; uint64_t par_list = 0, ks_list = 0, r_key = 0; int16_t isOK = 0; - - UsbCommand c = {CMD_READER_MIFARE, {true, 0, 0}}; + int tmpchar; + uint8_t blockNo = 0; + + char cmdp = param_getchar(Cmd, 0); + if ( cmdp == 'H' || cmdp == 'h') { + PrintAndLog("Usage: hf mf mifare "); + PrintAndLog(" sample: hf mf mifare 0"); + return 0; + } + + blockNo = param_get8(Cmd, 0); + UsbCommand c = {CMD_READER_MIFARE, {true, blockNo, 0}}; // message printf("-------------------------------------------------------------------------\n"); @@ -29,32 +39,32 @@ int CmdHF14AMifare(const char *Cmd) printf("Press button on the proxmark3 device to abort both proxmark3 and client.\n"); printf("-------------------------------------------------------------------------\n"); + clock_t t1 = clock(); start: clearCommandBuffer(); SendCommand(&c); //flush queue - while (ukbhit()) getchar(); + while (ukbhit()) { + tmpchar = getchar(); + (void)tmpchar; + } // wait cycle while (true) { printf("."); fflush(stdout); if (ukbhit()) { - getchar(); + tmpchar = getchar(); + (void)tmpchar; printf("\naborted via keyboard!\n"); break; } UsbCommand resp; - if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) { + if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { isOK = resp.arg[0]; - 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); - nr = bytes_to_num(resp.d.asBytes + 24, 4); printf("\n\n"); switch (isOK) { case -1 : PrintAndLog("Button pressed. Aborted.\n"); break; @@ -64,6 +74,11 @@ start: PrintAndLog("generating polynomial with 16 effective bits only, but shows unexpected behaviour.\n"); break; default: ; } + 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); + nr = bytes_to_num(resp.d.asBytes + 24, 4); break; } } @@ -81,12 +96,12 @@ start: c.arg[0] = false; goto start; } else { - isOK = 0; - printf("------------------------------------------------------------------\n"); PrintAndLog("Found valid key: %012"llx" \n", r_key); } - PrintAndLog(""); + t1 = clock() - t1; + if ( t1 > 0 ) + PrintAndLog("Time in darkside: %.0f ticks\n", (float)t1); return 0; } @@ -305,8 +320,10 @@ int CmdHF14AMfDump(const char *Cmd) } // Read keys A from file + size_t bytes_read; for (sectorNo=0; sectorNo 0 ) + PrintAndLog("Time to check 6 known keys: %.0f ticks", (float)t2 ); + + PrintAndLog("enter nested..."); // nested sectors iterations = 0; - PrintAndLog("nested..."); bool calibrate = true; + for (i = 0; i < NESTED_SECTOR_RETRY; i++) { - for (uint8_t sectorNo = 0; sectorNo < SectorsCnt; sectorNo++) { - for (trgKeyType = 0; trgKeyType < 2; trgKeyType++) { + for (uint8_t sectorNo = 0; sectorNo < SectorsCnt; ++sectorNo) { + for (trgKeyType = 0; trgKeyType < 2; ++trgKeyType) { + if (e_sector[sectorNo].foundKey[trgKeyType]) continue; - PrintAndLog("-----------------------------------------------"); + int16_t isOK = mfnested(blockNo, keyType, key, FirstBlockOfSector(sectorNo), trgKeyType, keyBlock, calibrate); - if(isOK) { - switch (isOK) { - case -1 : PrintAndLog("Error: No response from Proxmark.\n"); break; - case -2 : PrintAndLog("Button pressed. Aborted.\n"); break; - case -3 : PrintAndLog("Tag isn't vulnerable to Nested Attack (random numbers are not predictable).\n"); break; - default : PrintAndLog("Unknown Error.\n"); - } - free(e_sector); - return 2; - } else { - calibrate = false; + switch (isOK) { + case -1 : PrintAndLog("Error: No response from Proxmark.\n"); break; + case -2 : PrintAndLog("Button pressed. Aborted.\n"); break; + case -3 : PrintAndLog("Tag isn't vulnerable to Nested Attack (random numbers are not predictable).\n"); break; + case -4 : //key not found + calibrate = false; + iterations++; + continue; + case -5 : + calibrate = false; + iterations++; + e_sector[sectorNo].foundKey[trgKeyType] = 1; + e_sector[sectorNo].Key[trgKeyType] = bytes_to_num(keyBlock, 6); + continue; + + default : PrintAndLog("Unknown Error.\n"); } - - iterations++; + free(e_sector); + return 2; + } + } + } + + t1 = clock() - t1; + if ( t1 > 0 ) + PrintAndLog("Time in nested: %.0f ticks \n", (float)t1); - key64 = bytes_to_num(keyBlock, 6); - if (key64) { - PrintAndLog("Found valid key:%012"llx, key64); - e_sector[sectorNo].foundKey[trgKeyType] = 1; - e_sector[sectorNo].Key[trgKeyType] = key64; - } + // 20160116 If Sector A is found, but not Sector B, try just reading it of the tag? + PrintAndLog("trying to read key B..."); + for (i = 0; i < SectorsCnt; i++) { + // KEY A but not KEY B + if ( e_sector[i].foundKey[0] && !e_sector[i].foundKey[1] ) { + + uint8_t sectrail = (FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1); + + PrintAndLog("Reading block %d", sectrail); + + UsbCommand c = {CMD_MIFARE_READBL, {sectrail, 0, 0}}; + num_to_bytes(e_sector[i].Key[0], 6, c.d.asBytes); // KEY A + clearCommandBuffer(); + SendCommand(&c); + + UsbCommand resp; + if ( !WaitForResponseTimeout(CMD_ACK,&resp,1500)) continue; + + uint8_t isOK = resp.arg[0] & 0xff; + if (!isOK) continue; + + uint8_t *data = resp.d.asBytes; + key64 = bytes_to_num(data+10, 6); + if (key64) { + PrintAndLog("Data:%s", sprint_hex(data+10, 6)); + e_sector[i].foundKey[1] = TRUE; + e_sector[i].Key[1] = key64; } } } - printf("Time in nested: %1.3f (%1.3f sec per key)\n\n", ((float)clock() - time1)/CLOCKS_PER_SEC, ((float)clock() - time1)/iterations/CLOCKS_PER_SEC); - PrintAndLog("-----------------------------------------------\nIterations count: %d\n\n", iterations); //print them - PrintAndLog("|---|----------------|---|----------------|---|"); - PrintAndLog("|sec|key A |res|key B |res|"); - PrintAndLog("|---|----------------|---|----------------|---|"); - for (i = 0; i < SectorsCnt; i++) { - PrintAndLog("|%03d| %012"llx" | %d | %012"llx" | %d |", i, - e_sector[i].Key[0], e_sector[i].foundKey[0], e_sector[i].Key[1], e_sector[i].foundKey[1]); - } - PrintAndLog("|---|----------------|---|----------------|---|"); + printKeyTable( SectorsCnt, e_sector ); // transfer them to the emulator if (transferToEml) { @@ -799,14 +837,16 @@ int CmdHF14AMfNestedHard(const char *Cmd) uint8_t trgBlockNo = 0; uint8_t trgKeyType = 0; uint8_t key[6] = {0, 0, 0, 0, 0, 0}; + uint8_t trgkey[6] = {0, 0, 0, 0, 0, 0}; char ctmp; ctmp = param_getchar(Cmd, 0); - if (ctmp != 'R' && ctmp != 'r' && strlen(Cmd) < 20) { + + if (ctmp != 'R' && ctmp != 'r' && ctmp != 'T' && ctmp != 't' && strlen(Cmd) < 20) { PrintAndLog("Usage:"); PrintAndLog(" hf mf hardnested "); - PrintAndLog(" [w] [s]"); - PrintAndLog(" or hf mf hardnested r"); + PrintAndLog(" [known target key (12 hex symbols)] [w] [s]"); + PrintAndLog(" or hf mf hardnested r [known target key]"); PrintAndLog(" "); PrintAndLog("Options: "); PrintAndLog(" w: Acquire nonces and write them to binary file nonces.bin"); @@ -817,20 +857,27 @@ int CmdHF14AMfNestedHard(const char *Cmd) PrintAndLog(" sample2: hf mf hardnested 0 A FFFFFFFFFFFF 4 A w"); PrintAndLog(" sample3: hf mf hardnested 0 A FFFFFFFFFFFF 4 A w s"); PrintAndLog(" sample4: hf mf hardnested r"); - + PrintAndLog(" "); + PrintAndLog("Add the known target key to check if it is present in the remaining key space:"); + PrintAndLog(" sample5: hf mf hardnested 0 A A0A1A2A3A4A5 4 A FFFFFFFFFFFF"); return 0; } + bool know_target_key = false; bool nonce_file_read = false; bool nonce_file_write = false; bool slow = false; + int tests = 0; + if (ctmp == 'R' || ctmp == 'r') { - nonce_file_read = true; - + if (!param_gethex(Cmd, 1, trgkey, 12)) { + know_target_key = true; + } + } else if (ctmp == 'T' || ctmp == 't') { + tests = param_get32ex(Cmd, 1, 100, 10); } else { - blockNo = param_get8(Cmd, 0); ctmp = param_getchar(Cmd, 1); if (ctmp != 'a' && ctmp != 'A' && ctmp != 'b' && ctmp != 'B') { @@ -857,6 +904,12 @@ int CmdHF14AMfNestedHard(const char *Cmd) } uint16_t i = 5; + + if (!param_gethex(Cmd, 5, trgkey, 12)) { + know_target_key = true; + i++; + } + while ((ctmp = param_getchar(Cmd, i))) { if (ctmp == 's' || ctmp == 'S') { slow = true; @@ -870,12 +923,17 @@ int CmdHF14AMfNestedHard(const char *Cmd) } } - PrintAndLog("--target block no:%3d, target key type:%c, file action: %s, Slow: %s ", + PrintAndLog("--target block no:%3d, target key type:%c, known target key: 0x%02x%02x%02x%02x%02x%02x%s, file action: %s, Slow: %s, Tests: %d ", trgBlockNo, trgKeyType?'B':'A', + trgkey[0], trgkey[1], trgkey[2], trgkey[3], trgkey[4], trgkey[5], + know_target_key?"":" (not set)", nonce_file_write?"write":nonce_file_read?"read":"none", - slow?"Yes":"No"); - int16_t isOK = mfnestedhard(blockNo, keyType, key, trgBlockNo, trgKeyType, nonce_file_read, nonce_file_write, slow); + slow?"Yes":"No", + tests); + + int16_t isOK = mfnestedhard(blockNo, keyType, key, trgBlockNo, trgKeyType, know_target_key?trgkey:NULL, nonce_file_read, nonce_file_write, slow, tests); + if (isOK) { switch (isOK) { case 1 : PrintAndLog("Error: No response from Proxmark.\n"); break; @@ -908,6 +966,8 @@ int CmdHF14AMfChk(const char *Cmd) uint8_t *keyBlock = NULL, *p; uint8_t stKeyBlock = 20; + sector *e_sector = NULL; + int i, res; int keycnt = 0; char ctmp = 0x00; @@ -916,14 +976,15 @@ int CmdHF14AMfChk(const char *Cmd) uint8_t keyType = 0; uint64_t key64 = 0; + uint8_t tempkey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + int transferToEml = 0; int createDumpFile = 0; keyBlock = calloc(stKeyBlock, 6); if (keyBlock == NULL) return 1; - uint64_t defaultKeys[] = - { + uint64_t defaultKeys[] = { 0xffffffffffff, // Default key (first key used by program if no user defined key) 0x000000000000, // Blank key 0xa0a1a2a3a4a5, // NFCForum MAD key @@ -941,9 +1002,8 @@ int CmdHF14AMfChk(const char *Cmd) int defaultKeysSize = sizeof(defaultKeys) / sizeof(uint64_t); for (int defaultKeyCounter = 0; defaultKeyCounter < defaultKeysSize; defaultKeyCounter++) - { num_to_bytes(defaultKeys[defaultKeyCounter], 6, (uint8_t*)(keyBlock + defaultKeyCounter * 6)); - } + if (param_getchar(Cmd, 0)=='*') { blockNo = 3; @@ -954,9 +1014,9 @@ int CmdHF14AMfChk(const char *Cmd) case '4': SectorsCnt = 40; break; default: SectorsCnt = 16; } - } - else + } else { blockNo = param_get8(Cmd, 0); + } ctmp = param_getchar(Cmd, 1); switch (ctmp) { @@ -971,6 +1031,7 @@ int CmdHF14AMfChk(const char *Cmd) break; default: PrintAndLog("Key type must be A , B or ?"); + free(keyBlock); return 1; }; @@ -989,7 +1050,7 @@ int CmdHF14AMfChk(const char *Cmd) } keyBlock = p; } - PrintAndLog("chk key[%2d] %02x%02x%02x%02x%02x%02x", keycnt, + PrintAndLog("key[%2d] %02x%02x%02x%02x%02x%02x", keycnt, (keyBlock + 6*keycnt)[0],(keyBlock + 6*keycnt)[1], (keyBlock + 6*keycnt)[2], (keyBlock + 6*keycnt)[3], (keyBlock + 6*keycnt)[4], (keyBlock + 6*keycnt)[5], 6); keycnt++; @@ -1022,13 +1083,14 @@ int CmdHF14AMfChk(const char *Cmd) if (!p) { PrintAndLog("Cannot allocate memory for defKeys"); free(keyBlock); + fclose(f); return 2; } keyBlock = p; } memset(keyBlock + 6 * keycnt, 0, 6); num_to_bytes(strtoll(buf, NULL, 16), 6, keyBlock + 6*keycnt); - PrintAndLog("chk custom key[%2d] %012"llx, keycnt, bytes_to_num(keyBlock + 6*keycnt, 6)); + PrintAndLog("check key[%2d] %012"llx, keycnt, bytes_to_num(keyBlock + 6*keycnt, 6)); keycnt++; memset(buf, 0, sizeof(buf)); } @@ -1045,80 +1107,147 @@ int CmdHF14AMfChk(const char *Cmd) if (keycnt == 0) { PrintAndLog("No key specified, trying default keys"); for (;keycnt < defaultKeysSize; keycnt++) - PrintAndLog("chk default key[%2d] %02x%02x%02x%02x%02x%02x", keycnt, + PrintAndLog("key[%2d] %02x%02x%02x%02x%02x%02x", keycnt, (keyBlock + 6*keycnt)[0],(keyBlock + 6*keycnt)[1], (keyBlock + 6*keycnt)[2], (keyBlock + 6*keycnt)[3], (keyBlock + 6*keycnt)[4], (keyBlock + 6*keycnt)[5], 6); } // initialize storage for found keys - bool validKey[2][40]; - uint8_t foundKey[2][40][6]; - for (uint16_t t = 0; t < 2; t++) { - for (uint16_t sectorNo = 0; sectorNo < SectorsCnt; sectorNo++) { - validKey[t][sectorNo] = false; - for (uint16_t i = 0; i < 6; i++) { - foundKey[t][sectorNo][i] = 0xff; - } - } + e_sector = calloc(SectorsCnt, sizeof(sector)); + if (e_sector == NULL) { + free(keyBlock); + return 1; } + + uint8_t trgKeyType = 0; + uint32_t max_keys = keycnt > (USB_CMD_DATA_SIZE/6) ? (USB_CMD_DATA_SIZE/6) : keycnt; - for ( int t = !keyType; t < 2; keyType==2?(t++):(t=2) ) { - int b=blockNo; + // time + clock_t t1 = clock(); + + // check keys. + for (trgKeyType = !keyType; trgKeyType < 2; (keyType==2) ? (++trgKeyType) : (trgKeyType=2) ) { + + int b = blockNo; for (int i = 0; i < SectorsCnt; ++i) { - PrintAndLog("--sector:%2d, block:%3d, key type:%C, key count:%2d ", i, b, t?'B':'A', keycnt); - uint32_t max_keys = keycnt>USB_CMD_DATA_SIZE/6?USB_CMD_DATA_SIZE/6:keycnt; - for (uint32_t c = 0; c < keycnt; c+=max_keys) { - uint32_t size = keycnt-c>max_keys?max_keys:keycnt-c; - res = mfCheckKeys(b, t, true, size, &keyBlock[6*c], &key64); - if (res != 1) { - if (!res) { - PrintAndLog("Found valid key:[%012"llx"]",key64); - num_to_bytes(key64, 6, foundKey[t][i]); - validKey[t][i] = true; - } - } else { - PrintAndLog("Command execute timeout"); + + // skip already found keys. + if (e_sector[i].foundKey[trgKeyType]) continue; + + + for (uint32_t c = 0; c < keycnt; c += max_keys) { + + uint32_t size = keycnt-c > max_keys ? max_keys : keycnt-c; + + res = mfCheckKeys(b, trgKeyType, true, size, &keyBlock[6*c], &key64); + if (!res) { + //PrintAndLog("Sector:%3d Block:%3d, key type: %C -- Found key [%012"llx"]", i, b, trgKeyType ? 'B':'A', key64); + + e_sector[i].Key[trgKeyType] = key64; + e_sector[i].foundKey[trgKeyType] = TRUE; + break; + } else { + e_sector[i].Key[trgKeyType] = 0xffffffffffff; + e_sector[i].foundKey[trgKeyType] = FALSE; } + printf("."); } - b<127?(b+=4):(b+=16); + b < 127 ? ( b +=4 ) : ( b += 16 ); } } + t1 = clock() - t1; + if ( t1 > 0 ) + printf("\nTime in checkkeys: %.0f ticks\n", (float)t1); + + // 20160116 If Sector A is found, but not Sector B, try just reading it of the tag? + PrintAndLog("testing to read B..."); + for (i = 0; i < SectorsCnt; i++) { + // KEY A but not KEY B + if ( e_sector[i].foundKey[0] && !e_sector[i].foundKey[1] ) { + + uint8_t sectrail = (FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1); + + PrintAndLog("Reading block %d", sectrail); + + UsbCommand c = {CMD_MIFARE_READBL, {sectrail, 0, 0}}; + num_to_bytes(e_sector[i].Key[0], 6, c.d.asBytes); // KEY A + clearCommandBuffer(); + SendCommand(&c); - if (transferToEml) { - uint8_t block[16]; - for (uint16_t sectorNo = 0; sectorNo < SectorsCnt; sectorNo++) { - if (validKey[0][sectorNo] || validKey[1][sectorNo]) { - mfEmlGetMem(block, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1); - for (uint16_t t = 0; t < 2; t++) { - if (validKey[t][sectorNo]) { - memcpy(block + t*10, foundKey[t][sectorNo], 6); - } - } - mfEmlSetMem(block, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1); + UsbCommand resp; + if ( !WaitForResponseTimeout(CMD_ACK,&resp,1500)) continue; + + uint8_t isOK = resp.arg[0] & 0xff; + if (!isOK) continue; + + uint8_t *data = resp.d.asBytes; + key64 = bytes_to_num(data+10, 6); + if (key64) { + PrintAndLog("Data:%s", sprint_hex(data+10, 6)); + e_sector[i].foundKey[1] = 1; + e_sector[i].Key[1] = key64; } } - PrintAndLog("Found keys have been transferred to the emulator memory"); } + + //print them + printKeyTable( SectorsCnt, e_sector ); + + if (transferToEml) { + uint8_t block[16] = {0x00}; + for (uint8_t i = 0; i < SectorsCnt; ++i ) { + mfEmlGetMem(block, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1); + if (e_sector[i].foundKey[0]) + num_to_bytes(e_sector[i].Key[0], 6, block); + if (e_sector[i].foundKey[1]) + num_to_bytes(e_sector[i].Key[1], 6, block+10); + mfEmlSetMem(block, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1); + } + PrintAndLog("Found keys have been transferred to the emulator memory"); + } + if (createDumpFile) { FILE *fkeys = fopen("dumpkeys.bin","wb"); if (fkeys == NULL) { PrintAndLog("Could not create file dumpkeys.bin"); free(keyBlock); + free(e_sector); return 1; } - for (uint16_t t = 0; t < 2; t++) { - fwrite(foundKey[t], 1, 6*SectorsCnt, fkeys); + PrintAndLog("Printing keys to binary file dumpkeys.bin..."); + + for( i=0; i sizeof(data)) ? sizeof(data) : resp.arg[1]; - - memcpy(data, resp.d.asBytes, len); - - uint64_t corr_uid = 0; - if ( memcmp(data, "\x00\x00\x00\x00", 4) == 0 ) { - corr_uid = (data[3] << 24) | (data[2] << 16) | (data[1] << 8) | data[0]; - } - else { - corr_uid |= (uint64_t)data[2] << 48; - corr_uid |= (uint64_t)data[1] << 40; - corr_uid |= (uint64_t)data[0] << 32; - corr_uid |= data[7] << 24; - corr_uid |= data[6] << 16; - corr_uid |= data[5] << 8; - corr_uid |= data[4]; - } + PrintAndLog("Press pm3-button or send another cmd to abort simulation"); + + while( !ukbhit() ){ + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500) ) continue; + + if ( !(flags & FLAG_NR_AR_ATTACK) ) break; + + if ( (resp.arg[0] & 0xffff) != CMD_SIMULATE_MIFARE_CARD ) break; + + 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); + + uint64_t corr_uid = 0; + + // this IF? what was I thinking of? + if ( memcmp(data, "\x00\x00\x00\x00", 4) == 0 ) { + corr_uid = ((uint64_t)(data[3] << 24)) | (data[2] << 16) | (data[1] << 8) | data[0]; tryMfk32(corr_uid, data, key); - //tryMfk64(corr_uid, data, key); - PrintAndLog("--"); + } else { + corr_uid |= (uint64_t)data[2] << 48; + corr_uid |= (uint64_t)data[1] << 40; + corr_uid |= (uint64_t)data[0] << 32; + corr_uid |= (uint64_t)data[7] << 24; + corr_uid |= (uint64_t)data[6] << 16; + corr_uid |= (uint64_t)data[5] << 8; + corr_uid |= (uint64_t)data[4]; + tryMfk64(corr_uid, data, key); } - } + PrintAndLog("--"); } } return 0; @@ -1317,7 +1454,7 @@ int CmdHF14AMfELoad(const char *Cmd) if ( ctmp == 'h' || ctmp == 'H' || ctmp == 0x00) { PrintAndLog("It loads emul dump from the file `filename.eml`"); - PrintAndLog("Usage: hf mf eload [card memory] "); + 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"); @@ -1331,17 +1468,19 @@ 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 , NTAG 215 has 135blocks a 540 bytes. - case 'u' : numBlocks = 135; blockWidth = 8; 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; + if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5; fnameptr += len; @@ -1438,7 +1577,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) { @@ -1715,7 +1854,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; @@ -1756,6 +1895,7 @@ int CmdHF14AMfCLoad(const char *Cmd) if (mfCSetBlock(blockNum, buf8, NULL, flags)) { PrintAndLog("Can't set magic card block: %d", blockNum); + fclose(f); return 3; } blockNum++; @@ -1799,7 +1939,7 @@ int CmdHF14AMfCGetBlk(const char *Cmd) { return 1; } - PrintAndLog("data:%s", sprint_hex(data, sizeof(data))); + PrintAndLog("data: %s", sprint_hex(data, sizeof(data))); return 0; } @@ -1885,7 +2025,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) { @@ -1943,6 +2083,7 @@ int CmdHF14AMfSniff(const char *Cmd){ bool wantSaveToEmlFile = 0; //var + int tmpchar; int res = 0; int len = 0; int blockLen = 0; @@ -1993,7 +2134,8 @@ int CmdHF14AMfSniff(const char *Cmd){ printf("."); fflush(stdout); if (ukbhit()) { - getchar(); + tmpchar = getchar(); + (void)tmpchar; printf("\naborted via keyboard!\n"); break; } @@ -2004,7 +2146,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 @@ -2026,6 +2171,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++; @@ -2102,48 +2252,46 @@ int CmdHf14MfDecryptBytes(const char *Cmd){ return tryDecryptWord( nt, ar_enc, at_enc, data, len); } -static command_t CommandTable[] = -{ - {"help", CmdHelp, 1, "This help"}, - {"dbg", CmdHF14AMfDbg, 0, "Set default debug mode"}, - {"rdbl", CmdHF14AMfRdBl, 0, "Read MIFARE classic block"}, - {"rdsc", CmdHF14AMfRdSc, 0, "Read MIFARE classic sector"}, - {"dump", CmdHF14AMfDump, 0, "Dump MIFARE classic tag to binary file"}, - {"restore", CmdHF14AMfRestore, 0, "Restore MIFARE classic binary file to BLANK tag"}, - {"wrbl", CmdHF14AMfWrBl, 0, "Write MIFARE classic block"}, - {"chk", CmdHF14AMfChk, 0, "Test block keys"}, - {"mifare", CmdHF14AMifare, 0, "Read parity error messages."}, - {"nested", CmdHF14AMfNested, 0, "Test nested authentication"}, +static command_t CommandTable[] = { + {"help", CmdHelp, 1, "This help"}, + {"dbg", CmdHF14AMfDbg, 0, "Set default debug mode"}, + {"rdbl", CmdHF14AMfRdBl, 0, "Read MIFARE classic block"}, + {"rdsc", CmdHF14AMfRdSc, 0, "Read MIFARE classic sector"}, + {"dump", CmdHF14AMfDump, 0, "Dump MIFARE classic tag to binary file"}, + {"restore", CmdHF14AMfRestore, 0, "Restore MIFARE classic binary file to BLANK tag"}, + {"wrbl", CmdHF14AMfWrBl, 0, "Write MIFARE classic block"}, + {"chk", CmdHF14AMfChk, 0, "Test block keys"}, + {"mifare", CmdHF14AMifare, 0, "Read parity error messages."}, + {"nested", CmdHF14AMfNested, 0, "Test nested authentication"}, {"hardnested", CmdHF14AMfNestedHard, 0, "Nested attack for hardened Mifare cards"}, - {"sniff", CmdHF14AMfSniff, 0, "Sniff card-reader communication"}, - {"sim", CmdHF14AMf1kSim, 0, "Simulate MIFARE card"}, - {"eclr", CmdHF14AMfEClear, 0, "Clear simulator memory block"}, - {"eget", CmdHF14AMfEGet, 0, "Get simulator memory block"}, - {"eset", CmdHF14AMfESet, 0, "Set simulator memory block"}, - {"eload", CmdHF14AMfELoad, 0, "Load from file emul dump"}, - {"esave", CmdHF14AMfESave, 0, "Save to file emul dump"}, - {"ecfill", CmdHF14AMfECFill, 0, "Fill simulator memory with help of keys from simulator"}, - {"ekeyprn", CmdHF14AMfEKeyPrn, 0, "Print keys from simulator memory"}, - {"csetuid", CmdHF14AMfCSetUID, 0, "Set UID for magic Chinese card"}, - {"csetblk", CmdHF14AMfCSetBlk, 0, "Write block - Magic Chinese card"}, - {"cgetblk", CmdHF14AMfCGetBlk, 0, "Read block - Magic Chinese card"}, - {"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"}, - {NULL, NULL, 0, NULL} + {"sniff", CmdHF14AMfSniff, 0, "Sniff card-reader communication"}, + {"sim", CmdHF14AMf1kSim, 0, "Simulate MIFARE card"}, + {"eclr", CmdHF14AMfEClear, 0, "Clear simulator memory block"}, + {"eget", CmdHF14AMfEGet, 0, "Get simulator memory block"}, + {"eset", CmdHF14AMfESet, 0, "Set simulator memory block"}, + {"eload", CmdHF14AMfELoad, 0, "Load from file emul dump"}, + {"esave", CmdHF14AMfESave, 0, "Save to file emul dump"}, + {"ecfill", CmdHF14AMfECFill, 0, "Fill simulator memory with help of keys from simulator"}, + {"ekeyprn", CmdHF14AMfEKeyPrn, 0, "Print keys from simulator memory"}, + {"csetuid", CmdHF14AMfCSetUID, 0, "Set UID for magic Chinese card"}, + {"csetblk", CmdHF14AMfCSetBlk, 0, "Write block - Magic Chinese card"}, + {"cgetblk", CmdHF14AMfCGetBlk, 0, "Read block - Magic Chinese card"}, + {"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"}, + {NULL, NULL, 0, NULL} }; -int CmdHFMF(const char *Cmd) -{ +int CmdHFMF(const char *Cmd) { // flush - WaitForResponseTimeout(CMD_ACK,NULL,100); + clearCommandBuffer(); + //WaitForResponseTimeout(CMD_ACK,NULL,100); CmdsParse(CommandTable, Cmd); return 0; } -int CmdHelp(const char *Cmd) -{ +int CmdHelp(const char *Cmd) { CmdsHelp(CommandTable); return 0; }