mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-20 21:33:47 -07:00
hf mf darkside uses NG. checkbutton more seldom, shoulded interfere with syncing the prng so much
This commit is contained in:
parent
878e394cde
commit
3e22d99b03
3 changed files with 91 additions and 31 deletions
|
@ -1032,7 +1032,13 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_HF_MIFARE_READER: {
|
case CMD_HF_MIFARE_READER: {
|
||||||
ReaderMifare(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2]);
|
struct p {
|
||||||
|
uint8_t first_run;
|
||||||
|
uint8_t blockno;
|
||||||
|
uint8_t key_type;
|
||||||
|
} PACKED;
|
||||||
|
struct p *payload = (struct p *) packet->data.asBytes;
|
||||||
|
ReaderMifare(payload->first_run, payload->blockno, payload->key_type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_HF_MIFARE_READBL: {
|
case CMD_HF_MIFARE_READBL: {
|
||||||
|
|
|
@ -2791,6 +2791,8 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
|
||||||
static uint8_t par_low = 0;
|
static uint8_t par_low = 0;
|
||||||
static uint8_t mf_nr_ar3 = 0;
|
static uint8_t mf_nr_ar3 = 0;
|
||||||
|
|
||||||
|
int return_status = PM3_SUCCESS;
|
||||||
|
|
||||||
AddCrc14A(mf_auth, 2);
|
AddCrc14A(mf_auth, 2);
|
||||||
|
|
||||||
if (first_try) {
|
if (first_try) {
|
||||||
|
@ -2807,6 +2809,7 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
|
||||||
}
|
}
|
||||||
|
|
||||||
LED_C_ON();
|
LED_C_ON();
|
||||||
|
uint16_t checkbtn_cnt = 0;
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
for (i = 0; true; ++i) {
|
for (i = 0; true; ++i) {
|
||||||
|
|
||||||
|
@ -2815,10 +2818,15 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
// Test if the action was cancelled
|
// Test if the action was cancelled
|
||||||
if (BUTTON_PRESS()) {
|
if (checkbtn_cnt == 2000) {
|
||||||
|
if (BUTTON_PRESS() || data_available()) {
|
||||||
isOK = -1;
|
isOK = -1;
|
||||||
|
return_status = PM3_EABORTED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
checkbtn_cnt = 0;
|
||||||
|
}
|
||||||
|
checkbtn_cnt++;
|
||||||
|
|
||||||
// this part is from Piwi's faster nonce collecting part in Hardnested.
|
// this part is from Piwi's faster nonce collecting part in Hardnested.
|
||||||
if (!have_uid) { // need a full select cycle to get the uid first
|
if (!have_uid) { // need a full select cycle to get the uid first
|
||||||
|
@ -2876,8 +2884,15 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
|
||||||
ReaderTransmitPar(mf_nr_ar, sizeof(mf_nr_ar), par, NULL);
|
ReaderTransmitPar(mf_nr_ar, sizeof(mf_nr_ar), par, NULL);
|
||||||
|
|
||||||
// Receive answer. This will be a 4 Bit NACK when the 8 parity bits are OK after decoding
|
// Receive answer. This will be a 4 Bit NACK when the 8 parity bits are OK after decoding
|
||||||
if (ReaderReceive(receivedAnswer, receivedAnswerPar))
|
int resp_res = ReaderReceive(receivedAnswer, receivedAnswerPar);
|
||||||
|
if (resp_res == 4)
|
||||||
received_nack = true;
|
received_nack = true;
|
||||||
|
else if (resp_res == 32) {
|
||||||
|
// did we get lucky and got our dummykey to be valid?
|
||||||
|
isOK = -6;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// we didn't calibrate our clock yet,
|
// we didn't calibrate our clock yet,
|
||||||
// iceman: has to be calibrated every time.
|
// iceman: has to be calibrated every time.
|
||||||
|
@ -3000,15 +3015,25 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
|
||||||
|
|
||||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("Number of sent auth requests: %u", i);
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("Number of sent auth requests: %u", i);
|
||||||
|
|
||||||
uint8_t buf[32] = {0x00};
|
struct {
|
||||||
memset(buf, 0x00, sizeof(buf));
|
int32_t isOK;
|
||||||
num_to_bytes(cuid, 4, buf);
|
uint8_t cuid[4];
|
||||||
num_to_bytes(nt, 4, buf + 4);
|
uint8_t nt[4];
|
||||||
memcpy(buf + 8, par_list, 8);
|
uint8_t par_list[8];
|
||||||
memcpy(buf + 16, ks_list, 8);
|
uint8_t ks_list[8];
|
||||||
memcpy(buf + 24, mf_nr_ar, 8);
|
uint8_t nr[4];
|
||||||
|
uint8_t ar[4];
|
||||||
|
} PACKED payload;
|
||||||
|
|
||||||
reply_mix(CMD_ACK, isOK, 0, 0, buf, sizeof(buf));
|
payload.isOK = isOK;
|
||||||
|
num_to_bytes(cuid, 4, payload.cuid);
|
||||||
|
num_to_bytes(nt, 4, payload.nt);
|
||||||
|
memcpy(payload.par_list, par_list, sizeof(payload.par_list));
|
||||||
|
memcpy(payload.ks_list, ks_list, sizeof(payload.ks_list));
|
||||||
|
memcpy(payload.nr, mf_nr_ar, sizeof(payload.nr));
|
||||||
|
memcpy(payload.ar, mf_nr_ar + 4, sizeof(payload.ar));
|
||||||
|
|
||||||
|
reply_ng(CMD_HF_MIFARE_READER, return_status, (uint8_t*)&payload, sizeof(payload));
|
||||||
|
|
||||||
hf_field_off();
|
hf_field_off();
|
||||||
set_tracing(false);
|
set_tracing(false);
|
||||||
|
|
|
@ -30,7 +30,7 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) {
|
||||||
uint32_t nt = 0, nr = 0, ar = 0;
|
uint32_t nt = 0, nr = 0, ar = 0;
|
||||||
uint64_t par_list = 0, ks_list = 0;
|
uint64_t par_list = 0, ks_list = 0;
|
||||||
uint64_t *keylist = NULL, *last_keylist = NULL;
|
uint64_t *keylist = NULL, *last_keylist = NULL;
|
||||||
bool arg0 = true;
|
bool first_run = true;
|
||||||
|
|
||||||
// message
|
// message
|
||||||
PrintAndLogEx(NORMAL, "--------------------------------------------------------------------------------\n");
|
PrintAndLogEx(NORMAL, "--------------------------------------------------------------------------------\n");
|
||||||
|
@ -40,7 +40,15 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) {
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandMIX(CMD_HF_MIFARE_READER, arg0, blockno, key_type, NULL, 0);
|
struct {
|
||||||
|
uint8_t first_run;
|
||||||
|
uint8_t blockno;
|
||||||
|
uint8_t key_type;
|
||||||
|
} PACKED payload;
|
||||||
|
payload.first_run = first_run;
|
||||||
|
payload.blockno = blockno;
|
||||||
|
payload.key_type = key_type;
|
||||||
|
SendCommandNG(CMD_HF_MIFARE_READER, (uint8_t*)&payload, sizeof(payload));
|
||||||
|
|
||||||
//flush queue
|
//flush queue
|
||||||
while (kbd_enter_pressed()) {
|
while (kbd_enter_pressed()) {
|
||||||
|
@ -56,26 +64,47 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) {
|
||||||
}
|
}
|
||||||
|
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
|
if (WaitForResponseTimeout(CMD_HF_MIFARE_READER, &resp, 2000)) {
|
||||||
int16_t isOK = resp.oldarg[0];
|
if (resp.status == PM3_EABORTED) {
|
||||||
if (isOK < 0)
|
return -1;
|
||||||
return isOK;
|
}
|
||||||
|
|
||||||
uid = (uint32_t)bytes_to_num(resp.data.asBytes + 0, 4);
|
struct p {
|
||||||
nt = (uint32_t)bytes_to_num(resp.data.asBytes + 4, 4);
|
int32_t isOK;
|
||||||
par_list = bytes_to_num(resp.data.asBytes + 8, 8);
|
uint8_t cuid[4];
|
||||||
ks_list = bytes_to_num(resp.data.asBytes + 16, 8);
|
uint8_t nt[4];
|
||||||
nr = (uint32_t)bytes_to_num(resp.data.asBytes + 24, 4);
|
uint8_t par_list[8];
|
||||||
ar = (uint32_t)bytes_to_num(resp.data.asBytes + 28, 4);
|
uint8_t ks_list[8];
|
||||||
|
uint8_t nr[4];
|
||||||
|
uint8_t ar[4];
|
||||||
|
} PACKED;
|
||||||
|
|
||||||
|
struct p* package = (struct p*) resp.data.asBytes;
|
||||||
|
|
||||||
|
if (package->isOK == -6) {
|
||||||
|
*key = 0101;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (package->isOK < 0)
|
||||||
|
return package->isOK;
|
||||||
|
|
||||||
|
|
||||||
|
uid = (uint32_t)bytes_to_num(package->cuid, sizeof(package->cuid));
|
||||||
|
nt = (uint32_t)bytes_to_num(package->nt, sizeof(package->nr));
|
||||||
|
par_list = bytes_to_num(package->par_list, sizeof(package->par_list));
|
||||||
|
ks_list = bytes_to_num(package->ks_list, sizeof(package->ks_list));
|
||||||
|
nr = (uint32_t)bytes_to_num(package->nr, 4);
|
||||||
|
ar = (uint32_t)bytes_to_num(package->ar, 4);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PrintAndLogEx(NORMAL, "\n");
|
PrintAndLogEx(NORMAL, "\n");
|
||||||
|
|
||||||
if (par_list == 0 && arg0 == true) {
|
if (par_list == 0 && first_run == true) {
|
||||||
PrintAndLogEx(SUCCESS, "Parity is all zero. Most likely this card sends NACK on every authentication.");
|
PrintAndLogEx(SUCCESS, "Parity is all zero. Most likely this card sends NACK on every authentication.");
|
||||||
}
|
}
|
||||||
arg0 = false;
|
first_run = false;
|
||||||
|
|
||||||
uint32_t keycount = nonce2key(uid, nt, nr, ar, par_list, ks_list, &keylist);
|
uint32_t keycount = nonce2key(uid, nt, nr, ar, par_list, ks_list, &keylist);
|
||||||
|
|
||||||
|
@ -124,7 +153,7 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) {
|
||||||
PrintAndLogEx(FAILED, "all candidate keys failed. Restarting darkside attack");
|
PrintAndLogEx(FAILED, "all candidate keys failed. Restarting darkside attack");
|
||||||
free(last_keylist);
|
free(last_keylist);
|
||||||
last_keylist = keylist;
|
last_keylist = keylist;
|
||||||
arg0 = true;
|
first_run = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(last_keylist);
|
free(last_keylist);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue