hf iclass chk - rework OLD -> NG. And textual

This commit is contained in:
iceman1001 2021-05-03 09:31:51 +02:00
commit 80817cea00
9 changed files with 41 additions and 158 deletions

View file

@ -1525,7 +1525,6 @@ typedef struct iclass_premac {
*/ */
void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) { void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) {
uint8_t i = 0, isOK = 0;
// uint8_t lastChunk = ((arg0 >> 8) & 0xFF); // uint8_t lastChunk = ((arg0 >> 8) & 0xFF);
bool use_credit_key = ((arg0 >> 16) & 0xFF); bool use_credit_key = ((arg0 >> 16) & 0xFF);
uint8_t keyCount = arg1 & 0xFF; uint8_t keyCount = arg1 & 0xFF;
@ -1550,8 +1549,9 @@ void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) {
Iso15693InitReader(); Iso15693InitReader();
uint32_t start_time = 0, eof_time = 0; bool isOK = false;
uint32_t start_time = 0, eof_time = 0;
if (select_iclass_tag(&hdr, use_credit_key, &eof_time) == false) if (select_iclass_tag(&hdr, use_credit_key, &eof_time) == false)
goto out; goto out;
@ -1561,6 +1561,7 @@ void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) {
uint16_t checked = 0; uint16_t checked = 0;
// Keychunk loop // Keychunk loop
uint8_t i = 0;
for (i = 0; i < keyCount; i++) { for (i = 0; i < keyCount; i++) {
// Allow button press / usb cmd to interrupt device // Allow button press / usb cmd to interrupt device
@ -1588,13 +1589,12 @@ void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) {
// Auth Sequence MUST begin with reading e-purse. (block2) // Auth Sequence MUST begin with reading e-purse. (block2)
// Card selected, now read e-purse (cc) (block2) (only 8 bytes no CRC) // Card selected, now read e-purse (cc) (block2) (only 8 bytes no CRC)
iclass_send_as_reader(readcheck_cc, sizeof(readcheck_cc), &start_time, &eof_time); iclass_send_as_reader(readcheck_cc, sizeof(readcheck_cc), &start_time, &eof_time);
LED_B_OFF(); LED_B_OFF();
} }
out: out:
// send keyindex. // send keyindex.
reply_mix(CMD_HF_ICLASS_CHKKEYS, isOK, i, 0, 0, 0); reply_ng(CMD_HF_ICLASS_CHKKEYS, (isOK) ? PM3_SUCCESS : PM3_ESOFT, (uint8_t *)&i, sizeof(i));
switch_off(); switch_off();
} }

View file

@ -192,7 +192,7 @@ local function main(args)
elseif err == -4 then return oops([[ elseif err == -4 then return oops([[
Card is not vulnerable to Darkside attack (its random number generator seems to be based on the wellknown Card is not vulnerable to Darkside attack (its random number generator seems to be based on the wellknown
generating polynomial with 16 effective bits only, but shows unexpected behaviour.]]) generating polynomial with 16 effective bits only, but shows unexpected behaviour.]])
elseif err == -5 then return oops('Aborted via keyboard.') elseif err == -5 then return oops('aborted via keyboard.')
end end
-- The key is actually 8 bytes, so a -- The key is actually 8 bytes, so a
-- 6-byte key is sent as 00XXXXXX -- 6-byte key is sent as 00XXXXXX

View file

@ -2940,103 +2940,6 @@ static void add_key(uint8_t *key) {
} }
} }
/*
static int iclass_chk_keys(uint8_t *keyBlock, uint32_t keycount) {
iclass_premac_t *pre = calloc(keycount, sizeof(iclass_premac_t));
if (pre == NULL) {
return PM3_EMALLOC;
}
// max 42 keys inside USB_COMMAND. 512/4 = 103 mac
uint32_t chunksize = keycount > (PM3_CMD_DATA_SIZE / 4) ? (PM3_CMD_DATA_SIZE / 4) : keycount;
bool lastChunk = false;
// fast push mode
conn.block_after_ACK = true;
// keep track of position of found key
uint8_t found_offset = 0;
uint32_t key_offset = 0;
// main keychunk loop
for (key_offset = 0; key_offset < keycount; key_offset += chunksize) {
uint64_t t2 = msclock();
uint8_t timeout = 0;
if (kbd_enter_pressed()) {
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(WARNING, "Aborted via keyboard!");
goto out;
}
uint32_t keys = ((keycount - key_offset) > chunksize) ? chunksize : keycount - key_offset;
// last chunk?
if (keys == keycount - key_offset) {
lastChunk = true;
// Disable fast mode on last command
conn.block_after_ACK = false;
}
uint32_t flags = lastChunk << 8;
// bit 16
// - 1 indicates credit key
// - 0 indicates debit key (default)
flags |= (use_credit_key << 16);
clearCommandBuffer();
SendCommandOLD(CMD_HF_ICLASS_CHKKEYS, flags, keys, 0, pre + key_offset, 4 * keys);
PacketResponseNG resp;
bool looped = false;
while (!WaitForResponseTimeout(CMD_HF_ICLASS_CHKKEYS, &resp, 2000)) {
timeout++;
PrintAndLogEx(NORMAL, "." NOLF);
if (timeout > 120) {
PrintAndLogEx(WARNING, "\nNo response from Proxmark3. Aborting...");
goto out;
}
looped = true;
}
if (looped)
PrintAndLogEx(NORMAL, "");
found_offset = resp.oldarg[1] & 0xFF;
uint8_t isOK = resp.oldarg[0] & 0xFF;
t2 = msclock() - t2;
switch (isOK) {
case 1: {
found_key = true;
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(SUCCESS, "Found valid key " _GREEN_("%s")
, sprint_hex(keyBlock + (key_offset + found_offset) * 8, 8)
);
break;
}
case 0: {
PrintAndLogEx(INPLACE, "Chunk [%d/%d]", key_offset, keycount);
break;
}
case 99: {
}
default: {
break;
}
}
// both keys found.
if (found_key) {
break;
}
}
return PM3_SUCCESS;
}
*/
static int CmdHFiClassCheckKeys(const char *Cmd) { static int CmdHFiClassCheckKeys(const char *Cmd) {
CLIParserContext *ctx; CLIParserContext *ctx;
CLIParserInit(&ctx, "hf iclass chk", CLIParserInit(&ctx, "hf iclass chk",
@ -3103,11 +3006,10 @@ static int CmdHFiClassCheckKeys(const char *Cmd) {
return PM3_EMALLOC; return PM3_EMALLOC;
} }
PrintAndLogEx(SUCCESS, " CSN: " _GREEN_("%s"), sprint_hex(CSN, sizeof(CSN))); PrintAndLogEx(SUCCESS, " CSN: " _GREEN_("%s"), sprint_hex(CSN, sizeof(CSN)));
PrintAndLogEx(SUCCESS, " CCNR: " _GREEN_("%s"), sprint_hex(CCNR, sizeof(CCNR))); PrintAndLogEx(SUCCESS, " CCNR: " _GREEN_("%s"), sprint_hex(CCNR, sizeof(CCNR)));
PrintAndLogEx(SUCCESS, "Generating diversified keys %s", (use_elite || use_raw) ? NOLF : ""); PrintAndLogEx(INFO, "Generating diversified keys %s", (use_elite || use_raw) ? NOLF : "");
if (use_elite) if (use_elite)
PrintAndLogEx(NORMAL, "using " _YELLOW_("elite algo")); PrintAndLogEx(NORMAL, "using " _YELLOW_("elite algo"));
if (use_raw) if (use_raw)
@ -3129,14 +3031,11 @@ static int CmdHFiClassCheckKeys(const char *Cmd) {
uint8_t found_offset = 0; uint8_t found_offset = 0;
uint32_t key_offset = 0; uint32_t key_offset = 0;
// main keychunk loop // main keychunk loop
for (key_offset = 0; key_offset < keycount; key_offset += chunksize) { for (key_offset = 0; key_offset < keycount && (found_key == false); key_offset += chunksize) {
uint64_t t2 = msclock();
uint8_t timeout = 0;
if (kbd_enter_pressed()) { if (kbd_enter_pressed()) {
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(WARNING, "Aborted via keyboard!"); PrintAndLogEx(WARNING, "aborted via keyboard!");
goto out; goto out;
} }
@ -3159,11 +3058,12 @@ static int CmdHFiClassCheckKeys(const char *Cmd) {
PacketResponseNG resp; PacketResponseNG resp;
bool looped = false; bool looped = false;
while (!WaitForResponseTimeout(CMD_HF_ICLASS_CHKKEYS, &resp, 2000)) { uint8_t timeout = 0;
while (WaitForResponseTimeout(CMD_HF_ICLASS_CHKKEYS, &resp, 2000) == false) {
timeout++; timeout++;
PrintAndLogEx(NORMAL, "." NOLF); PrintAndLogEx(NORMAL, "." NOLF);
if (timeout > 120) { if (timeout > 10) {
PrintAndLogEx(WARNING, "\nNo response from Proxmark3. Aborting..."); PrintAndLogEx(WARNING, "\nno response from device, aborting...");
goto out; goto out;
} }
looped = true; looped = true;
@ -3172,33 +3072,17 @@ static int CmdHFiClassCheckKeys(const char *Cmd) {
if (looped) if (looped)
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
found_offset = resp.oldarg[1] & 0xFF; if (resp.status == PM3_SUCCESS) {
uint8_t isOK = resp.oldarg[0] & 0xFF; found_offset = resp.data.asBytes[0];
found_key = true;
t2 = msclock() - t2; PrintAndLogEx(NORMAL, "");
switch (isOK) { PrintAndLogEx(SUCCESS,
case 1: { "Found valid key " _GREEN_("%s")
found_key = true; , sprint_hex(keyBlock + (key_offset + found_offset) * 8, 8)
PrintAndLogEx(NORMAL, ""); );
PrintAndLogEx(SUCCESS, "Found valid key " _GREEN_("%s") } else {
, sprint_hex(keyBlock + (key_offset + found_offset) * 8, 8) PrintAndLogEx(INPLACE, "Chunk [%d/%d]", key_offset, keycount);
); fflush(stdout);
break;
}
case 0: {
PrintAndLogEx(INPLACE, "Chunk [%d/%d]", key_offset, keycount);
break;
}
case 99: {
}
default: {
break;
}
}
// both keys found.
if (found_key) {
break;
} }
} }
@ -3321,15 +3205,15 @@ static int CmdHFiClassLookUp(const char *Cmd) {
return PM3_EMALLOC; return PM3_EMALLOC;
} }
PrintAndLogEx(SUCCESS, "Generating diversified keys..."); PrintAndLogEx(INFO, "Generating diversified keys...");
GenerateMacKeyFrom(csn, CCNR, use_raw, use_elite, keyBlock, keycount, prekey); GenerateMacKeyFrom(csn, CCNR, use_raw, use_elite, keyBlock, keycount, prekey);
if (use_elite) if (use_elite)
PrintAndLogEx(SUCCESS, "Using " _YELLOW_("elite algo")); PrintAndLogEx(INFO, "Using " _YELLOW_("elite algo"));
if (use_raw) if (use_raw)
PrintAndLogEx(SUCCESS, "Using " _YELLOW_("raw mode")); PrintAndLogEx(INFO, "Using " _YELLOW_("raw mode"));
PrintAndLogEx(SUCCESS, "Sorting..."); PrintAndLogEx(INFO, "Sorting...");
// sort mac list. // sort mac list.
qsort(prekey, keycount, sizeof(iclass_prekey_t), cmp_uint32); qsort(prekey, keycount, sizeof(iclass_prekey_t), cmp_uint32);

View file

@ -2229,7 +2229,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
PrintAndLogEx(FAILED, "generating polynomial with 16 effective bits only, but shows unexpected behaviour."); PrintAndLogEx(FAILED, "generating polynomial with 16 effective bits only, but shows unexpected behaviour.");
goto noValidKeyFound; goto noValidKeyFound;
case -5 : case -5 :
PrintAndLogEx(WARNING, "\nAborted via keyboard."); PrintAndLogEx(WARNING, "\naborted via keyboard.");
goto noValidKeyFound; goto noValidKeyFound;
default : default :
PrintAndLogEx(SUCCESS, "\nFound valid key [ " _GREEN_("%012" PRIx64) " ]\n", key64); PrintAndLogEx(SUCCESS, "\nFound valid key [ " _GREEN_("%012" PRIx64) " ]\n", key64);
@ -3092,7 +3092,7 @@ static int CmdHF14AMfChk(const char *Cmd) {
fflush(stdout); fflush(stdout);
if (kbd_enter_pressed()) { if (kbd_enter_pressed()) {
PrintAndLogEx(INFO, "\naborted via keyboard!\n"); PrintAndLogEx(WARNING, "\naborted via keyboard!\n");
goto out; goto out;
} }
@ -5076,7 +5076,7 @@ static int CmdHF14AMfice(const char *Cmd) {
do { do {
if (kbd_enter_pressed()) { if (kbd_enter_pressed()) {
PrintAndLogEx(INFO, "\naborted via keyboard!\n"); PrintAndLogEx(WARNING, "\naborted via keyboard!\n");
break; break;
} }

View file

@ -1004,7 +1004,7 @@ static int MFPKeyCheck(uint8_t startSector, uint8_t endSector, uint8_t startKeyA
PrintAndLogEx(NORMAL, "." NOLF); PrintAndLogEx(NORMAL, "." NOLF);
if (kbd_enter_pressed()) { if (kbd_enter_pressed()) {
PrintAndLogEx(WARNING, "\nAborted via keyboard!\n"); PrintAndLogEx(WARNING, "\naborted via keyboard!\n");
DropField(); DropField();
return PM3_EOPABORTED; return PM3_EOPABORTED;
} }

View file

@ -3199,7 +3199,7 @@ static int CmdHF14AMfuOtpTearoff(const char *Cmd) {
while ((current <= (end - steps)) && (error_retries < 10)) { while ((current <= (end - steps)) && (error_retries < 10)) {
if (kbd_enter_pressed()) { if (kbd_enter_pressed()) {
PrintAndLogEx(INFO, "\naborted via keyboard!\n"); PrintAndLogEx(WARNING, "\naborted via keyboard!\n");
break; break;
} }
@ -3368,7 +3368,7 @@ static int counter_reset_tear(iso14a_card_select_t *card, uint8_t cnt_no) {
uint8_t resp[10] = {0}; uint8_t resp[10] = {0};
if (ul_select(card) == false) { if (ul_select(card) == false) {
PrintAndLogEx(FAILED, "failed to select card, exiting..."); PrintAndLogEx(FAILED, "failed to select card, exiting...");
return PM3_ESOFT; return PM3_ESOFT;
} }
if (ul_send_cmd_raw(cw, sizeof(cw), resp, sizeof(resp)) < 0) { if (ul_send_cmd_raw(cw, sizeof(cw), resp, sizeof(resp)) < 0) {
@ -3499,7 +3499,6 @@ static int CmdHF14AMfuEv1CounterTearoff(const char *Cmd) {
while (actual_time <= (time_limit - interval)) { while (actual_time <= (time_limit - interval)) {
DropField(); DropField();
loop++; loop++;
@ -3509,7 +3508,7 @@ static int CmdHF14AMfuEv1CounterTearoff(const char *Cmd) {
break; break;
} }
PrintAndLogEx(INPLACE, "Using tear-off delay " _GREEN_("%" PRIu32) " us (attempt %u)", actual_time, loop); PrintAndLogEx(INPLACE, "Using tear-off delay " _GREEN_("%" PRIu32) " µs (attempt %u)", actual_time, loop);
if (ul_select(&card) == false) { if (ul_select(&card) == false) {
PrintAndLogEx(FAILED, "BEFORE, failed to select card, looping..."); PrintAndLogEx(FAILED, "BEFORE, failed to select card, looping...");
@ -4013,14 +4012,14 @@ static command_t CommandTable[] = {
{"rdbl", CmdHF14AMfURdBl, IfPm3Iso14443a, "Read block"}, {"rdbl", CmdHF14AMfURdBl, IfPm3Iso14443a, "Read block"},
{"restore", CmdHF14AMfURestore, IfPm3Iso14443a, "Restore a dump onto a MFU MAGIC tag"}, {"restore", CmdHF14AMfURestore, IfPm3Iso14443a, "Restore a dump onto a MFU MAGIC tag"},
{"wrbl", CmdHF14AMfUWrBl, IfPm3Iso14443a, "Write block"}, {"wrbl", CmdHF14AMfUWrBl, IfPm3Iso14443a, "Write block"},
{"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("simulation") " -----------------------"}, {"---------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("simulation") " -----------------------"},
{"eload", CmdHF14AMfUeLoad, IfPm3Iso14443a, "load Ultralight .eml dump file into emulator memory"}, {"eload", CmdHF14AMfUeLoad, IfPm3Iso14443a, "load Ultralight .eml dump file into emulator memory"},
{"eview", CmdHF14AMfuEView, IfPm3Iso14443a, "View emulator memory"}, {"eview", CmdHF14AMfuEView, IfPm3Iso14443a, "View emulator memory"},
{"sim", CmdHF14AMfUSim, IfPm3Iso14443a, "Simulate MIFARE Ultralight from emulator memory"}, {"sim", CmdHF14AMfUSim, IfPm3Iso14443a, "Simulate MIFARE Ultralight from emulator memory"},
{"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("magic") " ----------------------------"}, {"---------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("magic") " ----------------------------"},
{"setpwd", CmdHF14AMfUCSetPwd, IfPm3Iso14443a, "Set 3DES key - Ultralight-C"}, {"setpwd", CmdHF14AMfUCSetPwd, IfPm3Iso14443a, "Set 3DES key - Ultralight-C"},
{"setuid", CmdHF14AMfUCSetUid, IfPm3Iso14443a, "Set UID - MAGIC tags only"}, {"setuid", CmdHF14AMfUCSetUid, IfPm3Iso14443a, "Set UID - MAGIC tags only"},
{"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("amiibo") " ----------------------------"}, {"---------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("amiibo") " ----------------------------"},
// {"decrypt", CmdHF14AMfUCDecryptAmiibo, IfPm3Iso14443a, "Decrypt a amiibo tag"}, // {"decrypt", CmdHF14AMfUCDecryptAmiibo, IfPm3Iso14443a, "Decrypt a amiibo tag"},
{NULL, NULL, NULL, NULL} {NULL, NULL, NULL, NULL}
}; };

View file

@ -525,7 +525,7 @@ static int CmdAWIDBrute(const char *Cmd) {
return PM3_ENODATA; return PM3_ENODATA;
} }
if (kbd_enter_pressed()) { if (kbd_enter_pressed()) {
PrintAndLogEx(INFO, "aborted via keyboard!"); PrintAndLogEx(WARNING, "aborted via keyboard!");
return sendPing(); return sendPing();
} }

View file

@ -536,7 +536,7 @@ static int CmdEM410xBrute(const char *Cmd) {
for (uint32_t c = 0; c < uidcnt; ++c) { for (uint32_t c = 0; c < uidcnt; ++c) {
if (kbd_enter_pressed()) { if (kbd_enter_pressed()) {
SendCommandNG(CMD_BREAK_LOOP, NULL, 0); SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
PrintAndLogEx(INFO, "Aborted via keyboard!\n"); PrintAndLogEx(WARNING, "aborted via keyboard!\n");
free(uidblock); free(uidblock);
return PM3_EOPABORTED; return PM3_EOPABORTED;
} }

View file

@ -562,7 +562,7 @@ static int CmdHIDBrute(const char *Cmd) {
} }
if (kbd_enter_pressed()) { if (kbd_enter_pressed()) {
PrintAndLogEx(INFO, "aborted via keyboard!"); PrintAndLogEx(WARNING, "aborted via keyboard!");
return sendPing(); return sendPing();
} }