Merge pull request #18 from AdamLaurie/master
Don't bother cracking KeyB when you can just read it out of data block
This commit is contained in:
commit
f3a793dc0c
1 changed files with 88 additions and 5 deletions
89
src/mfoc.c
89
src/mfoc.c
|
@ -108,7 +108,7 @@ int main(int argc, char *const argv[])
|
||||||
// Pointer to already broken keys, except defaults
|
// Pointer to already broken keys, except defaults
|
||||||
bKeys *bk;
|
bKeys *bk;
|
||||||
|
|
||||||
static mifare_param mp;
|
static mifare_param mp, mtmp;
|
||||||
static mifare_classic_tag mtDump;
|
static mifare_classic_tag mtDump;
|
||||||
|
|
||||||
mifare_cmd mc;
|
mifare_cmd mc;
|
||||||
|
@ -310,8 +310,39 @@ int main(int argc, char *const argv[])
|
||||||
// Save all information about successfull keyA authentization
|
// Save all information about successfull keyA authentization
|
||||||
memcpy(t.sectors[i].KeyA, mp.mpa.abtKey, sizeof(mp.mpa.abtKey));
|
memcpy(t.sectors[i].KeyA, mp.mpa.abtKey, sizeof(mp.mpa.abtKey));
|
||||||
t.sectors[i].foundKeyA = true;
|
t.sectors[i].foundKeyA = true;
|
||||||
|
// Although KeyA can never be directly read from the data sector, KeyB can, so
|
||||||
|
// if we need KeyB for this sector, it should be revealed by a data read with KeyA
|
||||||
|
// todo - check for duplicates in cracked key list (do we care? will not be huge overhead)
|
||||||
|
// todo - make code more modular! :)
|
||||||
|
if (!t.sectors[i].foundKeyB) {
|
||||||
|
if ((res = nfc_initiator_mifare_cmd(r.pdi, MC_READ, block, &mtmp)) >= 0) {
|
||||||
|
// print only for debugging as it messes up output!
|
||||||
|
//fprintf(stdout, " Data read with Key A revealed Key B: [%012llx] - checking Auth: ", bytes_to_num(mtmp.mpd.abtData + 10, sizeof(mtmp.mpa.abtKey)));
|
||||||
|
memcpy(mtmp.mpa.abtKey, mtmp.mpd.abtData + 10, sizeof(mtmp.mpa.abtKey));
|
||||||
|
memcpy(mtmp.mpa.abtAuthUid, t.nt.nti.nai.abtUid + t.nt.nti.nai.szUidLen - 4, sizeof(mtmp.mpa.abtAuthUid));
|
||||||
|
if ((res = nfc_initiator_mifare_cmd(r.pdi, MC_AUTH_B, block, &mtmp)) < 0) {
|
||||||
|
//fprintf(stdout, "Failed!\n");
|
||||||
|
mf_configure(r.pdi);
|
||||||
|
mf_anticollision(t, r);
|
||||||
|
} else {
|
||||||
|
//fprintf(stdout, "OK\n");
|
||||||
|
memcpy(t.sectors[i].KeyB, mtmp.mpd.abtData + 10, sizeof(t.sectors[i].KeyB));
|
||||||
|
t.sectors[i].foundKeyB = true;
|
||||||
|
bk->size++;
|
||||||
|
bk->brokenKeys = (uint64_t *) realloc((void *)bk->brokenKeys, bk->size * sizeof(uint64_t));
|
||||||
|
bk->brokenKeys[bk->size - 1] = bytes_to_num(mtmp.mpa.abtKey, sizeof(mtmp.mpa.abtKey));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (res != NFC_ERFTRANS) {
|
||||||
|
nfc_perror(r.pdi, "nfc_initiator_mifare_cmd");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
mf_anticollision(t, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if key reveal failed, try other keys
|
||||||
if (!t.sectors[i].foundKeyB) {
|
if (!t.sectors[i].foundKeyB) {
|
||||||
mc = MC_AUTH_B;
|
mc = MC_AUTH_B;
|
||||||
int res;
|
int res;
|
||||||
|
@ -378,14 +409,40 @@ int main(int argc, char *const argv[])
|
||||||
mf_anticollision(t, r);
|
mf_anticollision(t, r);
|
||||||
} else {
|
} else {
|
||||||
// Save all information about successfull authentization
|
// Save all information about successfull authentization
|
||||||
|
printf("Sector: %d, type %c\n", j, (dumpKeysA ? 'A' : 'B'));
|
||||||
if (dumpKeysA) {
|
if (dumpKeysA) {
|
||||||
memcpy(t.sectors[j].KeyA, mp.mpa.abtKey, sizeof(mp.mpa.abtKey));
|
memcpy(t.sectors[j].KeyA, mp.mpa.abtKey, sizeof(mp.mpa.abtKey));
|
||||||
t.sectors[j].foundKeyA = true;
|
t.sectors[j].foundKeyA = true;
|
||||||
|
// if we need KeyB for this sector it should be revealed by a data read with KeyA
|
||||||
|
if (!t.sectors[j].foundKeyB) {
|
||||||
|
if ((res = nfc_initiator_mifare_cmd(r.pdi, MC_READ, t.sectors[j].trailer, &mtmp)) >= 0) {
|
||||||
|
fprintf(stdout, " Data read with Key A revealed Key B: [%012llx] - checking Auth: ", bytes_to_num(mtmp.mpd.abtData + 10, sizeof(mtmp.mpa.abtKey)));
|
||||||
|
memcpy(mtmp.mpa.abtKey, mtmp.mpd.abtData + 10, sizeof(mtmp.mpa.abtKey));
|
||||||
|
memcpy(mtmp.mpa.abtAuthUid, t.nt.nti.nai.abtUid + t.nt.nti.nai.szUidLen - 4, sizeof(mtmp.mpa.abtAuthUid));
|
||||||
|
if ((res = nfc_initiator_mifare_cmd(r.pdi, MC_AUTH_B, t.sectors[j].trailer, &mtmp)) < 0) {
|
||||||
|
fprintf(stdout, "Failed!\n");
|
||||||
|
mf_configure(r.pdi);
|
||||||
|
mf_anticollision(t, r);
|
||||||
|
} else {
|
||||||
|
fprintf(stdout, "OK\n");
|
||||||
|
memcpy(t.sectors[j].KeyB, mtmp.mpd.abtData + 10, sizeof(t.sectors[j].KeyB));
|
||||||
|
t.sectors[j].foundKeyB = true;
|
||||||
|
bk->size++;
|
||||||
|
bk->brokenKeys = (uint64_t *) realloc((void *)bk->brokenKeys, bk->size * sizeof(uint64_t));
|
||||||
|
bk->brokenKeys[bk->size - 1] = bytes_to_num(mtmp.mpa.abtKey, sizeof(mtmp.mpa.abtKey));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (res != NFC_ERFTRANS) {
|
||||||
|
nfc_perror(r.pdi, "nfc_initiator_mifare_cmd");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
mf_anticollision(t, r);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
memcpy(t.sectors[j].KeyB, mp.mpa.abtKey, sizeof(mp.mpa.abtKey));
|
memcpy(t.sectors[j].KeyB, mp.mpa.abtKey, sizeof(mp.mpa.abtKey));
|
||||||
t.sectors[j].foundKeyB = true;
|
t.sectors[j].foundKeyB = true;
|
||||||
}
|
}
|
||||||
printf("Sector: %d, type %c\n", j, (dumpKeysA ? 'A' : 'B'));
|
|
||||||
fprintf(stdout, " Found Key: %c [%012llx]\n", (dumpKeysA ? 'A' : 'B'),
|
fprintf(stdout, " Found Key: %c [%012llx]\n", (dumpKeysA ? 'A' : 'B'),
|
||||||
bytes_to_num(mp.mpa.abtKey, 6));
|
bytes_to_num(mp.mpa.abtKey, 6));
|
||||||
mf_configure(r.pdi);
|
mf_configure(r.pdi);
|
||||||
|
@ -438,7 +495,7 @@ int main(int argc, char *const argv[])
|
||||||
// Save all information about successfull authentization
|
// Save all information about successfull authentization
|
||||||
bk->size++;
|
bk->size++;
|
||||||
bk->brokenKeys = (uint64_t *) realloc((void *)bk->brokenKeys, bk->size * sizeof(uint64_t));
|
bk->brokenKeys = (uint64_t *) realloc((void *)bk->brokenKeys, bk->size * sizeof(uint64_t));
|
||||||
bk->brokenKeys[bk->size - 1] = bytes_to_num(mp.mpa.abtKey, 6);
|
bk->brokenKeys[bk->size - 1] = bytes_to_num(mp.mpa.abtKey, sizeof(mp.mpa.abtKey));
|
||||||
if (dumpKeysA) {
|
if (dumpKeysA) {
|
||||||
memcpy(t.sectors[j].KeyA, mp.mpa.abtKey, sizeof(mp.mpa.abtKey));
|
memcpy(t.sectors[j].KeyA, mp.mpa.abtKey, sizeof(mp.mpa.abtKey));
|
||||||
t.sectors[j].foundKeyA = true;
|
t.sectors[j].foundKeyA = true;
|
||||||
|
@ -449,6 +506,32 @@ int main(int argc, char *const argv[])
|
||||||
}
|
}
|
||||||
fprintf(stdout, " Found Key: %c [%012llx]\n", (dumpKeysA ? 'A' : 'B'),
|
fprintf(stdout, " Found Key: %c [%012llx]\n", (dumpKeysA ? 'A' : 'B'),
|
||||||
bytes_to_num(mp.mpa.abtKey, 6));
|
bytes_to_num(mp.mpa.abtKey, 6));
|
||||||
|
// if we need KeyB for this sector, it should be revealed by a data read with KeyA
|
||||||
|
if (!t.sectors[j].foundKeyB) {
|
||||||
|
if ((res = nfc_initiator_mifare_cmd(r.pdi, MC_READ, t.sectors[j].trailer, &mtmp)) >= 0) {
|
||||||
|
fprintf(stdout, " Data read with Key A revealed Key B: [%012llx] - checking Auth: ", bytes_to_num(mtmp.mpd.abtData + 10, sizeof(mtmp.mpa.abtKey)));
|
||||||
|
memcpy(mtmp.mpa.abtKey, mtmp.mpd.abtData + 10, sizeof(mtmp.mpa.abtKey));
|
||||||
|
memcpy(mtmp.mpa.abtAuthUid, t.nt.nti.nai.abtUid + t.nt.nti.nai.szUidLen - 4, sizeof(mtmp.mpa.abtAuthUid));
|
||||||
|
if ((res = nfc_initiator_mifare_cmd(r.pdi, MC_AUTH_B, t.sectors[j].trailer, &mtmp)) < 0) {
|
||||||
|
fprintf(stdout, "Failed!\n");
|
||||||
|
mf_configure(r.pdi);
|
||||||
|
mf_anticollision(t, r);
|
||||||
|
} else {
|
||||||
|
fprintf(stdout, "OK\n");
|
||||||
|
memcpy(t.sectors[j].KeyB, mtmp.mpd.abtData + 10, sizeof(t.sectors[j].KeyB));
|
||||||
|
t.sectors[j].foundKeyB = true;
|
||||||
|
bk->size++;
|
||||||
|
bk->brokenKeys = (uint64_t *) realloc((void *)bk->brokenKeys, bk->size * sizeof(uint64_t));
|
||||||
|
bk->brokenKeys[bk->size - 1] = bytes_to_num(mtmp.mpa.abtKey, sizeof(mtmp.mpa.abtKey));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (res != NFC_ERFTRANS) {
|
||||||
|
nfc_perror(r.pdi, "nfc_initiator_mifare_cmd");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
mf_anticollision(t, r);
|
||||||
|
}
|
||||||
|
}
|
||||||
mf_configure(r.pdi);
|
mf_configure(r.pdi);
|
||||||
mf_anticollision(t, r);
|
mf_anticollision(t, r);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue