This commit is contained in:
iceman1001 2025-05-24 21:14:58 +02:00
commit 00c5af4256
2 changed files with 37 additions and 32 deletions

View file

@ -1467,8 +1467,9 @@ static void iclass_decode_credentials(uint8_t *data) {
bool has_values = (memcmp(b7, empty, PICOPASS_BLOCK_SIZE) != 0) && (memcmp(b7, zeros, PICOPASS_BLOCK_SIZE) != 0); bool has_values = (memcmp(b7, empty, PICOPASS_BLOCK_SIZE) != 0) && (memcmp(b7, zeros, PICOPASS_BLOCK_SIZE) != 0);
if (has_values && encryption == None) { if (has_values && encryption == None) {
// todo: remove preamble/sentinel
PrintAndLogEx(INFO, "------------------------ " _CYAN_("Block 7 decoder") " --------------------------"); PrintAndLogEx(INFO, "------------------------ " _CYAN_("Block 7 decoder") " --------------------------");
// todo: remove preamble/sentinel
if (has_new_pacs) { if (has_new_pacs) {
iclass_decode_credentials_new_pacs(b7); iclass_decode_credentials_new_pacs(b7);
} else { } else {
@ -1487,9 +1488,6 @@ static void iclass_decode_credentials(uint8_t *data) {
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
decode_wiegand(top, mid, bot, 0); decode_wiegand(top, mid, bot, 0);
} }
} else {
PrintAndLogEx(INFO, "No unencrypted legacy credential found");
} }
} }
@ -1950,7 +1948,7 @@ static int CmdHFiClassDump(const char *Cmd) {
return PM3_EINVARG; return PM3_EINVARG;
} }
} }
if (credit_key_len > 0 && credit_key_nr >= 0) { if (credit_key_len > 0 && credit_key_nr >= 0) {
PrintAndLogEx(ERR, "Please specify credit key or index, not both"); PrintAndLogEx(ERR, "Please specify credit key or index, not both");
return PM3_EINVARG; return PM3_EINVARG;
@ -2921,7 +2919,7 @@ static void iclass_cmp_print(uint8_t *b1, uint8_t *b2, const char *header1, cons
strcat(line1, header1); strcat(line1, header1);
strcat(line2, header2); strcat(line2, header2);
for (uint8_t i = 0; i < PICOPASS_BLOCK_SIZE; i++ ) { for (uint8_t i = 0; i < PICOPASS_BLOCK_SIZE; i++) {
int l1 = strlen(line1); int l1 = strlen(line1);
int l2 = strlen(line2); int l2 = strlen(line2);
@ -3011,7 +3009,7 @@ static int CmdHFiClass_TearBlock(const char *Cmd) {
bool verbose = arg_get_lit(ctx, 10); bool verbose = arg_get_lit(ctx, 10);
bool shallow_mod = arg_get_lit(ctx, 11); bool shallow_mod = arg_get_lit(ctx, 11);
int tearoff_start = arg_get_int_def(ctx, 12, 5000); int tearoff_start = arg_get_int_def(ctx, 12, 100);
int tearoff_increment = arg_get_int_def(ctx, 13, 10); int tearoff_increment = arg_get_int_def(ctx, 13, 10);
int tearoff_end = arg_get_int_def(ctx, 14, tearoff_start + tearoff_increment + 500); int tearoff_end = arg_get_int_def(ctx, 14, tearoff_start + tearoff_increment + 500);
int tearoff_loop = arg_get_int_def(ctx, 15, 1); int tearoff_loop = arg_get_int_def(ctx, 15, 1);
@ -3035,8 +3033,8 @@ static int CmdHFiClass_TearBlock(const char *Cmd) {
return PM3_EINVARG; return PM3_EINVARG;
} }
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
} }
if (key_nr >= 0) { if (key_nr >= 0) {
if (key_nr < ICLASS_KEYS_MAX) { if (key_nr < ICLASS_KEYS_MAX) {
auth = true; auth = true;
@ -3060,17 +3058,22 @@ static int CmdHFiClass_TearBlock(const char *Cmd) {
} }
if (tearoff_end <= tearoff_start) { if (tearoff_end <= tearoff_start) {
PrintAndLogEx(ERR, "Tearoff end delay must be bigger than the start delay."); PrintAndLogEx(ERR, "Tearoff end delay must be larger than the start delay");
return PM3_EINVARG; return PM3_EINVARG;
} }
if (tearoff_start < 0 || tearoff_end <= 0) { if (tearoff_start <= 0) {
PrintAndLogEx(ERR, "Tearoff start/end delays should be bigger than 0."); PrintAndLogEx(ERR, "Tearoff_start delays must be larger than 0");
return PM3_EINVARG;
}
if (tearoff_end <= 0) {
PrintAndLogEx(ERR, "Tearoff_end delays must be larger than 0");
return PM3_EINVARG; return PM3_EINVARG;
} }
if ((use_replay + rawkey + elite) > 1) { if ((use_replay + rawkey + elite) > 1) {
PrintAndLogEx(ERR, "Can not use a combo of 'elite', 'raw', 'nr'"); PrintAndLogEx(ERR, "Can not use a combo of `--elite`, `--raw`, `--nr`");
return PM3_EINVARG; return PM3_EINVARG;
} }
@ -3134,7 +3137,7 @@ static int CmdHFiClass_TearBlock(const char *Cmd) {
auth = false; auth = false;
} }
//perform initial read here, repeat if failed or 00s // perform initial read here, repeat if failed or 00s
uint8_t data_read_orig[8] = {0}; uint8_t data_read_orig[8] = {0};
uint8_t ff_data[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; uint8_t ff_data[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
bool first_read = false; bool first_read = false;
@ -3229,7 +3232,8 @@ static int CmdHFiClass_TearBlock(const char *Cmd) {
} }
} }
if (decrease && tearoff_start > 0) { // if there was an error reading repeat the tearoff with the same delay // if there was an error reading repeat the tearoff with the same delay
if (decrease && tearoff_start > 0) {
tearoff_start -= tearoff_increment; tearoff_start -= tearoff_increment;
} }
@ -3240,24 +3244,26 @@ static int CmdHFiClass_TearBlock(const char *Cmd) {
tear_success = false; tear_success = false;
} }
if ((tear_success == false) && (memcmp(data_read, zeros, 8) != 0) && (memcmp(data_read, data_read_orig, 8) != 0)) { // tearoff succeeded (partially) if ((tear_success == false) && (memcmp(data_read, zeros, 8) != 0) && (memcmp(data_read, data_read_orig, 8) != 0)) {
// tearoff succeeded (partially)
expected_values = false; expected_values = false;
if (memcmp(data_read, ff_data, 8) == 0 && memcmp(data_read_orig, ff_data, 8) != 0) { if (memcmp(data_read, ff_data, 8) == 0 && memcmp(data_read_orig, ff_data, 8) != 0) {
erase_phase = true; erase_phase = true;
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(SUCCESS, _BLUE_("Erase phase hit: ALL ONES")); PrintAndLogEx(SUCCESS, _CYAN_("Erase phase hit... ALL ONES"));
iclass_cmp_print(data_read_orig, data_read, "Original: ", "Read: "); iclass_cmp_print(data_read_orig, data_read, "Original: ", "Read: ");
} else { } else {
if (erase_phase) { if (erase_phase) {
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(SUCCESS, _MAGENTA_("Tearing! Write Phase (post erase)")); PrintAndLogEx(SUCCESS, _MAGENTA_("Tearing! Write phase (post erase)"));
iclass_cmp_print(data_read_orig, data_read, "Original: ", "Read: "); iclass_cmp_print(data_read_orig, data_read, "Original: ", "Read: ");
} else { } else {
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(SUCCESS, _CYAN_("Tearing! (unknown phase)")); PrintAndLogEx(SUCCESS, _CYAN_("Tearing! unknown phase"));
iclass_cmp_print(data_read_orig, data_read, "Original: ", "Read: "); iclass_cmp_print(data_read_orig, data_read, "Original: ", "Read: ");
} }
} }
@ -3269,6 +3275,7 @@ static int CmdHFiClass_TearBlock(const char *Cmd) {
isok = PM3_SUCCESS; isok = PM3_SUCCESS;
goto out; goto out;
} }
if (data_read[7] != data_read_orig[7]) { if (data_read[7] != data_read_orig[7]) {
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(SUCCESS, "Fuse changed, from %02x to %02x", data_read_orig[7], data_read[7]); PrintAndLogEx(SUCCESS, "Fuse changed, from %02x to %02x", data_read_orig[7], data_read[7]);
@ -3276,10 +3283,6 @@ static int CmdHFiClass_TearBlock(const char *Cmd) {
goto out; goto out;
} }
} }
} else { // tearoff did not succeed
// PrintAndLogEx(INFO, "Expected: %s", sprint_hex_inrow(data, sizeof(data)));
// PrintAndLogEx(INFO, "Read: %s", sprint_hex_inrow(data_read, sizeof(data_read)));
} }
if (tear_success) { // tearoff succeeded with expected values if (tear_success) { // tearoff succeeded with expected values
@ -3289,9 +3292,9 @@ static int CmdHFiClass_TearBlock(const char *Cmd) {
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "Read: " _GREEN_("%s") " %s" PrintAndLogEx(INFO, "Read: " _GREEN_("%s") " %s"
, sprint_hex_inrow(data_read, sizeof(data_read)), , sprint_hex_inrow(data_read, sizeof(data_read)),
(expected_values) ? _GREEN_(" -> Expected values!") : "" (expected_values) ? _GREEN_(" -> Expected values!") : ""
); );
} }
loop_count++; loop_count++;
@ -5950,5 +5953,6 @@ int info_iclass(bool shallow_mod) {
} }
} }
PrintAndLogEx(NORMAL, "");
return PM3_SUCCESS; return PM3_SUCCESS;
} }

