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
|
||||
* See AUTHORS file for a more comprehensive list of contributors.
|
||||
* 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
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
|
@ -68,6 +68,7 @@ static bool bUseKeyA;
|
|||
static bool bUseKeyFile;
|
||||
static bool bForceKeyFile;
|
||||
static bool bTolerateFailures;
|
||||
static bool bFormatCard;
|
||||
static bool magic2 = false;
|
||||
static uint8_t uiBlocks;
|
||||
static uint8_t keys[] = {
|
||||
|
@ -81,6 +82,8 @@ static uint8_t keys[] = {
|
|||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
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 = {
|
||||
.nmt = NMT_ISO14443A,
|
||||
|
@ -204,8 +207,10 @@ authenticate(uint32_t uiBlock)
|
|||
// Try to authenticate for the current sector
|
||||
if (nfc_initiator_mifare_cmd(pnd, mc, uiBlock, &mp))
|
||||
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++) {
|
||||
memcpy(mp.mpa.abtKey, keys + (key_index * 6), 6);
|
||||
if (nfc_initiator_mifare_cmd(pnd, mc, uiBlock, &mp)) {
|
||||
|
@ -407,10 +412,17 @@ write_card(int write_block_zero)
|
|||
}
|
||||
|
||||
if (is_trailer_block(uiBlock)) {
|
||||
// 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 + 6, mtDump.amb[uiBlock].mbt.abtAccessBits, 4);
|
||||
memcpy(mp.mpd.abtData + 10, mtDump.amb[uiBlock].mbt.abtKeyB, 6);
|
||||
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
|
||||
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 + 10, mtDump.amb[uiBlock].mbt.abtKeyB, 6);
|
||||
}
|
||||
|
||||
// Try to write the trailer
|
||||
if (nfc_initiator_mifare_cmd(pnd, MC_WRITE, uiBlock, &mp) == false) {
|
||||
|
@ -426,7 +438,10 @@ write_card(int write_block_zero)
|
|||
// Make sure a earlier write did not fail
|
||||
if (!bFailure) {
|
||||
// Try to write the data block
|
||||
memcpy(mp.mpd.abtData, mtDump.amb[uiBlock].mbd.abtData, 16);
|
||||
if(bFormatCard && uiBlock)
|
||||
memset(mp.mpd.abtData, 0x00, 16);
|
||||
else
|
||||
memcpy(mp.mpd.abtData, mtDump.amb[uiBlock].mbd.abtData, 16);
|
||||
// do not write a block 0 with incorrect BCC - card will be made invalid!
|
||||
if (uiBlock == 0) {
|
||||
if ((mp.mpd.abtData[0] ^ mp.mpd.abtData[1] ^ mp.mpd.abtData[2] ^ mp.mpd.abtData[3] ^ mp.mpd.abtData[4]) != 0x00 && !magic2) {
|
||||
|
@ -462,14 +477,25 @@ print_usage(const char *pcProgramName)
|
|||
{
|
||||
printf("Usage: ");
|
||||
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(" *** note that unlocked write will attempt to overwrite block 0 including UID\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(" *** 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(" *** 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(" 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(" <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("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
|
||||
|
@ -497,7 +523,7 @@ main(int argc, const char *argv[])
|
|||
bTolerateFailures = tolower((int)((unsigned char) * (argv[2]))) != (int)((unsigned char) * (argv[2]));
|
||||
bUseKeyFile = (argc > 4);
|
||||
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) {
|
||||
print_usage(argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
|
@ -505,6 +531,8 @@ main(int argc, const char *argv[])
|
|||
atAction = ACTION_WRITE;
|
||||
if (strcmp(command, "W") == 0)
|
||||
unlock = 1;
|
||||
if (strcmp(command, "f") == 0)
|
||||
bFormatCard = 1;
|
||||
bUseKeyA = tolower((int)((unsigned char) * (argv[2]))) == 'a';
|
||||
bTolerateFailures = tolower((int)((unsigned char) * (argv[2]))) != (int)((unsigned char) * (argv[2]));
|
||||
bUseKeyFile = (argc > 4);
|
||||
|
|
Loading…
Add table
Reference in a new issue