diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 5a70488fe..910763a23 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -49,7 +49,7 @@ static int usage_hf14_ice(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mf ice"); PrintAndLogEx(NORMAL, " hf mf ice f nonces.bin"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_dump(void) { @@ -61,7 +61,7 @@ static int usage_hf14_dump(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mf dump"); PrintAndLogEx(NORMAL, " hf mf dump 4"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_mifare(void) { @@ -74,7 +74,7 @@ static int usage_hf14_mifare(void) { PrintAndLogEx(NORMAL, " hf mf darkside"); PrintAndLogEx(NORMAL, " hf mf darkside 16"); PrintAndLogEx(NORMAL, " hf mf darkside 16 B"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_mfsim(void) { PrintAndLogEx(NORMAL, "Usage: hf mf sim [u ] [n ] [t] [a ] [s ] [i] [x] [e] [v]"); @@ -98,7 +98,7 @@ static int usage_hf14_mfsim(void) { PrintAndLogEx(NORMAL, " hf mf sim u 11223344556677"); PrintAndLogEx(NORMAL, " hf mf sim u 112233445566778899AA"); PrintAndLogEx(NORMAL, " hf mf sim u 11223344 i x"); - return 0; + return PM3_SUCCESS; } /* * static int usage_hf14_sniff(void) { @@ -112,14 +112,13 @@ static int usage_hf14_mfsim(void) { PrintAndLogEx(NORMAL, " f decrypt sequence, collect read and write commands and save the result of the sequence to emulator dump file `uid.eml`"); PrintAndLogEx(NORMAL, "Example:"); PrintAndLogEx(NORMAL, " hf mf sniff l d f"); - return 0; + return PM3_SUCCESS; } */ static int usage_hf14_nested(void) { PrintAndLogEx(NORMAL, "Usage:"); - PrintAndLogEx(NORMAL, " all sectors: hf mf nested [t,d]"); - PrintAndLogEx(NORMAL, " one sector: hf mf nested o "); - PrintAndLogEx(NORMAL, " [t]"); + PrintAndLogEx(NORMAL, " all sectors: hf mf nested [t,d]"); + PrintAndLogEx(NORMAL, " one sector: hf mf nested o [t]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h this help"); PrintAndLogEx(NORMAL, " card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, - 1K"); @@ -127,11 +126,11 @@ static int usage_hf14_nested(void) { PrintAndLogEx(NORMAL, " d write keys to binary file `hf-mf--key.bin`"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf nested 1 0 A FFFFFFFFFFFF -- nested attack against 1k,block 0, Key A using key FFFFFFFFFFFF"); - PrintAndLogEx(NORMAL, " hf mf nested 1 0 A FFFFFFFFFFFF t -- and transfer keys into emulator memory"); - PrintAndLogEx(NORMAL, " hf mf nested 1 0 A FFFFFFFFFFFF d -- or write keys to binary file "); - PrintAndLogEx(NORMAL, " hf mf nested o 0 A FFFFFFFFFFFF 4 A"); - return 0; + PrintAndLogEx(NORMAL, " hf mf nested 1 0 A FFFFFFFFFFFF -- nested attack against 1K, block 0, Key A using key FFFFFFFFFFFF"); + PrintAndLogEx(NORMAL, " hf mf nested 1 0 A FFFFFFFFFFFF t -- and transfer keys into emulator memory"); + PrintAndLogEx(NORMAL, " hf mf nested 1 0 A FFFFFFFFFFFF d -- or write keys to binary file "); + PrintAndLogEx(NORMAL, " hf mf nested o 0 A FFFFFFFFFFFF 4 A -- nested attack against ONE sector. Use block 0 Key A to find block 4 Key A"); + return PM3_SUCCESS; } static int usage_hf14_hardnested(void) { PrintAndLogEx(NORMAL, "Usage:"); @@ -164,7 +163,7 @@ static int usage_hf14_hardnested(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Add the known target key to check if it is present in the remaining key space:"); PrintAndLogEx(NORMAL, " hf mf hardnested 0 A A0A1A2A3A4A5 4 A FFFFFFFFFFFF"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_autopwn(void) { PrintAndLogEx(NORMAL, "Usage:"); @@ -200,7 +199,7 @@ static int usage_hf14_autopwn(void) { PrintAndLogEx(NORMAL, " hf mf autopwn * 1 f mfc_default_keys -- target Mifare classic card (size 1k) with default dictionary"); PrintAndLogEx(NORMAL, " hf mf autopwn k 0 A FFFFFFFFFFFF -- target Mifare classic card with Sector0 typeA with known key 'FFFFFFFFFFFF'"); PrintAndLogEx(NORMAL, " hf mf autopwn k 0 A FFFFFFFFFFFF * 1 f mfc_default_keys -- this command combines the two above (reduce the need for nested / hardnested attacks, by using a dictionary)"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_chk(void) { PrintAndLogEx(NORMAL, "Usage: hf mf chk [h] |<*card memory> [t|d] [] []"); @@ -219,7 +218,7 @@ static int usage_hf14_chk(void) { PrintAndLogEx(NORMAL, " hf mf chk 0 A mfc_default_keys.dic -- target block 0, Key A using default dictionary file"); PrintAndLogEx(NORMAL, " hf mf chk *1 ? t -- target all blocks, all keys, 1K, write to emulator memory"); PrintAndLogEx(NORMAL, " hf mf chk *1 ? d -- target all blocks, all keys, 1K, write to file"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_chk_fast(void) { PrintAndLogEx(NORMAL, "This is a improved checkkeys method speedwise. It checks Mifare Classic tags sector keys against a dictionary file with keys"); @@ -242,7 +241,7 @@ static int usage_hf14_chk_fast(void) { PrintAndLogEx(NORMAL, " hf mf fchk 1 d -- target 1K, write to file"); if (IfPm3Flash()) PrintAndLogEx(NORMAL, " hf mf fchk 1 m -- target 1K, use dictionary from flashmemory"); - return 0; + return PM3_SUCCESS; } /* static int usage_hf14_keybrute(void) { @@ -276,7 +275,7 @@ static int usage_hf14_restore(void) { PrintAndLogEx(NORMAL, " hf mf restore 1 u 12345678 -- restore from hf-mf-12345678-key.bin and hf-mf-12345678-data.bin"); PrintAndLogEx(NORMAL, " hf mf restore 1 u 12345678 k dumpkey.bin -- restore from dumpkey.bin and hf-mf-12345678-data.bin"); PrintAndLogEx(NORMAL, " hf mf restore 4 -- read the UID from tag with 4K memory first, then restore from hf-mf--key.bin and and hf-mf--data.bin"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_decryptbytes(void) { PrintAndLogEx(NORMAL, "Decrypt Crypto-1 encrypted bytes given some known state of crypto. See tracelog to gather needed values\n"); @@ -290,25 +289,25 @@ static int usage_hf14_decryptbytes(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mf decrypt b830049b 9248314a 9280e203 41e586f9\n"); PrintAndLogEx(NORMAL, " this sample decrypts 41e586f9 -> 3003999a Annotated: 30 03 [99 9a] auth block 3 [crc]"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_eget(void) { PrintAndLogEx(NORMAL, "Usage: hf mf eget "); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mf eget 0 "); - return 0; + return PM3_SUCCESS; } static int usage_hf14_eclr(void) { PrintAndLogEx(NORMAL, "It set card emulator memory to empty data blocks and key A/B FFFFFFFFFFFF \n"); PrintAndLogEx(NORMAL, "Usage: hf mf eclr"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_eset(void) { PrintAndLogEx(NORMAL, "Usage: hf mf eset "); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mf eset 1 000102030405060708090a0b0c0d0e0f "); - return 0; + return PM3_SUCCESS; } static int usage_hf14_eload(void) { PrintAndLogEx(NORMAL, "It loads emul dump from the file `filename.eml`"); @@ -318,7 +317,7 @@ static int usage_hf14_eload(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mf eload filename"); PrintAndLogEx(NORMAL, " hf mf eload 4 filename"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_esave(void) { PrintAndLogEx(NORMAL, "It saves emul dump into the file `filename.eml` or `cardID.eml`"); @@ -329,7 +328,7 @@ static int usage_hf14_esave(void) { PrintAndLogEx(NORMAL, " hf mf esave "); PrintAndLogEx(NORMAL, " hf mf esave 4"); PrintAndLogEx(NORMAL, " hf mf esave 4 filename"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_ecfill(void) { PrintAndLogEx(NORMAL, "Read card and transfer its data to emulator memory."); @@ -340,16 +339,20 @@ static int usage_hf14_ecfill(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mf ecfill A"); PrintAndLogEx(NORMAL, " hf mf ecfill A 4"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_ekeyprn(void) { PrintAndLogEx(NORMAL, "It prints the keys loaded in the emulator memory"); - PrintAndLogEx(NORMAL, "Usage: hf mf ekeyprn [card memory]"); - PrintAndLogEx(NORMAL, " [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K"); + PrintAndLogEx(NORMAL, "Usage: hf mf ekeyprn [card memory] [d]"); + PrintAndLogEx(NORMAL, "Options:"); + PrintAndLogEx(NORMAL, " h this help"); + PrintAndLogEx(NORMAL, " card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, - 1K"); + PrintAndLogEx(NORMAL, " d write keys to binary file `hf-mf--key.bin`"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf mf ekeyprn 1"); - return 0; + PrintAndLogEx(NORMAL, " hf mf ekeyprn 1"); + PrintAndLogEx(NORMAL, " hf mf ekeyprn d"); + return PM3_SUCCESS; } static int usage_hf14_csetuid(void) { @@ -365,7 +368,7 @@ static int usage_hf14_csetuid(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mf csetuid 01020304"); PrintAndLogEx(NORMAL, " hf mf csetuid 01020304 0004 08 w"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_csetblk(void) { PrintAndLogEx(NORMAL, "Set block data for magic Chinese card. Only works with magic cards"); @@ -379,7 +382,7 @@ static int usage_hf14_csetblk(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mf csetblk 1 01020304050607080910111213141516"); PrintAndLogEx(NORMAL, " hf mf csetblk 1 01020304050607080910111213141516 w"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_cload(void) { PrintAndLogEx(NORMAL, "It loads magic Chinese card from the file `filename.eml`"); @@ -395,7 +398,7 @@ static int usage_hf14_cload(void) { PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mf cload mydump"); PrintAndLogEx(NORMAL, " hf mf cload e"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_cgetblk(void) { PrintAndLogEx(NORMAL, "Get block data from magic Chinese card. Only works with magic cards\n"); @@ -406,7 +409,7 @@ static int usage_hf14_cgetblk(void) { PrintAndLogEx(NORMAL, " block number"); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mf cgetblk 1"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_cgetsc(void) { PrintAndLogEx(NORMAL, "Get sector data from magic Chinese card. Only works with magic cards\n"); @@ -417,7 +420,7 @@ static int usage_hf14_cgetsc(void) { PrintAndLogEx(NORMAL, " sector number"); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mf cgetsc 0"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_csave(void) { PrintAndLogEx(NORMAL, "It saves `magic Chinese` card dump into the file `filename.eml` or `cardID.eml`"); @@ -435,7 +438,7 @@ static int usage_hf14_csave(void) { PrintAndLogEx(NORMAL, " hf mf csave u 1"); PrintAndLogEx(NORMAL, " hf mf csave e 1"); PrintAndLogEx(NORMAL, " hf mf csave 4 o filename"); - return 0; + return PM3_SUCCESS; } static int usage_hf14_nack(void) { PrintAndLogEx(NORMAL, "Test a mifare classic based card for the NACK bug."); @@ -446,7 +449,7 @@ static int usage_hf14_nack(void) { PrintAndLogEx(NORMAL, " v verbose"); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mf nack"); - return 0; + return PM3_SUCCESS; } static int GetHFMF14AUID(uint8_t *uid, int *uidlen) { @@ -1373,9 +1376,12 @@ static int CmdHF14AMfNested(const char *Cmd) { // 20160116 If Sector A is found, but not Sector B, try just reading it of the tag? PrintAndLogEx(INFO, "trying to read key B..."); for (int i = 0; i < SectorsCnt; i++) { - // KEY A but not KEY B + // KEY A but not KEY B if (e_sector[i].foundKey[0] && !e_sector[i].foundKey[1]) { +// 0 - n +//GetSectorFromBlockNo(blockNo) + uint8_t sectrail = (FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1); PrintAndLogEx(SUCCESS, "reading block %d", sectrail); @@ -1616,6 +1622,13 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { } if (!know_target_key && nonce_file_read == false) { + + // check if tag doesn't have static/fixed nonce + if (detect_classic_static_nonce() != 0) { + PrintAndLogEx(WARNING, "Static/fixed nonce detected. Quitting..."); + return PM3_EOPABORTED; + } + uint64_t key64 = 0; // check if we can authenticate to sector if (mfCheckKeys(blockNo, keyType, true, 1, key, &key64) != PM3_SUCCESS) { @@ -2270,7 +2283,7 @@ all_found: _YELLOW_("A") ":keyA " ")" ); - + // Dump the keys PrintAndLogEx(NORMAL, ""); createMfcKeyDump(GenerateFilename("hf-mf-", "-key"), sectors_cnt, e_sector); @@ -2620,17 +2633,10 @@ static int CmdHF14AMfChk(const char *Cmd) { int createDumpFile = 0; int i, keycnt = 0; - keyBlock = calloc(ARRAYLEN(g_mifare_default_keys), 6); - if (keyBlock == NULL) return PM3_EMALLOC; - - for (int cnt = 0; cnt < ARRAYLEN(g_mifare_default_keys); cnt++) - num_to_bytes(g_mifare_default_keys[cnt], 6, (uint8_t *)(keyBlock + cnt * 6)); - if (param_getchar(Cmd, 0) == '*') { blockNo = 3; SectorsCnt = NumOfSectors(param_getchar(Cmd + 1, 0)); if (SectorsCnt == 0) { - free(keyBlock); return usage_hf14_chk(); } } else { @@ -2652,11 +2658,18 @@ static int CmdHF14AMfChk(const char *Cmd) { break; default: PrintAndLogEx(FAILED, "Key type must be A , B or ?"); - free(keyBlock); return PM3_ESOFT; }; } + // Allocate memory for keys to be tested + keyBlock = calloc(ARRAYLEN(g_mifare_default_keys), 6); + if (keyBlock == NULL) return PM3_EMALLOC; + + // Copy default keys to list + for (int cnt = 0; cnt < ARRAYLEN(g_mifare_default_keys); cnt++) + num_to_bytes(g_mifare_default_keys[cnt], 6, (uint8_t *)(keyBlock + cnt * 6)); + for (i = 2; param_getchar(Cmd, i); i++) { ctmp = tolower(param_getchar(Cmd, i)); @@ -2778,6 +2791,7 @@ static int CmdHF14AMfChk(const char *Cmd) { // check keys. for (trgKeyType = (keyType == 2) ? 0 : keyType; trgKeyType < 2; (keyType == 2) ? (++trgKeyType) : (trgKeyType = 2)) { + // loop sectors but block is used as to keep track of from which blocks to test int b = blockNo; for (i = 0; i < SectorsCnt; ++i) { @@ -2813,19 +2827,25 @@ static int CmdHF14AMfChk(const char *Cmd) { // 20160116 If Sector A is found, but not Sector B, try just reading it of the tag? if (keyType != 1) { PrintAndLogEx(INFO, "testing to read key B..."); + + // loop sectors but block is used as to keep track of from which blocks to test + int b = blockNo; for (i = 0; i < SectorsCnt; i++) { - // KEY A but not KEY B + + // 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); - - PrintAndLogEx(NORMAL, "Reading block %d", sectrail); + uint8_t s = GetSectorFromBlockNo(b); + uint8_t sectrail = (FirstBlockOfSector(s) + NumBlocksPerSector(s) - 1); + PrintAndLogEx(INFO, "Sector %u, First block of sector %u, Num of block %u", s, FirstBlockOfSector(s), NumBlocksPerSector(s)); + PrintAndLogEx(INFO, "Reading block %d", sectrail); mf_readblock_t payload; payload.blockno = sectrail; payload.keytype = 0; - num_to_bytes(e_sector[i].Key[0], 6, payload.key); // KEY A + // Use key A + num_to_bytes(e_sector[i].Key[0], 6, payload.key); clearCommandBuffer(); SendCommandNG(CMD_HF_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t)); @@ -2843,12 +2863,16 @@ static int CmdHF14AMfChk(const char *Cmd) { e_sector[i].Key[1] = key64; } } + b < 127 ? (b += 4) : (b += 16); } } out: //print keys - printKeyTable(SectorsCnt, e_sector); + if ( SectorsCnt == 1) + printKeyTableEx(SectorsCnt, e_sector, GetSectorFromBlockNo(blockNo)); + else + printKeyTable(SectorsCnt, e_sector); if (transferToEml) { // fast push mode @@ -2857,11 +2881,14 @@ out: for (i = 0; i < SectorsCnt; ++i) { uint8_t blockno = FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1; mfEmlGetMem(block, blockno, 1); - if (e_sector[i].foundKey[0]) + + 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); - if (i == SectorsCnt - 1) { + + if (i == SectorsCnt - 1) { // Disable fast mode on last packet conn.block_after_ACK = false; } @@ -3298,6 +3325,9 @@ static int CmdHF14AMfKeyBrute(const char *Cmd) { */ void printKeyTable(uint8_t sectorscnt, sector_t *e_sector) { + return printKeyTableEx(sectorscnt, e_sector, 0); +} +void printKeyTableEx(uint8_t sectorscnt, sector_t *e_sector, uint8_t start_sector) { char strA[12 + 1] = {0}; char strB[12 + 1] = {0}; PrintAndLogEx(NORMAL, "|---|----------------|---|----------------|---|"); @@ -3316,7 +3346,7 @@ void printKeyTable(uint8_t sectorscnt, sector_t *e_sector) { PrintAndLogEx(NORMAL, "|%03d| %s | %d | %s | %d |" - , i + , start_sector , strA, e_sector[i].foundKey[0] , strB, e_sector[i].foundKey[1] ); @@ -3564,34 +3594,85 @@ static int CmdHF14AMfECFill(const char *Cmd) { } static int CmdHF14AMfEKeyPrn(const char *Cmd) { - int i; - uint8_t numSectors; + + char filename[FILE_PATH_SIZE]; + char *fptr = filename; + uint8_t sectors_cnt = MIFARE_1K_MAXSECTOR; uint8_t data[16]; + uint8_t uid[4]; + uint8_t cmdp = 0; + bool errors = false, createDumpFile = false; - char c = tolower(param_getchar(Cmd, 0)); - if (c == 'h') - return usage_hf14_ekeyprn(); - - if (c != 0) { - numSectors = NumOfSectors(c); - if (numSectors == 0) return usage_hf14_ekeyprn(); - } else { - numSectors = MIFARE_1K_MAXSECTOR; + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + char ctmp = tolower(param_getchar(Cmd, cmdp)); + switch (ctmp) { + case 'd': + createDumpFile = true; + cmdp++; + break; + case 'h': + return usage_hf14_ekeyprn(); + case '0': + case '1': + case '2': + case '4': + sectors_cnt = NumOfSectors(ctmp); + if (sectors_cnt == 0) return usage_hf14_ekeyprn(); + cmdp++; + break; + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } } + // validations + if (errors) return usage_hf14_ekeyprn(); + + sector_t *e_sector = NULL; + + // create/initialize key storage structure + int32_t res = initSectorTable(&e_sector, sectors_cnt); + if (res != sectors_cnt) + return PM3_EMALLOC; + + // read UID from EMUL + if (mfEmlGetMem(data, 0, 1) != PM3_SUCCESS) { + PrintAndLogEx(WARNING, "error get block %d", 0); + free(e_sector); + return PM3_ESOFT; + } + + memcpy(uid, data, sizeof(uid)); + + // download keys from EMUL + for (int i = 0; i < sectors_cnt; i++) { - PrintAndLogEx(NORMAL, "|---|----------------|----------------|"); - PrintAndLogEx(NORMAL, "|sec|key A |key B |"); - PrintAndLogEx(NORMAL, "|---|----------------|----------------|"); - for (i = 0; i < numSectors; i++) { if (mfEmlGetMem(data, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1) != PM3_SUCCESS) { PrintAndLogEx(WARNING, "error get block %d", FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1); - break; - } - uint64_t keyA = bytes_to_num(data, 6); - uint64_t keyB = bytes_to_num(data + 10, 6); - PrintAndLogEx(NORMAL, "|%03d| %012" PRIx64 " | %012" PRIx64 " |", i, keyA, keyB); + e_sector[i].foundKey[0] = false; + e_sector[i].foundKey[1] = false; + } else { + e_sector[i].foundKey[0] = true; + e_sector[i].Key[0] = bytes_to_num(data, 6); + e_sector[i].foundKey[1] = true; + e_sector[i].Key[1] = bytes_to_num(data + 10, 6); + } } - PrintAndLogEx(NORMAL, "|---|----------------|----------------|"); + + // print keys + printKeyTable(sectors_cnt, e_sector); + + // dump the keys + if (createDumpFile) { + + fptr += sprintf(fptr, "hf-mf-"); + FillFileNameByUID(fptr + strlen(fptr), uid, "-key", sizeof(uid)); + + createMfcKeyDump(filename, sectors_cnt, e_sector); + } + + free(e_sector); return PM3_SUCCESS; } @@ -3985,6 +4066,31 @@ static int CmdHF14AMfCSave(const char *Cmd) { return PM3_EMALLOC; } + // Select card to get UID/UIDLEN information + clearCommandBuffer(); + SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT, 0, 0, NULL, 0); + PacketResponseNG resp; + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { + PrintAndLogEx(WARNING, "iso14443a card select failed"); + return PM3_ESOFT; + } + + /* + 0: couldn't read + 1: OK, with ATS + 2: OK, no ATS + 3: proprietary Anticollision + */ + uint64_t select_status = resp.oldarg[0]; + + if (select_status == 0) { + PrintAndLogEx(WARNING, "iso14443a card select failed"); + return select_status; + } + + iso14a_card_select_t card; + memcpy(&card, (iso14a_card_select_t *)resp.data.asBytes, sizeof(iso14a_card_select_t)); + flags = MAGIC_INIT + MAGIC_WUPC; for (i = 0; i < numblocks; i++) { if (i == 1) flags = 0; @@ -3999,7 +4105,7 @@ static int CmdHF14AMfCSave(const char *Cmd) { if (useuid) { fnameptr += sprintf(fnameptr, "hf-mf-"); - FillFileNameByUID(fnameptr, dump, "-dump", 4); + FillFileNameByUID(fnameptr, card.uid, "-dump", card.uidlen); } if (fillEmulator) { diff --git a/client/cmdhfmf.h b/client/cmdhfmf.h index 55997bd87..c650b90f9 100644 --- a/client/cmdhfmf.h +++ b/client/cmdhfmf.h @@ -22,5 +22,6 @@ int CmdHF14AMfDbg(const char *Cmd); // used by cmd hf mfu dbg void showSectorTable(void); void readerAttack(nonces_t data, bool setEmulatorMem, bool verbose); void printKeyTable(uint8_t sectorscnt, sector_t *e_sector); +void printKeyTableEx(uint8_t sectorscnt, sector_t *e_sector, uint8_t start_sector); void printKeyTable_fast(uint8_t sectorscnt, icesector_t *e_sector, uint64_t bar, uint64_t foo); #endif