Skip to content

Commit

Permalink
adapt text out for hf mf info
Browse files Browse the repository at this point in the history
  • Loading branch information
iceman1001 committed Dec 11, 2023
1 parent d1a3e8b commit c533d3a
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 60 deletions.
132 changes: 76 additions & 56 deletions client/src/cmdhfmf.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -2834,7 +2834,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {

// 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++) {
Expand Down Expand Up @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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[] = {
Expand All @@ -8828,19 +8830,20 @@ 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);
bool verbose = arg_get_lit(ctx, 6);
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;
}

Expand Down Expand Up @@ -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, "<none>");
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, "<N/A>");
}

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;
}
Expand All @@ -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]);
PrintAndLogEx(SUCCESS, "Sector 0 key B... " _GREEN_("%12" PRIX64), 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)
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)
if (fKeyType != 0xFF) {
PrintAndLogEx(SUCCESS, "Block 0.......... %s", sprint_hex(blockdata, MFBLOCK_SIZE));
}
} else {
PrintAndLogEx(INFO, "<N/A>");
}

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;
}

Expand Down
9 changes: 6 additions & 3 deletions client/src/mifare/mifarehost.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down
3 changes: 2 additions & 1 deletion client/src/mifare/mifarehost.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down

0 comments on commit c533d3a

Please sign in to comment.