add format/wipe command to nfc-mfclassic
This commit is contained in:
parent
7e5257dd44
commit
250068462b
1 changed files with 39 additions and 11 deletions
|
@ -9,7 +9,7 @@
|
||||||
* Copyright (C) 2012-2013 Ludovic Rousseau
|
* Copyright (C) 2012-2013 Ludovic Rousseau
|
||||||
* See AUTHORS file for a more comprehensive list of contributors.
|
* See AUTHORS file for a more comprehensive list of contributors.
|
||||||
* Additional contributors of this file:
|
* Additional contributors of this file:
|
||||||
* Copyright (C) 2011 Adam Laurie
|
* Copyright (C) 2011-2013 Adam Laurie
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
@ -68,6 +68,7 @@ static bool bUseKeyA;
|
||||||
static bool bUseKeyFile;
|
static bool bUseKeyFile;
|
||||||
static bool bForceKeyFile;
|
static bool bForceKeyFile;
|
||||||
static bool bTolerateFailures;
|
static bool bTolerateFailures;
|
||||||
|
static bool bFormatCard;
|
||||||
static bool magic2 = false;
|
static bool magic2 = false;
|
||||||
static uint8_t uiBlocks;
|
static uint8_t uiBlocks;
|
||||||
static uint8_t keys[] = {
|
static uint8_t keys[] = {
|
||||||
|
@ -81,6 +82,8 @@ static uint8_t keys[] = {
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0xab, 0xcd, 0xef, 0x12, 0x34, 0x56
|
0xab, 0xcd, 0xef, 0x12, 0x34, 0x56
|
||||||
};
|
};
|
||||||
|
static uint8_t default_key[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||||
|
static uint8_t default_acl[] = {0xff, 0x07, 0x80, 0x69};
|
||||||
|
|
||||||
static const nfc_modulation nmMifare = {
|
static const nfc_modulation nmMifare = {
|
||||||
.nmt = NMT_ISO14443A,
|
.nmt = NMT_ISO14443A,
|
||||||
|
@ -204,8 +207,10 @@ authenticate(uint32_t uiBlock)
|
||||||
// Try to authenticate for the current sector
|
// Try to authenticate for the current sector
|
||||||
if (nfc_initiator_mifare_cmd(pnd, mc, uiBlock, &mp))
|
if (nfc_initiator_mifare_cmd(pnd, mc, uiBlock, &mp))
|
||||||
return true;
|
return true;
|
||||||
} else {
|
}
|
||||||
// Try to guess the right key
|
|
||||||
|
// If formatting or not using key file, try to guess the right key
|
||||||
|
if (bFormatCard || !bUseKeyFile) {
|
||||||
for (size_t key_index = 0; key_index < num_keys; key_index++) {
|
for (size_t key_index = 0; key_index < num_keys; key_index++) {
|
||||||
memcpy(mp.mpa.abtKey, keys + (key_index * 6), 6);
|
memcpy(mp.mpa.abtKey, keys + (key_index * 6), 6);
|
||||||
if (nfc_initiator_mifare_cmd(pnd, mc, uiBlock, &mp)) {
|
if (nfc_initiator_mifare_cmd(pnd, mc, uiBlock, &mp)) {
|
||||||
|
@ -407,10 +412,17 @@ write_card(int write_block_zero)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_trailer_block(uiBlock)) {
|
if (is_trailer_block(uiBlock)) {
|
||||||
|
if (bFormatCard) {
|
||||||
|
// Copy the default key and reset the access bits
|
||||||
|
memcpy(mp.mpd.abtData, default_key, 6);
|
||||||
|
memcpy(mp.mpd.abtData + 6, default_acl, 4);
|
||||||
|
memcpy(mp.mpd.abtData + 10, default_key, 6);
|
||||||
|
} else {
|
||||||
// Copy the keys over from our key dump and store the retrieved access bits
|
// Copy the keys over from our key dump and store the retrieved access bits
|
||||||
memcpy(mp.mpd.abtData, mtDump.amb[uiBlock].mbt.abtKeyA, 6);
|
memcpy(mp.mpd.abtData, mtDump.amb[uiBlock].mbt.abtKeyA, 6);
|
||||||
memcpy(mp.mpd.abtData + 6, mtDump.amb[uiBlock].mbt.abtAccessBits, 4);
|
memcpy(mp.mpd.abtData + 6, mtDump.amb[uiBlock].mbt.abtAccessBits, 4);
|
||||||
memcpy(mp.mpd.abtData + 10, mtDump.amb[uiBlock].mbt.abtKeyB, 6);
|
memcpy(mp.mpd.abtData + 10, mtDump.amb[uiBlock].mbt.abtKeyB, 6);
|
||||||
|
}
|
||||||
|
|
||||||
// Try to write the trailer
|
// Try to write the trailer
|
||||||
if (nfc_initiator_mifare_cmd(pnd, MC_WRITE, uiBlock, &mp) == false) {
|
if (nfc_initiator_mifare_cmd(pnd, MC_WRITE, uiBlock, &mp) == false) {
|
||||||
|
@ -426,6 +438,9 @@ write_card(int write_block_zero)
|
||||||
// Make sure a earlier write did not fail
|
// Make sure a earlier write did not fail
|
||||||
if (!bFailure) {
|
if (!bFailure) {
|
||||||
// Try to write the data block
|
// Try to write the data block
|
||||||
|
if(bFormatCard && uiBlock)
|
||||||
|
memset(mp.mpd.abtData, 0x00, 16);
|
||||||
|
else
|
||||||
memcpy(mp.mpd.abtData, mtDump.amb[uiBlock].mbd.abtData, 16);
|
memcpy(mp.mpd.abtData, mtDump.amb[uiBlock].mbd.abtData, 16);
|
||||||
// do not write a block 0 with incorrect BCC - card will be made invalid!
|
// do not write a block 0 with incorrect BCC - card will be made invalid!
|
||||||
if (uiBlock == 0) {
|
if (uiBlock == 0) {
|
||||||
|
@ -462,14 +477,25 @@ print_usage(const char *pcProgramName)
|
||||||
{
|
{
|
||||||
printf("Usage: ");
|
printf("Usage: ");
|
||||||
printf("%s r|R|w|W a|b <dump.mfd> [<keys.mfd> [f]]\n", pcProgramName);
|
printf("%s r|R|w|W a|b <dump.mfd> [<keys.mfd> [f]]\n", pcProgramName);
|
||||||
printf(" r|R|w|W - Perform read from (r) or unlocked read from (R) or write to (w) or unlocked write to (W) card\n");
|
printf(" f|r|R|w|W - Perform format (f) or read from (r) or unlocked read from (R) or write to (w) or unlocked write to (W) card\n");
|
||||||
printf(" *** note that unlocked write will attempt to overwrite block 0 including UID\n");
|
printf(" *** format will reset all keys to FFFFFFFFFFFF and all data to 00 and all ACLs to default\n");
|
||||||
printf(" *** unlocked read does not require authentication and will reveal A and B keys\n");
|
printf(" *** unlocked read does not require authentication and will reveal A and B keys\n");
|
||||||
|
printf(" *** note that unlocked write will attempt to overwrite block 0 including UID\n");
|
||||||
printf(" *** unlocking only works with special Mifare 1K cards (Chinese clones)\n");
|
printf(" *** unlocking only works with special Mifare 1K cards (Chinese clones)\n");
|
||||||
printf(" a|A|b|B - Use A or B keys for action; Halt on errors (a|b) or tolerate errors (A|B)\n");
|
printf(" a|A|b|B - Use A or B keys for action; Halt on errors (a|b) or tolerate errors (A|B)\n");
|
||||||
printf(" <dump.mfd> - MiFare Dump (MFD) used to write (card to MFD) or (MFD to card)\n");
|
printf(" <dump.mfd> - MiFare Dump (MFD) used to write (card to MFD) or (MFD to card)\n");
|
||||||
printf(" <keys.mfd> - MiFare Dump (MFD) that contain the keys (optional)\n");
|
printf(" <keys.mfd> - MiFare Dump (MFD) that contain the keys (optional)\n");
|
||||||
printf(" f - Force using the keyfile even if UID does not match (optional)\n");
|
printf(" f - Force using the keyfile even if UID does not match (optional)\n");
|
||||||
|
printf("Examples: \n\n");
|
||||||
|
printf(" Read card to file, using key A:\n\n");
|
||||||
|
printf(" %s r a mycard.mfd\n\n", pcProgramName);
|
||||||
|
printf(" Write file to blank card, using key A:\n\n");
|
||||||
|
printf(" %s w a mycard.mfd\n\n", pcProgramName);
|
||||||
|
printf(" Write new data and/or keys to previously written card, using key A:\n\n");
|
||||||
|
printf(" %s w a newdata.mfd mycard.mfd\n\n", pcProgramName);
|
||||||
|
printf(" Format/wipe card (note two passes required to ensure writes for all ACL cases):\n\n");
|
||||||
|
printf(" %s f A dummy.mfd keyfile.mfd f\n", pcProgramName);
|
||||||
|
printf(" %s f B dummy.mfd keyfile.mfd f\n\n", pcProgramName);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -497,7 +523,7 @@ main(int argc, const char *argv[])
|
||||||
bTolerateFailures = tolower((int)((unsigned char) * (argv[2]))) != (int)((unsigned char) * (argv[2]));
|
bTolerateFailures = tolower((int)((unsigned char) * (argv[2]))) != (int)((unsigned char) * (argv[2]));
|
||||||
bUseKeyFile = (argc > 4);
|
bUseKeyFile = (argc > 4);
|
||||||
bForceKeyFile = ((argc > 5) && (strcmp((char *)argv[5], "f") == 0));
|
bForceKeyFile = ((argc > 5) && (strcmp((char *)argv[5], "f") == 0));
|
||||||
} else if (strcmp(command, "w") == 0 || strcmp(command, "W") == 0) {
|
} else if (strcmp(command, "w") == 0 || strcmp(command, "W") == 0 || strcmp(command, "f") == 0) {
|
||||||
if (argc < 4) {
|
if (argc < 4) {
|
||||||
print_usage(argv[0]);
|
print_usage(argv[0]);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
@ -505,6 +531,8 @@ main(int argc, const char *argv[])
|
||||||
atAction = ACTION_WRITE;
|
atAction = ACTION_WRITE;
|
||||||
if (strcmp(command, "W") == 0)
|
if (strcmp(command, "W") == 0)
|
||||||
unlock = 1;
|
unlock = 1;
|
||||||
|
if (strcmp(command, "f") == 0)
|
||||||
|
bFormatCard = 1;
|
||||||
bUseKeyA = tolower((int)((unsigned char) * (argv[2]))) == 'a';
|
bUseKeyA = tolower((int)((unsigned char) * (argv[2]))) == 'a';
|
||||||
bTolerateFailures = tolower((int)((unsigned char) * (argv[2]))) != (int)((unsigned char) * (argv[2]));
|
bTolerateFailures = tolower((int)((unsigned char) * (argv[2]))) != (int)((unsigned char) * (argv[2]));
|
||||||
bUseKeyFile = (argc > 4);
|
bUseKeyFile = (argc > 4);
|
||||||
|
|
Loading…
Add table
Reference in a new issue