Merge branch 'master' into allin

update
This commit is contained in:
tharexde 2020-09-24 23:08:04 +02:00
commit e794c47303
10 changed files with 243 additions and 74 deletions

View file

@ -43,3 +43,4 @@ eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
404142434445464748494a4b4c4d4e4f
303132333435363738393a3b3c3d3e3f
9CABF398358405AE2F0E2B3D31C99A8A # Default key
605F5E5D5C5B5A59605F5E5D5C5B5A59 # access control

View file

@ -27,4 +27,4 @@ eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
100f0e0d0c0b0a090807060504030201
404142434445464748494a4b4c4d4e4f
303132333435363738393a3b3c3d3e3f
605F5E5D5C5B5A59605F5E5D5C5B5A59

View file

@ -380,7 +380,7 @@ static int nxp_15693_print_signature(uint8_t *uid, uint8_t *signature) {
{"NXP Public key", "04A748B6A632FBEE2C0897702B33BEA1C074998E17B84ACA04FF267E5D2C91F6DC"},
{"NXP Ultralight Ev1", "0490933BDCD6E99B4E255E3DA55389A827564E11718E017292FAF23226A96614B8"},
{"NXP NTAG21x (2013)", "04494E1A386D3D3CFE3DC10E5DE68A499B1C202DB5B132393E89ED19FE5BE8BC61"},
{"MICRON Public key", "04f971eda742a4a80d32dcf6a814a707cc3dc396d35902f72929fdcd698b3468f2"},
{"MIKRON Public key", "04f971eda742a4a80d32dcf6a814a707cc3dc396d35902f72929fdcd698b3468f2"},
{"Spark1 Public key", "04d64bb732c0d214e7ec580736acf847284b502c25c0f7f2fa86aace1dada4387a"},
};
/*
@ -423,6 +423,16 @@ static int nxp_15693_print_signature(uint8_t *uid, uint8_t *signature) {
};
*/
uint8_t i;
uint8_t revuid[8];
for (i = 0; i < sizeof(revuid); i++) {
revuid[i] = uid[7 - i];
}
uint8_t revsign[32];
for (i = 0; i < sizeof(revsign); i++) {
revsign[i] = signature[31 - i];
}
int reason = 0;
bool is_valid = false;
for (i = 0; i < ARRAYLEN(nxp_15693_public_keys); i++) {
@ -432,22 +442,65 @@ static int nxp_15693_print_signature(uint8_t *uid, uint8_t *signature) {
int res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP128R1, key, uid, 8, signature, 32, false);
is_valid = (res == 0);
if (is_valid)
if (is_valid) {
reason = 1;
break;
}
// try with sha256
res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP128R1, key, uid, 8, signature, 32, true);
is_valid = (res == 0);
if (is_valid) {
reason = 2;
break;
}
// try with reversed uid / signature
res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP128R1, key, revuid, sizeof(revuid), revsign, sizeof(revsign), false);
is_valid = (res == 0);
if (is_valid) {
reason = 3;
break;
}
// try with sha256
res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP128R1, key, revuid, sizeof(revuid), revsign, sizeof(revsign), true);
is_valid = (res == 0);
if (is_valid) {
reason = 4;
break;
}
}
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Signature"));
if (is_valid == false || i == ARRAYLEN(nxp_15693_public_keys)) {
PrintAndLogEx(SUCCESS, "Signature verification " _RED_("failed"));
PrintAndLogEx(INFO, " Elliptic curve parameters: NID_secp128r1");
PrintAndLogEx(INFO, " TAG IC Signature: %s", sprint_hex_inrow(signature, 32));
PrintAndLogEx(SUCCESS, " Signature verification: " _RED_("failed"));
return PM3_ESOFT;
}
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Signature"));
PrintAndLogEx(INFO, " IC signature public key name: %s", nxp_15693_public_keys[i].desc);
PrintAndLogEx(INFO, "IC signature public key value: %s", nxp_15693_public_keys[i].value);
PrintAndLogEx(INFO, " Elliptic curve parameters: NID_secp128r1");
PrintAndLogEx(INFO, " TAG IC Signature: %s", sprint_hex(signature, 32));
PrintAndLogEx(SUCCESS, " Signature verified: " _GREEN_("successful"));
PrintAndLogEx(INFO, " TAG IC Signature: %s", sprint_hex_inrow(signature, 32));
PrintAndLogEx(SUCCESS, " Signature verification: " _GREEN_("successful"));
switch(reason) {
case 1:
PrintAndLogEx(INFO, " Params used: UID and signature, plain");
break;
case 2:
PrintAndLogEx(INFO, " Params used: UID and signature, SHA256");
break;
case 3:
PrintAndLogEx(INFO, " Params used: reversed UID and signature, plain");
break;
case 4:
PrintAndLogEx(INFO, " Params used: reversed UID and signature, SHA256");
break;
}
return PM3_SUCCESS;
}

