some fixes for mfu info where it had some debug messages from device side and didnt test pwd all the time. Also allow keygen to take a block number now

This commit is contained in:
iceman1001 2024-02-09 08:52:23 +01:00
commit 30012344a7
2 changed files with 48 additions and 27 deletions

View file

@ -3,6 +3,8 @@ 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]
- Changed `hf mfu keygen -b` - now takes a block number (@iceman1001)
- Fixed `hf mfu info` - now tries pwdgens better (@iceman1001)
- Changed `hf mf info` - now also checks sector 1 (@iceman1001) - Changed `hf mf info` - now also checks sector 1 (@iceman1001)
- Changed `lf em 410x` - now allows for card number zero. thanks @dangerousthings ! (@iceman1001) - Changed `lf em 410x` - now allows for card number zero. thanks @dangerousthings ! (@iceman1001)
- Changed `liblua` - now bugfixes applied and current version is v.5.2.4 (@iceman1001) - Changed `liblua` - now bugfixes applied and current version is v.5.2.4 (@iceman1001)

View file

@ -206,7 +206,7 @@ int ul_read_uid(uint8_t *uid) {
return PM3_ESOFT; return PM3_ESOFT;
} }
if (card.uidlen != 7) { if (card.uidlen != 7) {
PrintAndLogEx(WARNING, "Wrong sized UID, expected 7bytes got %d", card.uidlen); PrintAndLogEx(WARNING, "Wrong sized UID, expected 7 bytes, got " _RED_("%d"), card.uidlen);
return PM3_ESOFT; return PM3_ESOFT;
} }
memcpy(uid, card.uid, 7); memcpy(uid, card.uid, 7);
@ -1012,9 +1012,9 @@ static int ulev1_print_configuration(uint64_t tagtype, uint8_t *data, uint8_t st
PrintAndLogEx(INFO, " - user configuration %s", cfglck ? "permanently locked" : "writeable"); PrintAndLogEx(INFO, " - user configuration %s", cfglck ? "permanently locked" : "writeable");
PrintAndLogEx(INFO, " - %s access is protected with password", prot ? "read and write" : "write"); PrintAndLogEx(INFO, " - %s access is protected with password", prot ? "read and write" : "write");
PrintAndLogEx(INFO, " - %02X, Virtual Card Type Identifier is %sdefault", vctid, (vctid == 0x05) ? "" : "not "); PrintAndLogEx(INFO, " - %02X, Virtual Card Type Identifier is %sdefault", vctid, (vctid == 0x05) ? "" : "not ");
PrintAndLogEx(INFO, " PWD [%u/0x%02X]: %s- (cannot be read)", startPage + 2, startPage + 2, sprint_hex(data + 8, 4)); PrintAndLogEx(INFO, " PWD [%u/0x%02X]: %s- ( cannot be read )", startPage + 2, startPage + 2, sprint_hex(data + 8, 4));
PrintAndLogEx(INFO, " PACK [%u/0x%02X]: %s - (cannot be read)", startPage + 3, startPage + 3, sprint_hex(data + 12, 2)); PrintAndLogEx(INFO, " PACK [%u/0x%02X]: %s - ( cannot be read )", startPage + 3, startPage + 3, sprint_hex(data + 12, 2));
PrintAndLogEx(INFO, " RFU [%u/0x%02X]: %s- (cannot be read)", startPage + 3, startPage + 3, sprint_hex(data + 14, 2)); PrintAndLogEx(INFO, " RFU [%u/0x%02X]: %s- ( cannot be read )", startPage + 3, startPage + 3, sprint_hex(data + 14, 2));
if (tagtype & MFU_TT_NTAG_213_TT) { if (tagtype & MFU_TT_NTAG_213_TT) {
if (data[1] & 0x06) { if (data[1] & 0x06) {
@ -1629,7 +1629,6 @@ static int mfu_fingerprint(uint64_t tagtype, bool hasAuthKey, uint8_t *authkey,
keytype = 2; // UL_EV1/NTAG auth keytype = 2; // UL_EV1/NTAG auth
} }
if (getDeviceDebugLevel(&dbg_curr) != PM3_SUCCESS) { if (getDeviceDebugLevel(&dbg_curr) != PM3_SUCCESS) {
res = PM3_ESOFT; res = PM3_ESOFT;
goto out; goto out;
@ -1659,6 +1658,7 @@ static int mfu_fingerprint(uint64_t tagtype, bool hasAuthKey, uint8_t *authkey,
// read all memory // read all memory
uint32_t startindex = resp.oldarg[2]; uint32_t startindex = resp.oldarg[2];
uint32_t buffer_size = resp.oldarg[1]; uint32_t buffer_size = resp.oldarg[1];
if (buffer_size > maxbytes) { if (buffer_size > maxbytes) {
PrintAndLogEx(FAILED, "Data exceeded buffer size!"); PrintAndLogEx(FAILED, "Data exceeded buffer size!");
buffer_size = maxbytes; buffer_size = maxbytes;
@ -2085,8 +2085,8 @@ static int CmdHF14AMfUInfo(const char *Cmd) {
uint8_t startconfigblock = 0; uint8_t startconfigblock = 0;
uint8_t ulev1_conf[16] = {0x00}; uint8_t ulev1_conf[16] = {0x00};
for (uint8_t i = 0; i < ARRAYLEN(UL_TYPES_ARRAY); i++) { for (uint8_t i = 1; i < ARRAYLEN(UL_TYPES_ARRAY); i++) {
if (tagtype & UL_TYPES_ARRAY[i]) { if ((tagtype & UL_TYPES_ARRAY[i]) == UL_TYPES_ARRAY[i]) {
startconfigblock = UL_MEMORY_ARRAY[i] - 3; startconfigblock = UL_MEMORY_ARRAY[i] - 3;
break; break;
} }
@ -2114,7 +2114,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) {
// 0 = limitless. // 0 = limitless.
// 1-7 = limit. No automatic tries then. // 1-7 = limit. No automatic tries then.
// hasAuthKey, if we was called with key, skip test. // hasAuthKey, if we was called with key, skip test.
if (!authlim && !has_auth_key) { if (!authlim && (has_auth_key == false)) {
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(SUCCESS, "--- " _CYAN_("Known EV1/NTAG passwords")); PrintAndLogEx(SUCCESS, "--- " _CYAN_("Known EV1/NTAG passwords"));
// test pwd gen A // test pwd gen A
@ -2197,7 +2197,6 @@ static int CmdHF14AMfUInfo(const char *Cmd) {
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`hf mfu pwdgen -r`") " to get see known pwd gen algo suggestions"); PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`hf mfu pwdgen -r`") " to get see known pwd gen algo suggestions");
} }
} else { } else {
if (locked) { if (locked) {
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`hf mfu pwdgen -r`") " to get see known pwd gen algo suggestions"); PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`hf mfu pwdgen -r`") " to get see known pwd gen algo suggestions");
} }
@ -2707,26 +2706,31 @@ static int CmdHF14AMfUDump(const char *Cmd) {
} }
bool manual_pages = false; bool manual_pages = false;
if (start_page > 0) if (start_page > 0) {
manual_pages = true; manual_pages = true;
}
if (pages != 16) if (pages != 16) {
manual_pages = true; manual_pages = true;
}
uint8_t card_mem_size = 0; uint8_t card_mem_size = 0;
// Swap endianness // Swap endianness
if (swap_endian) { if (swap_endian) {
if (has_auth_key) if (has_auth_key) {
authKeyPtr = SwapEndian64(authenticationkey, ak_len, 8); authKeyPtr = SwapEndian64(authenticationkey, ak_len, 8);
}
if (has_pwd) if (has_pwd) {
authKeyPtr = SwapEndian64(authenticationkey, ak_len, 4); authKeyPtr = SwapEndian64(authenticationkey, ak_len, 4);
} }
}
uint64_t tagtype = GetHF14AMfU_Type(); uint64_t tagtype = GetHF14AMfU_Type();
if (tagtype == MFU_TT_UL_ERROR) if (tagtype == MFU_TT_UL_ERROR) {
return PM3_ESOFT; return PM3_ESOFT;
}
//get number of pages to read //get number of pages to read
if (manual_pages == false) { if (manual_pages == false) {
@ -2738,21 +2742,30 @@ static int CmdHF14AMfUDump(const char *Cmd) {
} }
} }
} }
ul_print_type(tagtype, 0); ul_print_type(tagtype, 0);
PrintAndLogEx(SUCCESS, "Reading tag memory..."); PrintAndLogEx(SUCCESS, "Reading tag memory...");
uint8_t keytype = 0; uint8_t keytype = 0;
if (has_auth_key || has_pwd) { if (has_auth_key || has_pwd) {
if (tagtype & MFU_TT_UL_C) if (tagtype & MFU_TT_UL_C)
keytype = 1; //UL_C auth keytype = 1; // UL_C auth
else else
keytype = 2; //UL_EV1/NTAG auth keytype = 2; // UL_EV1/NTAG auth
}
uint8_t dbg_curr = DBG_NONE;
if (getDeviceDebugLevel(&dbg_curr) != PM3_SUCCESS) {
return PM3_ESOFT;
}
if (setDeviceDebugLevel(DBG_NONE, false) != PM3_SUCCESS) {
return PM3_ESOFT;
} }
clearCommandBuffer(); clearCommandBuffer();
SendCommandMIX(CMD_HF_MIFAREU_READCARD, start_page, pages, keytype, authKeyPtr, ak_len); SendCommandMIX(CMD_HF_MIFAREU_READCARD, start_page, pages, keytype, authKeyPtr, ak_len);
PacketResponseNG resp; PacketResponseNG resp;
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) { if (WaitForResponseTimeout(CMD_ACK, &resp, 2500) == false) {
PrintAndLogEx(WARNING, "Command execute time-out"); PrintAndLogEx(WARNING, "Command execute time-out");
return PM3_ETIMEOUT; return PM3_ETIMEOUT;
} }
@ -2762,6 +2775,8 @@ static int CmdHF14AMfUDump(const char *Cmd) {
return PM3_ESOFT; return PM3_ESOFT;
} }
setDeviceDebugLevel(dbg_curr, false);
// read all memory // read all memory
uint8_t data[1024] = {0x00}; uint8_t data[1024] = {0x00};
memset(data, 0x00, sizeof(data)); memset(data, 0x00, sizeof(data));
@ -2769,7 +2784,7 @@ static int CmdHF14AMfUDump(const char *Cmd) {
uint32_t startindex = resp.oldarg[2]; uint32_t startindex = resp.oldarg[2];
uint32_t buffer_size = resp.oldarg[1]; uint32_t buffer_size = resp.oldarg[1];
if (buffer_size > sizeof(data)) { if (buffer_size > sizeof(data)) {
PrintAndLogEx(FAILED, "Data exceeded Buffer size!"); PrintAndLogEx(FAILED, "Data exceeded buffer size!");
buffer_size = sizeof(data); buffer_size = sizeof(data);
} }
@ -2793,9 +2808,10 @@ static int CmdHF14AMfUDump(const char *Cmd) {
// not ul_c and not std ul then attempt to collect info like // not ul_c and not std ul then attempt to collect info like
// VERSION, SIGNATURE, COUNTERS, TEARING, PACK, // VERSION, SIGNATURE, COUNTERS, TEARING, PACK,
if (!(tagtype & MFU_TT_UL_C || tagtype & MFU_TT_UL || tagtype & MFU_TT_MY_D_MOVE || tagtype & MFU_TT_MY_D_MOVE_LEAN)) { if (!(tagtype & MFU_TT_UL_C || tagtype & MFU_TT_UL || tagtype & MFU_TT_MY_D_MOVE || tagtype & MFU_TT_MY_D_MOVE_LEAN)) {
//attempt to read pack // attempt to read pack
bool has_key = (has_auth_key || has_pwd);
uint8_t get_pack[] = {0, 0}; uint8_t get_pack[] = {0, 0};
if (ul_auth_select(&card, tagtype, true, authKeyPtr, get_pack, sizeof(get_pack)) != PM3_SUCCESS) { if (ul_auth_select(&card, tagtype, has_key, authKeyPtr, get_pack, sizeof(get_pack)) != PM3_SUCCESS) {
//reset pack //reset pack
get_pack[0] = 0; get_pack[0] = 0;
get_pack[1] = 0; get_pack[1] = 0;
@ -2851,13 +2867,15 @@ static int CmdHF14AMfUDump(const char *Cmd) {
if (has_auth_key) { if (has_auth_key) {
uint8_t dummy_pack[] = {0, 0}; uint8_t dummy_pack[] = {0, 0};
ul_auth_select(&card, tagtype, has_auth_key, authKeyPtr, dummy_pack, sizeof(dummy_pack)); ul_auth_select(&card, tagtype, has_auth_key, authKeyPtr, dummy_pack, sizeof(dummy_pack));
} else } else {
ul_select(&card); ul_select(&card);
}
ulev1_readSignature(get_signature, sizeof(get_signature)); ulev1_readSignature(get_signature, sizeof(get_signature));
DropField(); DropField();
} }
// format and add keys to block dump output // format and add keys to block dump output
// only add keys if not partial read, and complete pages read // only add keys if not partial read, and complete pages read
if (!is_partial && pages == card_mem_size && (has_auth_key || has_pwd)) { if (!is_partial && pages == card_mem_size && (has_auth_key || has_pwd)) {
@ -3650,10 +3668,10 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) {
return PM3_SUCCESS; return PM3_SUCCESS;
} }
static int CmdHF14AMfUGenDiverseKeys(const char *Cmd) { static int CmdHF14AMfUKeyGen(const char *Cmd) {
CLIParserContext *ctx; CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfu keygen", CLIParserInit(&ctx, "hf mfu keygen",
"Set the 3DES key on MIFARE Ultralight-C tag. ", "Set the DES/3DES/AES key on MIFARE Ultralight-C tag. ",
"hf mfu keygen -r\n" "hf mfu keygen -r\n"
"hf mfu keygen --uid 11223344556677" "hf mfu keygen --uid 11223344556677"
); );
@ -3662,6 +3680,7 @@ static int CmdHF14AMfUGenDiverseKeys(const char *Cmd) {
arg_param_begin, arg_param_begin,
arg_str0("u", "uid", "<hex>", "<4|7> hex byte UID"), arg_str0("u", "uid", "<hex>", "<4|7> hex byte UID"),
arg_lit0("r", NULL, "Read UID from tag"), arg_lit0("r", NULL, "Read UID from tag"),
arg_u64_0("b", "blk", "<dec>", "Block number"),
arg_param_end arg_param_end
}; };
CLIExecWithReturn(ctx, Cmd, argtable, true); CLIExecWithReturn(ctx, Cmd, argtable, true);
@ -3670,6 +3689,7 @@ static int CmdHF14AMfUGenDiverseKeys(const char *Cmd) {
uint8_t uid[7]; uint8_t uid[7];
CLIGetHexWithReturn(ctx, 1, uid, &ulen); CLIGetHexWithReturn(ctx, 1, uid, &ulen);
bool read_tag = arg_get_lit(ctx, 2); bool read_tag = arg_get_lit(ctx, 2);
uint8_t block = arg_get_u64_def(ctx, 3, 1) & 0xFF;
CLIParserFree(ctx); CLIParserFree(ctx);
if (read_tag) { if (read_tag) {
@ -3706,7 +3726,6 @@ static int CmdHF14AMfUGenDiverseKeys(const char *Cmd) {
} }
uint8_t iv[8] = { 0x00 }; uint8_t iv[8] = { 0x00 };
uint8_t block = 0x01;
uint8_t mifarekeyA[] = { 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5 }; uint8_t mifarekeyA[] = { 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5 };
uint8_t mifarekeyB[] = { 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5 }; uint8_t mifarekeyB[] = { 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5 };
@ -5044,7 +5063,7 @@ static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"}, {"help", CmdHelp, AlwaysAvailable, "This help"},
{"list", CmdHF14AMfuList, AlwaysAvailable, "List MIFARE Ultralight / NTAG history"}, {"list", CmdHF14AMfuList, AlwaysAvailable, "List MIFARE Ultralight / NTAG history"},
{"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("recovery") " -------------------------"}, {"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("recovery") " -------------------------"},
{"keygen", CmdHF14AMfUGenDiverseKeys, AlwaysAvailable, "Generate 3DES MIFARE diversified keys"}, {"keygen", CmdHF14AMfUKeyGen, AlwaysAvailable, "Generate DES/3DES/AES MIFARE diversified keys"},
{"pwdgen", CmdHF14AMfUPwdGen, AlwaysAvailable, "Generate pwd from known algos"}, {"pwdgen", CmdHF14AMfUPwdGen, AlwaysAvailable, "Generate pwd from known algos"},
{"otptear", CmdHF14AMfuOtpTearoff, IfPm3Iso14443a, "Tear-off test on OTP bits"}, {"otptear", CmdHF14AMfuOtpTearoff, IfPm3Iso14443a, "Tear-off test on OTP bits"},
// {"tear_cnt", CmdHF14AMfuEv1CounterTearoff, IfPm3Iso14443a, "Tear-off test on Ev1/NTAG Counter bits"}, // {"tear_cnt", CmdHF14AMfuEv1CounterTearoff, IfPm3Iso14443a, "Tear-off test on Ev1/NTAG Counter bits"},