mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-05-12 11:18:11 -07:00
Handle tag loss & recovery in 'hf mfdes bruteaid'
This commit is contained in:
@@ -3,6 +3,7 @@ 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...
|
||||
|
||||
## [unreleased][unreleased]
|
||||
- Added tag loss detection & recovery into `hf mfdes bruteaid` (@kormax)
|
||||
- Added --credit option for `hf iclass legrec` command to perform a credit key recovery. This is experimental and unfinished as it only partially works.(@antiklesys)
|
||||
- Added hardening for all host binaries. Exact level of hardening depends on the OS (@doegox)
|
||||
- Added `hf aliro read` command (@kormax)
|
||||
|
||||
@@ -49,6 +49,8 @@
|
||||
|
||||
#define MAX_KEY_LEN 24
|
||||
#define MAX_KEYS_LIST_LEN 1024
|
||||
#define MFDES_BRUTEAID_RESELECT_ATTEMPTS 5
|
||||
#define MFDES_BRUTEAID_RESELECT_WAIT_MS 200
|
||||
|
||||
#define status(x) ( ((uint16_t)(0x91 << 8)) + (uint16_t)x )
|
||||
/*
|
||||
@@ -2251,6 +2253,36 @@ static int CmdHF14ADesBruteApps(const char *Cmd) {
|
||||
PrintAndLogEx(INPLACE, "Brute DESFire AID Progress " _YELLOW_("%0.1f") " %% current AID: %06X", progress, id);
|
||||
|
||||
res = DesfireSelectAIDHexNoFieldOn(&dctx, id);
|
||||
if (res == PM3_ECARDEXCHANGE || res == PM3_ETIMEOUT || res == PM3_ERFTRANS) {
|
||||
for (int attempt = 1; attempt <= MFDES_BRUTEAID_RESELECT_ATTEMPTS; attempt++) {
|
||||
printf("\33[2K\r"); // clear current inplace progress line before logging
|
||||
PrintAndLogEx(WARNING, "No card response while checking AID " _YELLOW_("%06X") ". Reselecting card (%d/%d)...",
|
||||
id, attempt, MFDES_BRUTEAID_RESELECT_ATTEMPTS);
|
||||
|
||||
msleep(MFDES_BRUTEAID_RESELECT_WAIT_MS);
|
||||
|
||||
res = DesfireSelectAIDHex(&dctx, 0x000000, false, 0);
|
||||
if (res != PM3_SUCCESS) {
|
||||
if (res == PM3_ECARDEXCHANGE || res == PM3_ETIMEOUT || res == PM3_ERFTRANS) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
res = DesfireSelectAIDHexNoFieldOn(&dctx, id);
|
||||
if (res == PM3_SUCCESS || res == PM3_EAPDU_FAIL ||
|
||||
(res != PM3_ECARDEXCHANGE && res != PM3_ETIMEOUT && res != PM3_ERFTRANS)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (res == PM3_ECARDEXCHANGE || res == PM3_ETIMEOUT || res == PM3_ERFTRANS) {
|
||||
PrintAndLogEx(FAILED, "Card is not responding after %d reselect attempts. Aborting at AID " _YELLOW_("%06X"),
|
||||
MFDES_BRUTEAID_RESELECT_ATTEMPTS, id);
|
||||
DropField();
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
if (res == PM3_SUCCESS) {
|
||||
printf("\33[2K\r"); // clear current line before printing
|
||||
|
||||
@@ -517,8 +517,12 @@ static int DESFIRESendRaw(bool activate_field, uint8_t *data, size_t datalen, ui
|
||||
PrintAndLogEx(SUCCESS, "raw<< %s", sprint_hex(result, *result_len));
|
||||
}
|
||||
|
||||
if (*result_len < 1) {
|
||||
return PM3_SUCCESS;
|
||||
if (*result_len == 0) {
|
||||
return PM3_ECARDEXCHANGE;
|
||||
}
|
||||
|
||||
if (*result_len < (1 + 2)) {
|
||||
return PM3_ECARDEXCHANGE;
|
||||
}
|
||||
|
||||
*result_len -= (1 + 2);
|
||||
@@ -538,6 +542,7 @@ static int DESFIRESendRaw(bool activate_field, uint8_t *data, size_t datalen, ui
|
||||
if (GetAPDULogging()) {
|
||||
PrintAndLogEx(ERR, "Command (%02x) ERROR: 0x%02x", data[0], rcode);
|
||||
}
|
||||
|
||||
return PM3_EAPDU_FAIL;
|
||||
}
|
||||
return PM3_SUCCESS;
|
||||
@@ -591,6 +596,9 @@ static int DesfireExchangeNative(bool activate_field, DesfireContext_t *ctx, uin
|
||||
|
||||
res = DESFIRESendRaw(activate_field, &cdata[sendindx], sendlen, buf, DESFIRE_BUFFER_SIZE, &buflen, &rcode);
|
||||
if (res != PM3_SUCCESS) {
|
||||
if (respcode != NULL) {
|
||||
*respcode = rcode;
|
||||
}
|
||||
uint16_t ssw = DESFIRE_GET_ISO_STATUS(rcode);
|
||||
PrintAndLogEx(DEBUG, "error DESFIRESendRaw %s", DesfireGetErrorString(res, &ssw));
|
||||
free(buf);
|
||||
@@ -638,8 +646,12 @@ static int DesfireExchangeNative(bool activate_field, DesfireContext_t *ctx, uin
|
||||
|
||||
res = DESFIRESendRaw(false, cdata, 1, buf, DESFIRE_BUFFER_SIZE, &buflen, &rcode);
|
||||
if (res != PM3_SUCCESS) {
|
||||
if (respcode != NULL) {
|
||||
*respcode = rcode;
|
||||
}
|
||||
uint16_t ssw = DESFIRE_GET_ISO_STATUS(rcode);
|
||||
PrintAndLogEx(DEBUG, "error DESFIRESendRaw %s", DesfireGetErrorString(res, &ssw));
|
||||
free(buf);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -716,6 +728,9 @@ static int DesfireExchangeISONative(bool activate_field, DesfireContext_t *ctx,
|
||||
|
||||
res = DESFIRESendApdu(activate_field, apdu, buf, DESFIRE_BUFFER_SIZE, &buflen, &sw);
|
||||
if (res != PM3_SUCCESS) {
|
||||
if (respcode != NULL && ((sw & 0xFF00) == 0x9100)) {
|
||||
*respcode = sw & 0xFF;
|
||||
}
|
||||
PrintAndLogEx(DEBUG, "error DESFIRESendApdu %s", DesfireGetErrorString(res, &sw));
|
||||
free(buf);
|
||||
return res;
|
||||
@@ -768,6 +783,9 @@ static int DesfireExchangeISONative(bool activate_field, DesfireContext_t *ctx,
|
||||
|
||||
res = DESFIRESendApdu(false, apdu, buf, DESFIRE_BUFFER_SIZE, &buflen, &sw);
|
||||
if (res != PM3_SUCCESS) {
|
||||
if (respcode != NULL && ((sw & 0xFF00) == 0x9100)) {
|
||||
*respcode = sw & 0xFF;
|
||||
}
|
||||
PrintAndLogEx(DEBUG, "error DESFIRESendApdu %s", DesfireGetErrorString(res, &sw));
|
||||
free(buf);
|
||||
return res;
|
||||
@@ -926,28 +944,36 @@ int DesfireSelectAID(DesfireContext_t *ctx, uint8_t *aid1, uint8_t *aid2) {
|
||||
|
||||
uint8_t resp[257] = {0};
|
||||
size_t resplen = 0;
|
||||
uint8_t respcode = 0;
|
||||
uint8_t respcode = 0xFF;
|
||||
|
||||
ctx->secureChannel = DACNone;
|
||||
int res = DesfireExchangeEx(true, ctx, MFDES_SELECT_APPLICATION, data, (aid2 == NULL) ? 3 : 6, &respcode, resp, &resplen, true, 0);
|
||||
if (res == PM3_SUCCESS) {
|
||||
if (resplen != 0) {
|
||||
if (res != PM3_SUCCESS) {
|
||||
if (res == PM3_EAPDU_FAIL && respcode == 0xFF && resplen == 0) {
|
||||
return PM3_ECARDEXCHANGE;
|
||||
}
|
||||
|
||||
// select operation fail
|
||||
if (respcode != MFDES_S_OPERATION_OK) {
|
||||
return PM3_EAPDU_FAIL;
|
||||
}
|
||||
|
||||
DesfireClearSession(ctx);
|
||||
ctx->appSelected = (aid1[0] != 0x00 || aid1[1] != 0x00 || aid1[2] != 0x00);
|
||||
ctx->selectedAID = DesfireAIDByteToUint(aid1);
|
||||
|
||||
return PM3_SUCCESS;
|
||||
return res;
|
||||
}
|
||||
|
||||
return res;
|
||||
if (resplen != 0) {
|
||||
return PM3_ECARDEXCHANGE;
|
||||
}
|
||||
|
||||
// no status byte received from card
|
||||
if (respcode == 0xFF) {
|
||||
return PM3_ECARDEXCHANGE;
|
||||
}
|
||||
|
||||
// select operation fail
|
||||
if (respcode != MFDES_S_OPERATION_OK) {
|
||||
return PM3_EAPDU_FAIL;
|
||||
}
|
||||
|
||||
DesfireClearSession(ctx);
|
||||
ctx->appSelected = (aid1[0] != 0x00 || aid1[1] != 0x00 || aid1[2] != 0x00);
|
||||
ctx->selectedAID = DesfireAIDByteToUint(aid1);
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
int DesfireSelectAIDHex(DesfireContext_t *ctx, uint32_t aid1, bool select_two, uint32_t aid2) {
|
||||
@@ -966,27 +992,36 @@ int DesfireSelectAIDHexNoFieldOn(DesfireContext_t *ctx, uint32_t aid) {
|
||||
|
||||
uint8_t resp[257] = {0};
|
||||
size_t resplen = 0;
|
||||
uint8_t respcode = 0;
|
||||
uint8_t respcode = 0xFF;
|
||||
|
||||
ctx->secureChannel = DACNone;
|
||||
int res = DesfireExchangeEx(false, ctx, MFDES_SELECT_APPLICATION, data, 3, &respcode, resp, &resplen, true, 0);
|
||||
if (res == PM3_SUCCESS) {
|
||||
if (resplen != 0) {
|
||||
if (res != PM3_SUCCESS) {
|
||||
if (res == PM3_EAPDU_FAIL && respcode == 0xFF && resplen == 0) {
|
||||
return PM3_ECARDEXCHANGE;
|
||||
}
|
||||
|
||||
// select operation fail
|
||||
if (respcode != MFDES_S_OPERATION_OK) {
|
||||
return PM3_EAPDU_FAIL;
|
||||
}
|
||||
|
||||
DesfireClearSession(ctx);
|
||||
ctx->appSelected = (aid != 0x000000);
|
||||
ctx->selectedAID = aid;
|
||||
|
||||
return PM3_SUCCESS;
|
||||
return res;
|
||||
}
|
||||
return res;
|
||||
|
||||
if (resplen != 0) {
|
||||
return PM3_ECARDEXCHANGE;
|
||||
}
|
||||
|
||||
// no status byte received from card
|
||||
if (respcode == 0xFF) {
|
||||
return PM3_ECARDEXCHANGE;
|
||||
}
|
||||
|
||||
// select operation fail
|
||||
if (respcode != MFDES_S_OPERATION_OK) {
|
||||
return PM3_EAPDU_FAIL;
|
||||
}
|
||||
|
||||
DesfireClearSession(ctx);
|
||||
ctx->appSelected = (aid != 0x000000);
|
||||
ctx->selectedAID = aid;
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
void DesfirePrintMADAID(uint32_t appid, bool verbose) {
|
||||
|
||||
Reference in New Issue
Block a user