mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-20 13:23:51 -07:00
added a fingerprint test for OTP algos
This commit is contained in:
parent
19dd580b3b
commit
df05e28923
3 changed files with 77 additions and 5 deletions
|
@ -65,7 +65,7 @@ static uint8_t default_3des_keys[][16] = {
|
||||||
|
|
||||||
static uint8_t default_pwd_pack[][4] = {
|
static uint8_t default_pwd_pack[][4] = {
|
||||||
{0xFF, 0xFF, 0xFF, 0xFF}, // PACK 0x00,0x00 -- factory default
|
{0xFF, 0xFF, 0xFF, 0xFF}, // PACK 0x00,0x00 -- factory default
|
||||||
{0x4E, 0x45, 0x78, 0x54},
|
{0x4E, 0x45, 0x78, 0x54}, // NExT
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint32_t UL_TYPES_ARRAY[] = {
|
static uint32_t UL_TYPES_ARRAY[] = {
|
||||||
|
@ -1144,6 +1144,46 @@ Lego Dimensions,
|
||||||
E1 10 12 00 01 03 A0 0C 34 03 13 D1 01 0F 54 02 65 6E
|
E1 10 12 00 01 03 A0 0C 34 03 13 D1 01 0F 54 02 65 6E
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *desc;
|
||||||
|
uint8_t mpos;
|
||||||
|
uint8_t mlen;
|
||||||
|
const char *match;
|
||||||
|
uint32_t (*otp)(const uint8_t *uid);
|
||||||
|
const char *hint;
|
||||||
|
} mfu_otp_identify_t;
|
||||||
|
|
||||||
|
static mfu_otp_identify_t mfu_otp_ident_table[] = {
|
||||||
|
{ "SALTO", 12, 4, "534C544F", ul_c_otpgenA, NULL },
|
||||||
|
// { "SAFLOK", 12, 4, NULL, ul_c_otpgenB, NULL },
|
||||||
|
// { "VINGCARD", 12, 4, NULL, ul_c_otpgenC, NULL },
|
||||||
|
// { "DORMA KABA", 12, 4, NULL, ul_c_otpgenD, NULL },
|
||||||
|
{ NULL, 0, 0, NULL, NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
static mfu_otp_identify_t *mfu_match_otp_fingerprint(uint8_t *data) {
|
||||||
|
uint8_t i = 0;
|
||||||
|
do {
|
||||||
|
int ml = 0;
|
||||||
|
uint8_t mtmp[40] = {0};
|
||||||
|
|
||||||
|
// static or dynamic created OTP to fingerprint.
|
||||||
|
if (mfu_otp_ident_table[i].match) {
|
||||||
|
param_gethex_to_eol(mfu_otp_ident_table[i].match, 0, mtmp, sizeof(mtmp), &ml);
|
||||||
|
} else {
|
||||||
|
uint32_t otp = mfu_otp_ident_table[i].otp(data);
|
||||||
|
num_to_bytes(otp, 4, mtmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool m2 = (memcmp(mtmp, data + mfu_otp_ident_table[i].mpos, mfu_otp_ident_table[i].mlen) == 0);
|
||||||
|
if (m2) {
|
||||||
|
PrintAndLogEx(DEBUG, "(fingerprint) found %s", mfu_otp_ident_table[i].desc);
|
||||||
|
return &mfu_otp_ident_table[i];
|
||||||
|
}
|
||||||
|
} while (mfu_otp_ident_table[++i].desc);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *desc;
|
const char *desc;
|
||||||
const char *version;
|
const char *version;
|
||||||
|
@ -1184,7 +1224,7 @@ static mfu_identify_t mfu_ident_table[] = {
|
||||||
"Snackworld", "0004040101000B03",
|
"Snackworld", "0004040101000B03",
|
||||||
9, 7, "483000E1100600",
|
9, 7, "483000E1100600",
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
"hf mfu dump -k %08x"
|
"hf mfu dump -k"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Amiibo", "0004040201001103",
|
"Amiibo", "0004040201001103",
|
||||||
|
@ -1324,15 +1364,36 @@ static int mfu_fingerprint(TagTypeUL_t tagtype, bool hasAuthKey, uint8_t *authke
|
||||||
if (item) {
|
if (item) {
|
||||||
PrintAndLogEx(SUCCESS, "Found " _GREEN_("%s"), item->desc);
|
PrintAndLogEx(SUCCESS, "Found " _GREEN_("%s"), item->desc);
|
||||||
|
|
||||||
if (item->Pwd) {
|
if (item->hint) {
|
||||||
|
if (item->Pwd) {
|
||||||
|
char s[40] = {0};
|
||||||
|
snprintf(s, sizeof(s), item->hint, item->Pwd(uid));
|
||||||
|
PrintAndLogEx(HINT, "Use `" _YELLOW_("%s") "`", s);
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(HINT, "Use `" _YELLOW_("%s") "`", item->hint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// OTP checks
|
||||||
|
mfu_otp_identify_t *item = mfu_match_otp_fingerprint(data);
|
||||||
|
if (item) {
|
||||||
|
PrintAndLogEx(SUCCESS, "Found " _GREEN_("%s"), item->desc);
|
||||||
|
|
||||||
|
if (item->hint) {
|
||||||
|
if (item->otp) {
|
||||||
char s[40] = {0};
|
char s[40] = {0};
|
||||||
snprintf(s, sizeof(s), item->hint, item->Pwd(uid));
|
snprintf(s, sizeof(s), item->hint, item->otp(uid));
|
||||||
PrintAndLogEx(HINT, "Use `" _YELLOW_("%s") "`", s);
|
PrintAndLogEx(HINT, "Use `" _YELLOW_("%s") "`", s);
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(HINT, "Use `" _YELLOW_("%s") "`", item->hint);
|
PrintAndLogEx(HINT, "Use `" _YELLOW_("%s") "`", item->hint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
free(data);
|
free(data);
|
||||||
|
@ -3248,7 +3309,7 @@ static int CmdHF14AMfUPwdGen(const char *Cmd) {
|
||||||
PrintAndLogEx(INFO, "----------------------------------");
|
PrintAndLogEx(INFO, "----------------------------------");
|
||||||
PrintAndLogEx(INFO, " algo | pwd | pack");
|
PrintAndLogEx(INFO, " algo | pwd | pack");
|
||||||
PrintAndLogEx(INFO, "-----------------+----------+-----");
|
PrintAndLogEx(INFO, "-----------------+----------+-----");
|
||||||
PrintAndLogEx(INFO, " EV1 | %08X | %04X", ul_ev1_pwdgenA(uid), ul_ev1_packgenA(uid));
|
PrintAndLogEx(INFO, " Transport EV1 | %08X | %04X", ul_ev1_pwdgenA(uid), ul_ev1_packgenA(uid));
|
||||||
PrintAndLogEx(INFO, " Amiibo | %08X | %04X", ul_ev1_pwdgenB(uid), ul_ev1_packgenB(uid));
|
PrintAndLogEx(INFO, " Amiibo | %08X | %04X", ul_ev1_pwdgenB(uid), ul_ev1_packgenB(uid));
|
||||||
PrintAndLogEx(INFO, " Lego Dimension | %08X | %04X", ul_ev1_pwdgenC(uid), ul_ev1_packgenC(uid));
|
PrintAndLogEx(INFO, " Lego Dimension | %08X | %04X", ul_ev1_pwdgenC(uid), ul_ev1_packgenC(uid));
|
||||||
PrintAndLogEx(INFO, " XYZ 3D printer | %08X | %04X", ul_ev1_pwdgenD(uid), ul_ev1_packgenD(uid));
|
PrintAndLogEx(INFO, " XYZ 3D printer | %08X | %04X", ul_ev1_pwdgenD(uid), ul_ev1_packgenD(uid));
|
||||||
|
@ -3256,6 +3317,9 @@ static int CmdHF14AMfUPwdGen(const char *Cmd) {
|
||||||
PrintAndLogEx(INFO, " NTAG tools | %08X | %04X", ul_ev1_pwdgenF(uid), ul_ev1_packgen_def(uid));
|
PrintAndLogEx(INFO, " NTAG tools | %08X | %04X", ul_ev1_pwdgenF(uid), ul_ev1_packgen_def(uid));
|
||||||
PrintAndLogEx(INFO, "-----------------+----------+-----");
|
PrintAndLogEx(INFO, "-----------------+----------+-----");
|
||||||
PrintAndLogEx(INFO, " Vingcard algo");
|
PrintAndLogEx(INFO, " Vingcard algo");
|
||||||
|
PrintAndLogEx(INFO, " Saflok algo");
|
||||||
|
PrintAndLogEx(INFO, " SALTO algo");
|
||||||
|
PrintAndLogEx(INFO, " Dorma Kaba algo");
|
||||||
PrintAndLogEx(INFO, "----------------------------------");
|
PrintAndLogEx(INFO, "----------------------------------");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -240,6 +240,12 @@ uint16_t ul_ev1_packgen_def(const uint8_t *uid) {
|
||||||
return 0x0000;
|
return 0x0000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MIFARE ULTRALIGHT OTP generators
|
||||||
|
uint32_t ul_c_otpgenA(const uint8_t *uid) {
|
||||||
|
return 0x534C544F;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------
|
//------------------------------------
|
||||||
// MFC key generation stuff
|
// MFC key generation stuff
|
||||||
// Each algo implementation should offer two key generation functions.
|
// Each algo implementation should offer two key generation functions.
|
||||||
|
|
|
@ -36,6 +36,8 @@ uint16_t ul_ev1_packgenC(const uint8_t *uid);
|
||||||
uint16_t ul_ev1_packgenD(const uint8_t *uid);
|
uint16_t ul_ev1_packgenD(const uint8_t *uid);
|
||||||
uint16_t ul_ev1_packgenE(const uint8_t *uid);
|
uint16_t ul_ev1_packgenE(const uint8_t *uid);
|
||||||
|
|
||||||
|
uint32_t ul_c_otpgenA(const uint8_t *uid);
|
||||||
|
|
||||||
int mfc_algo_ving_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t *key);
|
int mfc_algo_ving_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t *key);
|
||||||
int mfc_algo_ving_all(uint8_t *uid, uint8_t *keys);
|
int mfc_algo_ving_all(uint8_t *uid, uint8_t *keys);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue