mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-20 13:23:51 -07:00
ADD: @go_tus simple bruteforce for t55xx, refactored a bit.
ADD: @pwpiwi 's implementation of Hardnested
This commit is contained in:
parent
1a570b0a6a
commit
c188b1b9b2
18 changed files with 367 additions and 58 deletions
|
@ -432,7 +432,7 @@ void StandAloneMode14a()
|
||||||
SpinDelay(300);
|
SpinDelay(300);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!iso14443a_select_card(uid, &hi14a_card[selected], &cuid))
|
if (!iso14443a_select_card(uid, &hi14a_card[selected], &cuid, true, 0))
|
||||||
continue;
|
continue;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1131,6 +1131,9 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||||
case CMD_MIFAREU_WRITEBL:
|
case CMD_MIFAREU_WRITEBL:
|
||||||
MifareUWriteBlock(c->arg[0], c->arg[1], c->d.asBytes);
|
MifareUWriteBlock(c->arg[0], c->arg[1], c->d.asBytes);
|
||||||
break;
|
break;
|
||||||
|
case CMD_MIFARE_ACQUIRE_ENCRYPTED_NONCES:
|
||||||
|
MifareAcquireEncryptedNonces(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
|
||||||
|
break;
|
||||||
case CMD_MIFARE_NESTED:
|
case CMD_MIFARE_NESTED:
|
||||||
MifareNested(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
|
MifareNested(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -132,6 +132,7 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
||||||
//void MifareUWriteBlockCompat(uint8_t arg0,uint8_t *datain);
|
//void MifareUWriteBlockCompat(uint8_t arg0,uint8_t *datain);
|
||||||
void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain);
|
void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain);
|
||||||
void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
|
void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
|
||||||
|
void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint8_t *datain);
|
||||||
void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
|
void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
|
||||||
void Mifare1ksim(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
|
void Mifare1ksim(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
|
||||||
void MifareSetDbgLvl(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
|
void MifareSetDbgLvl(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
|
||||||
|
|
|
@ -529,7 +529,7 @@ int EPA_Setup()
|
||||||
// power up the field
|
// power up the field
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
|
||||||
// select the card
|
// select the card
|
||||||
return_code = iso14443a_select_card(uid, &card_select_info, NULL);
|
return_code = iso14443a_select_card(uid, &card_select_info, NULL, true, 0);
|
||||||
if (return_code == 1) {
|
if (return_code == 1) {
|
||||||
// send the PPS request
|
// send the PPS request
|
||||||
ReaderTransmit((uint8_t *)pps, sizeof(pps), NULL);
|
ReaderTransmit((uint8_t *)pps, sizeof(pps), NULL);
|
||||||
|
|
|
@ -1896,10 +1896,12 @@ int ReaderReceive(uint8_t *receivedAnswer, uint8_t *parity)
|
||||||
return Demod.len;
|
return Demod.len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* performs iso14443a anticollision procedure
|
// performs iso14443a anticollision (optional) and card select procedure
|
||||||
* fills the uid pointer unless NULL
|
// fills the uid and cuid pointer unless NULL
|
||||||
* fills resp_data unless NULL */
|
// fills the card info record unless NULL
|
||||||
int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, uint32_t *cuid_ptr) {
|
// if anticollision is false, then the UID must be provided in uid_ptr[]
|
||||||
|
// and num_cascades must be set (1: 4 Byte UID, 2: 7 Byte UID, 3: 10 Byte UID)
|
||||||
|
int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades) {
|
||||||
uint8_t wupa[] = { 0x52 }; // 0x26 - REQA 0x52 - WAKE-UP
|
uint8_t wupa[] = { 0x52 }; // 0x26 - REQA 0x52 - WAKE-UP
|
||||||
uint8_t sel_all[] = { 0x93,0x20 };
|
uint8_t sel_all[] = { 0x93,0x20 };
|
||||||
uint8_t sel_uid[] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
uint8_t sel_uid[] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||||
|
@ -1914,7 +1916,7 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
// Broadcast for a card, WUPA (0x52) will force response from all cards in the field
|
// Broadcast for a card, WUPA (0x52) will force response from all cards in the field
|
||||||
ReaderTransmitBitsPar(wupa,7,0, NULL);
|
ReaderTransmitBitsPar(wupa, 7, NULL, NULL);
|
||||||
|
|
||||||
// Receive the ATQA
|
// Receive the ATQA
|
||||||
if(!ReaderReceive(resp, resp_par)) return 0;
|
if(!ReaderReceive(resp, resp_par)) return 0;
|
||||||
|
@ -1925,10 +1927,12 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
|
||||||
memset(p_hi14a_card->uid,0,10);
|
memset(p_hi14a_card->uid,0,10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (anticollision) {
|
||||||
// clear uid
|
// clear uid
|
||||||
if (uid_ptr) {
|
if (uid_ptr) {
|
||||||
memset(uid_ptr,0,10);
|
memset(uid_ptr,0,10);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// check for proprietary anticollision:
|
// check for proprietary anticollision:
|
||||||
if ((resp[0] & 0x1F) == 0) {
|
if ((resp[0] & 0x1F) == 0) {
|
||||||
|
@ -1942,6 +1946,7 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
|
||||||
// SELECT_* (L1: 0x93, L2: 0x95, L3: 0x97)
|
// SELECT_* (L1: 0x93, L2: 0x95, L3: 0x97)
|
||||||
sel_uid[0] = sel_all[0] = 0x93 + cascade_level * 2;
|
sel_uid[0] = sel_all[0] = 0x93 + cascade_level * 2;
|
||||||
|
|
||||||
|
if (anticollision) {
|
||||||
// SELECT_ALL
|
// SELECT_ALL
|
||||||
ReaderTransmit(sel_all, sizeof(sel_all), NULL);
|
ReaderTransmit(sel_all, sizeof(sel_all), NULL);
|
||||||
if (!ReaderReceive(resp, resp_par)) return 0;
|
if (!ReaderReceive(resp, resp_par)) return 0;
|
||||||
|
@ -1977,6 +1982,14 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
|
||||||
} else { // no collision, use the response to SELECT_ALL as current uid
|
} else { // no collision, use the response to SELECT_ALL as current uid
|
||||||
memcpy(uid_resp, resp, 4);
|
memcpy(uid_resp, resp, 4);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (cascade_level < num_cascades - 1) {
|
||||||
|
uid_resp[0] = 0x88;
|
||||||
|
memcpy(uid_resp+1, uid_ptr+cascade_level*3, 3);
|
||||||
|
} else {
|
||||||
|
memcpy(uid_resp, uid_ptr+cascade_level*3, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
uid_resp_len = 4;
|
uid_resp_len = 4;
|
||||||
|
|
||||||
// calculate crypto UID. Always use last 4 Bytes.
|
// calculate crypto UID. Always use last 4 Bytes.
|
||||||
|
@ -1986,7 +1999,7 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
|
||||||
|
|
||||||
// Construct SELECT UID command
|
// Construct SELECT UID command
|
||||||
sel_uid[1] = 0x70; // transmitting a full UID (1 Byte cmd, 1 Byte NVB, 4 Byte UID, 1 Byte BCC, 2 Bytes CRC)
|
sel_uid[1] = 0x70; // transmitting a full UID (1 Byte cmd, 1 Byte NVB, 4 Byte UID, 1 Byte BCC, 2 Bytes CRC)
|
||||||
memcpy(sel_uid+2, uid_resp, 4); // the UID
|
memcpy(sel_uid+2, uid_resp, 4); // the UID received during anticollision, or the provided UID
|
||||||
sel_uid[6] = sel_uid[2] ^ sel_uid[3] ^ sel_uid[4] ^ sel_uid[5]; // calculate and add BCC
|
sel_uid[6] = sel_uid[2] ^ sel_uid[3] ^ sel_uid[4] ^ sel_uid[5]; // calculate and add BCC
|
||||||
AppendCrc14443a(sel_uid, 7); // calculate and add CRC
|
AppendCrc14443a(sel_uid, 7); // calculate and add CRC
|
||||||
ReaderTransmit(sel_uid, sizeof(sel_uid), NULL);
|
ReaderTransmit(sel_uid, sizeof(sel_uid), NULL);
|
||||||
|
@ -2002,11 +2015,10 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
|
||||||
uid_resp[0] = uid_resp[1];
|
uid_resp[0] = uid_resp[1];
|
||||||
uid_resp[1] = uid_resp[2];
|
uid_resp[1] = uid_resp[2];
|
||||||
uid_resp[2] = uid_resp[3];
|
uid_resp[2] = uid_resp[3];
|
||||||
|
|
||||||
uid_resp_len = 3;
|
uid_resp_len = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(uid_ptr) {
|
if(uid_ptr && anticollision) {
|
||||||
memcpy(uid_ptr + (cascade_level*3), uid_resp, uid_resp_len);
|
memcpy(uid_ptr + (cascade_level*3), uid_resp, uid_resp_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2127,7 +2139,7 @@ void ReaderIso14443a(UsbCommand *c)
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
if(!(param & ISO14A_NO_SELECT)) {
|
if(!(param & ISO14A_NO_SELECT)) {
|
||||||
iso14a_card_select_t *card = (iso14a_card_select_t*)buf;
|
iso14a_card_select_t *card = (iso14a_card_select_t*)buf;
|
||||||
arg0 = iso14443a_select_card(NULL,card,NULL);
|
arg0 = iso14443a_select_card(NULL,card,NULL, true, 0);
|
||||||
cmd_send(CMD_ACK,arg0,card->uidlen,0,buf,sizeof(iso14a_card_select_t));
|
cmd_send(CMD_ACK,arg0,card->uidlen,0,buf,sizeof(iso14a_card_select_t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2325,7 +2337,7 @@ void ReaderMifare(bool first_try)
|
||||||
SpinDelay(100);
|
SpinDelay(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("Mifare: Can't select card");
|
if (MF_DBGLEVEL >= 1) Dbprintf("Mifare: Can't select card");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ extern int ReaderReceive(uint8_t *receivedAnswer, uint8_t *par);
|
||||||
|
|
||||||
extern void iso14443a_setup(uint8_t fpga_minor_mode);
|
extern void iso14443a_setup(uint8_t fpga_minor_mode);
|
||||||
extern int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data);
|
extern int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data);
|
||||||
extern int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *resp_data, uint32_t *cuid_ptr);
|
extern int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *resp_data, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades);
|
||||||
extern void iso14a_set_trigger(bool enable);
|
extern void iso14a_set_trigger(bool enable);
|
||||||
|
|
||||||
#endif /* __ISO14443A_H */
|
#endif /* __ISO14443A_H */
|
||||||
|
|
|
@ -49,7 +49,7 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
||||||
LED_C_OFF();
|
LED_C_OFF();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
@ -96,7 +96,7 @@ void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes){
|
||||||
|
|
||||||
clear_trace();
|
clear_trace();
|
||||||
|
|
||||||
if(!iso14443a_select_card(NULL, NULL, NULL)) {
|
if(!iso14443a_select_card(NULL, NULL, NULL, true, 0)) {
|
||||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");
|
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");
|
||||||
OnError(0);
|
OnError(0);
|
||||||
return;
|
return;
|
||||||
|
@ -131,7 +131,7 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
|
||||||
|
|
||||||
clear_trace();
|
clear_trace();
|
||||||
|
|
||||||
int len = iso14443a_select_card(NULL, NULL, NULL);
|
int len = iso14443a_select_card(NULL, NULL, NULL, true, 0);
|
||||||
if(!len) {
|
if(!len) {
|
||||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%02X)",len);
|
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%02X)",len);
|
||||||
OnError(1);
|
OnError(1);
|
||||||
|
@ -207,7 +207,7 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
||||||
LED_C_OFF();
|
LED_C_OFF();
|
||||||
|
|
||||||
isOK = 1;
|
isOK = 1;
|
||||||
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {
|
||||||
isOK = 0;
|
isOK = 0;
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
||||||
}
|
}
|
||||||
|
@ -271,7 +271,7 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int len = iso14443a_select_card(NULL, NULL, NULL);
|
int len = iso14443a_select_card(NULL, NULL, NULL, true, 0);
|
||||||
if (!len) {
|
if (!len) {
|
||||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%d)",len);
|
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%d)",len);
|
||||||
OnError(1);
|
OnError(1);
|
||||||
|
@ -373,7 +373,7 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
||||||
LED_C_OFF();
|
LED_C_OFF();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
@ -427,7 +427,7 @@ void MifareUWriteBlockCompat(uint8_t arg0, uint8_t *datain)
|
||||||
clear_trace();
|
clear_trace();
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
|
||||||
if(!iso14443a_select_card(uid, NULL, NULL)) {
|
if(!iso14443a_select_card(uid, NULL, NULL, true, 0)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
||||||
OnError(0);
|
OnError(0);
|
||||||
return;
|
return;
|
||||||
|
@ -473,7 +473,7 @@ void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
|
||||||
|
|
||||||
clear_trace();
|
clear_trace();
|
||||||
|
|
||||||
if(!iso14443a_select_card(NULL, NULL, NULL)) {
|
if(!iso14443a_select_card(NULL, NULL, NULL, true, 0)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
||||||
OnError(0);
|
OnError(0);
|
||||||
return;
|
return;
|
||||||
|
@ -532,7 +532,7 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain){
|
||||||
|
|
||||||
clear_trace();
|
clear_trace();
|
||||||
|
|
||||||
if(!iso14443a_select_card(NULL, NULL, NULL)) {
|
if(!iso14443a_select_card(NULL, NULL, NULL, true, 0)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
||||||
OnError(0);
|
OnError(0);
|
||||||
return;
|
return;
|
||||||
|
@ -597,6 +597,138 @@ int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, uint8_t *parity) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// acquire encrypted nonces in order to perform the attack described in
|
||||||
|
// Carlo Meijer, Roel Verdult, "Ciphertext-only Cryptanalysis on Hardened
|
||||||
|
// Mifare Classic Cards" in Proceedings of the 22nd ACM SIGSAC Conference on
|
||||||
|
// Computer and Communications Security, 2015
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint8_t *datain)
|
||||||
|
{
|
||||||
|
uint64_t ui64Key = 0;
|
||||||
|
uint8_t uid[10];
|
||||||
|
uint32_t cuid;
|
||||||
|
uint8_t cascade_levels = 0;
|
||||||
|
struct Crypto1State mpcs = {0, 0};
|
||||||
|
struct Crypto1State *pcs;
|
||||||
|
pcs = &mpcs;
|
||||||
|
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||||
|
int16_t isOK = 0;
|
||||||
|
uint8_t par_enc[1];
|
||||||
|
uint8_t nt_par_enc = 0;
|
||||||
|
uint8_t buf[USB_CMD_DATA_SIZE];
|
||||||
|
uint32_t timeout;
|
||||||
|
|
||||||
|
uint8_t blockNo = arg0 & 0xff;
|
||||||
|
uint8_t keyType = (arg0 >> 8) & 0xff;
|
||||||
|
uint8_t targetBlockNo = arg1 & 0xff;
|
||||||
|
uint8_t targetKeyType = (arg1 >> 8) & 0xff;
|
||||||
|
ui64Key = bytes_to_num(datain, 6);
|
||||||
|
bool initialize = flags & 0x0001;
|
||||||
|
bool slow = flags & 0x0002;
|
||||||
|
bool field_off = flags & 0x0004;
|
||||||
|
|
||||||
|
#define AUTHENTICATION_TIMEOUT 848 // card times out 1ms after wrong authentication (according to NXP documentation)
|
||||||
|
#define PRE_AUTHENTICATION_LEADTIME 400 // some (non standard) cards need a pause after select before they are ready for first authentication
|
||||||
|
|
||||||
|
LED_A_ON();
|
||||||
|
LED_C_OFF();
|
||||||
|
|
||||||
|
if (initialize) {
|
||||||
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
clear_trace();
|
||||||
|
set_tracing(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
LED_C_ON();
|
||||||
|
|
||||||
|
uint16_t num_nonces = 0;
|
||||||
|
bool have_uid = false;
|
||||||
|
for (uint16_t i = 0; i <= USB_CMD_DATA_SIZE - 9; ) {
|
||||||
|
|
||||||
|
// Test if the action was cancelled
|
||||||
|
if(BUTTON_PRESS()) {
|
||||||
|
isOK = 2;
|
||||||
|
field_off = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!have_uid) { // need a full select cycle to get the uid first
|
||||||
|
iso14a_card_select_t card_info;
|
||||||
|
if(!iso14443a_select_card(uid, &card_info, &cuid, true, 0)) {
|
||||||
|
if (MF_DBGLEVEL >= 1) Dbprintf("AcquireNonces: Can't select card (ALL)");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (card_info.uidlen) {
|
||||||
|
case 4 : cascade_levels = 1; break;
|
||||||
|
case 7 : cascade_levels = 2; break;
|
||||||
|
case 10: cascade_levels = 3; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
have_uid = true;
|
||||||
|
} else { // no need for anticollision. We can directly select the card
|
||||||
|
if(!iso14443a_select_card(uid, NULL, NULL, false, cascade_levels)) {
|
||||||
|
if (MF_DBGLEVEL >= 1) Dbprintf("AcquireNonces: Can't select card (UID)");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (slow) {
|
||||||
|
timeout = GetCountSspClk() + PRE_AUTHENTICATION_LEADTIME;
|
||||||
|
while(GetCountSspClk() < timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t nt1;
|
||||||
|
if (mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1, NULL)) {
|
||||||
|
if (MF_DBGLEVEL >= 1) Dbprintf("AcquireNonces: Auth1 error");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// nested authentication
|
||||||
|
uint16_t len = mifare_sendcmd_short(pcs, AUTH_NESTED, 0x60 + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, par_enc, NULL);
|
||||||
|
if (len != 4) {
|
||||||
|
if (MF_DBGLEVEL >= 1) Dbprintf("AcquireNonces: Auth2 error len=%d", len);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// send a dummy byte as reader response in order to trigger the cards authentication timeout
|
||||||
|
uint8_t dummy_answer = 0;
|
||||||
|
ReaderTransmit(&dummy_answer, 1, NULL);
|
||||||
|
timeout = GetCountSspClk() + AUTHENTICATION_TIMEOUT;
|
||||||
|
|
||||||
|
num_nonces++;
|
||||||
|
if (num_nonces % 2) {
|
||||||
|
memcpy(buf+i, receivedAnswer, 4);
|
||||||
|
nt_par_enc = par_enc[0] & 0xf0;
|
||||||
|
} else {
|
||||||
|
nt_par_enc |= par_enc[0] >> 4;
|
||||||
|
memcpy(buf+i+4, receivedAnswer, 4);
|
||||||
|
memcpy(buf+i+8, &nt_par_enc, 1);
|
||||||
|
i += 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for the card to become ready again
|
||||||
|
while(GetCountSspClk() < timeout);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
LED_C_OFF();
|
||||||
|
|
||||||
|
crypto1_destroy(pcs);
|
||||||
|
|
||||||
|
LED_B_ON();
|
||||||
|
cmd_send(CMD_ACK, isOK, cuid, num_nonces, buf, sizeof(buf));
|
||||||
|
LED_B_OFF();
|
||||||
|
|
||||||
|
if (MF_DBGLEVEL >= 3) DbpString("AcquireEncryptedNonces finished");
|
||||||
|
|
||||||
|
if (field_off) {
|
||||||
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
|
LEDsoff();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// MIFARE nested authentication.
|
// MIFARE nested authentication.
|
||||||
//
|
//
|
||||||
|
@ -668,7 +800,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Can't select card");
|
if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Can't select card");
|
||||||
rtr--;
|
rtr--;
|
||||||
continue;
|
continue;
|
||||||
|
@ -741,7 +873,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Can't select card");
|
if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Can't select card");
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
@ -857,7 +989,7 @@ void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("ChkKeys: Halt error");
|
if (MF_DBGLEVEL >= 1) Dbprintf("ChkKeys: Halt error");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {
|
||||||
if (OLD_MF_DBGLEVEL >= 1) Dbprintf("ChkKeys: Can't select card");
|
if (OLD_MF_DBGLEVEL >= 1) Dbprintf("ChkKeys: Can't select card");
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
@ -952,7 +1084,7 @@ void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
||||||
|
|
||||||
bool isOK = true;
|
bool isOK = true;
|
||||||
|
|
||||||
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {
|
||||||
isOK = false;
|
isOK = false;
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
||||||
}
|
}
|
||||||
|
@ -1051,7 +1183,7 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain){
|
||||||
|
|
||||||
// read UID and return to client
|
// read UID and return to client
|
||||||
if (workFlags & MAGIC_UID) {
|
if (workFlags & MAGIC_UID) {
|
||||||
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {
|
||||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");
|
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");
|
||||||
OnErrorMagic(MAGIC_UID);
|
OnErrorMagic(MAGIC_UID);
|
||||||
};
|
};
|
||||||
|
@ -1222,7 +1354,7 @@ void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain){
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
clear_trace();
|
clear_trace();
|
||||||
|
|
||||||
int len = iso14443a_select_card(uid, NULL, &cuid);
|
int len = iso14443a_select_card(uid, NULL, &cuid, true, 0);
|
||||||
if(!len) {
|
if(!len) {
|
||||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");
|
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");
|
||||||
OnError(1);
|
OnError(1);
|
||||||
|
|
|
@ -25,7 +25,7 @@ bool InitDesfireCard(){
|
||||||
byte_t cardbuf[USB_CMD_DATA_SIZE] = {0x00};
|
byte_t cardbuf[USB_CMD_DATA_SIZE] = {0x00};
|
||||||
iso14a_card_select_t *card = (iso14a_card_select_t*)cardbuf;
|
iso14a_card_select_t *card = (iso14a_card_select_t*)cardbuf;
|
||||||
|
|
||||||
int len = iso14443a_select_card(NULL,card,NULL);
|
int len = iso14443a_select_card(NULL,card,NULL,true,0);
|
||||||
|
|
||||||
if (!len) {
|
if (!len) {
|
||||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||||
|
@ -114,7 +114,7 @@ void MifareDesfireGetInformation(){
|
||||||
|
|
||||||
// card select - information
|
// card select - information
|
||||||
iso14a_card_select_t *card = (iso14a_card_select_t*)cardbuf;
|
iso14a_card_select_t *card = (iso14a_card_select_t*)cardbuf;
|
||||||
byte_t isOK = iso14443a_select_card(NULL, card, NULL);
|
byte_t isOK = iso14443a_select_card(NULL, card, NULL, true, 0);
|
||||||
if ( isOK == 0) {
|
if ( isOK == 0) {
|
||||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) {
|
if (MF_DBGLEVEL >= MF_DBG_ERROR) {
|
||||||
Dbprintf("Can't select card");
|
Dbprintf("Can't select card");
|
||||||
|
|
|
@ -109,6 +109,7 @@ CMDSRCS = nonce2key/crapto1.c\
|
||||||
cmdhficlass.c \
|
cmdhficlass.c \
|
||||||
cmdhfmf.c \
|
cmdhfmf.c \
|
||||||
cmdhfmfu.c \
|
cmdhfmfu.c \
|
||||||
|
cmdhfmfhard.c \
|
||||||
cmdhfmfdes.c \
|
cmdhfmfdes.c \
|
||||||
cmdhftopaz.c \
|
cmdhftopaz.c \
|
||||||
cmdhw.c \
|
cmdhw.c \
|
||||||
|
|
|
@ -1987,7 +1987,11 @@ int getSamples(const char *Cmd, bool silent)
|
||||||
GetFromBigBuf(got,n,0);
|
GetFromBigBuf(got,n,0);
|
||||||
PrintAndLog("Data fetched");
|
PrintAndLog("Data fetched");
|
||||||
UsbCommand response;
|
UsbCommand response;
|
||||||
WaitForResponse(CMD_ACK, &response);
|
if ( !WaitForResponseTimeout(CMD_ACK, &response, 10000) ) {
|
||||||
|
PrintAndLog("timeout while waiting for reply.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t bits_per_sample = 8;
|
uint8_t bits_per_sample = 8;
|
||||||
|
|
||||||
//Old devices without this feature would send 0 at arg[0]
|
//Old devices without this feature would send 0 at arg[0]
|
||||||
|
@ -2030,9 +2034,9 @@ int CmdTuneSamples(const char *Cmd)
|
||||||
int timeout = 0;
|
int timeout = 0;
|
||||||
printf("\nMeasuring antenna characteristics, please wait...");
|
printf("\nMeasuring antenna characteristics, please wait...");
|
||||||
|
|
||||||
UsbCommand c = {CMD_MEASURE_ANTENNA_TUNING};
|
UsbCommand c = {CMD_MEASURE_ANTENNA_TUNING, {0,0,0}};
|
||||||
|
clearCommandBuffer();
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
|
|
||||||
UsbCommand resp;
|
UsbCommand resp;
|
||||||
while(!WaitForResponseTimeout(CMD_MEASURED_ANTENNA_TUNING,&resp,1000)) {
|
while(!WaitForResponseTimeout(CMD_MEASURED_ANTENNA_TUNING,&resp,1000)) {
|
||||||
timeout++;
|
timeout++;
|
||||||
|
@ -2080,7 +2084,6 @@ int CmdTuneSamples(const char *Cmd)
|
||||||
ShowGraphWindow();
|
ShowGraphWindow();
|
||||||
RepaintGraphWindow();
|
RepaintGraphWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2096,7 +2099,7 @@ int CmdLoad(const char *Cmd)
|
||||||
|
|
||||||
FILE *f = fopen(filename, "r");
|
FILE *f = fopen(filename, "r");
|
||||||
if (!f) {
|
if (!f) {
|
||||||
PrintAndLog("couldn't open '%s'", filename);
|
PrintAndLog("couldn't open '%s'", filename);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2115,11 +2118,13 @@ int CmdLoad(const char *Cmd)
|
||||||
int CmdLtrim(const char *Cmd)
|
int CmdLtrim(const char *Cmd)
|
||||||
{
|
{
|
||||||
int ds = atoi(Cmd);
|
int ds = atoi(Cmd);
|
||||||
if (GraphTraceLen<=0) return 0;
|
|
||||||
|
if (GraphTraceLen <= 0) return 0;
|
||||||
|
|
||||||
for (int i = ds; i < GraphTraceLen; ++i)
|
for (int i = ds; i < GraphTraceLen; ++i)
|
||||||
GraphBuffer[i-ds] = GraphBuffer[i];
|
GraphBuffer[i-ds] = GraphBuffer[i];
|
||||||
GraphTraceLen -= ds;
|
|
||||||
|
|
||||||
|
GraphTraceLen -= ds;
|
||||||
RepaintGraphWindow();
|
RepaintGraphWindow();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2128,9 +2133,7 @@ int CmdLtrim(const char *Cmd)
|
||||||
int CmdRtrim(const char *Cmd)
|
int CmdRtrim(const char *Cmd)
|
||||||
{
|
{
|
||||||
int ds = atoi(Cmd);
|
int ds = atoi(Cmd);
|
||||||
|
|
||||||
GraphTraceLen = ds;
|
GraphTraceLen = ds;
|
||||||
|
|
||||||
RepaintGraphWindow();
|
RepaintGraphWindow();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
100
client/cmdhfmf.c
100
client/cmdhfmf.c
|
@ -9,6 +9,7 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#include "cmdhfmf.h"
|
#include "cmdhfmf.h"
|
||||||
|
#include "cmdhfmfhard.h"
|
||||||
#include "nonce2key/nonce2key.h"
|
#include "nonce2key/nonce2key.h"
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
@ -791,6 +792,104 @@ int CmdHF14AMfNested(const char *Cmd)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int CmdHF14AMfNestedHard(const char *Cmd)
|
||||||
|
{
|
||||||
|
uint8_t blockNo = 0;
|
||||||
|
uint8_t keyType = 0;
|
||||||
|
uint8_t trgBlockNo = 0;
|
||||||
|
uint8_t trgKeyType = 0;
|
||||||
|
uint8_t key[6] = {0, 0, 0, 0, 0, 0};
|
||||||
|
|
||||||
|
char ctmp;
|
||||||
|
ctmp = param_getchar(Cmd, 0);
|
||||||
|
if (ctmp != 'R' && ctmp != 'r' && strlen(Cmd) < 20) {
|
||||||
|
PrintAndLog("Usage:");
|
||||||
|
PrintAndLog(" hf mf hardnested <block number> <key A|B> <key (12 hex symbols)>");
|
||||||
|
PrintAndLog(" <target block number> <target key A|B> [w] [s]");
|
||||||
|
PrintAndLog(" or hf mf hardnested r");
|
||||||
|
PrintAndLog(" ");
|
||||||
|
PrintAndLog("Options: ");
|
||||||
|
PrintAndLog(" w: Acquire nonces and write them to binary file nonces.bin");
|
||||||
|
PrintAndLog(" s: Slower acquisition (required by some non standard cards)");
|
||||||
|
PrintAndLog(" r: Read nonces.bin and start attack");
|
||||||
|
PrintAndLog(" ");
|
||||||
|
PrintAndLog(" sample1: hf mf hardnested 0 A FFFFFFFFFFFF 4 A");
|
||||||
|
PrintAndLog(" sample2: hf mf hardnested 0 A FFFFFFFFFFFF 4 A w");
|
||||||
|
PrintAndLog(" sample3: hf mf hardnested 0 A FFFFFFFFFFFF 4 A w s");
|
||||||
|
PrintAndLog(" sample4: hf mf hardnested r");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nonce_file_read = false;
|
||||||
|
bool nonce_file_write = false;
|
||||||
|
bool slow = false;
|
||||||
|
|
||||||
|
if (ctmp == 'R' || ctmp == 'r') {
|
||||||
|
|
||||||
|
nonce_file_read = true;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
blockNo = param_get8(Cmd, 0);
|
||||||
|
ctmp = param_getchar(Cmd, 1);
|
||||||
|
if (ctmp != 'a' && ctmp != 'A' && ctmp != 'b' && ctmp != 'B') {
|
||||||
|
PrintAndLog("Key type must be A or B");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (ctmp != 'A' && ctmp != 'a') {
|
||||||
|
keyType = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param_gethex(Cmd, 2, key, 12)) {
|
||||||
|
PrintAndLog("Key must include 12 HEX symbols");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
trgBlockNo = param_get8(Cmd, 3);
|
||||||
|
ctmp = param_getchar(Cmd, 4);
|
||||||
|
if (ctmp != 'a' && ctmp != 'A' && ctmp != 'b' && ctmp != 'B') {
|
||||||
|
PrintAndLog("Target key type must be A or B");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (ctmp != 'A' && ctmp != 'a') {
|
||||||
|
trgKeyType = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t i = 5;
|
||||||
|
while ((ctmp = param_getchar(Cmd, i))) {
|
||||||
|
if (ctmp == 's' || ctmp == 'S') {
|
||||||
|
slow = true;
|
||||||
|
} else if (ctmp == 'w' || ctmp == 'W') {
|
||||||
|
nonce_file_write = true;
|
||||||
|
} else {
|
||||||
|
PrintAndLog("Possible options are w and/or s");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintAndLog("--target block no:%3d, target key type:%c, file action: %s, Slow: %s ",
|
||||||
|
trgBlockNo,
|
||||||
|
trgKeyType?'B':'A',
|
||||||
|
nonce_file_write?"write":nonce_file_read?"read":"none",
|
||||||
|
slow?"Yes":"No");
|
||||||
|
int16_t isOK = mfnestedhard(blockNo, keyType, key, trgBlockNo, trgKeyType, nonce_file_read, nonce_file_write, slow);
|
||||||
|
if (isOK) {
|
||||||
|
switch (isOK) {
|
||||||
|
case 1 : PrintAndLog("Error: No response from Proxmark.\n"); break;
|
||||||
|
case 2 : PrintAndLog("Button pressed. Aborted.\n"); break;
|
||||||
|
default : break;
|
||||||
|
}
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int CmdHF14AMfChk(const char *Cmd)
|
int CmdHF14AMfChk(const char *Cmd)
|
||||||
{
|
{
|
||||||
if (strlen(Cmd)<3) {
|
if (strlen(Cmd)<3) {
|
||||||
|
@ -2017,6 +2116,7 @@ static command_t CommandTable[] =
|
||||||
{"chk", CmdHF14AMfChk, 0, "Test block keys"},
|
{"chk", CmdHF14AMfChk, 0, "Test block keys"},
|
||||||
{"mifare", CmdHF14AMifare, 0, "Read parity error messages."},
|
{"mifare", CmdHF14AMifare, 0, "Read parity error messages."},
|
||||||
{"nested", CmdHF14AMfNested, 0, "Test nested authentication"},
|
{"nested", CmdHF14AMfNested, 0, "Test nested authentication"},
|
||||||
|
{"hardnested", CmdHF14AMfNestedHard, 0, "Nested attack for hardened Mifare cards"},
|
||||||
{"sniff", CmdHF14AMfSniff, 0, "Sniff card-reader communication"},
|
{"sniff", CmdHF14AMfSniff, 0, "Sniff card-reader communication"},
|
||||||
{"sim", CmdHF14AMf1kSim, 0, "Simulate MIFARE card"},
|
{"sim", CmdHF14AMf1kSim, 0, "Simulate MIFARE card"},
|
||||||
{"eclr", CmdHF14AMfEClear, 0, "Clear simulator memory block"},
|
{"eclr", CmdHF14AMfEClear, 0, "Clear simulator memory block"},
|
||||||
|
|
|
@ -38,6 +38,7 @@ int CmdHF14AMfUWrBl(const char* cmd);
|
||||||
int CmdHF14AMfChk(const char* cmd);
|
int CmdHF14AMfChk(const char* cmd);
|
||||||
int CmdHF14AMifare(const char* cmd);
|
int CmdHF14AMifare(const char* cmd);
|
||||||
int CmdHF14AMfNested(const char* cmd);
|
int CmdHF14AMfNested(const char* cmd);
|
||||||
|
int CmdHF14AMfNestedHard(const char *Cmd);
|
||||||
int CmdHF14AMfSniff(const char* cmd);
|
int CmdHF14AMfSniff(const char* cmd);
|
||||||
int CmdHF14AMf1kSim(const char* cmd);
|
int CmdHF14AMf1kSim(const char* cmd);
|
||||||
int CmdHF14AMfEClear(const char* cmd);
|
int CmdHF14AMfEClear(const char* cmd);
|
||||||
|
|
|
@ -134,7 +134,7 @@ int usage_t55xx_detect(){
|
||||||
PrintAndLog("Examples:");
|
PrintAndLog("Examples:");
|
||||||
PrintAndLog(" lf t55xx detect");
|
PrintAndLog(" lf t55xx detect");
|
||||||
PrintAndLog(" lf t55xx detect 1");
|
PrintAndLog(" lf t55xx detect 1");
|
||||||
PrintAndLog(" lf t55xx detect 11223344");
|
PrintAndLog(" lf t55xx detect p 11223344");
|
||||||
PrintAndLog("");
|
PrintAndLog("");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -149,6 +149,14 @@ int usage_t55xx_wakup(){
|
||||||
PrintAndLog(" lf t55xx wakeup p 11223344 - send wakeup password");
|
PrintAndLog(" lf t55xx wakeup p 11223344 - send wakeup password");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
int usage_t55xx_bruteforce(){
|
||||||
|
PrintAndLog("Usage: lf t55xx bruteforce <start password> <end password>");
|
||||||
|
PrintAndLog(" password must be 4 bytes (8 hex symbols)");
|
||||||
|
PrintAndLog("Examples:");
|
||||||
|
PrintAndLog(" lf t55xx bruteforce aaaaaaaa bbbbbbbb");
|
||||||
|
PrintAndLog("");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
|
@ -1307,20 +1315,61 @@ int CmdT55xxWipe(const char *Cmd) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CmdT55xxBruteForce(const char *Cmd) {
|
||||||
|
uint32_t start_password = 0x00000000; //start password
|
||||||
|
uint32_t end_password = 0xFFFFFFFF; //end password
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
|
char cmdp = param_getchar(Cmd, 0);
|
||||||
|
if (cmdp == 'h' || cmdp == 'H') return usage_t55xx_bruteforce();
|
||||||
|
|
||||||
|
start_password = param_get32ex(Cmd, 0, 0, 16);
|
||||||
|
end_password = param_get32ex(Cmd, 1, 0, 16);
|
||||||
|
|
||||||
|
if ( start_password == end_password ) return usage_t55xx_bruteforce();
|
||||||
|
|
||||||
|
PrintAndLog("Start Password %08x", start_password);
|
||||||
|
PrintAndLog(" End Password %08x", end_password);
|
||||||
|
|
||||||
|
int i = start_password;
|
||||||
|
|
||||||
|
while ((!found) && (i <= end_password)){
|
||||||
|
|
||||||
|
AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, TRUE, i);
|
||||||
|
found = tryDetectModulation();
|
||||||
|
|
||||||
|
if (found)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if ((i % 0x100) == 0) printf("[%08x], ",i);
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintAndLog("");
|
||||||
|
|
||||||
|
if (found)
|
||||||
|
PrintAndLog("Found Password [%08x]", i);
|
||||||
|
else
|
||||||
|
PrintAndLog("NOT Found Last Password [%08x]", i);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static command_t CommandTable[] = {
|
static command_t CommandTable[] = {
|
||||||
{"help", CmdHelp, 1, "This help"},
|
{"help", CmdHelp, 1, "This help"},
|
||||||
{"config", CmdT55xxSetConfig, 1, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"},
|
{"bruceforce", CmdT55xxBruteForce,0, "Simple bruteforce attack to find password"},
|
||||||
{"detect", CmdT55xxDetect, 1, "[1] Try detecting the tag modulation from reading the configuration block."},
|
{"config", CmdT55xxSetConfig, 1, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"},
|
||||||
{"read", CmdT55xxReadBlock, 0, "b <block> p [password] [o] [1] -- Read T55xx block data. Optional [p password], [override], [page1]"},
|
{"detect", CmdT55xxDetect, 1, "[1] Try detecting the tag modulation from reading the configuration block."},
|
||||||
{"resetread",CmdResetRead, 0, "Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)"},
|
{"dump", CmdT55xxDump, 0, "[password] [o] Dump T55xx card block 0-7. Optional [password], [override]"},
|
||||||
{"write", CmdT55xxWriteBlock,0, "b <block> d <data> p [password] [1] -- Write T55xx block data. Optional [p password], [page1]"},
|
{"info", CmdT55xxInfo, 1, "[1] Show T55x7 configuration data (page 0/ blk 0)"},
|
||||||
{"trace", CmdT55xxReadTrace, 1, "[1] Show T55x7 traceability data (page 1/ blk 0-1)"},
|
{"read", CmdT55xxReadBlock, 0, "b <block> p [password] [o] [1] -- Read T55xx block data. Optional [p password], [override], [page1]"},
|
||||||
{"info", CmdT55xxInfo, 1, "[1] Show T55x7 configuration data (page 0/ blk 0)"},
|
{"resetread", CmdResetRead, 0, "Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)"},
|
||||||
{"dump", CmdT55xxDump, 0, "[password] [o] Dump T55xx card block 0-7. Optional [password], [override]"},
|
{"special", special, 0, "Show block changes with 64 different offsets"},
|
||||||
{"special", special, 0, "Show block changes with 64 different offsets"},
|
{"trace", CmdT55xxReadTrace, 1, "[1] Show T55x7 traceability data (page 1/ blk 0-1)"},
|
||||||
{"wakeup", CmdT55xxWakeUp, 0, "Send AOR wakeup command"},
|
{"wakeup", CmdT55xxWakeUp, 0, "Send AOR wakeup command"},
|
||||||
{"wipe", CmdT55xxWipe, 0, "Wipe a T55xx tag and set defaults (will destroy any data on tag)"},
|
{"wipe", CmdT55xxWipe, 0, "Wipe a T55xx tag and set defaults (will destroy any data on tag)"},
|
||||||
{NULL, NULL, 0, NULL}
|
{"write", CmdT55xxWriteBlock,0, "b <block> d <data> p [password] [1] -- Write T55xx block data. Optional [p password], [page1]"},
|
||||||
|
{NULL, NULL, 0, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
int CmdLFT55XX(const char *Cmd) {
|
int CmdLFT55XX(const char *Cmd) {
|
||||||
|
|
|
@ -75,6 +75,7 @@ int CmdT55xxInfo(const char *Cmd);
|
||||||
int CmdT55xxDetect(const char *Cmd);
|
int CmdT55xxDetect(const char *Cmd);
|
||||||
int CmdResetRead(const char *Cmd);
|
int CmdResetRead(const char *Cmd);
|
||||||
int CmdT55xxWipe(const char *Cmd);
|
int CmdT55xxWipe(const char *Cmd);
|
||||||
|
int CmdT55xxBruteForce(const char *Cmd);
|
||||||
|
|
||||||
char * GetBitRateStr(uint32_t id);
|
char * GetBitRateStr(uint32_t id);
|
||||||
char * GetSaferStr(uint32_t id);
|
char * GetSaferStr(uint32_t id);
|
||||||
|
@ -92,4 +93,5 @@ bool test(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk, bool *Q5)
|
||||||
int special(const char *Cmd);
|
int special(const char *Cmd);
|
||||||
int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password );
|
int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password );
|
||||||
|
|
||||||
|
bool detectPassword(int password);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -17,9 +17,9 @@
|
||||||
|
|
||||||
uint8_t* sample_buf;
|
uint8_t* sample_buf;
|
||||||
|
|
||||||
void GetFromBigBuf(uint8_t *dest, int bytes, int start_index)
|
void GetFromBigBuf(uint8_t *dest, int bytes, int start_index) {
|
||||||
{
|
sample_buf = dest;
|
||||||
sample_buf = dest;
|
UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {start_index, bytes, 0}};
|
||||||
UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {start_index, bytes, 0}};
|
clearCommandBuffer();
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
}
|
}
|
||||||
|
|
|
@ -168,6 +168,8 @@ typedef struct{
|
||||||
|
|
||||||
#define CMD_READER_MIFARE 0x0611
|
#define CMD_READER_MIFARE 0x0611
|
||||||
#define CMD_MIFARE_NESTED 0x0612
|
#define CMD_MIFARE_NESTED 0x0612
|
||||||
|
#define CMD_MIFARE_ACQUIRE_ENCRYPTED_NONCES 0x0613
|
||||||
|
|
||||||
|
|
||||||
#define CMD_MIFARE_READBL 0x0620
|
#define CMD_MIFARE_READBL 0x0620
|
||||||
#define CMD_MIFAREU_READBL 0x0720
|
#define CMD_MIFAREU_READBL 0x0720
|
||||||
|
|
|
@ -129,6 +129,7 @@ local _commands = {
|
||||||
|
|
||||||
CMD_READER_MIFARE = 0x0611,
|
CMD_READER_MIFARE = 0x0611,
|
||||||
CMD_MIFARE_NESTED = 0x0612,
|
CMD_MIFARE_NESTED = 0x0612,
|
||||||
|
CMD_MIFARE_ACQUIRE_ENCRYPTED_NONCES = 0x0613,
|
||||||
|
|
||||||
CMD_MIFARE_READBL = 0x0620,
|
CMD_MIFARE_READBL = 0x0620,
|
||||||
CMD_MIFAREU_READBL = 0x0720,
|
CMD_MIFAREU_READBL = 0x0720,
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
//generic
|
//generic
|
||||||
|
uint8_t justNoise(uint8_t *BitStream, size_t size);
|
||||||
size_t addParity(uint8_t *BitSource, uint8_t *dest, uint8_t sourceLen, uint8_t pLen, uint8_t pType);
|
size_t addParity(uint8_t *BitSource, uint8_t *dest, uint8_t sourceLen, uint8_t pLen, uint8_t pType);
|
||||||
int askdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr, uint8_t amp, uint8_t askType);
|
int askdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr, uint8_t amp, uint8_t askType);
|
||||||
int BiphaseRawDecode(uint8_t * BitStream, size_t *size, int offset, int invert);
|
int BiphaseRawDecode(uint8_t * BitStream, size_t *size, int offset, int invert);
|
||||||
|
|
|
@ -171,6 +171,7 @@ typedef struct{
|
||||||
|
|
||||||
#define CMD_READER_MIFARE 0x0611
|
#define CMD_READER_MIFARE 0x0611
|
||||||
#define CMD_MIFARE_NESTED 0x0612
|
#define CMD_MIFARE_NESTED 0x0612
|
||||||
|
#define CMD_MIFARE_ACQUIRE_ENCRYPTED_NONCES 0x0613
|
||||||
|
|
||||||
#define CMD_MIFARE_READBL 0x0620
|
#define CMD_MIFARE_READBL 0x0620
|
||||||
#define CMD_MIFAREU_READBL 0x0720
|
#define CMD_MIFAREU_READBL 0x0720
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue