chg: mad makeover

This commit is contained in:
iceman1001 2020-06-09 08:51:12 +02:00
parent 147be1765c
commit a0cbaee138
3 changed files with 89 additions and 78 deletions

View file

@ -4496,7 +4496,7 @@ static int CmdHF14AMfMAD(const char *Cmd) {
void *argtable[] = { void *argtable[] = {
arg_param_begin, arg_param_begin,
arg_lit0("vV", "verbose", "show technical data"), arg_lit0("vV", "verbose", "show technical data"),
arg_str0("aA", "aid", "print all sectors with aid", NULL), arg_str0("aA", "aid", "print all sectors with specified aid", NULL),
arg_str0("kK", "key", "key for printing sectors", NULL), arg_str0("kK", "key", "key for printing sectors", NULL),
arg_lit0("bB", "keyb", "use key B for access printing sectors (by default: key A)"), arg_lit0("bB", "keyb", "use key B for access printing sectors (by default: key A)"),
arg_param_end arg_param_end
@ -4543,7 +4543,7 @@ static int CmdHF14AMfMAD(const char *Cmd) {
if (aidlen == 2) { if (aidlen == 2) {
uint16_t aaid = (aid[0] << 8) + aid[1]; uint16_t aaid = (aid[0] << 8) + aid[1];
PrintAndLogEx(NORMAL, "\n-------------- AID 0x%04x ---------------", aaid); PrintAndLogEx(INFO, "-------------- " _CYAN_("AID 0x%04x") " ---------------", aaid);
uint16_t mad[7 + 8 + 8 + 8 + 8] = {0}; uint16_t mad[7 + 8 + 8 + 8 + 8] = {0};
size_t madlen = 0; size_t madlen = 0;
@ -4621,58 +4621,57 @@ static int CmdHFMFNDEF(const char *Cmd) {
uint8_t data[4096] = {0}; uint8_t data[4096] = {0};
int datalen = 0; int datalen = 0;
PrintAndLogEx(NORMAL, "");
if (mfReadSector(MF_MAD1_SECTOR, MF_KEY_A, (uint8_t *)g_mifare_mad_key, sector0)) { if (mfReadSector(MF_MAD1_SECTOR, MF_KEY_A, (uint8_t *)g_mifare_mad_key, sector0)) {
PrintAndLogEx(ERR, "read sector 0 error. card don't have MAD or don't have MAD on default keys."); PrintAndLogEx(ERR, "error, read sector 0. card don't have MAD or don't have MAD on default keys");
return PM3_ESOFT; return PM3_ESOFT;
} }
bool haveMAD2 = false; bool haveMAD2 = false;
int res = MADCheck(sector0, NULL, verbose, &haveMAD2); int res = MADCheck(sector0, NULL, verbose, &haveMAD2);
if (res) { if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "MAD error %d.", res); PrintAndLogEx(ERR, "MAD error %d", res);
return res; return res;
} }
if (haveMAD2) { if (haveMAD2) {
if (mfReadSector(MF_MAD2_SECTOR, MF_KEY_A, (uint8_t *)g_mifare_mad_key, sector10)) { if (mfReadSector(MF_MAD2_SECTOR, MF_KEY_A, (uint8_t *)g_mifare_mad_key, sector10)) {
PrintAndLogEx(ERR, "read sector 0x10 error. card don't have MAD or don't have MAD on default keys."); PrintAndLogEx(ERR, "error, read sector 0x10. card don't have MAD or don't have MAD on default keys");
return PM3_ESOFT; return PM3_ESOFT;
} }
} }
uint16_t mad[7 + 8 + 8 + 8 + 8] = {0}; uint16_t mad[7 + 8 + 8 + 8 + 8] = {0};
size_t madlen = 0; size_t madlen = 0;
if (MADDecode(sector0, (haveMAD2 ? sector10 : NULL), mad, &madlen)) { res = MADDecode(sector0, (haveMAD2 ? sector10 : NULL), mad, &madlen);
PrintAndLogEx(ERR, "can't decode mad."); if (res != PM3_SUCCESS) {
return PM3_ESOFT; PrintAndLogEx(ERR, "can't decode MAD");
return res;
} }
printf("data reading:"); PrintAndLogEx(INFO, "data reading:");
for (int i = 0; i < madlen; i++) { for (int i = 0; i < madlen; i++) {
if (ndefAID == mad[i]) { if (ndefAID == mad[i]) {
uint8_t vsector[16 * 4] = {0}; uint8_t vsector[16 * 4] = {0};
if (mfReadSector(i + 1, keyB ? MF_KEY_B : MF_KEY_A, ndefkey, vsector)) { if (mfReadSector(i + 1, keyB ? MF_KEY_B : MF_KEY_A, ndefkey, vsector)) {
PrintAndLogEx(ERR, "read sector %d error.", i + 1); PrintAndLogEx(ERR, "error, reading sector %d ", i + 1);
return PM3_ESOFT; return PM3_ESOFT;
} }
memcpy(&data[datalen], vsector, 16 * 3); memcpy(&data[datalen], vsector, 16 * 3);
datalen += 16 * 3; datalen += 16 * 3;
printf("."); PrintAndLogEx(INPLACE, ".");
} }
} }
printf(" OK\n"); PrintAndLogEx(NORMAL, "");
if (!datalen) { if (!datalen) {
PrintAndLogEx(ERR, "no NDEF data."); PrintAndLogEx(WARNING, "no NDEF data");
return PM3_SUCCESS; return PM3_SUCCESS;
} }
if (verbose2) { if (verbose2) {
PrintAndLogEx(NORMAL, "NDEF data:"); PrintAndLogEx(SUCCESS, "NDEF data:");
dump_buffer(data, datalen, stdout, 1); dump_buffer(data, datalen, stdout, 1);
} }

View file

@ -1423,63 +1423,61 @@ static int CmdHFMFPNDEF(const char *Cmd) {
uint8_t data[4096] = {0}; uint8_t data[4096] = {0};
int datalen = 0; int datalen = 0;
PrintAndLogEx(NORMAL, "");
if (mfpReadSector(MF_MAD1_SECTOR, MF_KEY_A, (uint8_t *)g_mifarep_mad_key, sector0, verbose)) { if (mfpReadSector(MF_MAD1_SECTOR, MF_KEY_A, (uint8_t *)g_mifarep_mad_key, sector0, verbose)) {
PrintAndLogEx(ERR, "read sector 0 error. card don't have MAD or don't have MAD on default keys."); PrintAndLogEx(ERR, "error, read sector 0. card don't have MAD or don't have MAD on default keys");
return 2; return PM3_ESOFT;
} }
bool haveMAD2 = false; bool haveMAD2 = false;
int res = MADCheck(sector0, NULL, verbose, &haveMAD2); int res = MADCheck(sector0, NULL, verbose, &haveMAD2);
if (res) { if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "MAD error %d.", res); PrintAndLogEx(ERR, "MAD error %d", res);
return res; return res;
} }
if (haveMAD2) { if (haveMAD2) {
if (mfpReadSector(MF_MAD2_SECTOR, MF_KEY_A, (uint8_t *)g_mifarep_mad_key, sector10, verbose)) { if (mfpReadSector(MF_MAD2_SECTOR, MF_KEY_A, (uint8_t *)g_mifarep_mad_key, sector10, verbose)) {
PrintAndLogEx(ERR, "read sector 0x10 error. card don't have MAD or don't have MAD on default keys."); PrintAndLogEx(ERR, "error, read sector 0x10. card don't have MAD or don't have MAD on default keys");
return 2; return PM3_ESOFT;
} }
} }
uint16_t mad[7 + 8 + 8 + 8 + 8] = {0}; uint16_t mad[7 + 8 + 8 + 8 + 8] = {0};
size_t madlen = 0; size_t madlen = 0;
if (MADDecode(sector0, (haveMAD2 ? sector10 : NULL), mad, &madlen)) { res = MADDecode(sector0, (haveMAD2 ? sector10 : NULL), mad, &madlen);
PrintAndLogEx(ERR, "can't decode mad."); if (res != PM3_SUCCESS) {
return 10; PrintAndLogEx(ERR, "can't decode MAD");
return res;
} }
printf("data reading:"); PrintAndLogEx(INFO, "data reading:");
for (int i = 0; i < madlen; i++) { for (int i = 0; i < madlen; i++) {
if (ndefAID == mad[i]) { if (ndefAID == mad[i]) {
uint8_t vsector[16 * 4] = {0}; uint8_t vsector[16 * 4] = {0};
if (mfpReadSector(i + 1, keyB ? MF_KEY_B : MF_KEY_A, ndefkey, vsector, false)) { if (mfpReadSector(i + 1, keyB ? MF_KEY_B : MF_KEY_A, ndefkey, vsector, false)) {
PrintAndLogEx(ERR, "read sector %d error.", i + 1); PrintAndLogEx(ERR, "error, reading sector %d", i + 1);
return 2; return PM3_ESOFT;
} }
memcpy(&data[datalen], vsector, 16 * 3); memcpy(&data[datalen], vsector, 16 * 3);
datalen += 16 * 3; datalen += 16 * 3;
printf("."); PrintAndLogEx(INPLACE, ".");
} }
} }
printf(" OK\n"); PrintAndLogEx(NORMAL, "");
if (!datalen) { if (!datalen) {
PrintAndLogEx(ERR, "no NDEF data."); PrintAndLogEx(ERR, "no NDEF data");
return 11; return PM3_SUCCESS;
} }
if (verbose2) { if (verbose2) {
PrintAndLogEx(NORMAL, "NDEF data:"); PrintAndLogEx(INFO, "NDEF data:");
dump_buffer(data, datalen, stdout, 1); dump_buffer(data, datalen, stdout, 1);
} }
NDEFDecodeAndPrint(data, datalen, verbose); NDEFDecodeAndPrint(data, datalen, verbose);
return PM3_SUCCESS; return PM3_SUCCESS;
} }

View file

@ -11,7 +11,7 @@
#include "mad.h" #include "mad.h"
#include "ui.h" #include "ui.h"
#include "commonutil.h" // ARRAYLEN #include "commonutil.h" // ARRAYLEN
#include "pm3_cmd.h"
#include "crc.h" #include "crc.h"
#include "util.h" #include "util.h"
@ -110,21 +110,20 @@ static const char *GetAIDDescription(uint16_t AID) {
} }
static int madCRCCheck(uint8_t *sector, bool verbose, int MADver) { static int madCRCCheck(uint8_t *sector, bool verbose, int MADver) {
if (MADver == 1) { if (MADver == 2) {
uint8_t crc = CRC8Mad(&sector[16 + 1], 15 + 16); uint8_t crc = CRC8Mad(&sector[16 + 1], 15 + 16);
if (crc != sector[16]) { if (crc != sector[16]) {
PrintAndLogEx(WARNING, "Wrong MAD%d CRC. Calculated: 0x%02x, from card: 0x%02x", MADver, crc, sector[16]); PrintAndLogEx(WARNING, _RED_("Wrong MAD %d CRC") " calculated: 0x%02x != 0x%02x", MADver, crc, sector[16]);
return 3; return PM3_ESOFT;
}; };
} else { } else {
uint8_t crc = CRC8Mad(&sector[1], 15 + 16 + 16); uint8_t crc = CRC8Mad(&sector[1], 15 + 16 + 16);
if (crc != sector[0]) { if (crc != sector[0]) {
PrintAndLogEx(WARNING, "Wrong MAD%d CRC. Calculated: 0x%02x, from card: 0x%02x", MADver, crc, sector[16]); PrintAndLogEx(WARNING, _RED_("Wrong MAD %d CRC") " calculated: 0x%02x != 0x%02x", MADver, crc, sector[16]);
return 3; return PM3_ESOFT;
}; };
} }
return PM3_SUCCESS;
return 0;
} }
static uint16_t madGetAID(uint8_t *sector, int MADver, int sectorNo) { static uint16_t madGetAID(uint8_t *sector, int MADver, int sectorNo) {
@ -135,54 +134,53 @@ static uint16_t madGetAID(uint8_t *sector, int MADver, int sectorNo) {
} }
int MADCheck(uint8_t *sector0, uint8_t *sector10, bool verbose, bool *haveMAD2) { int MADCheck(uint8_t *sector0, uint8_t *sector10, bool verbose, bool *haveMAD2) {
int res = 0;
if (!sector0) if (sector0 == NULL)
return 1; return PM3_EINVARG;
uint8_t GPB = sector0[3 * 16 + 9]; uint8_t GPB = sector0[3 * 16 + 9];
if (verbose) if (verbose)
PrintAndLogEx(NORMAL, "GPB: 0x%02x", GPB); PrintAndLogEx(INFO, "GPB: 0x%02x", GPB);
// DA (MAD available) // DA (MAD available)
if (!(GPB & 0x80)) { if (!(GPB & 0x80)) {
PrintAndLogEx(ERR, "DA=0! MAD not available."); PrintAndLogEx(ERR, "DA=0! MAD not available.");
return 1; return PM3_ESOFT;
} }
// MA (multi-application card) // MA (multi-application card)
if (verbose) { if (verbose) {
if (GPB & 0x40) if (GPB & 0x40)
PrintAndLogEx(NORMAL, "Multi application card."); PrintAndLogEx(INFO, "Multi application card.");
else else
PrintAndLogEx(NORMAL, "Single application card."); PrintAndLogEx(INFO, "Single application card.");
} }
uint8_t MADVer = GPB & 0x03; uint8_t MADVer = GPB & 0x03;
if (verbose) if (verbose)
PrintAndLogEx(NORMAL, "MAD version: %d", MADVer); PrintAndLogEx(INFO, "MAD version: %d", MADVer);
// MAD version // MAD version
if ((MADVer != 0x01) && (MADVer != 0x02)) { if ((MADVer != 0x01) && (MADVer != 0x02)) {
PrintAndLogEx(ERR, "Wrong MAD version: 0x%02x", MADVer); PrintAndLogEx(ERR, "Wrong MAD version: 0x%02x", MADVer);
return 2; return PM3_ESOFT;
}; };
if (haveMAD2) if (haveMAD2)
*haveMAD2 = (MADVer == 2); *haveMAD2 = (MADVer == 2);
res = madCRCCheck(sector0, true, 1); int res = madCRCCheck(sector0, true, 1);
if (verbose && !res) if (verbose && res == PM3_SUCCESS)
PrintAndLogEx(NORMAL, "CRC8-MAD1 OK."); PrintAndLogEx(INFO, "CRC8-MAD1 (%s)", _GREEN_("ok"));
if (MADVer == 2 && sector10) { if (MADVer == 2 && sector10) {
int res2 = madCRCCheck(sector10, true, 2); int res2 = madCRCCheck(sector10, true, 2);
if (!res) if (res == PM3_SUCCESS)
res = res2; res = res2;
if (verbose && !res2) if (verbose && !res2)
PrintAndLogEx(NORMAL, "CRC8-MAD2 OK."); PrintAndLogEx(INFO, "CRC8-MAD2 (%)", _GREEN_("ok"));
} }
return res; return res;
@ -191,7 +189,11 @@ int MADCheck(uint8_t *sector0, uint8_t *sector10, bool verbose, bool *haveMAD2)
int MADDecode(uint8_t *sector0, uint8_t *sector10, uint16_t *mad, size_t *madlen) { int MADDecode(uint8_t *sector0, uint8_t *sector10, uint16_t *mad, size_t *madlen) {
*madlen = 0; *madlen = 0;
bool haveMAD2 = false; bool haveMAD2 = false;
MADCheck(sector0, sector10, false, &haveMAD2); int res = MADCheck(sector0, sector10, false, &haveMAD2);
if (res != PM3_SUCCESS) {
PrintAndLogEx(INFO, "Not a valid MAD");
return res;
}
for (int i = 1; i < 16; i++) { for (int i = 1; i < 16; i++) {
mad[*madlen] = madGetAID(sector0, 1, i); mad[*madlen] = madGetAID(sector0, 1, i);
@ -208,51 +210,63 @@ int MADDecode(uint8_t *sector0, uint8_t *sector10, uint16_t *mad, size_t *madlen
(*madlen)++; (*madlen)++;
} }
} }
return PM3_SUCCESS;
return 0;
} }
int MAD1DecodeAndPrint(uint8_t *sector, bool verbose, bool *haveMAD2) { int MAD1DecodeAndPrint(uint8_t *sector, bool verbose, bool *haveMAD2) {
// check MAD1 only // check MAD1 only
MADCheck(sector, NULL, verbose, haveMAD2); int res = MADCheck(sector, NULL, verbose, haveMAD2);
if (verbose) {
if (res == PM3_SUCCESS)
PrintAndLogEx(INFO, "CRC8-MAD1 (%s)", _GREEN_("ok"));
else
PrintAndLogEx(INFO, "CRC8-MAD1 (%s)", _RED_("fail"));
}
// info byte // info byte
uint8_t InfoByte = sector[16 + 1] & 0x3f; uint8_t InfoByte = sector[16 + 1] & 0x3f;
if (InfoByte) { if (InfoByte) {
PrintAndLogEx(NORMAL, "Card publisher sector: 0x%02x", InfoByte); PrintAndLogEx(INFO, "Card publisher sector: " _GREEN_("0x%02x"), InfoByte);
} else { } else {
if (verbose) if (verbose)
PrintAndLogEx(NORMAL, "Card publisher sector not present."); PrintAndLogEx(WARNING, "Card publisher sector not present");
} }
if (InfoByte == 0x10 || InfoByte >= 0x28) if (InfoByte == 0x10 || InfoByte >= 0x28)
PrintAndLogEx(WARNING, "Info byte error"); PrintAndLogEx(WARNING, "Info byte error");
PrintAndLogEx(NORMAL, "00 MAD1"); PrintAndLogEx(INFO, " 00 MAD 1");
for (int i = 1; i < 16; i++) { for (int i = 1; i < 16; i++) {
uint16_t AID = madGetAID(sector, 1, i); uint16_t AID = madGetAID(sector, 1, i);
PrintAndLogEx(NORMAL, "%02d [%04X] %s", i, AID, GetAIDDescription(AID)); PrintAndLogEx(INFO, " %02d [%04X] %s", i, AID, GetAIDDescription(AID));
}; }
return 0; return PM3_SUCCESS;
} }
int MAD2DecodeAndPrint(uint8_t *sector, bool verbose) { int MAD2DecodeAndPrint(uint8_t *sector, bool verbose) {
PrintAndLogEx(NORMAL, "16 MAD2"); PrintAndLogEx(INFO, " 16 MAD 2");
int res = madCRCCheck(sector, true, 2); int res = madCRCCheck(sector, true, 2);
if (verbose) {
if (verbose && !res) if (res == PM3_SUCCESS)
PrintAndLogEx(NORMAL, "CRC8-MAD2 OK."); PrintAndLogEx(INFO, "CRC8-MAD2 (%s)", _GREEN_("ok"));
else
PrintAndLogEx(INFO, "CRC8-MAD2 (%s)", _RED_("fail"));
}
uint8_t InfoByte = sector[1] & 0x3f; uint8_t InfoByte = sector[1] & 0x3f;
PrintAndLogEx(NORMAL, "MAD2 Card publisher sector: 0x%02x", InfoByte); if (InfoByte) {
PrintAndLogEx(INFO, "MAD2 Card publisher sector: " _GREEN_("0x%02x"), InfoByte);
} else {
if (verbose)
PrintAndLogEx(WARNING, "Card publisher sector not present");
}
for (int i = 1; i < 8 + 8 + 7 + 1; i++) { for (int i = 1; i < 8 + 8 + 7 + 1; i++) {
uint16_t AID = madGetAID(sector, 2, i); uint16_t AID = madGetAID(sector, 2, i);
PrintAndLogEx(NORMAL, "%02d [%04X] %s", i + 16, AID, GetAIDDescription(AID)); PrintAndLogEx(INFO, "%02d [%04X] %s", i + 16, AID, GetAIDDescription(AID));
}; }
return 0; return PM3_SUCCESS;
} }