View file

@ -3739,12 +3739,13 @@
"--nr replay of NR/MAC", "--nr replay of NR/MAC",
"-v, --verbose verbose output", "-v, --verbose verbose output",
"--shallow use shallow (ASK) reader modulation instead of OOK", "--shallow use shallow (ASK) reader modulation instead of OOK",
"-s <dec> tearoff delay start (in us) must be between 1 and 43000 (43ms). Precision is about 1/3us.", "-s <dec> tearoff delay start (in us) must be between 1 and 43000 (43ms). Precision is about 1/3 us",
"-i <dec> tearoff delay increment (in us) - default 10.", "-i <dec> tearoff delay increment (in us) - default 10",
"-e <dec> tearoff delay end (in us) must be a higher value than the start delay.", "-e <dec> tearoff delay end (in us) must be a higher value than the start delay",
"--loop <dec> number of times to loop per tearoff time." "--loop <dec> number of times to loop per tearoff time",
"--sleep <ms> Sleep between each tear"
], ],
"usage": "hf iclass tear [-hv] [-k <hex>] [--ki <dec>] --blk <dec> -d <hex> [-m <hex>] [--credit] [--elite] [--raw] [--nr] [--shallow] -s <dec> [-i <dec>] [-e <dec>] [--loop <dec>]" "usage": "hf iclass tear [-hv] [-k <hex>] [--ki <dec>] --blk <dec> -d <hex> [-m <hex>] [--credit] [--elite] [--raw] [--nr] [--shallow] -s <dec> [-i <dec>] [-e <dec>] [--loop <dec>] [--sleep <ms>]"
}, },
"hf iclass unhash": { "hf iclass unhash": {
"command": "hf iclass unhash", "command": "hf iclass unhash",
@ -13354,6 +13355,6 @@
"metadata": { "metadata": {
"commands_extracted": 767, "commands_extracted": 767,
"extracted_by": "PM3Help2JSON v1.00", "extracted_by": "PM3Help2JSON v1.00",
"extracted_on": "2025-05-23T15:21:08" "extracted_on": "2025-05-24T19:13:03"
} }
} }