Merge branch 'master' of https://github.com/RfidResearchGroup/proxmark3 into autopwn_restyle
This commit is contained in:
201
client/cmdhfmf.c
201
client/cmdhfmf.c
@@ -751,12 +751,56 @@ static uint8_t NumBlocksPerSector(uint8_t sectorNo) {
|
||||
return 16;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t GetSectorFromBlockNo(uint8_t blockNo) {
|
||||
if (blockNo < 128)
|
||||
return blockNo / 4;
|
||||
else
|
||||
return 32 + ((128 - blockNo) / 16);
|
||||
}
|
||||
|
||||
static char GetFormatFromSector(uint8_t sectorNo) {
|
||||
switch (sectorNo) {
|
||||
case MIFARE_MINI_MAXSECTOR:
|
||||
return '0';
|
||||
case MIFARE_1K_MAXSECTOR:
|
||||
return '1';
|
||||
case MIFARE_2K_MAXSECTOR:
|
||||
return '2';
|
||||
case MIFARE_4K_MAXSECTOR:
|
||||
return '4';
|
||||
default :
|
||||
return ' ';
|
||||
}
|
||||
}
|
||||
|
||||
static int FastDumpWithEcFill(uint8_t numsectors){
|
||||
PacketResponseNG resp;
|
||||
|
||||
mfc_eload_t payload;
|
||||
payload.sectorcnt = numsectors;
|
||||
payload.keytype = 0;
|
||||
|
||||
// ecfill key A
|
||||
clearCommandBuffer();
|
||||
SendCommandNG(CMD_HF_MIFARE_EML_LOAD, (uint8_t *)&payload, sizeof(payload));
|
||||
|
||||
int res = WaitForResponseTimeout(CMD_HF_MIFARE_EML_LOAD, &resp, 2000);
|
||||
if ( res != PM3_SUCCESS) {
|
||||
}
|
||||
|
||||
// ecfill key B
|
||||
payload.keytype = 1;
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommandNG(CMD_HF_MIFARE_EML_LOAD, (uint8_t *)&payload, sizeof(payload));
|
||||
res = WaitForResponseTimeout(CMD_HF_MIFARE_EML_LOAD, &resp, 2000);
|
||||
if ( res != PM3_SUCCESS) {
|
||||
|
||||
}
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdHF14AMfDump(const char *Cmd) {
|
||||
|
||||
uint64_t t1 = msclock();
|
||||
@@ -1242,7 +1286,12 @@ static int CmdHF14AMfNested(const char *Cmd) {
|
||||
}
|
||||
|
||||
PrintAndLogEx(SUCCESS, "Testing known keys. Sector count=%d", SectorsCnt);
|
||||
mfCheckKeys_fast(SectorsCnt, true, true, 1, ARRAYLEN(g_mifare_default_keys) + 1, keyBlock, e_sector, false);
|
||||
int res = mfCheckKeys_fast(SectorsCnt, true, true, 1, ARRAYLEN(g_mifare_default_keys) + 1, keyBlock, e_sector, false);
|
||||
if ( res == PM3_SUCCESS ) {
|
||||
// all keys found
|
||||
PrintAndLogEx(SUCCESS, "Fast check found all keys");
|
||||
goto jumptoend;
|
||||
}
|
||||
|
||||
uint64_t t2 = msclock() - t1;
|
||||
PrintAndLogEx(SUCCESS, "Time to check %d known keys: %.0f seconds\n", ARRAYLEN(g_mifare_default_keys), (float)t2 / 1000.0);
|
||||
@@ -1329,6 +1378,7 @@ static int CmdHF14AMfNested(const char *Cmd) {
|
||||
}
|
||||
}
|
||||
|
||||
jumptoend:
|
||||
|
||||
//print them
|
||||
printKeyTable(SectorsCnt, e_sector);
|
||||
@@ -1612,56 +1662,69 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
|
||||
bool legacy_mfchk = false;
|
||||
bool prng_type = false;
|
||||
bool verbose = false;
|
||||
bool has_filename = false;
|
||||
bool errors = false;
|
||||
|
||||
// Parse the options given by the user
|
||||
ctmp = tolower(param_getchar(Cmd, 0));
|
||||
while ((ctmp = param_getchar(Cmd, cmdp))) {
|
||||
while ( (ctmp = param_getchar(Cmd, cmdp)) && !errors ) {
|
||||
switch (tolower(ctmp)) {
|
||||
case 'h':
|
||||
return usage_hf14_autopwn();
|
||||
case 'f':
|
||||
if (param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) {
|
||||
PrintAndLogEx(FAILED, "Filename too long");
|
||||
errors = true;
|
||||
} else {
|
||||
has_filename = true;
|
||||
}
|
||||
cmdp ++;
|
||||
cmdp += 2;
|
||||
break;
|
||||
case 'l':
|
||||
legacy_mfchk = true;
|
||||
cmdp++;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = true;
|
||||
cmdp++;
|
||||
break;
|
||||
case '*':
|
||||
// Get the number of sectors
|
||||
sectors_cnt = NumOfSectors(param_getchar(Cmd, cmdp + 1));
|
||||
block_cnt = NumOfBlocks(param_getchar(Cmd, cmdp + 1));
|
||||
cmdp ++;
|
||||
cmdp += 2;
|
||||
break;
|
||||
case 'k':
|
||||
// Get the known block number
|
||||
if (param_getchar(Cmd, cmdp + 1) == 0x00) {
|
||||
PrintAndLogEx(WARNING, "Sector number is missing");
|
||||
return PM3_EINVARG;
|
||||
errors = true;
|
||||
break;
|
||||
}
|
||||
|
||||
blockNo = param_get8(Cmd, cmdp + 1);
|
||||
|
||||
// Get the knonwn block type
|
||||
ctmp = tolower(param_getchar(Cmd, cmdp + 2));
|
||||
if (ctmp != 'a' && ctmp != 'b') {
|
||||
PrintAndLogEx(WARNING, "Key type must be A or B");
|
||||
return PM3_EINVARG;
|
||||
errors = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ctmp != 'a') {
|
||||
keyType = 1;
|
||||
}
|
||||
|
||||
// Get the known block key
|
||||
if (param_gethex(Cmd, cmdp + 3, key, 12)) {
|
||||
PrintAndLogEx(WARNING, "Key must include 12 HEX symbols");
|
||||
errors = true;
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
know_target_key = true;
|
||||
cmdp += 3;
|
||||
case 's':
|
||||
slow = true;
|
||||
cmdp++;
|
||||
break;
|
||||
case 'i':
|
||||
SetSIMDInstr(SIMD_AUTO);
|
||||
@@ -1695,7 +1758,10 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
|
||||
PrintAndLogEx(WARNING, "Unknown parameter '%c'\n", ctmp);
|
||||
return usage_hf14_autopwn();
|
||||
}
|
||||
cmdp++;
|
||||
}
|
||||
|
||||
if ( errors ) {
|
||||
return usage_hf14_autopwn();
|
||||
}
|
||||
|
||||
// Create the key storage stucture
|
||||
@@ -1732,19 +1798,20 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
|
||||
|
||||
// check the user supplied key
|
||||
if (know_target_key == false)
|
||||
PrintAndLogEx(WARNING, "No known key was supplied, key recovery might fail");
|
||||
PrintAndLogEx(WARNING, "no known key was supplied, key recovery might fail");
|
||||
else {
|
||||
if (verbose) PrintAndLogEx(INFO, _YELLOW_("======================= START KNOWN KEY ATTACK ======================="));
|
||||
if (verbose) {
|
||||
PrintAndLogEx(INFO, _YELLOW_("======================= START KNOWN KEY ATTACK ======================="));
|
||||
}
|
||||
if (mfCheckKeys(FirstBlockOfSector(blockNo), keyType, true, 1, key, &key64) == PM3_SUCCESS) {
|
||||
PrintAndLogEx(INFO, "Using valid key: sector: %3d key type: %c key: " _YELLOW_("%s") "(used for nested / hardnested attack)",
|
||||
PrintAndLogEx(INFO, "target sector:%3u key type: %c -- using valid key [ " _YELLOW_("%s") "] (used for nested / hardnested attack)",
|
||||
blockNo,
|
||||
keyType ? 'B' : 'A',
|
||||
sprint_hex(key, sizeof(key))
|
||||
);
|
||||
|
||||
// Store the key for the nested / hardnested attack (if supplied by the user)
|
||||
e_sector[blockNo].Key[keyType] = bytes_to_num(key, 6);
|
||||
e_sector[blockNo].foundKey[keyType] = 'U';
|
||||
e_sector[blockNo].Key[keyType] = key64;
|
||||
} else {
|
||||
know_target_key = false;
|
||||
PrintAndLogEx(FAILED, "Key is wrong. Can't authenticate to sector:"_RED_("%3d") " key type: "_RED_("%c") " key: " _RED_("%s"),
|
||||
@@ -1752,8 +1819,9 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
|
||||
keyType ? 'B' : 'A',
|
||||
sprint_hex(key, sizeof(key))
|
||||
);
|
||||
PrintAndLogEx(WARNING, "Falling back to dictionary");
|
||||
PrintAndLogEx(WARNING, "falling back to dictionary");
|
||||
}
|
||||
|
||||
// Check if the user supplied key is used by other sectors
|
||||
for (int i = 0; i < sectors_cnt; i++) {
|
||||
for (int j = 0; j < 2; j++) {
|
||||
@@ -1768,13 +1836,13 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
|
||||
know_target_key = true;
|
||||
blockNo = i;
|
||||
keyType = j;
|
||||
PrintAndLogEx(SUCCESS, "Found valid key: sector: %3d key type: %c key: " _YELLOW_("%s") "(used for nested / hardnested attack)",
|
||||
PrintAndLogEx(SUCCESS, "target sector:%3u key type: %c -- found valid key [ " _YELLOW_("%s") "] (used for nested / hardnested attack)",
|
||||
i,
|
||||
j ? 'B' : 'A',
|
||||
sprint_hex(key, sizeof(key))
|
||||
);
|
||||
} else {
|
||||
PrintAndLogEx(SUCCESS, "Found valid key: sector: %3d key type: %c key: " _YELLOW_("%s"),
|
||||
PrintAndLogEx(SUCCESS, "target sector:%3u key type: %c -- found valid key [ " _YELLOW_("%s") "]",
|
||||
i,
|
||||
j ? 'B' : 'A',
|
||||
sprint_hex(key, sizeof(key))
|
||||
@@ -1787,16 +1855,21 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
|
||||
if (verbose) PrintAndLogEx(INFO, _YELLOW_("======================= STOP KNOWN KEY ATTACK ======================="));
|
||||
}
|
||||
|
||||
bool load_success = true;
|
||||
// Load the dictionary
|
||||
if (strlen(filename) != 0) {
|
||||
if (has_filename) {
|
||||
int res = loadFileDICTIONARY_safe(filename, (void**) &keyBlock, 6, &key_cnt);
|
||||
if (res != PM3_SUCCESS || key_cnt <= 0 || keyBlock == NULL) {
|
||||
if (res != PM3_SUCCESS || key_cnt == 0 || keyBlock == NULL) {
|
||||
PrintAndLogEx(FAILED, "An error occurred while loading the dictionary! (we will use the default keys now)");
|
||||
if (keyBlock != NULL) free(keyBlock);
|
||||
goto useDefaultKeys;
|
||||
if (keyBlock != NULL)
|
||||
free(keyBlock);
|
||||
|
||||
load_success = false;
|
||||
}
|
||||
} else {
|
||||
useDefaultKeys:
|
||||
|
||||
}
|
||||
|
||||
if ( has_filename == false || load_success == false ) {
|
||||
keyBlock = calloc(ARRAYLEN(g_mifare_default_keys), 6);
|
||||
if (keyBlock == NULL) {
|
||||
free(e_sector);
|
||||
@@ -1807,6 +1880,7 @@ useDefaultKeys:
|
||||
num_to_bytes(g_mifare_default_keys[cnt], 6, keyBlock + cnt * 6);
|
||||
}
|
||||
key_cnt = ARRAYLEN(g_mifare_default_keys);
|
||||
PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") "keys from hardcoded default array", key_cnt);
|
||||
}
|
||||
|
||||
// Use the dictionary to find sector keys on the card
|
||||
@@ -1833,10 +1907,12 @@ useDefaultKeys:
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
} else {
|
||||
|
||||
int chunksize = key_cnt > (PM3_CMD_DATA_SIZE / 6) ? (PM3_CMD_DATA_SIZE / 6) : key_cnt;
|
||||
bool firstChunk = true, lastChunk = false;
|
||||
|
||||
for (uint8_t strategy = 1; strategy < 3; strategy++) {
|
||||
PrintAndLogEx(INFO, "Running strategy %u", strategy);
|
||||
PrintAndLogEx(INFO, "running strategy %u", strategy);
|
||||
// main keychunk loop
|
||||
for (int i = 0; i < key_cnt; i += chunksize) {
|
||||
|
||||
@@ -1855,7 +1931,7 @@ useDefaultKeys:
|
||||
if (firstChunk)
|
||||
firstChunk = false;
|
||||
// all keys, aborted
|
||||
if (res == 0 || res == 2) {
|
||||
if (res == PM3_SUCCESS) {
|
||||
i = key_cnt;
|
||||
strategy = 3;
|
||||
break; // Exit the loop
|
||||
@@ -1875,20 +1951,19 @@ useDefaultKeys:
|
||||
e_sector[i].foundKey[j] = 'D';
|
||||
num_to_bytes(e_sector[i].Key[j], 6, tmp_key);
|
||||
|
||||
|
||||
// Store valid credentials for the nested / hardnested attack if none exist
|
||||
if (know_target_key == false) {
|
||||
num_to_bytes(e_sector[i].Key[j], 6, key);
|
||||
know_target_key = true;
|
||||
blockNo = i;
|
||||
keyType = j;
|
||||
PrintAndLogEx(SUCCESS, "Found valid key: sector: %3d key type: %c key: " _YELLOW_("%s") "(used for nested / hardnested attack)",
|
||||
PrintAndLogEx(SUCCESS, "target sector:%3u key type: %c -- found valid key [ " _YELLOW_("%s") "] (used for nested / hardnested attack)",
|
||||
i,
|
||||
j ? 'B' : 'A',
|
||||
sprint_hex(tmp_key, sizeof(tmp_key))
|
||||
);
|
||||
} else {
|
||||
PrintAndLogEx(SUCCESS, "Found valid key: sector: %3d key type: %c key: " _YELLOW_("%s"),
|
||||
PrintAndLogEx(SUCCESS, "target sector:%3u key type: %c -- found valid key [ " _YELLOW_("%s") "]",
|
||||
i,
|
||||
j ? 'B' : 'A',
|
||||
sprint_hex(tmp_key, sizeof(tmp_key))
|
||||
@@ -1926,21 +2001,11 @@ useDefaultKeys:
|
||||
PrintAndLogEx(SUCCESS, "\nFound valid key: %012" PRIx64 "\n", key64);
|
||||
break;
|
||||
}
|
||||
num_to_bytes(key64, 6, key);
|
||||
// Check if the darkside key is valid
|
||||
if (mfCheckKeys(FirstBlockOfSector(blockNo), keyType, true, 1, key, &key64) != PM3_SUCCESS) {
|
||||
PrintAndLogEx(FAILED, "The key generated by the darkside attack is not valid!"
|
||||
_RED_("%3d") " key type: "_RED_("%c") " key: " _RED_("%s"),
|
||||
blockNo,
|
||||
keyType ? 'B' : 'A',
|
||||
sprint_hex(key, sizeof(key))
|
||||
);
|
||||
goto noValidKeyFound;
|
||||
}
|
||||
|
||||
// Store the keys
|
||||
e_sector[blockNo].Key[keyType] = bytes_to_num(key, 6);
|
||||
e_sector[blockNo].Key[keyType] = key64;
|
||||
e_sector[blockNo].foundKey[keyType] = 'S';
|
||||
PrintAndLogEx(SUCCESS, "Found valid key: sector: %3d key type: %c key: " _YELLOW_("%s") "(used for nested / hardnested attack)",
|
||||
PrintAndLogEx(SUCCESS, "target sector:%3u key type: %c -- found valid key [ " _YELLOW_("%s") "] (used for nested / hardnested attack)",
|
||||
blockNo,
|
||||
keyType ? 'B' : 'A',
|
||||
sprint_hex(key, sizeof(key))
|
||||
@@ -1953,6 +2018,7 @@ noValidKeyFound:
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
}
|
||||
|
||||
free(keyBlock);
|
||||
// Clear the needed variables
|
||||
num_to_bytes(0, 6, tmp_key);
|
||||
@@ -1979,7 +2045,7 @@ noValidKeyFound:
|
||||
if (mfCheckKeys(FirstBlockOfSector(i), j, true, 1, tmp_key, &key64) == PM3_SUCCESS) {
|
||||
e_sector[i].Key[j] = bytes_to_num(tmp_key, 6);
|
||||
e_sector[i].foundKey[j] = 'R';
|
||||
PrintAndLogEx(SUCCESS, "Found valid key: sector: %3d key type: %c key: " _YELLOW_("%s"),
|
||||
PrintAndLogEx(SUCCESS, "target sector:%3u key type: %c -- found valid key [ " _YELLOW_("%s") "]",
|
||||
i,
|
||||
j ? 'B' : 'A',
|
||||
sprint_hex(tmp_key, sizeof(tmp_key))
|
||||
@@ -1995,7 +2061,7 @@ noValidKeyFound:
|
||||
if (e_sector[current_sector_i].foundKey[0] && !e_sector[current_sector_i].foundKey[1]) {
|
||||
if (verbose) {
|
||||
PrintAndLogEx(INFO, _YELLOW_("======================= START READ B KEY ATTACK ======================="));
|
||||
PrintAndLogEx(INFO, "Reading B key: sector: %3d key type: %c",
|
||||
PrintAndLogEx(INFO, "reading B key: sector: %3d key type: %c",
|
||||
current_sector_i,
|
||||
current_key_type_i ? 'B' : 'A');
|
||||
}
|
||||
@@ -2021,13 +2087,13 @@ noValidKeyFound:
|
||||
e_sector[current_sector_i].foundKey[current_key_type_i] = 'A';
|
||||
e_sector[current_sector_i].Key[current_key_type_i] = key64;
|
||||
num_to_bytes(key64, 6, tmp_key);
|
||||
PrintAndLogEx(SUCCESS, "Found valid key: sector: %3d key type: %c key: " _YELLOW_("%s"),
|
||||
PrintAndLogEx(SUCCESS, "target sector:%3u key type: %c -- found valid key [ " _YELLOW_("%s") "]",
|
||||
current_sector_i,
|
||||
current_key_type_i ? 'B' : 'A',
|
||||
sprint_hex(tmp_key, sizeof(tmp_key))
|
||||
);
|
||||
} else {
|
||||
if (verbose) PrintAndLogEx(WARNING, "Unknown B key: sector: %3d key type: %c (reading the B key was not possible, maybe due to insufficient access rights) ",
|
||||
if (verbose) PrintAndLogEx(WARNING, "unknown B key: sector: %3d key type: %c (reading the B key was not possible, maybe due to insufficient access rights) ",
|
||||
current_sector_i,
|
||||
current_key_type_i ? 'B' : 'A'
|
||||
);
|
||||
@@ -2043,7 +2109,7 @@ skipReadBKey:
|
||||
uint8_t retries = 0;
|
||||
if (verbose) {
|
||||
PrintAndLogEx(INFO, _YELLOW_("======================= START NESTED ATTACK ======================="));
|
||||
PrintAndLogEx(INFO, "Sector no: %3d, target key type: %c",
|
||||
PrintAndLogEx(INFO, "sector no: %3d, target key type: %c",
|
||||
current_sector_i,
|
||||
current_key_type_i ? 'B' : 'A');
|
||||
}
|
||||
@@ -2089,7 +2155,7 @@ tryNested:
|
||||
tryHardnested: // If the nested attack fails then we try the hardnested attack
|
||||
if (verbose) {
|
||||
PrintAndLogEx(INFO, _YELLOW_("======================= START HARDNESTED ATTACK ======================="));
|
||||
PrintAndLogEx(INFO, "Sector no: %3d, target key type: %c, Slow: %s",
|
||||
PrintAndLogEx(INFO, "sector no: %3d, target key type: %c, Slow: %s",
|
||||
current_sector_i,
|
||||
current_key_type_i ? 'B' : 'A',
|
||||
slow ? "Yes" : "No");
|
||||
@@ -2121,7 +2187,7 @@ tryHardnested: // If the nested attack fails then we try the hardnested attack
|
||||
}
|
||||
// Check if the key was found
|
||||
if (e_sector[current_sector_i].foundKey[current_key_type_i]) {
|
||||
PrintAndLogEx(SUCCESS, "Found valid key: sector: %3d key type: %c key: " _YELLOW_("%s"),
|
||||
PrintAndLogEx(SUCCESS, "target sector:%3u key type: %c -- found valid key [ " _YELLOW_("%s") "]",
|
||||
current_sector_i,
|
||||
current_key_type_i ? 'B' : 'A',
|
||||
sprint_hex(tmp_key, sizeof(tmp_key))
|
||||
@@ -2134,7 +2200,7 @@ tryHardnested: // If the nested attack fails then we try the hardnested attack
|
||||
|
||||
// Show the results to the user
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(INFO, "Found Keys:");
|
||||
PrintAndLogEx(INFO, "found Keys:");
|
||||
|
||||
char strA[12 + 1] = {0};
|
||||
char strB[12 + 1] = {0};
|
||||
@@ -2172,10 +2238,11 @@ tryHardnested: // If the nested attack fails then we try the hardnested attack
|
||||
);
|
||||
|
||||
// Dump the keys
|
||||
PrintAndLogEx(INFO, "\nSaving keys");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(INFO, "saving keys");
|
||||
createMfcKeyDump(sectors_cnt, e_sector, GenerateFilename("hf-mf-", "-key.bin"));
|
||||
|
||||
PrintAndLogEx(SUCCESS, "Transferring keys to simulator memory (Cmd Error: 04 can occur)");
|
||||
PrintAndLogEx(SUCCESS, "transferring keys to simulator memory (Cmd Error: 04 can occur)");
|
||||
|
||||
for (current_sector_i = 0; current_sector_i < sectors_cnt; current_sector_i++) {
|
||||
mfEmlGetMem(block, current_sector_i, 1);
|
||||
@@ -2187,13 +2254,8 @@ tryHardnested: // If the nested attack fails then we try the hardnested attack
|
||||
mfEmlSetMem(block, FirstBlockOfSector(current_sector_i) + NumBlocksPerSector(current_sector_i) - 1, 1);
|
||||
}
|
||||
|
||||
// using ecfill trick, keys already in emulator mem, load data using Key A
|
||||
clearCommandBuffer();
|
||||
SendCommandMIX(CMD_HF_MIFARE_EML_LOAD, sectors_cnt, 0, 0, NULL, 0);
|
||||
|
||||
// using ecfill trick, keys already in emulator mem, load data using Key B
|
||||
clearCommandBuffer();
|
||||
SendCommandMIX(CMD_HF_MIFARE_EML_LOAD, sectors_cnt, 1, 0, NULL, 0);
|
||||
// use ecfill trick
|
||||
FastDumpWithEcFill(sectors_cnt);
|
||||
|
||||
bytes = block_cnt * MFBLOCK_SIZE;
|
||||
dump = calloc(bytes, sizeof(uint8_t));
|
||||
@@ -2204,7 +2266,7 @@ tryHardnested: // If the nested attack fails then we try the hardnested attack
|
||||
}
|
||||
memset(dump, 0, bytes);
|
||||
|
||||
PrintAndLogEx(INFO, "Downloading the card content from emulator memory");
|
||||
PrintAndLogEx(INFO, "downloading the card content from emulator memory");
|
||||
if (!GetFromDevice(BIG_BUF_EML, dump, bytes, 0, NULL, 0, NULL, 2500, false)) {
|
||||
PrintAndLogEx(ERR, "Fail, transfer from device time-out");
|
||||
free(e_sector);
|
||||
@@ -2226,7 +2288,7 @@ tryHardnested: // If the nested attack fails then we try the hardnested attack
|
||||
|
||||
// Generate and show statistics
|
||||
t1 = msclock() - t1;
|
||||
PrintAndLogEx(INFO, "Autopwn execution time: " _YELLOW_("%.0f") " seconds", (float)t1 / 1000.0);
|
||||
PrintAndLogEx(INFO, "autopwn execution time: " _YELLOW_("%.0f") " seconds", (float)t1 / 1000.0);
|
||||
|
||||
free(dump);
|
||||
free(e_sector);
|
||||
@@ -2436,7 +2498,7 @@ static int CmdHF14AMfChk_fast(const char *Cmd) {
|
||||
firstChunk = false;
|
||||
|
||||
// all keys, aborted
|
||||
if (res == 0 || res == 2)
|
||||
if (res == PM3_SUCCESS || res == 2)
|
||||
goto out;
|
||||
} // end chunks of keys
|
||||
firstChunk = true;
|
||||
@@ -2464,6 +2526,13 @@ out:
|
||||
|
||||
printKeyTable(sectorsCnt, e_sector);
|
||||
|
||||
if ( use_flashmemory && found_keys == (sectorsCnt << 1) ) {
|
||||
PrintAndLogEx(SUCCESS, "Card dumped aswell. run " _YELLOW_("`%s %c`"),
|
||||
"hf mf esave",
|
||||
GetFormatFromSector(sectorsCnt)
|
||||
);
|
||||
}
|
||||
|
||||
if (transferToEml) {
|
||||
// fast push mode
|
||||
conn.block_after_ACK = true;
|
||||
@@ -2482,6 +2551,10 @@ out:
|
||||
mfEmlSetMem(block, blockno, 1);
|
||||
}
|
||||
PrintAndLogEx(SUCCESS, "Found keys have been transferred to the emulator memory");
|
||||
|
||||
if ( found_keys == (sectorsCnt << 1) ) {
|
||||
FastDumpWithEcFill(sectorsCnt);
|
||||
}
|
||||
}
|
||||
|
||||
if (createDumpFile) {
|
||||
@@ -3459,8 +3532,12 @@ static int CmdHF14AMfECFill(const char *Cmd) {
|
||||
}
|
||||
|
||||
PrintAndLogEx(NORMAL, "--params: numSectors: %d, keyType: %c\n", numSectors, (keyType == 0) ? 'A' : 'B');
|
||||
|
||||
mfc_eload_t payload;
|
||||
payload.sectorcnt = numSectors;
|
||||
payload.keytype = keyType;
|
||||
clearCommandBuffer();
|
||||
SendCommandMIX(CMD_HF_MIFARE_EML_LOAD, numSectors, keyType, 0, NULL, 0);
|
||||
SendCommandNG(CMD_HF_MIFARE_EML_LOAD, (uint8_t *)&payload, sizeof(payload));
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user