renamed the hf iclass trdbl -> hf iclass tear

This commit is contained in:
iceman1001 2025-05-23 17:29:28 +02:00
commit d4bc190dd4
5 changed files with 50 additions and 30 deletions

View file

@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file.
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
## [unreleased][unreleased] ## [unreleased][unreleased]
- Renamed `hf iclass trbl` -> `hf iclass tear` (@iceman1001)
- Changed `hw tearoff` - the device side message is now debug log controlled (@iceman1001) - Changed `hw tearoff` - the device side message is now debug log controlled (@iceman1001)
- Changed `pm3.sh` - Serial ports enumeration on Proxspace3.xx / MINGW environments, now using powershell.exe since wmic is deprecated (@iceman1001) - Changed `pm3.sh` - Serial ports enumeration on Proxspace3.xx / MINGW environments, now using powershell.exe since wmic is deprecated (@iceman1001)
- Fixed and updated `hf iclass trbl` to correctly use the credit key when passed and show partial tearoff results (@antiklesys) - Fixed and updated `hf iclass trbl` to correctly use the credit key when passed and show partial tearoff results (@antiklesys)

View file

@ -2919,10 +2919,14 @@ static int CmdHFiClass_ReadBlock(const char *Cmd) {
static int CmdHFiClass_TearBlock(const char *Cmd) { static int CmdHFiClass_TearBlock(const char *Cmd) {
CLIParserContext *ctx; CLIParserContext *ctx;
CLIParserInit(&ctx, "hf iclass trbl", CLIParserInit(&ctx, "hf iclass tear",
"Tear off an iCLASS tag block", "Tear off an iCLASS tag block\n"
"hf iclass trbl --blk 10 -d AAAAAAAAAAAAAAAA -k 001122334455667B --tdb 100 --tde 150\n" "e-purse usually 300-500us to trigger the erase phase\n"
"hf iclass trbl --blk 10 -d AAAAAAAAAAAAAAAA --ki 0 --tdb 100 --tde 150"); "also seen 1800-2100us on some cards\n",
"hf iclass tear --blk 10 -d AAAAAAAAAAAAAAAA -k 001122334455667B -s 300 -e 600\n"
"hf iclass tear --blk 10 -d AAAAAAAAAAAAAAAA --ki 0 -s 300 -e 600\n"
"hf iclass tear --blk 2 -d fdffffffffffffff --ki 1 --credit -s 400 -e 500"
);
void *argtable[] = { void *argtable[] = {
arg_param_begin, arg_param_begin,
@ -2937,9 +2941,9 @@ static int CmdHFiClass_TearBlock(const char *Cmd) {
arg_lit0(NULL, "nr", "replay of NR/MAC"), arg_lit0(NULL, "nr", "replay of NR/MAC"),
arg_lit0("v", "verbose", "verbose output"), arg_lit0("v", "verbose", "verbose output"),
arg_lit0(NULL, "shallow", "use shallow (ASK) reader modulation instead of OOK"), arg_lit0(NULL, "shallow", "use shallow (ASK) reader modulation instead of OOK"),
arg_int1(NULL, "s", "<dec>", "tearoff delay start (in us) must be between 1 and 43000 (43ms). Precision is about 1/3us."), arg_int1("s", NULL, "<dec>", "tearoff delay start (in us) must be between 1 and 43000 (43ms). Precision is about 1/3us."),
arg_int0(NULL, "i", "<dec>", "tearoff delay increment (in us) - default 10."), arg_int0("i", NULL, "<dec>", "tearoff delay increment (in us) - default 10."),
arg_int0(NULL, "e", "<dec>", "tearoff delay end (in us) must be a higher value than the start delay."), arg_int0("e", NULL, "<dec>", "tearoff delay end (in us) must be a higher value than the start delay."),
arg_int0(NULL, "loop", "<dec>", "number of times to loop per tearoff time."), arg_int0(NULL, "loop", "<dec>", "number of times to loop per tearoff time."),
arg_param_end arg_param_end
}; };
@ -3075,10 +3079,10 @@ static int CmdHFiClass_TearBlock(const char *Cmd) {
picopass_hdr_t *hdr = &r->header.hdr; picopass_hdr_t *hdr = &r->header.hdr;
uint8_t pagemap = get_pagemap(hdr); uint8_t pagemap = get_pagemap(hdr);
if (pagemap == PICOPASS_NON_SECURE_PAGEMODE) { if (pagemap == PICOPASS_NON_SECURE_PAGEMODE) {
PrintAndLogEx(INFO, "Card in non-secure page mode detected"); PrintAndLogEx(INFO, "Card in non-secure page mode detected");
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};
@ -3172,7 +3176,7 @@ 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 (decrease && tearoff_start > 0) { // if there was an error reading repeat the tearoff with the same delay
tearoff_start -= tearoff_increment; tearoff_start -= tearoff_increment;
} }
@ -3183,7 +3187,7 @@ 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;
@ -3199,18 +3203,31 @@ static int CmdHFiClass_TearBlock(const char *Cmd) {
PrintAndLogEx(INFO, "Original: %s", sprint_hex_inrow(data_read_orig, sizeof(data_read))); PrintAndLogEx(INFO, "Original: %s", sprint_hex_inrow(data_read_orig, sizeof(data_read)));
PrintAndLogEx(INFO, "Read: "_CYAN_("%s"), sprint_hex_inrow(data_read, sizeof(data_read))); PrintAndLogEx(INFO, "Read: "_CYAN_("%s"), sprint_hex_inrow(data_read, sizeof(data_read)));
} else { } else {
PrintAndLogEx(SUCCESS, _CYAN_("Tearing!(unknown phase)!")); PrintAndLogEx(SUCCESS, _CYAN_("Tearing! (unknown phase)"));
PrintAndLogEx(INFO, "Original: %s", sprint_hex_inrow(data_read_orig, sizeof(data_read))); PrintAndLogEx(INFO, "Original: %s", sprint_hex_inrow(data_read_orig, sizeof(data_read)));
PrintAndLogEx(INFO, "Read: "_CYAN_("%s"), sprint_hex_inrow(data_read, sizeof(data_read))); PrintAndLogEx(INFO, "Read: "_CYAN_("%s"), sprint_hex_inrow(data_read, sizeof(data_read)));
} }
} }
} else { //tearoff did not succeed if (blockno == 1) {
if (data_read[0] != data_read_orig[0]) {
PrintAndLogEx(SUCCESS, "Application limit changed, from %u to %u", data_read_orig[0], data_read[0]);
isok = PM3_SUCCESS;
goto out;
}
if (data_read[7] != data_read_orig[7]) {
PrintAndLogEx(SUCCESS, "Fuse changed, from %02x to %02x", data_read_orig[7], data_read[7]);
isok = PM3_SUCCESS;
goto out;
}
}
} else { // tearoff did not succeed
PrintAndLogEx(INFO, "Read: %s", sprint_hex_inrow(data_read, sizeof(data_read))); PrintAndLogEx(INFO, "Read: %s", sprint_hex_inrow(data_read, sizeof(data_read)));
PrintAndLogEx(INFO, "Expected: %s", sprint_hex_inrow(data, sizeof(data))); PrintAndLogEx(INFO, "Expected: %s", sprint_hex_inrow(data, sizeof(data)));
} }
if (tear_success) { //tearoff succeeded with expected values if (tear_success) { // tearoff succeeded with expected values
read_ok = true; read_ok = true;
tear_success = true; tear_success = true;
if (expected_values) { if (expected_values) {
@ -3219,7 +3236,7 @@ static int CmdHFiClass_TearBlock(const char *Cmd) {
PrintAndLogEx(INFO, "Read: "_GREEN_("%s"), sprint_hex_inrow(data_read, sizeof(data_read))); PrintAndLogEx(INFO, "Read: "_GREEN_("%s"), sprint_hex_inrow(data_read, sizeof(data_read)));
} }
loop_count++; loop_count++;
if (loop_count == tearoff_loop){ if (loop_count == tearoff_loop) {
tearoff_start += tearoff_increment; tearoff_start += tearoff_increment;
loop_count = 0; loop_count = 0;
} }
@ -5662,7 +5679,7 @@ static command_t CommandTable[] = {
{"view", CmdHFiClassView, AlwaysAvailable, "Display content from tag dump file"}, {"view", CmdHFiClassView, AlwaysAvailable, "Display content from tag dump file"},
{"wrbl", CmdHFiClass_WriteBlock, IfPm3Iclass, "Write Picopass / iCLASS block"}, {"wrbl", CmdHFiClass_WriteBlock, IfPm3Iclass, "Write Picopass / iCLASS block"},
{"creditepurse", CmdHFiClassCreditEpurse, IfPm3Iclass, "Credit epurse value"}, {"creditepurse", CmdHFiClassCreditEpurse, IfPm3Iclass, "Credit epurse value"},
{"trbl", CmdHFiClass_TearBlock, IfPm3Iclass, "Performs tearoff attack on iClass block"}, {"tear", CmdHFiClass_TearBlock, IfPm3Iclass, "Performs tearoff attack on iClass block"},
{"-----------", CmdHelp, AlwaysAvailable, "--------------------- " _CYAN_("Recovery") " --------------------"}, {"-----------", CmdHelp, AlwaysAvailable, "--------------------- " _CYAN_("Recovery") " --------------------"},
// {"autopwn", CmdHFiClassAutopwn, IfPm3Iclass, "Automatic key recovery tool for iCLASS"}, // {"autopwn", CmdHFiClassAutopwn, IfPm3Iclass, "Automatic key recovery tool for iCLASS"},
{"chk", CmdHFiClassCheckKeys, IfPm3Iclass, "Check keys"}, {"chk", CmdHFiClassCheckKeys, IfPm3Iclass, "Check keys"},

View file

@ -281,7 +281,7 @@ const static vocabulary_t vocabulary[] = {
{ 1, "hf iclass view" }, { 1, "hf iclass view" },
{ 0, "hf iclass wrbl" }, { 0, "hf iclass wrbl" },
{ 0, "hf iclass creditepurse" }, { 0, "hf iclass creditepurse" },
{ 0, "hf iclass trbl" }, { 0, "hf iclass tear" },
{ 0, "hf iclass chk" }, { 0, "hf iclass chk" },
{ 1, "hf iclass loclass" }, { 1, "hf iclass loclass" },
{ 1, "hf iclass lookup" }, { 1, "hf iclass lookup" },

View file

@ -3717,12 +3717,13 @@
], ],
"usage": "hf iclass sniff [-hj]" "usage": "hf iclass sniff [-hj]"
}, },
"hf iclass trbl": { "hf iclass tear": {
"command": "hf iclass trbl", "command": "hf iclass tear",
"description": "Tear off an iCLASS tag block", "description": "Tear off an iCLASS tag block e-purse usually 300-500us to trigger the erase phase also seen 1800-2100us on some cards",
"notes": [ "notes": [
"hf iclass trbl --blk 10 -d AAAAAAAAAAAAAAAA -k 001122334455667B --tdb 100 --tde 150", "hf iclass tear --blk 10 -d AAAAAAAAAAAAAAAA -k 001122334455667B -s 300 -e 600",
"hf iclass trbl --blk 10 -d AAAAAAAAAAAAAAAA --ki 0 --tdb 100 --tde 150" "hf iclass tear --blk 10 -d AAAAAAAAAAAAAAAA --ki 0 -s 300 -e 600",
"hf iclass tear --blk 2 -d fdffffffffffffff --ki 1 --credit -s 400 -e 500"
], ],
"offline": false, "offline": false,
"options": [ "options": [
@ -3738,11 +3739,12 @@
"--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/3us.",
"--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."
], ],
"usage": "hf iclass trbl [-hv] [-k <hex>] [--ki <dec>] --blk <dec> -d <hex> [-m <hex>] [--credit] [--elite] [--raw] [--nr] [--shallow] --s <dec> [--i <dec>] [--e <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>]"
}, },
"hf iclass unhash": { "hf iclass unhash": {
"command": "hf iclass unhash", "command": "hf iclass unhash",
@ -13352,6 +13354,6 @@
"metadata": { "metadata": {
"commands_extracted": 767, "commands_extracted": 767,
"extracted_by": "PM3Help2JSON v1.00", "extracted_by": "PM3Help2JSON v1.00",
"extracted_on": "2025-05-23T08:30:58" "extracted_on": "2025-05-23T15:21:08"
} }
} }

View file

@ -404,7 +404,7 @@ Check column "offline" for their availability.
|`hf iclass view `|Y |`Display content from tag dump file` |`hf iclass view `|Y |`Display content from tag dump file`
|`hf iclass wrbl `|N |`Write Picopass / iCLASS block` |`hf iclass wrbl `|N |`Write Picopass / iCLASS block`
|`hf iclass creditepurse `|N |`Credit epurse value` |`hf iclass creditepurse `|N |`Credit epurse value`
|`hf iclass trbl `|N |`Performs tearoff attack on iClass block` |`hf iclass tear `|N |`Performs tearoff attack on iClass block`
|`hf iclass chk `|N |`Check keys` |`hf iclass chk `|N |`Check keys`
|`hf iclass loclass `|Y |`Use loclass to perform bruteforce reader attack` |`hf iclass loclass `|Y |`Use loclass to perform bruteforce reader attack`
|`hf iclass lookup `|Y |`Uses authentication trace to check for key in dictionary file` |`hf iclass lookup `|Y |`Uses authentication trace to check for key in dictionary file`