From c533d3aba832dbd672816e9735ad603ff8074abb Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 11 Dec 2023 23:37:05 +0100 Subject: [PATCH] adapt text out for hf mf info --- client/src/cmdhfmf.c | 142 +++++++++++++++++++-------------- client/src/mifare/mifarehost.c | 9 ++- client/src/mifare/mifarehost.h | 3 +- 3 files changed, 89 insertions(+), 65 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index d65e48040..f361b5c6f 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -1767,7 +1767,7 @@ static int CmdHF14AMfNested(const char *Cmd) { //TODO: single mode broken? can't } PrintAndLogEx(SUCCESS, "Testing known keys. Sector count "_YELLOW_("%d"), SectorsCnt); - int res = mfCheckKeys_fast(SectorsCnt, true, true, 1, ARRAYLEN(g_mifare_default_keys) + 1, keyBlock, e_sector, use_flashmemory); + int res = mfCheckKeys_fast(SectorsCnt, true, true, 1, ARRAYLEN(g_mifare_default_keys) + 1, keyBlock, e_sector, use_flashmemory, false); if (res == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "Fast check found all keys"); goto jumptoend; @@ -1809,7 +1809,7 @@ static int CmdHF14AMfNested(const char *Cmd) { //TODO: single mode broken? can't e_sector[sectorNo].foundKey[trgKeyType] = 1; e_sector[sectorNo].Key[trgKeyType] = bytes_to_num(keyBlock, 6); - mfCheckKeys_fast(SectorsCnt, true, true, 2, 1, keyBlock, e_sector, false); + mfCheckKeys_fast(SectorsCnt, true, true, 2, 1, keyBlock, e_sector, false, false); continue; default : PrintAndLogEx(ERR, "Unknown error\n"); @@ -2023,7 +2023,7 @@ static int CmdHF14AMfNestedStatic(const char *Cmd) { } PrintAndLogEx(SUCCESS, "Testing known keys. Sector count "_YELLOW_("%d"), SectorsCnt); - int res = mfCheckKeys_fast(SectorsCnt, true, true, 1, ARRAYLEN(g_mifare_default_keys) + 1, keyBlock, e_sector, false); + int res = mfCheckKeys_fast(SectorsCnt, true, true, 1, ARRAYLEN(g_mifare_default_keys) + 1, keyBlock, e_sector, false, false); if (res == PM3_SUCCESS) { // all keys found PrintAndLogEx(SUCCESS, "Fast check found all keys"); @@ -2056,7 +2056,7 @@ static int CmdHF14AMfNestedStatic(const char *Cmd) { e_sector[sectorNo].foundKey[trgKeyType] = 1; e_sector[sectorNo].Key[trgKeyType] = bytes_to_num(keyBlock, 6); - // mfCheckKeys_fast(SectorsCnt, true, true, 2, 1, keyBlock, e_sector, false); + // mfCheckKeys_fast(SectorsCnt, true, true, 2, 1, keyBlock, e_sector, false, false); continue; default : PrintAndLogEx(ERR, "unknown error.\n"); @@ -2713,7 +2713,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { lastChunk = true; } - res = mfCheckKeys_fast(sector_cnt, firstChunk, lastChunk, strategy, size, keyBlock + (i * MIFARE_KEY_SIZE), e_sector, false); + res = mfCheckKeys_fast(sector_cnt, firstChunk, lastChunk, strategy, size, keyBlock + (i * MIFARE_KEY_SIZE), e_sector, false, verbose); if (firstChunk) { firstChunk = false; } @@ -2834,7 +2834,7 @@ noValidKeyFound: // Try the found keys are reused if (bytes_to_num(tmp_key, MIFARE_KEY_SIZE) != 0) { - // The fast check --> mfCheckKeys_fast(sector_cnt, true, true, 2, 1, tmp_key, e_sector, false); + // The fast check --> mfCheckKeys_fast(sector_cnt, true, true, 2, 1, tmp_key, e_sector, false, verbose); // Returns false keys, so we just stick to the slower mfchk. for (int i = 0; i < sector_cnt; i++) { for (int j = MF_KEY_A; j <= MF_KEY_B; j++) { @@ -3259,7 +3259,7 @@ static int CmdHF14AMfChk_fast(const char *Cmd) { if (use_flashmemory) { PrintAndLogEx(SUCCESS, "Using dictionary in flash memory"); - mfCheckKeys_fast(sectorsCnt, true, true, 1, 0, keyBlock, e_sector, use_flashmemory); + mfCheckKeys_fast(sectorsCnt, true, true, 1, 0, keyBlock, e_sector, use_flashmemory, false); } else { // strategys. 1= deep first on sector 0 AB, 2= width first on all sectors @@ -3280,7 +3280,7 @@ static int CmdHF14AMfChk_fast(const char *Cmd) { if (size == keycnt - i) lastChunk = true; - int res = mfCheckKeys_fast(sectorsCnt, firstChunk, lastChunk, strategy, size, keyBlock + (i * MIFARE_KEY_SIZE), e_sector, false); + int res = mfCheckKeys_fast(sectorsCnt, firstChunk, lastChunk, strategy, size, keyBlock + (i * MIFARE_KEY_SIZE), e_sector, false, false); if (firstChunk) firstChunk = false; @@ -8799,9 +8799,11 @@ static int CmdHFMFHidEncode(const char *Cmd) { static int CmdHF14AMfInfo(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf mf info", - "Information and check vulnerabilities in the mfc card\n" - "To check some of them need to specify key and/or specific keys in the copmmand line", - "hf mf info -k ffffffff -nv\n" + "Information and check vulnerabilities in a MIFARE Classic card\n" + "Some cards in order to extract information you need to specify key\n" + "and/or specific keys in the copmmand line", + "hf mf info\n" + "hf mf info -k ffffffff -n -v\n" ); void *argtable[] = { @@ -8828,7 +8830,7 @@ static int CmdHF14AMfInfo(const char *Cmd) { } int keylen = 0; - uint8_t key[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + uint8_t key[MIFARE_KEY_SIZE] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; CLIGetHexWithReturn(ctx, 4, key, &keylen); bool do_nack_test = arg_get_lit(ctx, 5); @@ -8836,11 +8838,12 @@ static int CmdHF14AMfInfo(const char *Cmd) { CLIParserFree(ctx); uint8_t dbg_curr = DBG_NONE; - if (getDeviceDebugLevel(&dbg_curr) != PM3_SUCCESS) + if (getDeviceDebugLevel(&dbg_curr) != PM3_SUCCESS) { return PM3_EFAILED; + } - if (keylen != 0 && keylen != 6) { - PrintAndLogEx(ERR, "Key length must be 6 bytes"); + if (keylen != 0 && keylen != MIFARE_KEY_SIZE) { + PrintAndLogEx(ERR, "Key length must be %u bytes", MIFARE_KEY_SIZE); return PM3_EINVARG; } @@ -8878,26 +8881,37 @@ static int CmdHF14AMfInfo(const char *Cmd) { return select_status; } - PrintAndLogEx(INFO, "--- " _CYAN_("ISO14443-a Information") "---------------------"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "--- " _CYAN_("ISO14443-a Information") " ---------------------"); PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s"), sprint_hex(card.uid, card.uidlen)); PrintAndLogEx(SUCCESS, "ATQA: " _GREEN_("%02X %02X"), card.atqa[1], card.atqa[0]); PrintAndLogEx(SUCCESS, " SAK: " _GREEN_("%02X [%" PRIu64 "]"), card.sak, resp.oldarg[0]); - if (setDeviceDebugLevel(verbose ? DBG_INFO : DBG_NONE, false) != PM3_SUCCESS) + if (setDeviceDebugLevel(verbose ? DBG_INFO : DBG_NONE, false) != PM3_SUCCESS) { return PM3_EFAILED; + } - PrintAndLogEx(INFO, "--- " _CYAN_("Backdoors Information") "---------------------"); - if (detect_mf_magic(true) == 0) - PrintAndLogEx(INFO, ""); + uint8_t signature[32] = {0}; + int res = read_mfc_ev1_signature(signature); + if (res == PM3_SUCCESS) { + mfc_ev1_print_signature(card.uid, card.uidlen, signature, sizeof(signature)); + } - PrintAndLogEx(INFO, "--- " _CYAN_("Keys Information") "---------------------"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "--- " _CYAN_("Magic Tag Information")); + if (detect_mf_magic(true) == 0) { + PrintAndLogEx(INFO, ""); + } + + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "--- " _CYAN_("Keys Information")); uint8_t fkey[MIFARE_KEY_SIZE] = {0}; uint8_t fKeyType = 0xff; int sectorsCnt = 1; uint8_t *keyBlock = NULL; uint32_t keycnt = 0; - int res = mfLoadKeys(&keyBlock, &keycnt, NULL, 0, NULL, 0); + res = mfLoadKeys(&keyBlock, &keycnt, NULL, 0, NULL, 0); if (res != PM3_SUCCESS) { return res; } @@ -8908,89 +8922,95 @@ static int CmdHF14AMfInfo(const char *Cmd) { free(keyBlock); return PM3_EMALLOC; } - res = mfCheckKeys_fast(sectorsCnt, true, true, 1, keycnt, keyBlock, e_sector, false); + + res = mfCheckKeys_fast(sectorsCnt, true, true, 1, keycnt, keyBlock, e_sector, false, verbose); if (res == PM3_SUCCESS) { uint8_t blockdata[MFBLOCK_SIZE] = {0}; if (e_sector[0].foundKey[0]) { - PrintAndLogEx(SUCCESS, "Sector 0 key A... %12llx", e_sector[0].Key[0]); + PrintAndLogEx(SUCCESS, "Sector 0 key A... " _GREEN_("%12" PRIX64), e_sector[0].Key[0]); - num_to_bytes(e_sector[0].Key[0], MIFARE_KEY_SIZE, fkey); - if (mfReadBlock(0, MF_KEY_A, key, blockdata) == PM3_SUCCESS) + num_to_bytes(e_sector[0].Key[MF_KEY_A], MIFARE_KEY_SIZE, fkey); + if (mfReadBlock(0, MF_KEY_A, key, blockdata) == PM3_SUCCESS) { fKeyType = MF_KEY_A; - } - - if (e_sector[0].foundKey[1]) { - PrintAndLogEx(SUCCESS, "Sector 0 key B... %12llx", e_sector[0].Key[1]); - - if (fKeyType == 0xff) { - num_to_bytes(e_sector[0].Key[1], MIFARE_KEY_SIZE, fkey); - if (mfReadBlock(0, MF_KEY_B, key, blockdata) == PM3_SUCCESS) - fKeyType = MF_KEY_B; } } - if (fKeyType != 0xff) + if (e_sector[0].foundKey[1]) { + PrintAndLogEx(SUCCESS, "Sector 0 key B... " _GREEN_("%12" PRIX64), e_sector[0].Key[1]); + + if (fKeyType == 0xFF) { + num_to_bytes(e_sector[0].Key[MF_KEY_B], MIFARE_KEY_SIZE, fkey); + if (mfReadBlock(0, MF_KEY_B, key, blockdata) == PM3_SUCCESS) { + fKeyType = MF_KEY_B; + } + } + } + + if (fKeyType != 0xFF) { PrintAndLogEx(SUCCESS, "Block 0.......... %s", sprint_hex(blockdata, MFBLOCK_SIZE)); + } + } else { + PrintAndLogEx(INFO, ""); } free(keyBlock); free(e_sector); - PrintAndLogEx(INFO, "--- " _CYAN_("RNG Information") "---------------------"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "--- " _CYAN_("RNG Information")); res = detect_classic_static_nonce(); - if (res == NONCE_STATIC) - PrintAndLogEx(SUCCESS, "Static nonce: " _YELLOW_("yes")); + if (res == NONCE_STATIC) { + PrintAndLogEx(SUCCESS, "Static nonce... " _YELLOW_("yes")); + } - if (res == NONCE_FAIL && verbose) - PrintAndLogEx(SUCCESS, "Static nonce: " _RED_("read failed")); + if (res == NONCE_FAIL && verbose) { + PrintAndLogEx(SUCCESS, "Static nonce... " _RED_("read failed")); + } if (res == NONCE_NORMAL) { // not static res = detect_classic_prng(); if (res == 1) - PrintAndLogEx(SUCCESS, "Prng detection: " _GREEN_("weak")); + PrintAndLogEx(SUCCESS, "Prng... " _GREEN_("weak")); else if (res == 0) - PrintAndLogEx(SUCCESS, "Prng detection: " _YELLOW_("hard")); + PrintAndLogEx(SUCCESS, "Prng... " _YELLOW_("hard")); else - PrintAndLogEx(FAILED, "Prng detection: " _RED_("fail")); + PrintAndLogEx(FAILED, "Prng... " _RED_("fail")); // detect static encrypted nonce - if (keylen == 6) { + if (keylen == MIFARE_KEY_SIZE) { res = detect_classic_static_encrypted_nonce(blockn, keytype, key); if (res == NONCE_STATIC) { - PrintAndLogEx(SUCCESS, "Static nested nonce: " _YELLOW_("yes")); - fKeyType = 0xff; // dont detect twice + PrintAndLogEx(SUCCESS, "Static nested nonce... " _YELLOW_("yes")); + fKeyType = 0xFF; // dont detect twice } if (res == NONCE_STATIC_ENC) { - PrintAndLogEx(SUCCESS, "Static encrypted nonce: " _YELLOW_("yes")); - fKeyType = 0xff; // dont detect twice + PrintAndLogEx(SUCCESS, "Static encrypted nonce... " _RED_("yes")); + fKeyType = 0xFF; // dont detect twice } } - if (fKeyType != 0xff) { + + if (fKeyType != 0xFF) { res = detect_classic_static_encrypted_nonce(0, fKeyType, fkey); if (res == NONCE_STATIC) - PrintAndLogEx(SUCCESS, "Static nested nonce: " _YELLOW_("yes")); + PrintAndLogEx(SUCCESS, "Static nested nonce... " _YELLOW_("yes")); if (res == NONCE_STATIC_ENC) - PrintAndLogEx(SUCCESS, "Static encrypted nonce: " _YELLOW_("yes")); + PrintAndLogEx(SUCCESS, "Static encrypted nonce... " _RED_("yes")); } - if (do_nack_test) + if (do_nack_test) { detect_classic_nackbug(verbose); + } } - uint8_t signature[32] = {0}; - res = read_mfc_ev1_signature(signature); - if (res == PM3_SUCCESS) { - PrintAndLogEx(INFO, "--- " _CYAN_("Signature Information") "---------------------"); - mfc_ev1_print_signature(card.uid, card.uidlen, signature, sizeof(signature)); - } - - if (setDeviceDebugLevel(dbg_curr, false) != PM3_SUCCESS) + if (setDeviceDebugLevel(dbg_curr, false) != PM3_SUCCESS) { return PM3_EFAILED; + } + PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } diff --git a/client/src/mifare/mifarehost.c b/client/src/mifare/mifarehost.c index 8c129b8d9..f838675d3 100644 --- a/client/src/mifare/mifarehost.c +++ b/client/src/mifare/mifarehost.c @@ -222,7 +222,7 @@ int mfCheckKeys(uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t keyc // 1 == // 2 == Time-out, aborting int mfCheckKeys_fast(uint8_t sectorsCnt, uint8_t firstChunk, uint8_t lastChunk, uint8_t strategy, - uint32_t size, uint8_t *keyBlock, sector_t *e_sector, bool use_flashmemory) { + uint32_t size, uint8_t *keyBlock, sector_t *e_sector, bool use_flashmemory, bool verbose) { uint64_t t2 = msclock(); @@ -256,7 +256,9 @@ int mfCheckKeys_fast(uint8_t sectorsCnt, uint8_t firstChunk, uint8_t lastChunk, // time to convert the returned data. uint8_t curr_keys = resp.oldarg[0]; - PrintAndLogEx(INFO, "Chunk %.1fs | found %u/%u keys (%u)", (float)(t2 / 1000.0), curr_keys, (sectorsCnt << 1), size); + if (verbose) { + PrintAndLogEx(INFO, "Chunk %.1fs | found %u/%u keys (%u)", (float)(t2 / 1000.0), curr_keys, (sectorsCnt << 1), size); + } // all keys? if (curr_keys == sectorsCnt * 2 || lastChunk) { @@ -1385,8 +1387,9 @@ int detect_mf_magic(bool is_mfc) { uint8_t payload[] = { is_mfc }; SendCommandNG(CMD_HF_MIFARE_CIDENT, payload, sizeof(payload)); if (WaitForResponseTimeout(CMD_HF_MIFARE_CIDENT, &resp, 1500)) { - if (resp.status == PM3_SUCCESS) + if (resp.status == PM3_SUCCESS) { isGeneration = resp.data.asBytes[0]; + } } switch (isGeneration) { diff --git a/client/src/mifare/mifarehost.h b/client/src/mifare/mifarehost.h index 5eacabda3..b30c7a9ae 100644 --- a/client/src/mifare/mifarehost.h +++ b/client/src/mifare/mifarehost.h @@ -74,7 +74,8 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *resultKey); int mfCheckKeys(uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t keycnt, uint8_t *keyBlock, uint64_t *key); int mfCheckKeys_fast(uint8_t sectorsCnt, uint8_t firstChunk, uint8_t lastChunk, - uint8_t strategy, uint32_t size, uint8_t *keyBlock, sector_t *e_sector, bool use_flashmemory); + uint8_t strategy, uint32_t size, uint8_t *keyBlock, sector_t *e_sector, + bool use_flashmemory, bool verbose); int mfCheckKeys_file(uint8_t *destfn, uint64_t *key);