phase 1 of keys check

This commit is contained in:
merlokk 2021-08-09 19:32:14 +03:00
commit 6799626eaf

View file

@ -1034,32 +1034,6 @@ static int desfire_print_signature(uint8_t *uid, uint8_t uidlen, uint8_t *signat
return PM3_SUCCESS; return PM3_SUCCESS;
} }
static int handler_desfire_getkeysettings(uint8_t *key_settings, uint8_t *num_keys) {
if (key_settings == NULL) {
PrintAndLogEx(DEBUG, "KEY_SETTINGS=NULL");
return PM3_EINVARG;
}
if (num_keys == NULL) {
PrintAndLogEx(DEBUG, "NUM_KEYS=NULL");
return PM3_EINVARG;
}
sAPDU apdu = {0x90, MFDES_GET_KEY_SETTINGS, 0x00, 0x00, 0x00, NULL}; //0x45
uint32_t recv_len = 0;
uint16_t sw = 0;
uint8_t data[2] = {0};
int res = send_desfire_cmd(&apdu, false, data, &recv_len, &sw, 0, true);
if (res != PM3_SUCCESS)
return res;
if (sw != status(MFDES_S_OPERATION_OK))
return PM3_ESOFT;
*key_settings = data[0];
*num_keys = data[1];
return res;
}
static int handler_desfire_select_application(uint8_t *aid) { static int handler_desfire_select_application(uint8_t *aid) {
if (g_debugMode > 1) { if (g_debugMode > 1) {
if (aid == NULL) { if (aid == NULL) {
@ -1108,24 +1082,6 @@ static int handler_desfire_fileids(uint8_t *dest, uint32_t *file_ids_len) {
return res; return res;
} }
// none, verified
static int handler_desfire_filesettings(uint8_t file_id, uint8_t *dest, uint32_t *destlen) {
if (g_debugMode > 1) {
if (dest == NULL) PrintAndLogEx(ERR, "DEST=NULL");
if (destlen == NULL) PrintAndLogEx(ERR, "DESTLEN=NULL");
}
if (dest == NULL || destlen == NULL) return PM3_EINVARG;
sAPDU apdu = {0x90, MFDES_GET_FILE_SETTINGS, 0x00, 0x00, 0x01, &file_id}; // 0xF5
uint16_t sw = 0;
int res = send_desfire_cmd(&apdu, false, dest, destlen, &sw, 0, true);
if (res != PM3_SUCCESS) {
PrintAndLogEx(WARNING, _RED_(" Can't get file settings -> %s"), DesfireGetErrorString(res, &sw));
DropFieldDesfire();
return res;
}
return res;
}
static void swap24(uint8_t *data) { static void swap24(uint8_t *data) {
if (data == NULL) return; if (data == NULL) return;
uint8_t tmp = data[0]; uint8_t tmp = data[0];
@ -1460,19 +1416,23 @@ static void DesFill2bPattern(
(*startPattern)++; (*startPattern)++;
} }
static int AuthCheckDesfire(uint8_t *aid, static int AuthCheckDesfire(DesfireContext *dctx,
uint8_t *aid,
uint8_t deskeyList[MAX_KEYS_LIST_LEN][8], uint32_t deskeyListLen, uint8_t deskeyList[MAX_KEYS_LIST_LEN][8], uint32_t deskeyListLen,
uint8_t aeskeyList[MAX_KEYS_LIST_LEN][16], uint32_t aeskeyListLen, uint8_t aeskeyList[MAX_KEYS_LIST_LEN][16], uint32_t aeskeyListLen,
uint8_t k3kkeyList[MAX_KEYS_LIST_LEN][24], uint32_t k3kkeyListLen, uint8_t k3kkeyList[MAX_KEYS_LIST_LEN][24], uint32_t k3kkeyListLen,
uint8_t cmdKdfAlgo, uint8_t kdfInputLen, uint8_t *kdfInput, uint8_t cmdKdfAlgo, uint8_t kdfInputLen, uint8_t *kdfInput,
uint8_t foundKeys[4][0xE][24 + 1], bool *result) { uint8_t foundKeys[4][0xE][24 + 1],
bool *result,
bool verbose) {
uint32_t curaid = (aid[0] & 0xFF) + ((aid[1] & 0xFF) << 8) + ((aid[2] & 0xFF) << 16); uint32_t curaid = (aid[0] & 0xFF) + ((aid[1] & 0xFF) << 8) + ((aid[2] & 0xFF) << 16);
int res = handler_desfire_select_application(aid); int res = DesfireSelectAIDHex(dctx, curaid, false, 0);
if (res != PM3_SUCCESS) { if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "AID 0x%06X does not exist.", curaid); PrintAndLogEx(ERR, "AID 0x%06X does not exist.", curaid);
return res; DropField();
return PM3_ESOFT;
} }
int usedkeys[0xF] = {0}; int usedkeys[0xF] = {0};
@ -1481,45 +1441,15 @@ static int AuthCheckDesfire(uint8_t *aid,
bool aes = false; bool aes = false;
bool k3kdes = false; bool k3kdes = false;
uint8_t num_keys = 0; uint8_t data[250] = {0};
uint8_t key_setting = 0; size_t datalen = 0;
res = handler_desfire_getkeysettings(&key_setting, &num_keys);
if (res != PM3_SUCCESS) { res = DesfireGetKeySettings(dctx, data, &datalen);
if (res != PM3_SUCCESS && datalen < 2) {
PrintAndLogEx(ERR, "Could not get key settings"); PrintAndLogEx(ERR, "Could not get key settings");
return res; return res;
} }
uint8_t num_keys = data[1];
if (memcmp(aid, "\x00\x00\x00", 3) != 0) {
uint8_t file_ids[33] = {0};
uint32_t file_ids_len = 0;
// Get File IDs
if (handler_desfire_fileids(file_ids, &file_ids_len) == PM3_SUCCESS) {
for (int j = (int)file_ids_len - 1; j >= 0; j--) {
uint8_t filesettings[20] = {0};
uint32_t fileset_len = 0;
res = handler_desfire_filesettings(file_ids[j], filesettings, &fileset_len);
if (res == PM3_SUCCESS) {
uint16_t accrights = (filesettings[3] << 8) + filesettings[2];
uint8_t change_access_rights = accrights & 0xF;
uint8_t read_write_access = (accrights >> 4) & 0xF;
uint8_t write_access = (accrights >> 8) & 0xF;
uint8_t read_access = (accrights >> 12) & 0xF;
if (change_access_rights == 0xE) change_access_rights = 0x0;
if (read_write_access == 0xE) read_write_access = 0x0;
if (write_access == 0xE) write_access = 0x0;
if (read_access == 0xE) read_access = 0x0;
usedkeys[change_access_rights] = 1;
usedkeys[read_write_access] = 1;
usedkeys[write_access] = 1;
usedkeys[read_access] = 1;
if (res == PM3_SUCCESS) {
switch (num_keys >> 6) { switch (num_keys >> 6) {
case 0: case 0:
des = true; des = true;
@ -1534,22 +1464,41 @@ static int AuthCheckDesfire(uint8_t *aid,
default: default:
break; break;
} }
if (curaid != 0) {
FileListS fileList = {0};
size_t filescount = 0;
bool isopresent = 0;
res = DesfireFillFileList(dctx, fileList, &filescount, &isopresent);
if (res == PM3_SUCCESS) {
if (filescount > 0) {
for (int i = 0; i < filescount; i++) {
if (fileList[i].fileSettings.rAccess < 0x0e)
usedkeys[fileList[i].fileSettings.rAccess] = 1;
if (fileList[i].fileSettings.wAccess < 0x0e)
usedkeys[fileList[i].fileSettings.wAccess] = 1;
if (fileList[i].fileSettings.rwAccess < 0x0e)
usedkeys[fileList[i].fileSettings.rwAccess] = 1;
if (fileList[i].fileSettings.chAccess < 0x0e)
usedkeys[fileList[i].fileSettings.chAccess] = 1;
} }
} else {
for (int i = 0; i < 0xE; i++)
usedkeys[i] = 1;
}
} else {
for (int i = 0; i < 0xE; i++)
usedkeys[i] = 1;
} }
} }
if (file_ids_len == 0) { if (verbose) {
for (uint8_t z = 0; z < 0xE; z++) { PrintAndLogEx(INFO, "Check: %s %s %s %s " NOLF, (des) ? "DES" : "", (tdes) ? "2TDEA" : "", (k3kdes) ? "3TDEA" : "", (aes) ? "AES" : "");
usedkeys[z] = 1; PrintAndLogEx(NORMAL, "keys: " NOLF);
des = true; for (int i = 0; i < 0xE; i++)
tdes = true; if (usedkeys[i] == 1)
aes = true; PrintAndLogEx(NORMAL, "%02x " NOLF, i);
k3kdes = true; PrintAndLogEx(NORMAL, "");
}
}
}
} else {
des = true;
} }
int error; int error;
@ -1906,7 +1855,7 @@ static int CmdHF14aDesChk(const char *Cmd) {
uint32_t curaid = (app_ids[x * 3] & 0xFF) + ((app_ids[(x * 3) + 1] & 0xFF) << 8) + ((app_ids[(x * 3) + 2] & 0xFF) << 16); uint32_t curaid = (app_ids[x * 3] & 0xFF) + ((app_ids[(x * 3) + 1] & 0xFF) << 8) + ((app_ids[(x * 3) + 2] & 0xFF) << 16);
PrintAndLogEx(ERR, "Checking aid 0x%06X...", curaid); PrintAndLogEx(ERR, "Checking aid 0x%06X...", curaid);
res = AuthCheckDesfire(&app_ids[x * 3], deskeyList, deskeyListLen, aeskeyList, aeskeyListLen, k3kkeyList, k3kkeyListLen, cmdKDFAlgo, kdfInputLen, kdfInput, foundKeys, &result); res = AuthCheckDesfire(&dctx, &app_ids[x * 3], deskeyList, deskeyListLen, aeskeyList, aeskeyListLen, k3kkeyList, k3kkeyListLen, cmdKDFAlgo, kdfInputLen, kdfInput, foundKeys, &result, (verbose == false));
if (res == PM3_EOPABORTED) { if (res == PM3_EOPABORTED) {
break; break;
} }
@ -1949,6 +1898,7 @@ static int CmdHF14aDesChk(const char *Cmd) {
// save keys to json // save keys to json
if ((jsonnamelen > 0) && result) { if ((jsonnamelen > 0) && result) {
DropField();
// MIFARE DESFire info // MIFARE DESFire info
SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT, 0, 0, NULL, 0); SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT, 0, 0, NULL, 0);
@ -1977,6 +1927,7 @@ static int CmdHF14aDesChk(const char *Cmd) {
saveFileJSON((char *)jsonname, jsfMfDesfireKeys, data, 0xE, NULL); saveFileJSON((char *)jsonname, jsfMfDesfireKeys, data, 0xE, NULL);
} }
DropField();
return PM3_SUCCESS; return PM3_SUCCESS;
} }