View file

@ -1176,6 +1176,7 @@ static int desfire_print_signature(uint8_t *uid, uint8_t uidlen, uint8_t *signat
{"Mifare Plus EV1", "044409ADC42F91A8394066BA83D872FB1D16803734E911170412DDF8BAD1A4DADFD0416291AFE1C748253925DA39A5F39A1C557FFACD34C62E"}
};
uint32_t i;
bool is_valid = false;
@ -1190,24 +1191,29 @@ static int desfire_print_signature(uint8_t *uid, uint8_t uidlen, uint8_t *signat
if (is_valid)
break;
}
// PrintAndLogEx(NORMAL, "");
// PrintAndLogEx(INFO, "--- " _CYAN_("Tag Signature"));
if (is_valid == false || i == ARRAYLEN(nxp_desfire_public_keys)) {
PrintAndLogEx(SUCCESS, "Signature verification " _RED_("failed"));
PrintAndLogEx(INFO, " Elliptic curve parameters: NID_secp224r1");
PrintAndLogEx(INFO, " TAG IC Signature: %s", sprint_hex_inrow(signature, 16));
PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 16, 16));
PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 32, 16));
PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 48, signature_len - 48));
PrintAndLogEx(SUCCESS, " Signature verification: " _RED_("failed"));
return PM3_ESOFT;
}
// PrintAndLogEx(NORMAL, "");
// PrintAndLogEx(INFO, "--- " _CYAN_("Tag Signature"));
PrintAndLogEx(INFO, " IC signature public key name: " _GREEN_("%s"), nxp_desfire_public_keys[i].desc);
PrintAndLogEx(INFO, "IC signature public key value: %.32s", nxp_desfire_public_keys[i].value);
PrintAndLogEx(INFO, " : %.32s", nxp_desfire_public_keys[i].value + 16);
PrintAndLogEx(INFO, " : %.32s", nxp_desfire_public_keys[i].value + 32);
PrintAndLogEx(INFO, " : %.32s", nxp_desfire_public_keys[i].value + 48);
PrintAndLogEx(INFO, " : %.32s", nxp_desfire_public_keys[i].value + 64);
PrintAndLogEx(INFO, " : %.32s", nxp_desfire_public_keys[i].value + 96);
PrintAndLogEx(INFO, " Elliptic curve parameters: NID_secp224r1");
PrintAndLogEx(INFO, " TAG IC Signature: %s", sprint_hex_inrow(signature, 16));
PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 16, 16));
PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 32, 16));
PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 48, signature_len - 48));
PrintAndLogEx(SUCCESS, " Signature verified: " _GREEN_("successful"));
PrintAndLogEx(SUCCESS, " Signature verification: " _GREEN_("successful"));
return PM3_SUCCESS;
}

View file

@ -58,9 +58,9 @@ static char *getCardSizeStr(uint8_t fsize) {
// is LSB set?
if (fsize & 1)
snprintf(retStr, sizeof(buf), "0x%02X (" _YELLOW_("%d - %d bytes") ")", fsize, usize, lsize);
snprintf(retStr, sizeof(buf), "0x%02X (" _GREEN_("%d - %d bytes") ")", fsize, usize, lsize);
else
snprintf(retStr, sizeof(buf), "0x%02X (" _YELLOW_("%d bytes") ")", fsize, lsize);
snprintf(retStr, sizeof(buf), "0x%02X (" _GREEN_("%d bytes") ")", fsize, lsize);
return buf;
}
@ -88,18 +88,17 @@ static char *getVersionStr(uint8_t major, uint8_t minor) {
char *retStr = buf;
if (major == 0x00)
snprintf(retStr, sizeof(buf), "%x.%x (" _YELLOW_("DESFire MF3ICD40") ")", major, minor);
snprintf(retStr, sizeof(buf), "%x.%x (" _GREEN_("DESFire MF3ICD40") ")", major, minor);
else if (major == 0x01 && minor == 0x00)
snprintf(retStr, sizeof(buf), "%x.%x (" _YELLOW_("DESFire EV1") ")", major, minor);
snprintf(retStr, sizeof(buf), "%x.%x (" _GREEN_("DESFire EV1") ")", major, minor);
else if (major == 0x12 && minor == 0x00)
snprintf(retStr, sizeof(buf), "%x.%x (" _YELLOW_("DESFire EV2") ")", major, minor);
snprintf(retStr, sizeof(buf), "%x.%x (" _GREEN_("DESFire EV2") ")", major, minor);
else if (major == 0x33 && minor == 0x00)
snprintf(retStr, sizeof(buf), "%x.%x (" _YELLOW_("DESFire EV3") ")", major, minor);
snprintf(retStr, sizeof(buf), "%x.%x (" _GREEN_("DESFire EV3") ")", major, minor);
else if (major == 0x30 && minor == 0x00)
snprintf(retStr, sizeof(buf), "%x.%x (" _YELLOW_("DESFire Light") ")", major, minor);
snprintf(retStr, sizeof(buf), "%x.%x (" _GREEN_("DESFire Light") ")", major, minor);
else if (major == 0x11 && minor == 0x00)
snprintf(retStr, sizeof(buf), "%x.%x (" _YELLOW_("Plus EV1") ")", major, minor);
snprintf(retStr, sizeof(buf), "%x.%x (" _GREEN_("Plus EV1") ")", major, minor);
else
snprintf(retStr, sizeof(buf), "%x.%x (" _YELLOW_("Unknown") ")", major, minor);
return buf;
@ -186,21 +185,26 @@ static int plus_print_signature(uint8_t *uid, uint8_t uidlen, uint8_t *signature
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Signature"));
if (is_valid == false || i == ARRAYLEN(nxp_plus_public_keys)) {
PrintAndLogEx(SUCCESS, "Signature verification " _RED_("failed"));
PrintAndLogEx(INFO, " Elliptic curve parameters: NID_secp224r1");
PrintAndLogEx(INFO, " TAG IC Signature: %s", sprint_hex_inrow(signature, 16));
PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 16, 16));
PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 32, 16));
PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 48, signature_len - 48));
PrintAndLogEx(SUCCESS, " Signature verification: " _RED_("failed"));
return PM3_ESOFT;
}
PrintAndLogEx(INFO, " IC signature public key name: " _GREEN_("%s"), nxp_plus_public_keys[i].desc);
PrintAndLogEx(INFO, "IC signature public key value: %.32s", nxp_plus_public_keys[i].value);
PrintAndLogEx(INFO, " : %.32s", nxp_plus_public_keys[i].value + 16);
PrintAndLogEx(INFO, " : %.32s", nxp_plus_public_keys[i].value + 32);
PrintAndLogEx(INFO, " : %.32s", nxp_plus_public_keys[i].value + 48);
PrintAndLogEx(INFO, " : %.32s", nxp_plus_public_keys[i].value + 64);
PrintAndLogEx(INFO, " : %.32s", nxp_plus_public_keys[i].value + 96);
PrintAndLogEx(INFO, " Elliptic curve parameters: NID_secp224r1");
PrintAndLogEx(INFO, " TAG IC Signature: %s", sprint_hex_inrow(signature, 16));
PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 16, 16));
PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 32, 16));
PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 48, signature_len - 48));
PrintAndLogEx(SUCCESS, " Signature verified: " _GREEN_("successful"));
PrintAndLogEx(SUCCESS, " Signature verification: " _GREEN_("successful"));
return PM3_SUCCESS;
}
@ -356,10 +360,8 @@ static int CmdHFMFPInfo(const char *Cmd) {
}
if (card.sak == 0x20) {
PrintAndLogEx(INFO, " SAK: " _GREEN_("MIFARE Plus SL0/SL3") " or " _GREEN_("MIFARE DESFire"));
if (card.ats_len > 0) {
PrintAndLogEx(INFO, " SAK: " _GREEN_("MIFARE Plus SL0/SL3") " or " _GREEN_("MIFARE DESFire"));
SLmode = 3;
// check SL0
uint8_t data[250] = {0};
@ -368,15 +370,22 @@ static int CmdHFMFPInfo(const char *Cmd) {
uint8_t cmd[3 + 16] = {0xa8, 0x90, 0x90, 0x00};
int res = ExchangeRAW14a(cmd, sizeof(cmd), true, false, data, sizeof(data), &datalen, false);
// DESFire answers 0x1C
// DESFire answers 0x1C or 67 00
// Plus answers 0x0B, 0x09
PrintAndLogEx(INFO, "ICEE: %s", sprint_hex(data, datalen));
if (memcmp(data, "\x67\x00", 2) == 0) {
PrintAndLogEx(INFO, "\tMost likely a MIFARE DESFire tag");
if ( data[0] != 0x0b && data[0] != 0x09 && data[0] != 0x1C && data[0] != 0x67) {
PrintAndLogEx(INFO, _RED_("Send copy to iceman of this command output!"));
PrintAndLogEx(INFO, "data: %s", sprint_hex(data, datalen));
}
if ((memcmp(data, "\x67\x00", 2) == 0) ||
(memcmp(data, "\x1C\x83\x0C", 3) == 0)
) {
PrintAndLogEx(INFO, " result: " _RED_("MIFARE DESFire"));
PrintAndLogEx(HINT, "Hint: Try " _YELLOW_("`hf mfdes info`"));
DropField();
return PM3_SUCCESS;
} else {
PrintAndLogEx(INFO, " result: " _GREEN_("MIFARE Plus SL0/SL3"));
}
if (!res && datalen > 1 && data[0] == 0x09) {

View file

@ -272,14 +272,14 @@ uint32_t UL_TYPES_ARRAY[] = {
UNKNOWN, UL, UL_C, UL_EV1_48, UL_EV1_128, NTAG,
NTAG_203, NTAG_210, NTAG_212, NTAG_213, NTAG_215, NTAG_216,
MY_D, MY_D_NFC, MY_D_MOVE, MY_D_MOVE_NFC, MY_D_MOVE_LEAN, FUDAN_UL,
UL_EV1, NTAG_213_F, NTAG_216_F, UL_NANO_40, NTAG_I2C_1K
UL_EV1, NTAG_213_F, NTAG_216_F, UL_NANO_40, NTAG_I2C_1K, NTAG_213_TT
};
uint8_t UL_MEMORY_ARRAY[ARRAYLEN(UL_TYPES_ARRAY)] = {
MAX_UL_BLOCKS, MAX_UL_BLOCKS, MAX_ULC_BLOCKS, MAX_ULEV1a_BLOCKS, MAX_ULEV1b_BLOCKS, MAX_NTAG_203,
MAX_NTAG_203, MAX_NTAG_210, MAX_NTAG_212, MAX_NTAG_213, MAX_NTAG_215, MAX_NTAG_216,
MAX_UL_BLOCKS, MAX_MY_D_NFC, MAX_MY_D_MOVE, MAX_MY_D_MOVE, MAX_MY_D_MOVE_LEAN, MAX_UL_BLOCKS,
MAX_ULEV1a_BLOCKS, MAX_NTAG_213, MAX_NTAG_216, MAX_UL_NANO_40, MAX_NTAG_I2C_1K
MAX_ULEV1a_BLOCKS, MAX_NTAG_213, MAX_NTAG_216, MAX_UL_NANO_40, MAX_NTAG_I2C_1K, MAX_NTAG_213
};
//------------------------------------
@ -493,7 +493,7 @@ static int ul_fudan_check(void) {
return (!resp.data.asBytes[0]) ? FUDAN_UL : UL; //if response == 0x00 then Fudan, else Genuine NXP
}
static int ul_print_default(uint8_t *data) {
static int ul_print_default(uint8_t *data, uint8_t *real_uid) {
uint8_t uid[7];
uid[0] = data[0];
@ -503,10 +503,14 @@ static int ul_print_default(uint8_t *data) {
uid[4] = data[5];
uid[5] = data[6];
uid[6] = data[7];
bool mful_uid_layout = true;
PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s"), sprint_hex(uid, 7));
PrintAndLogEx(SUCCESS, " UID[0]: %02X, %s", uid[0], getTagInfo(uid[0]));
if (uid[0] == 0x05 && ((uid[1] & 0xf0) >> 4) == 2) { // is infineon and 66RxxP
if (memcmp(uid, real_uid, 7) != 0) {
mful_uid_layout = false;
}
PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s"), sprint_hex(real_uid, 7));
PrintAndLogEx(SUCCESS, " UID[0]: %02X, %s", real_uid[0], getTagInfo(real_uid[0]));
if (real_uid[0] == 0x05 && ((real_uid[1] & 0xf0) >> 4) == 2) { // is infineon and 66RxxP
uint8_t chip = (data[8] & 0xC7); // 11000111 mask, bit 3,4,5 RFU
switch (chip) {
case 0xC2:
@ -520,20 +524,23 @@ static int ul_print_default(uint8_t *data) {
break; //512 pages /2 sectors
}
}
// CT (cascade tag byte) 0x88 xor SN0 xor SN1 xor SN2
int crc0 = 0x88 ^ uid[0] ^ uid[1] ^ uid[2];
if (data[3] == crc0)
PrintAndLogEx(SUCCESS, " BCC0: %02X (" _GREEN_("ok") ")", data[3]);
else
PrintAndLogEx(NORMAL, " BCC0: %02X, crc should be %02X", data[3], crc0);
if (mful_uid_layout) {
// CT (cascade tag byte) 0x88 xor SN0 xor SN1 xor SN2
int crc0 = 0x88 ^ uid[0] ^ uid[1] ^ uid[2];
if (data[3] == crc0)
PrintAndLogEx(SUCCESS, " BCC0: %02X (" _GREEN_("ok") ")", data[3]);
else
PrintAndLogEx(NORMAL, " BCC0: %02X, crc should be %02X", data[3], crc0);
int crc1 = uid[3] ^ uid[4] ^ uid[5] ^ uid[6];
if (data[8] == crc1)
PrintAndLogEx(SUCCESS, " BCC1: %02X (" _GREEN_("ok") ")", data[8]);
else
PrintAndLogEx(NORMAL, " BCC1: %02X, crc should be %02X", data[8], crc1);
PrintAndLogEx(SUCCESS, " Internal: %02X (%s)", data[9], (data[9] == 0x48) ? _GREEN_("default") : _RED_("not default"));
int crc1 = uid[3] ^ uid[4] ^ uid[5] ^ uid[6];
if (data[8] == crc1)
PrintAndLogEx(SUCCESS, " BCC1: %02X (" _GREEN_("ok") ")", data[8]);
else
PrintAndLogEx(NORMAL, " BCC1: %02X, crc should be %02X", data[8], crc1);
PrintAndLogEx(SUCCESS, " Internal: %02X (%s)", data[9], (data[9] == 0x48) ? _GREEN_("default") : _RED_("not default"));
} else {
PrintAndLogEx(SUCCESS, "Blocks 0-2: %s", sprint_hex(data + 0, 12));
}
PrintAndLogEx(SUCCESS, " Lock: %s - %s",
sprint_hex(data + 10, 2),
@ -678,6 +685,8 @@ int ul_print_type(uint32_t tagtype, uint8_t spaces) {
PrintAndLogEx(SUCCESS, "%*sTYPE: " _YELLOW_("NTAG 213 144bytes (NT2H1311G0DU)"), spaces, "");
else if (tagtype & NTAG_213_F)
PrintAndLogEx(SUCCESS, "%*sTYPE: " _YELLOW_("NTAG 213F 144bytes (NT2H1311F0DTL)"), spaces, "");
else if (tagtype & NTAG_213_TT)
PrintAndLogEx(SUCCESS, "%*sTYPE: " _YELLOW_("NTAG 213TT 144bytes (NT2H1311TTDU)"), spaces, "");
else if (tagtype & NTAG_215)
PrintAndLogEx(SUCCESS, "%*sTYPE: " _YELLOW_("NTAG 215 504bytes (NT2H1511G0DU)"), spaces, "");
else if (tagtype & NTAG_216)
@ -758,7 +767,7 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st
PrintAndLogEx(INFO, " cfg0 [%u/0x%02X]: %s", startPage, startPage, sprint_hex(data, 4));
if ((tagtype & (NTAG_213_F | NTAG_216_F))) {
if ((tagtype & (NTAG_213_F | NTAG_213_TT | NTAG_216_F))) {
uint8_t mirror_conf = (data[0] & 0xC0);
uint8_t mirror_byte = (data[0] & 0x30);
bool sleep_en = (data[0] & 0x08);
@ -801,7 +810,7 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st
break;
}
// valid mirror start page and byte position within start page.
if (tagtype & NTAG_213_F) {
if ((tagtype & NTAG_213_F)||(tagtype & NTAG_213_TT)) {
switch (mirror_conf) {
case 1:
{ PrintAndLogEx(INFO, " mirror start block %02X | byte pos %02X - %s", data[2], mirror_byte, (data[2] >= 0x4 && data[2] <= 0x24) ? "OK" : "Invalid value"); break;}
@ -880,7 +889,7 @@ static int ulev1_print_signature(TagTypeUL_t tagtype, uint8_t *uid, uint8_t *sig
{"NXP Public key", "04A748B6A632FBEE2C0897702B33BEA1C074998E17B84ACA04FF267E5D2C91F6DC"},
{"NXP Ultralight Ev1", "0490933BDCD6E99B4E255E3DA55389A827564E11718E017292FAF23226A96614B8"},
{"NXP NTAG21x (2013)", "04494E1A386D3D3CFE3DC10E5DE68A499B1C202DB5B132393E89ED19FE5BE8BC61"},
{"MICRON Public key", "04f971eda742a4a80d32dcf6a814a707cc3dc396d35902f72929fdcd698b3468f2"},
{"MIKRON Public key", "04f971eda742a4a80d32dcf6a814a707cc3dc396d35902f72929fdcd698b3468f2"},
};
/*
@ -945,17 +954,19 @@ static int ulev1_print_signature(TagTypeUL_t tagtype, uint8_t *uid, uint8_t *sig
}
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Signature"));
if (is_valid == false || i == ARRAYLEN(nxp_mfu_public_keys)) {
PrintAndLogEx(SUCCESS, "Signature verification " _RED_("failed"));
PrintAndLogEx(INFO, " Elliptic curve parameters: NID_secp128r1");
PrintAndLogEx(INFO, " TAG IC Signature: %s", sprint_hex_inrow(signature, signature_len));
PrintAndLogEx(SUCCESS, " Signature verification: " _RED_("failed"));
return PM3_ESOFT;
}
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Signature"));
PrintAndLogEx(INFO, " IC signature public key name: %s", nxp_mfu_public_keys[i].desc);
PrintAndLogEx(INFO, "IC signature public key value: %s", nxp_mfu_public_keys[i].value);
PrintAndLogEx(INFO, " Elliptic curve parameters: NID_secp128r1");
PrintAndLogEx(INFO, " TAG IC Signature: %s", sprint_hex_inrow(signature, signature_len));
PrintAndLogEx(SUCCESS, " Signature verified: " _GREEN_("successful"));
PrintAndLogEx(SUCCESS, " Signature verification: " _GREEN_("successful"));
return PM3_SUCCESS;
}
@ -1088,6 +1099,7 @@ uint32_t GetHF14AMfU_Type(void) {
MF0UNH1001DUx 0004030203000B03
NT2L1001G0DUx 0004040102000B03
NT2H1001G0DUx 0004040202000B03
NT2H1311TTDUx 0004040203000F03
Micron UL 0034210101000E03
*/
@ -1104,6 +1116,7 @@ uint32_t GetHF14AMfU_Type(void) {
else if (memcmp(version, "\x00\x04\x04\x02\x01\x00\x13", 7) == 0) { tagtype = NTAG_216; break; }
else if (memcmp(version, "\x00\x04\x04\x04\x01\x00\x0F", 7) == 0) { tagtype = NTAG_213_F; break; }
else if (memcmp(version, "\x00\x04\x04\x04\x01\x00\x13", 7) == 0) { tagtype = NTAG_216_F; break; }
else if (memcmp(version, "\x00\x04\x04\x02\x03\x00\x0F", 7) == 0) { tagtype = NTAG_213_TT; break; }
else if (memcmp(version, "\x00\x04\x04\x05\x02\x01\x13", 7) == 0) { tagtype = NTAG_I2C_1K; break; }
else if (memcmp(version, "\x00\x04\x04\x05\x02\x01\x15", 7) == 0) { tagtype = NTAG_I2C_2K; break; }
else if (memcmp(version, "\x00\x04\x04\x05\x02\x02\x13", 7) == 0) { tagtype = NTAG_I2C_1K_PLUS; break; }
@ -1208,7 +1221,6 @@ static int CmdHF14AMfUInfo(const char *Cmd) {
uint8_t *key = pwd;
uint8_t pack[4] = {0, 0, 0, 0};
int len;
uint8_t uid[7];
char tempStr[50];
@ -1261,9 +1273,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) {
PrintAndLogEx(ERR, "Error: tag didn't answer to READ");
return PM3_ESOFT;
} else if (status == 16) {
memcpy(uid, data, 3);
memcpy(uid + 3, data + 4, 4);
ul_print_default(data);
ul_print_default(data, card.uid);
ndef_print_CC(data + 12);
} else {
locked = true;
@ -1328,7 +1338,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) {
}
// NTAG counters?
if ((tagtype & (NTAG_213 | NTAG_213_F | NTAG_215 | NTAG_216))) {
if ((tagtype & (NTAG_213 | NTAG_213_F | NTAG_213_TT | NTAG_215 | NTAG_216))) {
if (ntag_print_counter()) {
// failed - re-select
if (ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack)) == PM3_ESOFT) return PM3_ESOFT;
@ -1336,7 +1346,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) {
}
// Read signature
if ((tagtype & (UL_EV1_48 | UL_EV1_128 | UL_EV1 | UL_NANO_40 | NTAG_213 | NTAG_213_F | NTAG_215 | NTAG_216 | NTAG_216_F | NTAG_I2C_1K | NTAG_I2C_2K | NTAG_I2C_1K_PLUS | NTAG_I2C_2K_PLUS))) {
if ((tagtype & (UL_EV1_48 | UL_EV1_128 | UL_EV1 | UL_NANO_40 | NTAG_213 | NTAG_213_F | NTAG_213_TT | NTAG_215 | NTAG_216 | NTAG_216_F | NTAG_I2C_1K | NTAG_I2C_2K | NTAG_I2C_1K_PLUS | NTAG_I2C_2K_PLUS))) {
uint8_t ulev1_signature[32] = {0x00};
status = ulev1_readSignature(ulev1_signature, sizeof(ulev1_signature));
if (status == -1) {
@ -1345,7 +1355,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) {
return PM3_ESOFT;
}
if (status == 32) {
ulev1_print_signature(tagtype, uid, ulev1_signature, sizeof(ulev1_signature));
ulev1_print_signature(tagtype, card.uid, ulev1_signature, sizeof(ulev1_signature));
} else {
// re-select
if (ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack)) == PM3_ESOFT) return PM3_ESOFT;
@ -2022,7 +2032,7 @@ static int CmdHF14AMfUDump(const char *Cmd) {
uint8_t n = 0;
// NTAG has 1 counter, at 0x02
if ((tagtype & (NTAG_213 | NTAG_213_F | NTAG_215 | NTAG_216))) {
if ((tagtype & (NTAG_213 | NTAG_213_F | NTAG_213_TT | NTAG_215 | NTAG_216))) {
n = 2;
}

View file

@ -57,6 +57,7 @@ typedef enum TAGTYPE_UL {
NTAG_216_F = 0x800000,
UL_EV1 = 0x1000000,
UL_NANO_40 = 0x2000000,
NTAG_213_TT = 0x4000000,
UL_MAGIC = UL | MAGIC,
UL_C_MAGIC = UL_C | MAGIC,
UL_ERROR = 0xFFFFFF,

View file

@ -1522,7 +1522,7 @@ out:
}
static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"-----------", CmdHelp, AlwaysAvailable, "-------------- " _CYAN_("Direct") " --------------"},
{"awid", CmdLFAWID, AlwaysAvailable, "{ AWID RFIDs... }"},
{"cotag", CmdLFCOTAG, AlwaysAvailable, "{ COTAG CHIPs... }"},
{"em", CmdLFEM4X, AlwaysAvailable, "{ EM4X CHIPs & RFIDs... }"},
@ -1549,16 +1549,17 @@ static command_t CommandTable[] = {
{"t55xx", CmdLFT55XX, AlwaysAvailable, "{ T55xx CHIPs... }"},
{"viking", CmdLFViking, AlwaysAvailable, "{ Viking RFIDs... }"},
{"visa2000", CmdLFVisa2k, AlwaysAvailable, "{ Visa2000 RFIDs... }"},
{"", CmdHelp, AlwaysAvailable, ""},
{"-----------", CmdHelp, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"},
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"config", CmdLFConfig, IfPm3Lf, "Get/Set config for LF sampling, bit/sample, decimation, frequency"},
{"cmdread", CmdLFCommandRead, IfPm3Lf, "Modulate LF reader field to send command before read (all periods in microseconds)"},
{"read", CmdLFRead, IfPm3Lf, "Read LF tag"},
{"search", CmdLFfind, AlwaysAvailable, "Read and Search for valid known tag (in offline mode it you can load first then search)"},
{"sim", CmdLFSim, IfPm3Lf, "Simulate LF tag from buffer with optional GAP (in microseconds)"},
{"simask", CmdLFaskSim, IfPm3Lf, "Simulate LF ASK tag from demodbuffer or input"},
{"simfsk", CmdLFfskSim, IfPm3Lf, "Simulate LF FSK tag from demodbuffer or input"},
{"simpsk", CmdLFpskSim, IfPm3Lf, "Simulate LF PSK tag from demodbuffer or input"},
// {"simpsk", CmdLFnrzSim, IfPm3Lf, "Simulate LF NRZ tag from demodbuffer or input"},
{"simask", CmdLFaskSim, IfPm3Lf, "Simulate " _YELLOW_("LF ASK tag") " from demodbuffer or input"},
{"simfsk", CmdLFfskSim, IfPm3Lf, "Simulate " _YELLOW_("LF FSK tag") " from demodbuffer or input"},
{"simpsk", CmdLFpskSim, IfPm3Lf, "Simulate " _YELLOW_("LF PSK tag") " from demodbuffer or input"},
// {"simpsk", CmdLFnrzSim, IfPm3Lf, "Simulate " _YELLOW_("LF NRZ tag") " from demodbuffer or input"},
{"simbidir", CmdLFSimBidir, IfPm3Lf, "Simulate LF tag (with bidirectional data transmission between reader and tag)"},
{"sniff", CmdLFSniff, IfPm3Lf, "Sniff LF traffic between reader and tag"},
{"tune", CmdLFTune, IfPm3Lf, "Continuously measure LF antenna tuning"},

View file

@ -168,7 +168,11 @@ void CmdsHelp(const command_t Commands[]) {
while (Commands[i].Name) {
if (Commands[i].IsAvailable()) {
g_printAndLog = PRINTANDLOG_PRINT;
PrintAndLogEx(NORMAL, _GREEN_("%-16s")" %s", Commands[i].Name, Commands[i].Help);
if (Commands[i].Name[0] == '-' || Commands[i].Name[0] == ' ') {
PrintAndLogEx(NORMAL, "%-16s %s", Commands[i].Name, Commands[i].Help);
} else {
PrintAndLogEx(NORMAL, _GREEN_("%-16s")" %s", Commands[i].Name, Commands[i].Help);
}
g_printAndLog = PRINTANDLOG_PRINT | PRINTANDLOG_LOG;
}
++i;

84
tools/recover_pk.py Executable file
View file

@ -0,0 +1,84 @@
#!/usr/bin/env python3
# @doegox -- 2020
import sslcrypto
import binascii
import sys
debug = False
def recover(data, signature, alghash=None):
recovered = set()
if len(signature) == 32:
curve = sslcrypto.ecc.get_curve("secp128r1")
recoverable = False
elif len(signature) == 33:
curve = sslcrypto.ecc.get_curve("secp128r1")
recoverable = True
elif len(signature) == 56:
curve = sslcrypto.ecc.get_curve("secp224r1")
recoverable = False
elif len(signature) == 57:
curve = sslcrypto.ecc.get_curve("secp224r1")
recoverable = True
else:
print("Unsupported signature size %i" % len(signature))
exit(1)
if (recoverable):
try:
pk = curve.recover(signature, data, hash=alghash)
recovered.add(pk)
if debug:
print("Possible Pk: ", binascii.hexlify(pk))
except:
pass
else:
for i in range(2):
# Brute force RECID
recid = bytes([27+i])
try:
pk = curve.recover(recid + signature, data, hash=alghash)
recovered.add(pk)
if debug:
print("Possible Pk: ", binascii.hexlify(pk))
except:
pass
return recovered
def recover_multiple(uids, sigs, alghash=None):
recovered = set()
assert len(uids) == len(sigs)
for i in range(len(uids)):
data = binascii.unhexlify(uids[i])
if debug:
print("UID (%2i): " % len(data), binascii.hexlify(data))
signature = binascii.unhexlify(sigs[i])
if debug:
print("Signature (%2i): " % len(signature), binascii.hexlify(signature))
recovered_tmp = recover(data, signature, alghash)
if i == 0:
if recovered_tmp == set():
break
else:
recovered = recovered_tmp
else:
recovered &= recovered_tmp
return recovered
if len(sys.argv) < 3 or len(sys.argv) % 2 == 0:
print("Usage: \n%s UID SIGN [UID SIGN] [...]" % sys.argv[0])
print("Example: \n%s 04ee45daa34084 ebb6102bff74b087d18a57a54bc375159a04ea9bc61080b7f4a85afe1587d73b" % sys.argv[0])
exit(1)
print("Assuming no hash was used in the signature generation:")
recovered = recover_multiple(sys.argv[1:][::2], sys.argv[1:][1::2])
print("Possible uncompressed Pk(s):")
for pk in list(recovered):
print(binascii.hexlify(pk).decode('utf8'))
print("Assuming SHA-256 was used in the signature generation:")
recovered = recover_multiple(sys.argv[1:][::2], sys.argv[1:][1::2], alghash="sha256")
print("Possible uncompressed Pk(s):")
for pk in list(recovered):
print(binascii.hexlify(pk).decode('utf8'))