read extra mf-ul EV1 blocks
This commit is contained in:
parent
fe04b85678
commit
c04dd91e98
2 changed files with 92 additions and 27 deletions
|
@ -9,6 +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) 2017 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:
|
||||||
|
@ -133,6 +134,19 @@ typedef struct {
|
||||||
uint8_t otp[4];
|
uint8_t otp[4];
|
||||||
} mifareul_block_manufacturer;
|
} mifareul_block_manufacturer;
|
||||||
|
|
||||||
|
// MIFARE Ultralight EV1 Config Pages
|
||||||
|
typedef struct {
|
||||||
|
uint8_t mod;
|
||||||
|
uint8_t rfui[2];
|
||||||
|
uint8_t auth0;
|
||||||
|
uint8_t access;
|
||||||
|
uint8_t vctid;
|
||||||
|
uint8_t rfui1[2];
|
||||||
|
uint8_t pwd[4];
|
||||||
|
uint8_t pack[2];
|
||||||
|
uint8_t rfui2[2];
|
||||||
|
} mifareul_block_config;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t abtData[16];
|
uint8_t abtData[16];
|
||||||
} mifareul_block_data;
|
} mifareul_block_data;
|
||||||
|
@ -140,12 +154,24 @@ typedef struct {
|
||||||
typedef union {
|
typedef union {
|
||||||
mifareul_block_manufacturer mbm;
|
mifareul_block_manufacturer mbm;
|
||||||
mifareul_block_data mbd;
|
mifareul_block_data mbd;
|
||||||
|
mifareul_block_config mbc;
|
||||||
} mifareul_block;
|
} mifareul_block;
|
||||||
|
|
||||||
|
// standard UL tag - 1 manuf block + 3 user blocks
|
||||||
typedef struct {
|
typedef struct {
|
||||||
mifareul_block amb[4];
|
mifareul_block amb[4];
|
||||||
} mifareul_tag;
|
} mifareul_tag;
|
||||||
|
|
||||||
|
// UL EV1 MF0UL11 tag - 1 manuf block + 3 user blocks + 1 config block
|
||||||
|
typedef struct {
|
||||||
|
mifareul_block amb[5];
|
||||||
|
} mifareul_ev1_mf0ul11_tag;
|
||||||
|
|
||||||
|
// UL EV1 MF0UL21 tag - 1 manuf block + 8 user blocks + 1 config block
|
||||||
|
typedef struct {
|
||||||
|
mifareul_block amb[10];
|
||||||
|
} mifareul_ev1_mf0ul21_tag;
|
||||||
|
|
||||||
// Reset struct alignment to default
|
// Reset struct alignment to default
|
||||||
# pragma pack()
|
# pragma pack()
|
||||||
|
|
||||||
|
|
|
@ -62,11 +62,19 @@
|
||||||
#define MAX_UID_LEN 10
|
#define MAX_UID_LEN 10
|
||||||
#define BLOCK_COUNT 0xf
|
#define BLOCK_COUNT 0xf
|
||||||
|
|
||||||
|
#define EV1_NONE 0
|
||||||
|
#define EV1_UL11 1
|
||||||
|
#define EV1_UL21 2
|
||||||
|
|
||||||
static nfc_device *pnd;
|
static nfc_device *pnd;
|
||||||
static nfc_target nt;
|
static nfc_target nt;
|
||||||
static mifare_param mp;
|
static mifare_param mp;
|
||||||
static mifareul_tag mtDump;
|
static mifareul_ev1_mf0ul21_tag mtDump; // use the largest tag type for internal storage
|
||||||
static const uint32_t uiBlocks = BLOCK_COUNT;
|
static uint32_t uiBlocks = BLOCK_COUNT;
|
||||||
|
static uint32_t uiReadPages = 0;
|
||||||
|
static uint8_t iPWD[4] = { 0x0 };
|
||||||
|
static uint8_t iPACK[2] = { 0x0 };
|
||||||
|
static uint8_t iEV1Type= EV1_NONE;
|
||||||
|
|
||||||
// special unlock command
|
// special unlock command
|
||||||
uint8_t abtUnlock1[1] = { 0x40 };
|
uint8_t abtUnlock1[1] = { 0x40 };
|
||||||
|
@ -105,7 +113,6 @@ read_card(void)
|
||||||
{
|
{
|
||||||
uint32_t page;
|
uint32_t page;
|
||||||
bool bFailure = false;
|
bool bFailure = false;
|
||||||
uint32_t uiReadPages = 0;
|
|
||||||
uint32_t uiFailedPages = 0;
|
uint32_t uiFailedPages = 0;
|
||||||
|
|
||||||
printf("Reading %d pages |", uiBlocks + 1);
|
printf("Reading %d pages |", uiBlocks + 1);
|
||||||
|
@ -127,6 +134,21 @@ read_card(void)
|
||||||
printf("Done, %d of %d pages read (%d pages failed).\n", uiReadPages, uiBlocks + 1, uiFailedPages);
|
printf("Done, %d of %d pages read (%d pages failed).\n", uiReadPages, uiBlocks + 1, uiFailedPages);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
|
// copy EV1 secrets to dump data
|
||||||
|
switch(iEV1Type) {
|
||||||
|
case EV1_UL11:
|
||||||
|
memcpy(mtDump.amb[4].mbc.pwd, iPWD, 4);
|
||||||
|
memcpy(mtDump.amb[4].mbc.pack, iPACK, 2);
|
||||||
|
break;
|
||||||
|
case EV1_UL21:
|
||||||
|
memcpy(mtDump.amb[9].mbc.pwd, iPWD, 4);
|
||||||
|
memcpy(mtDump.amb[9].mbc.pack, iPACK, 2);
|
||||||
|
break;
|
||||||
|
case EV1_NONE:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return (!bFailure);
|
return (!bFailure);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -445,7 +467,6 @@ main(int argc, const char *argv[])
|
||||||
{
|
{
|
||||||
int iAction = 0;
|
int iAction = 0;
|
||||||
uint8_t iUID[MAX_UID_LEN] = { 0x0 };
|
uint8_t iUID[MAX_UID_LEN] = { 0x0 };
|
||||||
uint8_t iPWD[4] = { 0x0 };
|
|
||||||
size_t szUID = 0;
|
size_t szUID = 0;
|
||||||
bool bOTP = false;
|
bool bOTP = false;
|
||||||
bool bLock = false;
|
bool bLock = false;
|
||||||
|
@ -569,8 +590,8 @@ main(int argc, const char *argv[])
|
||||||
nfc_exit(context);
|
nfc_exit(context);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
// Test if we are dealing with a MIFARE compatible tag
|
|
||||||
|
|
||||||
|
// Test if we are dealing with a MIFARE compatible tag
|
||||||
if (nt.nti.nai.abtAtqa[1] != 0x44) {
|
if (nt.nti.nai.abtAtqa[1] != 0x44) {
|
||||||
ERR("tag is not a MIFARE Ultralight card\n");
|
ERR("tag is not a MIFARE Ultralight card\n");
|
||||||
nfc_close(pnd);
|
nfc_close(pnd);
|
||||||
|
@ -590,13 +611,28 @@ main(int argc, const char *argv[])
|
||||||
if(!bPWD)
|
if(!bPWD)
|
||||||
printf("Tag is EV1 - PASSWORD may be required\n");
|
printf("Tag is EV1 - PASSWORD may be required\n");
|
||||||
printf("EV1 storage size: ");
|
printf("EV1 storage size: ");
|
||||||
if(abtRx[6] == 0x0b)
|
if(abtRx[6] == 0x0b) {
|
||||||
printf("48 bytes\n");
|
printf("48 bytes\n");
|
||||||
else if(abtRx[6] == 0x0e)
|
uiBlocks= 0x13;
|
||||||
|
iEV1Type= EV1_UL11;
|
||||||
|
}
|
||||||
|
else if(abtRx[6] == 0x0e) {
|
||||||
printf("128 bytes\n");
|
printf("128 bytes\n");
|
||||||
|
uiBlocks= 0x28;
|
||||||
|
iEV1Type= EV1_UL21;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
printf("unknown!\n");
|
printf("unknown!\n");
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
// re-init non EV1 tag
|
||||||
|
if (nfc_initiator_select_passive_target(pnd, nmMifare, (szUID) ? iUID : NULL, szUID, &nt) <= 0) {
|
||||||
|
ERR("no tag was found\n");
|
||||||
|
nfc_close(pnd);
|
||||||
|
nfc_exit(context);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// EV1 login required
|
// EV1 login required
|
||||||
if(bPWD){
|
if(bPWD){
|
||||||
|
@ -606,12 +642,14 @@ main(int argc, const char *argv[])
|
||||||
ERR("AUTH failed!\n");
|
ERR("AUTH failed!\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
printf("Success - PACK: %02x%02x\n", abtRx[0], abtRx[1]);
|
printf("Success - PACK: %02x%02x\n", abtRx[0], abtRx[1]);
|
||||||
|
memcpy(iPACK, abtRx, 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iAction == 1) {
|
if (iAction == 1) {
|
||||||
if (read_card()) {
|
bool bRF= read_card();
|
||||||
printf("Writing data to file: %s ... ", argv[2]);
|
printf("Writing data to file: %s ... ", argv[2]);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
pfDump = fopen(argv[2], "wb");
|
pfDump = fopen(argv[2], "wb");
|
||||||
|
@ -621,7 +659,7 @@ main(int argc, const char *argv[])
|
||||||
nfc_exit(context);
|
nfc_exit(context);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
if (fwrite(&mtDump, 1, sizeof(mtDump), pfDump) != sizeof(mtDump)) {
|
if (fwrite(&mtDump, 1, uiReadPages * 4, pfDump) != uiReadPages * 4) {
|
||||||
printf("Could not write to file: %s\n", argv[2]);
|
printf("Could not write to file: %s\n", argv[2]);
|
||||||
fclose(pfDump);
|
fclose(pfDump);
|
||||||
nfc_close(pnd);
|
nfc_close(pnd);
|
||||||
|
@ -630,7 +668,8 @@ main(int argc, const char *argv[])
|
||||||
}
|
}
|
||||||
fclose(pfDump);
|
fclose(pfDump);
|
||||||
printf("Done.\n");
|
printf("Done.\n");
|
||||||
}
|
if(!bRF)
|
||||||
|
printf("Warning! Read failed - partial data written to file!\n");
|
||||||
} else if (iAction == 2) {
|
} else if (iAction == 2) {
|
||||||
write_card(bOTP, bLock, bUID);
|
write_card(bOTP, bLock, bUID);
|
||||||
} else if (iAction == 3) {
|
} else if (iAction == 3) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue