diff --git a/armsrc/appmain.c b/armsrc/appmain.c index d4faff5a1..e52af017f 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1668,7 +1668,7 @@ static void PacketReceived(PacketCommandNG *packet) { case CMD_HF_MIFARE_READBL: { mf_readblock_t *payload = (mf_readblock_t *)packet->data.asBytes; uint8_t outbuf[16]; - int16_t retval = mifare_cmd_readblocks(MF_WAKE_WUPA, MIFARE_AUTH_KEYA + (payload->keytype & 1), payload->key, ISO14443A_CMD_READBLOCK, payload->blockno, 1, outbuf); + int16_t retval = mifare_cmd_readblocks(MF_WAKE_WUPA, MIFARE_AUTH_KEYA + payload->keytype, payload->key, ISO14443A_CMD_READBLOCK, payload->blockno, 1, outbuf); reply_ng(CMD_HF_MIFARE_READBL, retval, outbuf, sizeof(outbuf)); break; } @@ -1716,7 +1716,7 @@ static void PacketReceived(PacketCommandNG *packet) { uint8_t *key = packet->data.asBytes; uint8_t *block_data = packet->data.asBytes + 10; - int16_t retval = mifare_cmd_writeblocks(MF_WAKE_WUPA, MIFARE_AUTH_KEYA + (key_type & 1), key, ISO14443A_CMD_WRITEBLOCK, block_no, 1, block_data); + int16_t retval = mifare_cmd_writeblocks(MF_WAKE_WUPA, MIFARE_AUTH_KEYA + (key_type & 0xF), key, ISO14443A_CMD_WRITEBLOCK, block_no, 1, block_data); // convert ng style retval to old status if (retval >= 0) { diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index af8fa972a..60de108ce 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -244,7 +244,7 @@ void MifareReadSector(uint8_t sector_no, uint8_t key_type, uint8_t *key) { uint8_t num_blocks = NumBlocksPerSector(sector_no); uint8_t outbuf[16 * 16]; - int16_t retval = mifare_cmd_readblocks(MF_WAKE_WUPA, MIFARE_AUTH_KEYA + (key_type & 1), key, ISO14443A_CMD_READBLOCK, block_no, num_blocks, outbuf); + int16_t retval = mifare_cmd_readblocks(MF_WAKE_WUPA, MIFARE_AUTH_KEYA + (key_type & 0xF), key, ISO14443A_CMD_READBLOCK, block_no, num_blocks, outbuf); reply_old(CMD_ACK, retval == PM3_SUCCESS, 0, 0, outbuf, 16 * num_blocks); } @@ -975,7 +975,7 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, } // nested authentication - uint16_t len = mifare_sendcmd_short(pcs, AUTH_NESTED, MIFARE_AUTH_KEYA + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, par_enc, NULL); + uint16_t len = mifare_sendcmd_short(pcs, AUTH_NESTED, MIFARE_AUTH_KEYA + (targetKeyType & 0xF), targetBlockNo, receivedAnswer, par_enc, NULL); // wait for the card to become ready again CHK_TIMEOUT(); @@ -1215,7 +1215,7 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8 // nested authentication auth2_time = auth1_time + delta_time; - len = mifare_sendcmd_short(pcs, AUTH_NESTED, MIFARE_AUTH_KEYA + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, par, &auth2_time); + len = mifare_sendcmd_short(pcs, AUTH_NESTED, MIFARE_AUTH_KEYA + (targetKeyType & 0xF), targetBlockNo, receivedAnswer, par, &auth2_time); if (len != 4) { if (g_dbglevel >= DBG_INFO) Dbprintf("Nested: Auth2 error len=%d", len); continue; @@ -1340,7 +1340,7 @@ void MifareStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, target_nt[1] = prng_successor(nt1, 320); } - len = mifare_sendcmd_short(pcs, AUTH_NESTED, MIFARE_AUTH_KEYA + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, par, NULL); + len = mifare_sendcmd_short(pcs, AUTH_NESTED, MIFARE_AUTH_KEYA + (targetKeyType & 0xF), targetBlockNo, receivedAnswer, par, NULL); if (len != 4) { continue; }; @@ -1365,7 +1365,7 @@ void MifareStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, continue; }; - len = mifare_sendcmd_short(pcs, AUTH_NESTED, MIFARE_AUTH_KEYA + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, par, NULL); + len = mifare_sendcmd_short(pcs, AUTH_NESTED, MIFARE_AUTH_KEYA + (targetKeyType & 0xF), targetBlockNo, receivedAnswer, par, NULL); if (len != 4) { continue; }; diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index 416497d79..901154c7b 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -142,7 +142,7 @@ int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, return mifare_classic_authex(pcs, uid, blockNo, keyType, ui64Key, isNested, NULL, NULL); } int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t *ntptr, uint32_t *timing) { - return mifare_classic_authex_cmd(pcs, uid, blockNo, (keyType & 1) ? MIFARE_AUTH_KEYB : MIFARE_AUTH_KEYA, ui64Key, isNested, ntptr, NULL, timing); + return mifare_classic_authex_cmd(pcs, uid, blockNo, MIFARE_AUTH_KEYA + (keyType & 0xF), ui64Key, isNested, ntptr, NULL, timing); } int mifare_classic_authex_cmd(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t cmd, uint64_t ui64Key, uint8_t isNested, uint32_t *ntptr, uint32_t *ntencptr, uint32_t *timing) { diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index ace8dd5c2..230fea8b6 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -952,6 +952,7 @@ static int CmdHF14AMfWrBl(const char *Cmd) { arg_int1(NULL, "blk", "", "block number"), arg_lit0("a", NULL, "input key type is key A (def)"), arg_lit0("b", NULL, "input key type is key B"), + arg_int0("c", NULL, "", "input key type is key A + offset"), arg_lit0(NULL, "force", "override warnings"), arg_str0("k", "key", "", "key, 6 hex bytes"), arg_str0("d", "data", "", "bytes to write, 16 hex bytes"), @@ -964,21 +965,27 @@ static int CmdHF14AMfWrBl(const char *Cmd) { uint8_t keytype = MF_KEY_A; if (arg_get_lit(ctx, 2) && arg_get_lit(ctx, 3)) { CLIParserFree(ctx); - PrintAndLogEx(WARNING, "Input key type must be A or B"); + PrintAndLogEx(WARNING, "Choose one single input key type"); return PM3_EINVARG; } else if (arg_get_lit(ctx, 3)) { - keytype = MF_KEY_B;; + keytype = MF_KEY_B; } - - bool force = arg_get_lit(ctx, 4); + uint8_t prev_keytype = keytype; + keytype = arg_get_int_def(ctx, 4, keytype); + if ((arg_get_lit(ctx, 2) || arg_get_lit(ctx, 3)) && (keytype != prev_keytype)) { + CLIParserFree(ctx); + PrintAndLogEx(WARNING, "Choose one single input key type"); + return PM3_EINVARG; + } + bool force = arg_get_lit(ctx, 5); int keylen = 0; uint8_t key[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; - CLIGetHexWithReturn(ctx, 5, key, &keylen); + CLIGetHexWithReturn(ctx, 6, key, &keylen); uint8_t block[MFBLOCK_SIZE] = {0x00}; int blen = 0; - CLIGetHexWithReturn(ctx, 6, block, &blen); + CLIGetHexWithReturn(ctx, 7, block, &blen); CLIParserFree(ctx); if (keylen && keylen != 6) { @@ -1053,6 +1060,7 @@ static int CmdHF14AMfRdBl(const char *Cmd) { arg_int1(NULL, "blk", "", "block number"), arg_lit0("a", NULL, "input key type is key A (def)"), arg_lit0("b", NULL, "input key type is key B"), + arg_int0("c", NULL, "", "input key type is key A + offset"), arg_str0("k", "key", "", "key, 6 hex bytes"), arg_lit0("v", "verbose", "verbose output"), arg_param_end @@ -1063,16 +1071,24 @@ static int CmdHF14AMfRdBl(const char *Cmd) { uint8_t keytype = MF_KEY_A; if (arg_get_lit(ctx, 2) && arg_get_lit(ctx, 3)) { CLIParserFree(ctx); - PrintAndLogEx(WARNING, "Input key type must be A or B"); + PrintAndLogEx(WARNING, "Choose one single input key type"); return PM3_EINVARG; } else if (arg_get_lit(ctx, 3)) { keytype = MF_KEY_B; } + keytype = arg_get_int_def(ctx, 4, keytype); + uint8_t prev_keytype = keytype; + keytype = arg_get_int_def(ctx, 4, keytype); + if ((arg_get_lit(ctx, 2) || arg_get_lit(ctx, 3)) && (keytype != prev_keytype)) { + CLIParserFree(ctx); + PrintAndLogEx(WARNING, "Choose one single input key type"); + return PM3_EINVARG; + } int keylen = 0; uint8_t key[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; - CLIGetHexWithReturn(ctx, 4, key, &keylen); - bool verbose = arg_get_lit(ctx, 5); + CLIGetHexWithReturn(ctx, 5, key, &keylen); + bool verbose = arg_get_lit(ctx, 6); CLIParserFree(ctx); if (keylen && keylen != 6) { @@ -1112,6 +1128,7 @@ static int CmdHF14AMfRdSc(const char *Cmd) { arg_param_begin, arg_lit0("a", NULL, "input key specified is A key (def)"), arg_lit0("b", NULL, "input key specified is B key"), + arg_int0("c", NULL, "", "input key type is key A + offset"), arg_str0("k", "key", "", "key specified as 6 hex bytes"), arg_int1("s", "sec", "", "sector number"), arg_lit0("v", "verbose", "verbose output"), @@ -1121,18 +1138,25 @@ static int CmdHF14AMfRdSc(const char *Cmd) { uint8_t keytype = MF_KEY_A; if (arg_get_lit(ctx, 1) && arg_get_lit(ctx, 2)) { CLIParserFree(ctx); - PrintAndLogEx(WARNING, "Input key type must be A or B"); + PrintAndLogEx(WARNING, "Choose one single input key type"); return PM3_EINVARG; } else if (arg_get_lit(ctx, 2)) { keytype = MF_KEY_B; } + uint8_t prev_keytype = keytype; + keytype = arg_get_int_def(ctx, 3, keytype); + if ((arg_get_lit(ctx, 1) || arg_get_lit(ctx, 2)) && (keytype != prev_keytype)) { + CLIParserFree(ctx); + PrintAndLogEx(WARNING, "Choose one single input key type"); + return PM3_EINVARG; + } int keylen = 0; uint8_t key[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; - CLIGetHexWithReturn(ctx, 3, key, &keylen); + CLIGetHexWithReturn(ctx, 4, key, &keylen); - int s = arg_get_int_def(ctx, 4, 0); - bool verbose = arg_get_lit(ctx, 5); + int s = arg_get_int_def(ctx, 5, 0); + bool verbose = arg_get_lit(ctx, 6); CLIParserFree(ctx); if (keylen && keylen != 6) { @@ -1611,9 +1635,11 @@ static int CmdHF14AMfNested(const char *Cmd) { //TODO: single mode broken? can't arg_int0(NULL, "blk", "", "Input block number"), arg_lit0("a", NULL, "Input key specified is A key (default)"), arg_lit0("b", NULL, "Input key specified is B key"), + arg_int0("c", NULL, "", "input key type is key A + offset"), arg_int0(NULL, "tblk", "", "Target block number"), arg_lit0(NULL, "ta", "Target A key (default)"), arg_lit0(NULL, "tb", "Target B key"), + arg_int0(NULL, "tc", "", "Nested input key type is key A + offset (you must specify a single block as well!)"), arg_lit0(NULL, "emu", "Fill simulator keys from found keys"), arg_lit0(NULL, "dump", "Dump found keys to file"), arg_lit0(NULL, "mem", "Use dictionary from flashmemory"), @@ -1637,29 +1663,42 @@ static int CmdHF14AMfNested(const char *Cmd) { //TODO: single mode broken? can't if (arg_get_lit(ctx, 7) && arg_get_lit(ctx, 8)) { CLIParserFree(ctx); - PrintAndLogEx(WARNING, "Input key type must be A or B"); + PrintAndLogEx(WARNING, "Choose one single input key type"); return PM3_EINVARG; } else if (arg_get_lit(ctx, 8)) { keyType = MF_KEY_B; } + uint8_t prev_keytype = keyType; + keyType = arg_get_int_def(ctx, 9, keyType); + if ((arg_get_lit(ctx, 7) || arg_get_lit(ctx, 8)) && (keyType != prev_keytype)) { + CLIParserFree(ctx); + PrintAndLogEx(WARNING, "Choose one single input key type"); + return PM3_EINVARG; + } - int trgBlockNo = arg_get_int_def(ctx, 9, -1); + int trgBlockNo = arg_get_int_def(ctx, 10, -1); uint8_t trgKeyType = MF_KEY_A; - if (arg_get_lit(ctx, 10) && arg_get_lit(ctx, 11)) { + if (arg_get_lit(ctx, 11) && arg_get_lit(ctx, 12)) { CLIParserFree(ctx); - PrintAndLogEx(WARNING, "Target key type must be A or B"); + PrintAndLogEx(WARNING, "Choose one single target key type"); return PM3_EINVARG; - } else if (arg_get_lit(ctx, 11)) { + } else if (arg_get_lit(ctx, 12)) { trgKeyType = MF_KEY_B; } - - bool transferToEml = arg_get_lit(ctx, 12); - bool createDumpFile = arg_get_lit(ctx, 13); + uint8_t prev_trgkeytype = trgKeyType; + trgKeyType = arg_get_int_def(ctx, 13, trgKeyType); + if ((arg_get_lit(ctx, 11) || arg_get_lit(ctx, 12)) && (trgKeyType != prev_trgkeytype)) { + CLIParserFree(ctx); + PrintAndLogEx(WARNING, "Choose one single target key type"); + return PM3_EINVARG; + } + bool transferToEml = arg_get_lit(ctx, 14); + bool createDumpFile = arg_get_lit(ctx, 15); bool singleSector = trgBlockNo > -1; - bool use_flashmemory = arg_get_lit(ctx, 14); - bool ignore_static_encrypted = arg_get_lit(ctx, 15); + bool use_flashmemory = arg_get_lit(ctx, 16); + bool ignore_static_encrypted = arg_get_lit(ctx, 17); CLIParserFree(ctx); @@ -1725,7 +1764,11 @@ static int CmdHF14AMfNested(const char *Cmd) { //TODO: single mode broken? can't // check if we can authenticate to sector if (mfCheckKeys(blockNo, keyType, true, 1, key, &key64) != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "Wrong key. Can't authenticate to block:%3d key type:%c", blockNo, keyType ? 'B' : 'A'); + if (keyType < 2) { + PrintAndLogEx(WARNING, "Wrong key. Can't authenticate to block:%3d key type:%c", blockNo, keyType ? 'B' : 'A'); + } else { + PrintAndLogEx(WARNING, "Wrong key. Can't authenticate to block:%3d key type:%02x", blockNo, MIFARE_AUTH_KEYA + keyType); + } return PM3_EOPABORTED; } @@ -1972,7 +2015,7 @@ static int CmdHF14AMfNestedStatic(const char *Cmd) { if (arg_get_lit(ctx, 7) && arg_get_lit(ctx, 8)) { CLIParserFree(ctx); - PrintAndLogEx(WARNING, "Input key type must be A or B"); + PrintAndLogEx(WARNING, "Choose one single input key type"); return PM3_EINVARG; } else if (arg_get_lit(ctx, 8)) { keyType = MF_KEY_B; @@ -2023,7 +2066,11 @@ static int CmdHF14AMfNestedStatic(const char *Cmd) { // check if we can authenticate to sector if (mfCheckKeys(blockNo, keyType, true, 1, key, &key64) != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "Wrong key. Can't authenticate to block: %3d key type: %c", blockNo, keyType ? 'B' : 'A'); + if (keyType < 2) { + PrintAndLogEx(WARNING, "Wrong key. Can't authenticate to block:%3d key type:%c", blockNo, keyType ? 'B' : 'A'); + } else { + PrintAndLogEx(WARNING, "Wrong key. Can't authenticate to block:%3d key type:%02x", blockNo, MIFARE_AUTH_KEYA + keyType); + } return PM3_EOPABORTED; } @@ -2246,7 +2293,7 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { uint8_t keytype = MF_KEY_A; if (arg_get_lit(ctx, 3) && arg_get_lit(ctx, 4)) { CLIParserFree(ctx); - PrintAndLogEx(WARNING, "Input key type must be A or B"); + PrintAndLogEx(WARNING, "Choose one single input key type"); return PM3_EINVARG; } else if (arg_get_lit(ctx, 4)) { keytype = MF_KEY_B; @@ -2257,7 +2304,7 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { uint8_t trg_keytype = MF_KEY_A; if (arg_get_lit(ctx, 6) && arg_get_lit(ctx, 7)) { CLIParserFree(ctx); - PrintAndLogEx(WARNING, "Input key type must be A or B"); + PrintAndLogEx(WARNING, "Choose one single target key type"); return PM3_EINVARG; } else if (arg_get_lit(ctx, 7)) { trg_keytype = MF_KEY_B; @@ -2367,7 +2414,11 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { uint64_t key64 = 0; // check if we can authenticate to sector if (mfCheckKeys(blockno, keytype, true, 1, key, &key64) != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "Key is wrong. Can't authenticate to block: %3d key type: %c", blockno, (keytype == MF_KEY_B) ? 'B' : 'A'); + if (keytype < 2) { + PrintAndLogEx(WARNING, "Wrong key. Can't authenticate to block:%3d key type:%c", blockno, keytype ? 'B' : 'A'); + } else { + PrintAndLogEx(WARNING, "Wrong key. Can't authenticate to block:%3d key type:%02x", blockno, MIFARE_AUTH_KEYA + keytype); + } return PM3_EWRONGANSWER; } } @@ -2466,7 +2517,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { uint8_t keytype = MF_KEY_A; if (arg_get_lit(ctx, 3) && arg_get_lit(ctx, 4)) { CLIParserFree(ctx); - PrintAndLogEx(WARNING, "Input key type must be A or B"); + PrintAndLogEx(WARNING, "Choose one single input key type"); return PM3_EINVARG; } else if (arg_get_lit(ctx, 4)) { keytype = MF_KEY_B; @@ -3010,7 +3061,7 @@ tryNested: case PM3_ESTATIC_NONCE: { PrintAndLogEx(ERR, "Error: Static encrypted nonce detected. Aborted\n"); - e_sector[current_sector_i].Key[current_key_type_i] = 0xffffffffffff;; + e_sector[current_sector_i].Key[current_key_type_i] = 0xffffffffffff; e_sector[current_sector_i].foundKey[current_key_type_i] = false; // Show the results to the user PrintAndLogEx(NORMAL, ""); @@ -3061,7 +3112,7 @@ tryHardnested: // If the nested attack fails then we try the hardnested attack case PM3_ESTATIC_NONCE: { PrintAndLogEx(ERR, "\nError: Static encrypted nonce detected. Aborted\n"); - e_sector[current_sector_i].Key[current_key_type_i] = 0xffffffffffff;; + e_sector[current_sector_i].Key[current_key_type_i] = 0xffffffffffff; e_sector[current_sector_i].foundKey[current_key_type_i] = false; // Show the results to the user @@ -3269,7 +3320,7 @@ static int CmdHF14AMfChk_fast(const char *Cmd) { 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"); + PrintAndLogEx(WARNING, "Choose one single input key type"); return PM3_EINVARG; } else if (arg_get_lit(ctx, 12)) { keytype = MF_KEY_B; @@ -4841,7 +4892,7 @@ static int CmdHF14AMfECFill(const char *Cmd) { uint8_t keytype = MF_KEY_A; if (arg_get_lit(ctx, 1) && arg_get_lit(ctx, 2)) { CLIParserFree(ctx); - PrintAndLogEx(WARNING, "Input key type must be A or B"); + PrintAndLogEx(WARNING, "Choose one single input key type"); return PM3_EINVARG; } else if (arg_get_lit(ctx, 2)) { keytype = MF_KEY_B; @@ -8935,19 +8986,19 @@ static int CmdHF14AMfValue(const char *Cmd) { uint8_t keytype = MF_KEY_A; if (arg_get_lit(ctx, 2) && arg_get_lit(ctx, 3)) { CLIParserFree(ctx); - PrintAndLogEx(WARNING, "Input key type must be A or B"); + PrintAndLogEx(WARNING, "Choose one single input key type"); return PM3_EINVARG; } else if (arg_get_lit(ctx, 3)) { - keytype = MF_KEY_B;; + keytype = MF_KEY_B; } uint8_t transferkeytype = MF_KEY_A; if (arg_get_lit(ctx, 9) && arg_get_lit(ctx, 10)) { CLIParserFree(ctx); - PrintAndLogEx(WARNING, "Input key type must be A or B"); + PrintAndLogEx(WARNING, "Choose one single transfer key type"); return PM3_EINVARG; } else if (arg_get_lit(ctx, 10)) { - transferkeytype = MF_KEY_B;; + transferkeytype = MF_KEY_B; } int keylen = 0; @@ -9335,7 +9386,7 @@ static int CmdHF14AMfInfo(const char *Cmd) { uint8_t keytype = MF_KEY_A; if (arg_get_lit(ctx, 2) && arg_get_lit(ctx, 3)) { CLIParserFree(ctx); - PrintAndLogEx(WARNING, "Input key type must be A or B"); + PrintAndLogEx(WARNING, "Choose one single input key type"); return PM3_EINVARG; } else if (arg_get_lit(ctx, 3)) { keytype = MF_KEY_B;