mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-22 06:13:51 -07:00
added new command 'hf mf wipe' - which takes a keyfile to wipe a MFC to default values
This commit is contained in:
parent
b639586159
commit
f4694a4cd5
1 changed files with 131 additions and 9 deletions
|
@ -868,16 +868,16 @@ static int CmdHF14AMfDump(const char *Cmd) {
|
||||||
CLIParserInit(&ctx, "hf mf dump",
|
CLIParserInit(&ctx, "hf mf dump",
|
||||||
"Dump MIFARE Classic tag to binary file\n"
|
"Dump MIFARE Classic tag to binary file\n"
|
||||||
"If no <name> given, UID will be used as filename",
|
"If no <name> given, UID will be used as filename",
|
||||||
"hf mf dump --mini --> MIFARE Mini\n"
|
"hf mf dump --mini --> MIFARE Mini\n"
|
||||||
"hf mf dump --1k --> MIFARE Classic 1k\n"
|
"hf mf dump --1k --> MIFARE Classic 1k\n"
|
||||||
"hf mf dump --2k --> MIFARE 2k\n"
|
"hf mf dump --2k --> MIFARE 2k\n"
|
||||||
"hf mf dump --4k --> MIFARE 4k\n"
|
"hf mf dump --4k --> MIFARE 4k\n"
|
||||||
"hf mf dump -f hf-mf-066C8B78-key-5.bin --> MIFARE 1k with keys from specified file\n");
|
"hf mf dump --keys hf-mf-066C8B78-key.bin --> MIFARE 1k with keys from specified file\n");
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_str0("f", "file", "<filename>", "filename of dump"),
|
arg_str0("f", "file", "<fn>", "filename of dump"),
|
||||||
arg_str0("k", "keys", "<filename>", "filename of keys"),
|
arg_str0("k", "keys", "<fn>", "filename of keys"),
|
||||||
arg_lit0(NULL, "mini", "MIFARE Classic Mini / S20"),
|
arg_lit0(NULL, "mini", "MIFARE Classic Mini / S20"),
|
||||||
arg_lit0(NULL, "1k", "MIFARE Classic 1k / S50 (default)"),
|
arg_lit0(NULL, "1k", "MIFARE Classic 1k / S50 (default)"),
|
||||||
arg_lit0(NULL, "2k", "MIFARE Classic/Plus 2k"),
|
arg_lit0(NULL, "2k", "MIFARE Classic/Plus 2k"),
|
||||||
|
@ -1294,7 +1294,7 @@ static int CmdHF14AMfRestore(const char *Cmd) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(fdump);
|
fclose(fdump);
|
||||||
PrintAndLogEx(INFO, "Finish restore");
|
PrintAndLogEx(INFO, "Done!");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5441,7 +5441,6 @@ static int CmdHf14AGen3Freeze(const char *Cmd) {
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void des_decrypt(void *out, const void *in, const void *key) {
|
static void des_decrypt(void *out, const void *in, const void *key) {
|
||||||
mbedtls_des_context ctx;
|
mbedtls_des_context ctx;
|
||||||
mbedtls_des_setkey_dec(&ctx, key);
|
mbedtls_des_setkey_dec(&ctx, key);
|
||||||
|
@ -5582,6 +5581,127 @@ static int CmdHf14AMfSuperCard(const char *Cmd) {
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int CmdHF14AMfWipe(const char *Cmd) {
|
||||||
|
CLIParserContext *ctx;
|
||||||
|
CLIParserInit(&ctx, "hf mf wipe",
|
||||||
|
"Wipe card to zeros and default keys/acc. This command taks a key file to wipe card\n"
|
||||||
|
"New A/B keys FF FF FF FF FF FF\n"
|
||||||
|
"New acc FF 07 80\n"
|
||||||
|
"New GDB 69",
|
||||||
|
"hf mf wipe"
|
||||||
|
);
|
||||||
|
void *argtable[] = {
|
||||||
|
arg_param_begin,
|
||||||
|
arg_str0("f", "file", "<fn>", "key filename"),
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
|
||||||
|
int keyfnlen = 0;
|
||||||
|
char keyFilename[FILE_PATH_SIZE] = {0};
|
||||||
|
CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)keyFilename, FILE_PATH_SIZE, &keyfnlen);
|
||||||
|
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
|
char *fptr;
|
||||||
|
if (keyfnlen == 0) {
|
||||||
|
fptr = GenerateFilename("hf-mf-", "-key.bin");
|
||||||
|
if (fptr == NULL)
|
||||||
|
return PM3_ESOFT;
|
||||||
|
|
||||||
|
strcpy(keyFilename, fptr);
|
||||||
|
free(fptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *keys;
|
||||||
|
size_t keyslen = 0;
|
||||||
|
if (loadFile_safeEx(keyFilename, ".bin", (void **)&keys, (size_t *)&keyslen, false) != PM3_SUCCESS) {
|
||||||
|
PrintAndLogEx(FAILED, "failed to load key file");
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t keyA[MIFARE_4K_MAXSECTOR * 6];
|
||||||
|
uint8_t keyB[MIFARE_4K_MAXSECTOR * 6];
|
||||||
|
uint8_t num_sectors = 0;
|
||||||
|
|
||||||
|
switch (keyslen) {
|
||||||
|
case (MIFARE_MINI_MAXSECTOR * 2 * 6): {
|
||||||
|
PrintAndLogEx(INFO, "Loaded keys matching MIFARE Classic Mini 320b");
|
||||||
|
memcpy(keyA, keys, (MIFARE_MINI_MAXSECTOR * 6));
|
||||||
|
memcpy(keyB, keys + (MIFARE_MINI_MAXSECTOR * 6), (MIFARE_MINI_MAXSECTOR * 6));
|
||||||
|
num_sectors = NumOfSectors('0');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (MIFARE_1K_MAXSECTOR * 2 * 6): {
|
||||||
|
PrintAndLogEx(INFO, "Loaded keys matching MIFARE Classic 1K");
|
||||||
|
memcpy(keyA, keys, (MIFARE_1K_MAXSECTOR * 6));
|
||||||
|
memcpy(keyB, keys + (MIFARE_1K_MAXSECTOR * 6), (MIFARE_1K_MAXSECTOR * 6));
|
||||||
|
num_sectors = NumOfSectors('1');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (MIFARE_4K_MAXSECTOR * 2 * 6): {
|
||||||
|
PrintAndLogEx(INFO, "Loaded keys matching MIFARE Classic 4K");
|
||||||
|
memcpy(keyA, keys, (MIFARE_4K_MAXSECTOR * 6));
|
||||||
|
memcpy(keyB, keys + (MIFARE_4K_MAXSECTOR * 6), (MIFARE_4K_MAXSECTOR * 6));
|
||||||
|
num_sectors = NumOfSectors('4');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
PrintAndLogEx(INFO, "wrong key file size");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t zeros[MFBLOCK_SIZE] = {0};
|
||||||
|
memset(zeros, 0x00, sizeof(zeros));
|
||||||
|
uint8_t st[MFBLOCK_SIZE] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x80, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
||||||
|
|
||||||
|
// time to wipe card
|
||||||
|
for (uint8_t s = 0; s < num_sectors; s++) {
|
||||||
|
|
||||||
|
for (uint8_t b = 0; b < NumBlocksPerSector(s); b++) {
|
||||||
|
|
||||||
|
uint8_t data[26];
|
||||||
|
memset(data, 0, sizeof(data));
|
||||||
|
if (mfIsSectorTrailer(b)) {
|
||||||
|
memcpy(data + 10, st, sizeof(st));
|
||||||
|
} else {
|
||||||
|
memcpy(data + 10, zeros, sizeof(zeros));
|
||||||
|
}
|
||||||
|
|
||||||
|
// try both A/B keys, start with B key first
|
||||||
|
for (int8_t kt = 1; kt > -1; kt--) {
|
||||||
|
|
||||||
|
if (kt == 0)
|
||||||
|
memcpy(data, keyA + (s * 6), 6);
|
||||||
|
else
|
||||||
|
memcpy(data, keyB + (s * 6), 6);
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, "Writing to block %3d: %s", FirstBlockOfSector(s) + b, sprint_hex(data + 10, MFBLOCK_SIZE));
|
||||||
|
clearCommandBuffer();
|
||||||
|
SendCommandMIX(CMD_HF_MIFARE_WRITEBL, FirstBlockOfSector(s) + b, kt, 0, data, sizeof(data));
|
||||||
|
PacketResponseNG resp;
|
||||||
|
|
||||||
|
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||||
|
uint8_t isOK = resp.oldarg[0] & 0xff;
|
||||||
|
if (isOK == 0) {
|
||||||
|
PrintAndLogEx(FAILED, "isOk: %02x", isOK);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(WARNING, "Command execute timeout");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, "Done!");
|
||||||
|
out:
|
||||||
|
free(keys);
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static command_t CommandTable[] = {
|
static command_t CommandTable[] = {
|
||||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||||
{"list", CmdHF14AMfList, AlwaysAvailable, "List MIFARE history"},
|
{"list", CmdHF14AMfList, AlwaysAvailable, "List MIFARE history"},
|
||||||
|
@ -5607,7 +5727,9 @@ static command_t CommandTable[] = {
|
||||||
{"rdsc", CmdHF14AMfRdSc, IfPm3Iso14443a, "Read MIFARE Classic sector"},
|
{"rdsc", CmdHF14AMfRdSc, IfPm3Iso14443a, "Read MIFARE Classic sector"},
|
||||||
{"restore", CmdHF14AMfRestore, IfPm3Iso14443a, "Restore MIFARE Classic binary file to BLANK tag"},
|
{"restore", CmdHF14AMfRestore, IfPm3Iso14443a, "Restore MIFARE Classic binary file to BLANK tag"},
|
||||||
{"setmod", CmdHf14AMfSetMod, IfPm3Iso14443a, "Set MIFARE Classic EV1 load modulation strength"},
|
{"setmod", CmdHf14AMfSetMod, IfPm3Iso14443a, "Set MIFARE Classic EV1 load modulation strength"},
|
||||||
|
{"wipe", CmdHF14AMfWipe, IfPm3Iso14443a, "Wipe card to zeros and default keys/acc"},
|
||||||
{"wrbl", CmdHF14AMfWrBl, IfPm3Iso14443a, "Write MIFARE Classic block"},
|
{"wrbl", CmdHF14AMfWrBl, IfPm3Iso14443a, "Write MIFARE Classic block"},
|
||||||
|
|
||||||
// {"sniff", CmdHF14AMfSniff, 0, "Sniff card-reader communication"},
|
// {"sniff", CmdHF14AMfSniff, 0, "Sniff card-reader communication"},
|
||||||
{"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("simulation") " -----------------------"},
|
{"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("simulation") " -----------------------"},
|
||||||
{"sim", CmdHF14AMfSim, IfPm3Iso14443a, "Simulate MIFARE card"},
|
{"sim", CmdHF14AMfSim, IfPm3Iso14443a, "Simulate MIFARE card"},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue