From 6b3f12ffe99fdc94bde7e0bedd96de744c5f4393 Mon Sep 17 00:00:00 2001 From: tcprst Date: Wed, 25 Nov 2020 14:02:52 -0500 Subject: [PATCH] hf iclass dump - now uses cliparser --- client/src/cmdhficlass.c | 222 +++++++++++++++++++-------------------- doc/cheatsheet.md | 15 ++- 2 files changed, 117 insertions(+), 120 deletions(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 284317a47..a3eb00e55 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -71,27 +71,6 @@ static int usage_hf_iclass_sim(void) { PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } -static int usage_hf_iclass_dump(void) { - PrintAndLogEx(NORMAL, "Dump all memory from a iCLASS tag\n"); - PrintAndLogEx(NORMAL, "Usage: hf iclass dump f k c [e|r|v]\n"); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h : Show this help"); - PrintAndLogEx(NORMAL, " f : specify a filename to save dump to"); - PrintAndLogEx(NORMAL, " k : access Key as 16 hex symbols or 1 hex to select key from memory OR NR/MAC for replay"); - PrintAndLogEx(NORMAL, " c : credit key as 16 hex symbols or 1 hex to select key from memory"); - PrintAndLogEx(NORMAL, " e : elite computations applied to key"); - PrintAndLogEx(NORMAL, " r : raw, the key is interpreted as raw block 3/4"); - PrintAndLogEx(NORMAL, " n : replay of NR/MAC"); - PrintAndLogEx(NORMAL, " v : verbose output"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, _YELLOW_("\thf iclass dump k 001122334455667B")); - PrintAndLogEx(NORMAL, _YELLOW_("\thf iclass dump k AAAAAAAAAAAAAAAA c 001122334455667B")); - PrintAndLogEx(NORMAL, _YELLOW_("\thf iclass dump k AAAAAAAAAAAAAAAA e")); - PrintAndLogEx(NORMAL, _YELLOW_("\thf iclass dump k 0")); - PrintAndLogEx(NORMAL, ""); - return PM3_SUCCESS; -} static int usage_hf_iclass_restore(void) { PrintAndLogEx(NORMAL, "Restore data from dumpfile onto a iCLASS tag\n"); PrintAndLogEx(NORMAL, "Usage: hf iclass restore f b l k c e|r\n"); @@ -1359,104 +1338,115 @@ static bool select_only(uint8_t *CSN, uint8_t *CCNR, bool verbose) { } static int CmdHFiClassDump(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf iclass dump", + "Dump all memory from a iCLASS tag", + "hf iclass dump -k 001122334455667B\n" + "hf iclass dump -k AAAAAAAAAAAAAAAA --credit 001122334455667B\n" + "hf iclass dump -k AAAAAAAAAAAAAAAA --elite\n" + "hf iclass dump --ki 0\n" + "hf iclass dump --ki 0 --ci 2"); - uint8_t KEY[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - uint8_t CreditKEY[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - uint8_t keyNbr = 0; - uint8_t dataLen = 0; - uint8_t app_limit1 = 0, app_limit2 = 0; - uint8_t fileNameLen = 0; + void *argtable[] = { + arg_param_begin, + arg_str0("f", "file", "", "filename to save dump to"), + arg_str0("k", "key", "", "debit key as 16 hex symbols OR NR/MAC for replay"), + arg_int0(NULL, "ki", "", "debit key index to select key from memory 'hf iclass managekeys'"), + arg_str0(NULL, "credit", "", "credit key as 16 hex symbols"), + arg_int0(NULL, "ci", "", "credit key index to select key from memory 'hf iclass managekeys'"), + arg_lit0(NULL, "elite", "elite computations applied to key"), + arg_lit0(NULL, "raw", "raw, the key is interpreted as raw block 3/4"), + arg_lit0(NULL, "nr", "replay of NR/MAC"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + + int fnlen = 0; char filename[FILE_PATH_SIZE] = {0}; - char tempStr[50] = {0}; - bool have_credit_key = false; - bool elite = false; - bool rawkey = false; - bool use_replay = false; - bool errors = false; - bool auth = false; - uint8_t cmdp = 0; + CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); - while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch (tolower(param_getchar(Cmd, cmdp))) { - case 'h': - return usage_hf_iclass_dump(); - case 'c': - auth = true; - have_credit_key = true; - dataLen = param_getstr(Cmd, cmdp + 1, tempStr, sizeof(tempStr)); - if (dataLen == 16) { - errors = param_gethex(tempStr, 0, CreditKEY, dataLen); - } else if (dataLen == 1) { - keyNbr = param_get8(Cmd, cmdp + 1); - if (keyNbr < ICLASS_KEYS_MAX) { - memcpy(CreditKEY, iClass_Key_Table[keyNbr], 8); - PrintAndLogEx(INFO, "AA2 (credit) index %u", keyNbr); - } else { - PrintAndLogEx(WARNING, "\nERROR: Credit KeyNbr is invalid\n"); - errors = true; - } - } else { - PrintAndLogEx(WARNING, "\nERROR: Credit Key is incorrect length\n"); - errors = true; - } - cmdp += 2; - break; - case 'e': - PrintAndLogEx(SUCCESS, "Using " _YELLOW_("elite algo")); - elite = true; - cmdp++; - break; - case 'f': - fileNameLen = param_getstr(Cmd, cmdp + 1, filename, sizeof(filename)); - if (fileNameLen < 1) { - PrintAndLogEx(WARNING, "no filename found after f"); - errors = true; - } - cmdp += 2; - break; - case 'k': - auth = true; - dataLen = param_getstr(Cmd, cmdp + 1, tempStr, sizeof(tempStr)); - if (dataLen == 16) { - errors = param_gethex(tempStr, 0, KEY, dataLen); - } else if (dataLen == 1) { - keyNbr = param_get8(Cmd, cmdp + 1); - if (keyNbr < ICLASS_KEYS_MAX) { - memcpy(KEY, iClass_Key_Table[keyNbr], 8); - PrintAndLogEx(INFO, "AA1 (debit) index %u", keyNbr); - } else { - PrintAndLogEx(WARNING, "\nERROR: Credit KeyNbr is invalid\n"); - errors = true; - } - } else { - PrintAndLogEx(WARNING, "\nERROR: Credit Key is incorrect length\n"); - errors = true; - } - cmdp += 2; - break; - case 'r': - PrintAndLogEx(SUCCESS, "Using " _YELLOW_("raw mode")); - rawkey = true; - cmdp++; - break; - case 'n': - PrintAndLogEx(SUCCESS, "Using " _YELLOW_("replay NR/MAC mode")); - use_replay = true; - cmdp++; - break; - default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'\n", param_getchar(Cmd, cmdp)); - errors = true; - break; + int key_len = 0; + uint8_t key[8] = {0}; + bool have_debit_key = false; + + CLIGetHexWithReturn(ctx, 2, key, &key_len); + + int deb_key_nr = arg_get_int_def(ctx, 3, -1); + + if (key_len > 0 && deb_key_nr >= 0) { + PrintAndLogEx(ERR, "Please specify debit key or index, not both"); + CLIParserFree(ctx); + return PM3_EINVARG; + } + + if (key_len > 0) { + have_debit_key = true; + if (key_len != 8) { + PrintAndLogEx(ERR, "Debit key is incorrect length"); + CLIParserFree(ctx); + return PM3_EINVARG; } } - if ((use_replay + rawkey + elite) > 1) { - PrintAndLogEx(FAILED, "Can not use a combo of 'e', 'r', 'n'"); - errors = true; + if (deb_key_nr >= 0) { + if (deb_key_nr < ICLASS_KEYS_MAX) { + have_debit_key = true; + memcpy(key, iClass_Key_Table[deb_key_nr], 8); + PrintAndLogEx(INFO, "AA1 (debit) index %u", deb_key_nr); + } else { + PrintAndLogEx(ERR, "Key number is invalid"); + CLIParserFree(ctx); + return PM3_EINVARG; + } } - if (errors) return usage_hf_iclass_dump(); + int credit_key_len = 0; + uint8_t credit_key[8] = {0}; + bool have_credit_key = false; + + CLIGetHexWithReturn(ctx, 4, credit_key, &credit_key_len); + + int credit_key_nr = arg_get_int_def(ctx, 5, -1); + + if (credit_key_len > 0 && credit_key_nr >= 0) { + PrintAndLogEx(ERR, "Please specify credit key or index, not both"); + CLIParserFree(ctx); + return PM3_EINVARG; + } + + if (credit_key_len > 0) { + have_credit_key = true; + if (key_len != 8) { + PrintAndLogEx(ERR, "Credit key is incorrect length"); + CLIParserFree(ctx); + return PM3_EINVARG; + } + } + + if (credit_key_nr >= 0) { + if (credit_key_nr < ICLASS_KEYS_MAX) { + have_credit_key = true; + memcpy(key, iClass_Key_Table[credit_key_nr], 8); + PrintAndLogEx(INFO, "AA2 (credit) index %u", credit_key_nr); + } else { + PrintAndLogEx(ERR, "Key number is invalid"); + CLIParserFree(ctx); + return PM3_EINVARG; + } + } + + bool elite = arg_get_lit(ctx, 6); + bool rawkey = arg_get_lit(ctx, 7); + bool use_replay = arg_get_lit(ctx, 8); + + CLIParserFree(ctx); + + if ((use_replay + rawkey + elite) > 1) { + PrintAndLogEx(FAILED, "Can not use a combo of 'e', 'r', 'n'"); + return PM3_EINVARG; + } + + uint8_t app_limit1 = 0, app_limit2 = 0; uint32_t flags = (FLAG_ICLASS_READER_INIT | FLAG_ICLASS_READER_CLEARTRACE); @@ -1511,11 +1501,11 @@ static int CmdHFiClassDump(const char *Cmd) { if (pagemap == PICOPASS_NON_SECURE_PAGEMODE) { PrintAndLogEx(INFO, "Dumping all available memory, block 3 - %u (0x%02x)", app_limit1, app_limit1); - if (auth) { + if (have_debit_key) { PrintAndLogEx(INFO, "No keys needed, ignoring user supplied key"); } } else { - if (auth == false) { + if (have_debit_key == false) { PrintAndLogEx(FAILED, "Run command with keys"); return PM3_ESOFT; } @@ -1528,10 +1518,10 @@ static int CmdHFiClassDump(const char *Cmd) { .req.use_credit_key = false, .req.use_replay = use_replay, .req.send_reply = true, - .req.do_auth = auth, + .req.do_auth = have_debit_key, .end_block = app_limit1, }; - memcpy(payload.req.key, KEY, 8); + memcpy(payload.req.key, key, 8); // tags configured for NON SECURE PAGE, acts different if (pagemap == PICOPASS_NON_SECURE_PAGEMODE) { @@ -1606,7 +1596,7 @@ static int CmdHFiClassDump(const char *Cmd) { if (have_credit_key && pagemap != 0x01) { // AA2 authenticate credit key - memcpy(payload.req.key, CreditKEY, 8); + memcpy(payload.req.key, credit_key, 8); payload.req.use_credit_key = true; payload.start_block = app_limit1 + 1; diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index 9699fabf0..c466a4784 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -62,9 +62,16 @@ Dump iCLASS card contents ``` Options --- -k : *Access Key as 16 hex symbols or 1 hex to select key from memory +-f, --file filename to save dump to +-k, --key debit key as 16 hex symbols OR NR/MAC for replay + --ki debit key index to select key from memory 'hf iclass managekeys' + --credit credit key as 16 hex symbols + --ci credit key index to select key from memory 'hf iclass managekeys' + --elite elite computations applied to key + --raw raw, the key is interpreted as raw block 3/4 + --nr replay of NR/MAC -m3 --> hf iclass dump k 0 +pm3 --> hf iclass dump --ki 0 ``` Read iCLASS Block @@ -161,7 +168,7 @@ pm3 --> hf iclass sim 3 Simulate iCLASS Sequence ``` -pm3 --> hf iclass dump k 0 +pm3 --> hf iclass dump --ki 0 pm3 --> hf iclass eload -f hf-iclass-db883702f8ff12e0.bin pm3 --> hf iclass sim 3 ``` @@ -177,7 +184,7 @@ e : If 'e' is specified, elite computations applied to key pm3 --> hf iclass sim 2 pm3 --> hf iclass loclass -f iclass_mac_attack.bin pm3 --> hf iclass managekeys n 7 k -pm3 --> hf iclass dump k 7 e +pm3 --> hf iclass dump --ki 7 --elite ``` Verify custom iCLASS key