mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 13:53:55 -07:00
chg: 'hf iclass rdbl' - now retries 10 ten times and uses NG
This commit is contained in:
parent
a037766e26
commit
305c54f3cf
3 changed files with 85 additions and 40 deletions
|
@ -1237,7 +1237,11 @@ static void PacketReceived(PacketCommandNG *packet) {
|
|||
break;
|
||||
}
|
||||
case CMD_HF_ICLASS_READBL: {
|
||||
iClass_ReadBlk(packet->oldarg[0]);
|
||||
struct p {
|
||||
uint8_t blockno;
|
||||
} PACKED;
|
||||
struct p *payload = (struct p *)packet->data.asBytes;
|
||||
iClass_ReadBlk( payload->blockno );
|
||||
break;
|
||||
}
|
||||
case CMD_HF_ICLASS_AUTH: { //check
|
||||
|
|
|
@ -1720,7 +1720,7 @@ static int SendIClassAnswer(uint8_t *resp, int respLen, uint16_t delay) {
|
|||
static void TransmitIClassCommand(const uint8_t *cmd, int len, int *samples, int *wait) {
|
||||
|
||||
int c = 0;
|
||||
volatile uint32_t b;
|
||||
// volatile uint32_t b;
|
||||
bool firstpart = true;
|
||||
uint8_t sendbyte;
|
||||
|
||||
|
@ -1758,10 +1758,12 @@ static void TransmitIClassCommand(const uint8_t *cmd, int len, int *samples, int
|
|||
}
|
||||
|
||||
// Prevent rx holding register from overflowing
|
||||
/*
|
||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
||||
b = AT91C_BASE_SSC->SSC_RHR;
|
||||
(void)b;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
time_rdr = GetCountSspClk();
|
||||
|
@ -1949,12 +1951,11 @@ void setupIclassReader() {
|
|||
LED_A_ON();
|
||||
}
|
||||
|
||||
bool sendCmdGetResponseWithRetries(uint8_t *command, size_t cmdsize, uint8_t *resp, uint8_t expected_size, uint8_t retries) {
|
||||
bool sendCmdGetResponseWithRetries(uint8_t *command, size_t cmdsize, uint8_t *resp, uint8_t expected_size, int8_t retries) {
|
||||
while (retries-- > 0) {
|
||||
|
||||
ReaderTransmitIClass(command, cmdsize);
|
||||
|
||||
|
||||
//iceman - if received size is bigger than expected, we smash the stack here
|
||||
// since its called with fixed sized arrays
|
||||
|
||||
|
@ -1967,7 +1968,7 @@ bool sendCmdGetResponseWithRetries(uint8_t *command, size_t cmdsize, uint8_t *re
|
|||
// 0xBB is the internal debug separator byte..
|
||||
if (expected_size != got_n || (resp[0] == 0xBB || resp[7] == 0xBB || resp[2] == 0xBB)) {
|
||||
//try again
|
||||
SpinDelayUs(400);
|
||||
SpinDelayUs(360);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -2456,10 +2457,14 @@ bool iClass_ReadBlock(uint8_t blockno, uint8_t *data, uint8_t len) {
|
|||
// turn off afterwards
|
||||
// readblock 8 + 2. only want 8.
|
||||
void iClass_ReadBlk(uint8_t blockno) {
|
||||
uint8_t data[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
bool isOK = iClass_ReadBlock(blockno, data, sizeof(data));
|
||||
reply_mix(CMD_ACK, isOK, 0, 0, data, sizeof(data));
|
||||
struct p {
|
||||
bool isOK;
|
||||
uint8_t blockdata[8];
|
||||
} PACKED result;
|
||||
|
||||
result.isOK = iClass_ReadBlock(blockno, result.blockdata, sizeof(result.blockdata));
|
||||
switch_off();
|
||||
reply_ng(CMD_HF_ICLASS_READBL, PM3_SUCCESS, (uint8_t *)&result, sizeof(result));
|
||||
}
|
||||
|
||||
// turn off afterwards
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
#define NUM_CSNS 9
|
||||
#define ICLASS_KEYS_MAX 8
|
||||
#define ICLASS_AUTH_RETRY 10
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
|
@ -662,6 +663,10 @@ static int CmdHFiClassSim(const char *Cmd) {
|
|||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdHFiClassInfo(const char *Cmd) {
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdHFiClassReader(const char *Cmd) {
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (cmdp == 'h') return usage_hf_iclass_reader();
|
||||
|
@ -1563,36 +1568,62 @@ static int CmdHFiClassCloneTag(const char *Cmd) {
|
|||
}
|
||||
|
||||
static int ReadBlock(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite, bool rawkey, bool verbose, bool auth) {
|
||||
// block 0,1 should always be able to read, and block 5 on some cards.
|
||||
if (auth || blockno >= 2) {
|
||||
uint8_t MAC[4] = {0x00, 0x00, 0x00, 0x00};
|
||||
uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
if (!select_and_auth(KEY, MAC, div_key, (keyType == 0x18), elite, rawkey, verbose))
|
||||
return 0;
|
||||
|
||||
int numberAuthRetries = ICLASS_AUTH_RETRY;
|
||||
// return data.
|
||||
struct p {
|
||||
bool isOK;
|
||||
uint8_t blockdata[8];
|
||||
} PACKED;
|
||||
|
||||
struct p *result = NULL;
|
||||
|
||||
do {
|
||||
// block 0,1 should always be able to read, and block 5 on some cards.
|
||||
if (auth || blockno >= 2) {
|
||||
uint8_t MAC[4] = {0x00, 0x00, 0x00, 0x00};
|
||||
uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
if (!select_and_auth(KEY, MAC, div_key, (keyType == 0x18), elite, rawkey, verbose)) {
|
||||
numberAuthRetries--;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
uint8_t CSN[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
uint8_t CCNR[12] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
if (!select_only(CSN, CCNR, (keyType == 0x18), verbose)) {
|
||||
numberAuthRetries--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
PacketResponseNG resp;
|
||||
clearCommandBuffer();
|
||||
uint8_t payload[] = { blockno };
|
||||
SendCommandNG(CMD_HF_ICLASS_READBL, payload, sizeof(payload));
|
||||
|
||||
if (WaitForResponseTimeout(CMD_HF_ICLASS_READBL, &resp, 2000) == 0) {
|
||||
PrintAndLogEx(WARNING, "Command execute timeout");
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
|
||||
if ( resp.status != PM3_SUCCESS ) {
|
||||
PrintAndLogEx(ERR, "failed to communicate with card");
|
||||
return PM3_EWRONGANSVER;
|
||||
}
|
||||
|
||||
result = (struct p*)resp.data.asBytes;
|
||||
if (result->isOK)
|
||||
break;
|
||||
|
||||
} while (numberAuthRetries);
|
||||
|
||||
if ( numberAuthRetries > 0 ) {
|
||||
PrintAndLogEx(SUCCESS, "block %02X: %s\n", blockno, sprint_hex(result->blockdata, sizeof(result->blockdata)));
|
||||
} else {
|
||||
uint8_t CSN[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
uint8_t CCNR[12] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
if (!select_only(CSN, CCNR, (keyType == 0x18), verbose))
|
||||
return 0;
|
||||
PrintAndLogEx(ERR,"failed to authenticate and read block");
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
PacketResponseNG resp;
|
||||
clearCommandBuffer();
|
||||
SendCommandMIX(CMD_HF_ICLASS_READBL, blockno, 0, 0, NULL, 0);
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 4500)) {
|
||||
PrintAndLogEx(WARNING, "Command execute timeout");
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t isOK = resp.oldarg[0] & 0xff;
|
||||
if (!isOK) {
|
||||
PrintAndLogEx(WARNING, "read block failed");
|
||||
return 0;
|
||||
}
|
||||
//data read is stored in: resp.data.asBytes[0-15]
|
||||
PrintAndLogEx(NORMAL, "block %02X: %s\n", blockno, sprint_hex(resp.data.asBytes, 8));
|
||||
// should decrypt it if file is accessable.
|
||||
return 1;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdHFiClass_ReadBlock(const char *Cmd) {
|
||||
|
@ -1613,14 +1644,16 @@ static int CmdHFiClass_ReadBlock(const char *Cmd) {
|
|||
case 'h':
|
||||
return usage_hf_iclass_readblock();
|
||||
case 'b':
|
||||
blockno = param_get8ex(Cmd, cmdp + 1, 06, 16);
|
||||
blockno = param_get8ex(Cmd, cmdp + 1, 7, 16);
|
||||
cmdp += 2;
|
||||
break;
|
||||
case 'c':
|
||||
PrintAndLogEx(SUCCESS, "Using " _YELLOW_("CREDIT"));
|
||||
keyType = 0x18;
|
||||
cmdp++;
|
||||
break;
|
||||
case 'e':
|
||||
PrintAndLogEx(SUCCESS, "Using " _YELLOW_("elite algo"));
|
||||
elite = true;
|
||||
cmdp++;
|
||||
break;
|
||||
|
@ -1632,6 +1665,7 @@ static int CmdHFiClass_ReadBlock(const char *Cmd) {
|
|||
} else if (dataLen == 1) {
|
||||
keyNbr = param_get8(Cmd, cmdp + 1);
|
||||
if (keyNbr < ICLASS_KEYS_MAX) {
|
||||
PrintAndLogEx(SUCCESS, "Using key[%d] %s", keyNbr, sprint_hex(iClass_Key_Table[keyNbr], 8 ));
|
||||
memcpy(KEY, iClass_Key_Table[keyNbr], 8);
|
||||
} else {
|
||||
PrintAndLogEx(WARNING, "\nERROR: Credit KeyNbr is invalid\n");
|
||||
|
@ -1644,6 +1678,7 @@ static int CmdHFiClass_ReadBlock(const char *Cmd) {
|
|||
cmdp += 2;
|
||||
break;
|
||||
case 'r':
|
||||
PrintAndLogEx(SUCCESS, "Using " _YELLOW_("raw mode"));
|
||||
rawkey = true;
|
||||
cmdp++;
|
||||
break;
|
||||
|
@ -2127,7 +2162,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) {
|
|||
|
||||
// Get CSN / UID and CCNR
|
||||
PrintAndLogEx(SUCCESS, "Reading tag CSN");
|
||||
for (uint8_t i = 0; i < 10 && !got_csn; i++) {
|
||||
for (uint8_t i = 0; i < ICLASS_AUTH_RETRY && !got_csn; i++) {
|
||||
got_csn = select_only(CSN, CCNR, false, false);
|
||||
if (got_csn == false)
|
||||
PrintAndLogEx(WARNING, "one more try\n");
|
||||
|
@ -2611,18 +2646,19 @@ static command_t CommandTable[] = {
|
|||
{"dump", CmdHFiClassReader_Dump, IfPm3Iclass, "[options..] Authenticate and Dump iClass tag's AA1"},
|
||||
{"eload", CmdHFiClassELoad, IfPm3Iclass, "[f <fname>] (experimental) Load data into iClass emulator memory"},
|
||||
{"encrypt", CmdHFiClassEncryptBlk, AlwaysAvailable, "[options..] Encrypt given block data"},
|
||||
{"info", CmdHFiClassInfo, AlwaysAvailable, " Tag information"},
|
||||
{"list", CmdHFiClassList, AlwaysAvailable, " List iClass history"},
|
||||
{"loclass", CmdHFiClass_loclass, AlwaysAvailable, "[options..] Use loclass to perform bruteforce of reader attack dump"},
|
||||
{"lookup", CmdHFiClassLookUp, AlwaysAvailable, "[options..] Uses authentication trace to check for key in dictionary file"},
|
||||
{"managekeys", CmdHFiClassManageKeys, AlwaysAvailable, "[options..] Manage the keys to use with iClass"},
|
||||
{"permutekey", CmdHFiClassPermuteKey, IfPm3Iclass, " Permute function from 'heart of darkness' paper"},
|
||||
{"readblk", CmdHFiClass_ReadBlock, IfPm3Iclass, "[options..] Read iClass block"},
|
||||
{"rdbl", CmdHFiClass_ReadBlock, IfPm3Iclass, "[options..] Read iClass block"},
|
||||
{"reader", CmdHFiClassReader, IfPm3Iclass, " Act like an iClass reader"},
|
||||
{"readtagfile", CmdHFiClassReadTagFile, AlwaysAvailable, "[options..] Display Content from tagfile"},
|
||||
{"replay", CmdHFiClassReader_Replay, IfPm3Iclass, "<mac> Read an iClass tag via Replay Attack"},
|
||||
{"sim", CmdHFiClassSim, IfPm3Iclass, "[options..] Simulate iClass tag"},
|
||||
{"sniff", CmdHFiClassSniff, IfPm3Iclass, " Eavesdrop iClass communication"},
|
||||
{"writeblk", CmdHFiClass_WriteBlock, IfPm3Iclass, "[options..] Write iClass block"},
|
||||
{"wrbl", CmdHFiClass_WriteBlock, IfPm3Iclass, "[options..] Write iClass block"},
|
||||
{NULL, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue