mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2024-09-20 15:26:13 +08:00
hf mf fchk: allow to crack a single key and show progress info
This commit is contained in:
parent
29c180285e
commit
98273d00ae
|
@ -1557,10 +1557,14 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
|
|||
uint8_t sectorcnt = arg0 & 0xFF; // 16;
|
||||
uint8_t firstchunk = (arg0 >> 8) & 0xF;
|
||||
uint8_t lastchunk = (arg0 >> 12) & 0xF;
|
||||
uint16_t singleSectorParams = (arg0 >> 16) & 0xFFFF;
|
||||
uint8_t strategy = arg1 & 0xFF;
|
||||
uint8_t use_flashmem = (arg1 >> 8) & 0xFF;
|
||||
uint16_t keyCount = arg2 & 0xFF;
|
||||
uint8_t status = 0;
|
||||
bool singleSectorMode = (singleSectorParams >> 15) & 1;
|
||||
uint8_t keytype = (singleSectorParams >> 8) & 1;
|
||||
uint8_t blockn = singleSectorParams & 0xFF;
|
||||
|
||||
struct Crypto1State mpcs = {0, 0};
|
||||
struct Crypto1State *pcs;
|
||||
|
@ -1661,6 +1665,37 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
|
|||
chk_data.pcs = pcs;
|
||||
chk_data.block = 0;
|
||||
|
||||
if (singleSectorMode) {
|
||||
chk_data.block = blockn;
|
||||
chk_data.keyType = keytype;
|
||||
for (uint16_t i = 0; i < keyCount; ++i) {
|
||||
|
||||
// Allow button press / usb cmd to interrupt device
|
||||
if (BUTTON_PRESS() || data_available()) {
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
WDT_HIT();
|
||||
|
||||
chk_data.key = bytes_to_num(datain + i * 6, 6);
|
||||
if (chkKey(&chk_data) == 0) {
|
||||
reply_old(CMD_ACK, 1, 0, 0, datain + i * 6, 6);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
reply_mix(CMD_ACK, 0, 0, 0, 0, 0);
|
||||
out:
|
||||
LEDsoff();
|
||||
crypto1_deinit(pcs);
|
||||
set_tracing(false);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
BigBuf_free();
|
||||
BigBuf_Clear_ext(false);
|
||||
g_dbglevel = oldbg;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// keychunk loop - depth first one sector.
|
||||
if (strategy == 1 || use_flashmem) {
|
||||
|
||||
|
|
|
@ -3241,6 +3241,9 @@ static int CmdHF14AMfChk_fast(const char *Cmd) {
|
|||
arg_lit0(NULL, "dump", "Dump found keys to binary file"),
|
||||
arg_lit0(NULL, "mem", "Use dictionary from flashmemory"),
|
||||
arg_str0("f", "file", "<fn>", "filename of dictionary"),
|
||||
arg_int0(NULL, "blk", "<dec>", "block number (single block recovery mode)"),
|
||||
arg_lit0("a", NULL, "single block recovery key A"),
|
||||
arg_lit0("b", NULL, "single block recovery key B"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
@ -3262,6 +3265,16 @@ static int CmdHF14AMfChk_fast(const char *Cmd) {
|
|||
char filename[FILE_PATH_SIZE] = {0};
|
||||
CLIParamStrToBuf(arg_get_str(ctx, 9), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
|
||||
|
||||
int blockn = arg_get_int_def(ctx, 10, -1);
|
||||
uint8_t keytype = MF_KEY_A;
|
||||
if (arg_get_lit(ctx, 11) && arg_get_lit(ctx, 12)) {
|
||||
CLIParserFree(ctx);
|
||||
PrintAndLogEx(WARNING, "Input key type must be A or B");
|
||||
return PM3_EINVARG;
|
||||
} else if (arg_get_lit(ctx, 12)) {
|
||||
keytype = MF_KEY_B;
|
||||
}
|
||||
|
||||
CLIParserFree(ctx);
|
||||
|
||||
//validations
|
||||
|
@ -3309,12 +3322,16 @@ static int CmdHF14AMfChk_fast(const char *Cmd) {
|
|||
// time
|
||||
uint64_t t1 = msclock();
|
||||
|
||||
uint16_t singleSectorParams = 0;
|
||||
if (blockn != -1) {
|
||||
singleSectorParams = (blockn & 0xFF)| keytype << 8 | 1 << 15;
|
||||
}
|
||||
if (use_flashmemory) {
|
||||
PrintAndLogEx(SUCCESS, "Using dictionary in flash memory");
|
||||
mfCheckKeys_fast(sectorsCnt, true, true, 1, 0, keyBlock, e_sector, use_flashmemory, false);
|
||||
mfCheckKeys_fast_ex(sectorsCnt, true, true, 1, 0, keyBlock, e_sector, use_flashmemory, false, false, singleSectorParams);
|
||||
} else {
|
||||
|
||||
// strategys. 1= deep first on sector 0 AB, 2= width first on all sectors
|
||||
// strategies. 1= deep first on sector 0 AB, 2= width first on all sectors
|
||||
for (uint8_t strategy = 1; strategy < 3; strategy++) {
|
||||
PrintAndLogEx(INFO, "Running strategy %u", strategy);
|
||||
|
||||
|
@ -3322,33 +3339,41 @@ static int CmdHF14AMfChk_fast(const char *Cmd) {
|
|||
for (i = 0; i < keycnt; i += chunksize) {
|
||||
|
||||
if (kbd_enter_pressed()) {
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(WARNING, "\naborted via keyboard!\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
PrintAndLogEx(INPLACE, "Testing %5i/%5i %02.1f%%", i, keycnt, (float)i * 100 / keycnt);
|
||||
uint32_t size = ((keycnt - i) > chunksize) ? chunksize : keycnt - i;
|
||||
|
||||
// last chunk?
|
||||
if (size == keycnt - i)
|
||||
lastChunk = true;
|
||||
|
||||
int res = mfCheckKeys_fast(sectorsCnt, firstChunk, lastChunk, strategy, size, keyBlock + (i * MIFARE_KEY_SIZE), e_sector, false, false);
|
||||
|
||||
int res = mfCheckKeys_fast_ex(sectorsCnt, firstChunk, lastChunk, strategy, size, keyBlock + (i * MIFARE_KEY_SIZE), e_sector, false, false, true, singleSectorParams);
|
||||
if (firstChunk)
|
||||
firstChunk = false;
|
||||
|
||||
// all keys, aborted
|
||||
if (res == PM3_SUCCESS || res == 2)
|
||||
if (res == PM3_SUCCESS || res == 2) {
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
goto out;
|
||||
|
||||
}
|
||||
} // end chunks of keys
|
||||
PrintAndLogEx(INPLACE, "Testing %5i/%5i 100.00%%", keycnt, keycnt);
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
firstChunk = true;
|
||||
lastChunk = false;
|
||||
if (blockn != -1) break;
|
||||
} // end strategy
|
||||
}
|
||||
out:
|
||||
t1 = msclock() - t1;
|
||||
PrintAndLogEx(INFO, "time in checkkeys (fast) " _YELLOW_("%.1fs") "\n", (float)(t1 / 1000.0));
|
||||
PrintAndLogEx(INFO, "Time in checkkeys (fast) " _YELLOW_("%.1fs") "\n", (float)(t1 / 1000.0));
|
||||
|
||||
if (blockn != -1) {
|
||||
goto out2;
|
||||
}
|
||||
|
||||
// check..
|
||||
uint8_t found_keys = 0;
|
||||
|
@ -3413,7 +3438,7 @@ out:
|
|||
free(fptr);
|
||||
}
|
||||
}
|
||||
|
||||
out2:
|
||||
free(keyBlock);
|
||||
free(e_sector);
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
|
|
|
@ -221,21 +221,24 @@ int mfCheckKeys(uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t keyc
|
|||
// 0 == ok all keys found
|
||||
// 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, bool verbose) {
|
||||
int mfCheckKeys_fast_ex(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,
|
||||
bool verbose, bool quiet, uint16_t singleSectorParams) {
|
||||
|
||||
uint64_t t2 = msclock();
|
||||
|
||||
// send keychunk
|
||||
clearCommandBuffer();
|
||||
SendCommandOLD(CMD_HF_MIFARE_CHKKEYS_FAST, (sectorsCnt | (firstChunk << 8) | (lastChunk << 12)), ((use_flashmemory << 8) | strategy), size, keyBlock, 6 * size);
|
||||
SendCommandOLD(CMD_HF_MIFARE_CHKKEYS_FAST, (sectorsCnt | (firstChunk << 8) | (lastChunk << 12) | (singleSectorParams << 16)), ((use_flashmemory << 8) | strategy), size, keyBlock, 6 * size);
|
||||
PacketResponseNG resp;
|
||||
|
||||
uint32_t timeout = 0;
|
||||
while (WaitForResponseTimeout(CMD_ACK, &resp, 2000) == false) {
|
||||
|
||||
PrintAndLogEx((timeout) ? NORMAL : INFO, "." NOLF);
|
||||
fflush(stdout);
|
||||
if (! quiet) {
|
||||
PrintAndLogEx((timeout) ? NORMAL : INFO, "." NOLF);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
timeout++;
|
||||
|
||||
|
@ -249,13 +252,22 @@ int mfCheckKeys_fast(uint8_t sectorsCnt, uint8_t firstChunk, uint8_t lastChunk,
|
|||
}
|
||||
t2 = msclock() - t2;
|
||||
|
||||
if (timeout) {
|
||||
if (timeout && ! quiet) {
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
}
|
||||
|
||||
// time to convert the returned data.
|
||||
uint8_t curr_keys = resp.oldarg[0];
|
||||
|
||||
if ((singleSectorParams >> 15) & 1) {
|
||||
if (curr_keys) {
|
||||
uint64_t foo = bytes_to_num(resp.data.asBytes, 6);
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(SUCCESS, _GREEN_("Key %s for block %2i found: %012" PRIx64), (singleSectorParams >> 8) & 1 ? "B":"A", singleSectorParams & 0xFF, foo);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
PrintAndLogEx(INFO, "Chunk %.1fs | found %u/%u keys (%u)", (float)(t2 / 1000.0), curr_keys, (sectorsCnt << 1), size);
|
||||
}
|
||||
|
@ -317,6 +329,11 @@ int mfCheckKeys_fast(uint8_t sectorsCnt, uint8_t firstChunk, uint8_t lastChunk,
|
|||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
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, bool verbose) {
|
||||
return mfCheckKeys_fast_ex(sectorsCnt, firstChunk, lastChunk, strategy, size, keyBlock, e_sector, use_flashmemory, verbose, false, 0);
|
||||
}
|
||||
|
||||
// Trigger device to use a binary file on flash mem as keylist for mfCheckKeys.
|
||||
// As of now, 255 keys possible in the file
|
||||
// 6 * 255 = 1500 bytes
|
||||
|
|
|
@ -76,6 +76,9 @@ int mfCheckKeys(uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t keyc
|
|||
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, bool verbose);
|
||||
int mfCheckKeys_fast_ex(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,
|
||||
bool verbose, bool quiet, uint16_t singleSectorParams);
|
||||
|
||||
int mfCheckKeys_file(uint8_t *destfn, uint64_t *key);
|
||||
|
||||
|
|
Loading…
Reference in a new issue