mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-05-12 11:18:11 -07:00
Merge branch 'RfidResearchGroup:master' into master
This commit is contained in:
+20
-16
@@ -646,30 +646,34 @@ static int CmdHF14AJookiClone(const char *Cmd) {
|
||||
has_pwd = true;
|
||||
}
|
||||
|
||||
// 0 - no authentication
|
||||
// 2 - pwd (4 bytes)
|
||||
uint8_t keytype = 0, blockno = 4, i = 0;
|
||||
// keytype = 0 - no authentication
|
||||
// keytype = 2 - pwd (4 bytes)
|
||||
uint8_t i = 0;
|
||||
mful_writeblock_t packetw = {
|
||||
.keytype = 0, // no key
|
||||
.block_no = 4,
|
||||
.use_schann = false,
|
||||
.keylen = 0,
|
||||
};
|
||||
|
||||
while ((i * 4) < dlen) {
|
||||
|
||||
uint8_t cmddata[8] = {0};
|
||||
memcpy(cmddata, data + (i * 4), 4);
|
||||
memcpy(packetw.data, data + (i * 4), 4);
|
||||
if (has_pwd) {
|
||||
memcpy(cmddata + 4, pwd, 4);
|
||||
keytype = 2;
|
||||
packetw.keytype = 2;
|
||||
memcpy(packetw.key, pwd, 4);
|
||||
packetw.keylen = 4;
|
||||
}
|
||||
clearCommandBuffer();
|
||||
SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, blockno, keytype, 0, cmddata, sizeof(cmddata));
|
||||
|
||||
SendCommandNG(CMD_HF_MIFAREU_WRITEBL, (uint8_t *)&packetw, sizeof(packetw));
|
||||
PacketResponseNG resp;
|
||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||
uint8_t isOK = resp.oldarg[0] & 0xff;
|
||||
PrintAndLogEx(SUCCESS, "Write block %d ( %s )", blockno, isOK ? _GREEN_("ok") : _RED_("fail"));
|
||||
} else {
|
||||
PrintAndLogEx(WARNING, "command execution time out");
|
||||
}
|
||||
|
||||
blockno++;
|
||||
if (WaitForResponseTimeout(CMD_HF_MIFAREU_WRITEBL, &resp, 1500) == false) {
|
||||
PrintAndLogEx(WARNING, "command execution time out");
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
PrintAndLogEx(SUCCESS, "Write block %d ( %s )", packetw.block_no, resp.status == PM3_SUCCESS ? _GREEN_("ok") : _RED_("fail"));
|
||||
packetw.block_no++;
|
||||
i++;
|
||||
}
|
||||
|
||||
|
||||
+118
-101
@@ -3879,9 +3879,40 @@ static int CmdHF14AMfURestore(const char *Cmd) {
|
||||
|
||||
uint64_t tagtype = GetHF14AMfU_Type();
|
||||
if (tagtype == MFU_TT_UL_ERROR) {
|
||||
free(dump);
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
if ((tagtype & MFU_TT_UL_C) == MFU_TT_UL_C) {
|
||||
if ((has_key == true) && (ak_len != 16)) {
|
||||
PrintAndLogEx(ERR, "UL-C key must be 16 bytes");
|
||||
free(dump);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
if (write_extra == true) {
|
||||
PrintAndLogEx(ERR, "Option -e incompatible with your UL-C card");
|
||||
free(dump);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
} else if ((tagtype & MFU_TT_UL_AES) == MFU_TT_UL_AES) {
|
||||
if ((has_key == true) && (ak_len != 16)) {
|
||||
PrintAndLogEx(ERR, "UL-AES key must be 16 bytes");
|
||||
free(dump);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
if (write_extra == true) {
|
||||
PrintAndLogEx(ERR, "Option -e incompatible with your UL-AEScard");
|
||||
free(dump);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
} else {
|
||||
if ((has_key == true) && (ak_len == 16)) {
|
||||
PrintAndLogEx(ERR, "UL PWD must be 4 bytes");
|
||||
free(dump);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
}
|
||||
|
||||
if ((tagtype & MFU_TT_UL_AES) == MFU_TT_UL_AES) {
|
||||
PrintAndLogEx(ERR, "Sorry, UL-AES not yet supported. Feel free to implement!");
|
||||
free(dump);
|
||||
@@ -3905,18 +3936,23 @@ static int CmdHF14AMfURestore(const char *Cmd) {
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t data[20] = {0};
|
||||
uint8_t keytype = 0;
|
||||
mful_writeblock_t packetw = {
|
||||
.keytype = 0,
|
||||
.keylen = 0,
|
||||
.use_schann = use_schann,
|
||||
};
|
||||
if (has_key) {
|
||||
|
||||
if ((tagtype & MFU_TT_UL_C) == MFU_TT_UL_C) {
|
||||
keytype = 1; // UL_C auth
|
||||
packetw.keytype = 1; // UL_C auth
|
||||
packetw.keylen = 16;
|
||||
} else if ((tagtype & MFU_TT_UL_AES) == MFU_TT_UL_AES) {
|
||||
keytype = 3; // UL_AES auth
|
||||
packetw.keytype = 3; // UL_AES auth
|
||||
packetw.keylen = 16;
|
||||
} else {
|
||||
keytype = 2; // UL_EV1/NTAG auth
|
||||
packetw.keytype = 2; // UL_EV1/NTAG auth
|
||||
packetw.keylen = 4;
|
||||
}
|
||||
memcpy(data + 4, auth_key_ptr, ak_len);
|
||||
memcpy(packetw.key, auth_key_ptr, ak_len);
|
||||
}
|
||||
|
||||
// write version, signature, pack
|
||||
@@ -3930,59 +3966,51 @@ static int CmdHF14AMfURestore(const char *Cmd) {
|
||||
// pwd
|
||||
if (has_key || read_key) {
|
||||
|
||||
memcpy(data, auth_key_ptr, 4);
|
||||
memcpy(packetw.data, auth_key_ptr, 4);
|
||||
if (read_key) {
|
||||
// try reading key from dump and use.
|
||||
memcpy(data, mem->data + (bytes_read - MFU_DUMP_PREFIX_LENGTH - 8), 4);
|
||||
memcpy(packetw.data, mem->data + (bytes_read - MFU_DUMP_PREFIX_LENGTH - 8), 4);
|
||||
}
|
||||
packetw.block_no = MFU_NTAG_SPECIAL_PWD;
|
||||
|
||||
PrintAndLogEx(INFO, "special PWD block written 0x%X - %s", MFU_NTAG_SPECIAL_PWD, sprint_hex(data, 4));
|
||||
|
||||
mful_writeblock_t packet = {
|
||||
.block_no = MFU_NTAG_SPECIAL_PWD,
|
||||
.keytype = keytype,
|
||||
.keylen = 4,
|
||||
.use_schann = use_schann,
|
||||
};
|
||||
memcpy(packet.key, auth_key_ptr, 4); // password to authenticate
|
||||
|
||||
memcpy(packet.data, data, 4); // new password
|
||||
|
||||
PrintAndLogEx(INFO, "special PWD block written 0x%X - %s", MFU_NTAG_SPECIAL_PWD, sprint_hex(packetw.data, 4));
|
||||
clearCommandBuffer();
|
||||
SendCommandNG(CMD_HF_MIFAREU_WRITEBL, (uint8_t *)&packet, sizeof(packet));
|
||||
// SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, MFU_NTAG_SPECIAL_PWD, keytype, 0, data, sizeof(data));
|
||||
SendCommandNG(CMD_HF_MIFAREU_WRITEBL, (uint8_t *)&packetw, sizeof(packetw));
|
||||
wait4response(CMD_HF_MIFAREU_WRITEBL, MFU_NTAG_SPECIAL_PWD);
|
||||
|
||||
// copy the new key
|
||||
keytype = 2;
|
||||
memcpy(authenticationkey, data, 4);
|
||||
memcpy(data + 4, authenticationkey, 4);
|
||||
packetw.keytype = 2;
|
||||
packetw.keylen = 4;
|
||||
memcpy(packetw.key, packetw.data, 4);
|
||||
}
|
||||
|
||||
// pack
|
||||
memcpy(data, mem->data + (bytes_read - MFU_DUMP_PREFIX_LENGTH - 4), 2);
|
||||
data[2] = 0;
|
||||
data[3] = 0;
|
||||
PrintAndLogEx(INFO, "special PACK block written 0x%X - %s", MFU_NTAG_SPECIAL_PACK, sprint_hex(data, 4));
|
||||
memcpy(packetw.data, mem->data + (bytes_read - MFU_DUMP_PREFIX_LENGTH - 4), 2);
|
||||
packetw.data[2] = 0;
|
||||
packetw.data[3] = 0;
|
||||
packetw.block_no = MFU_NTAG_SPECIAL_PACK;
|
||||
PrintAndLogEx(INFO, "special PACK block written 0x%X - %s", MFU_NTAG_SPECIAL_PACK, sprint_hex(packetw.data, 4));
|
||||
clearCommandBuffer();
|
||||
SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, MFU_NTAG_SPECIAL_PACK, keytype, 0, data, sizeof(data));
|
||||
SendCommandNG(CMD_HF_MIFAREU_WRITEBL, (uint8_t *)&packetw, sizeof(packetw));
|
||||
wait4response(CMD_HF_MIFAREU_WRITEBL, MFU_NTAG_SPECIAL_PACK);
|
||||
|
||||
// Signature
|
||||
for (uint8_t s = MFU_NTAG_SPECIAL_SIGNATURE, i = 0; s < MFU_NTAG_SPECIAL_SIGNATURE + 8; s++, i += 4) {
|
||||
memcpy(data, mem->signature + i, 4);
|
||||
PrintAndLogEx(INFO, "special SIG block written 0x%X - %s", s, sprint_hex(data, 4));
|
||||
memcpy(packetw.data, mem->signature + i, 4);
|
||||
packetw.block_no = s;
|
||||
PrintAndLogEx(INFO, "special SIG block written 0x%X - %s", s, sprint_hex(packetw.data, 4));
|
||||
clearCommandBuffer();
|
||||
SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, s, keytype, 0, data, sizeof(data));
|
||||
SendCommandNG(CMD_HF_MIFAREU_WRITEBL, (uint8_t *)&packetw, sizeof(packetw));
|
||||
wait4response(CMD_HF_MIFAREU_WRITEBL, s);
|
||||
}
|
||||
|
||||
// Version
|
||||
for (uint8_t s = MFU_NTAG_SPECIAL_VERSION, i = 0; s < MFU_NTAG_SPECIAL_VERSION + 2; s++, i += 4) {
|
||||
memcpy(data, mem->version + i, 4);
|
||||
PrintAndLogEx(INFO, "special VERSION block written 0x%X - %s", s, sprint_hex(data, 4));
|
||||
memcpy(packetw.data, mem->version + i, 4);
|
||||
packetw.block_no = s;
|
||||
PrintAndLogEx(INFO, "special VERSION block written 0x%X - %s", s, sprint_hex(packetw.data, 4));
|
||||
clearCommandBuffer();
|
||||
SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, s, keytype, 0, data, sizeof(data));
|
||||
SendCommandNG(CMD_HF_MIFAREU_WRITEBL, (uint8_t *)&packetw, sizeof(packetw));
|
||||
wait4response(CMD_HF_MIFAREU_WRITEBL, s);
|
||||
}
|
||||
}
|
||||
@@ -3995,9 +4023,10 @@ static int CmdHF14AMfURestore(const char *Cmd) {
|
||||
for (uint8_t b = 4; b < pages - 5; b++) {
|
||||
|
||||
//Send write Block
|
||||
memcpy(data, mem->data + (b * 4), 4);
|
||||
memcpy(packetw.data, mem->data + (b * 4), 4);
|
||||
packetw.block_no = b;
|
||||
clearCommandBuffer();
|
||||
SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, b, keytype, 0, data, sizeof(data));
|
||||
SendCommandNG(CMD_HF_MIFAREU_WRITEBL, (uint8_t *)&packetw, sizeof(packetw));
|
||||
wait4response(CMD_HF_MIFAREU_WRITEBL, b);
|
||||
PrintAndLogEx(NORMAL, "." NOLF);
|
||||
fflush(stdout);
|
||||
@@ -4009,7 +4038,7 @@ static int CmdHF14AMfURestore(const char *Cmd) {
|
||||
|
||||
PrintAndLogEx(INFO, "Restoring configuration blocks");
|
||||
|
||||
PrintAndLogEx(INFO, "Authentication with keytype[%x] %s\n", (uint8_t)(keytype & 0xff), sprint_hex(auth_key_ptr, 4));
|
||||
PrintAndLogEx(INFO, "Authentication with keytype[%i] = %s\n", packetw.keytype, sprint_hex(packetw.key, packetw.keylen));
|
||||
|
||||
#if defined ICOPYX
|
||||
// otp, uid, lock, dynlockbits, cfg0, cfg1, pwd, pack
|
||||
@@ -4020,11 +4049,12 @@ static int CmdHF14AMfURestore(const char *Cmd) {
|
||||
#endif
|
||||
for (uint8_t i = 0; i < ARRAYLEN(blocks); i++) {
|
||||
uint8_t b = blocks[i];
|
||||
memcpy(data, mem->data + (b * 4), 4);
|
||||
memcpy(packetw.data, mem->data + (b * 4), 4);
|
||||
packetw.block_no = b;
|
||||
clearCommandBuffer();
|
||||
SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, b, keytype, 0, data, sizeof(data));
|
||||
SendCommandNG(CMD_HF_MIFAREU_WRITEBL, (uint8_t *)&packetw, sizeof(packetw));
|
||||
wait4response(CMD_HF_MIFAREU_WRITEBL, b);
|
||||
PrintAndLogEx(INFO, "special block written " _YELLOW_("%u") " - %s", b, sprint_hex(data, 4));
|
||||
PrintAndLogEx(INFO, "special block written " _YELLOW_("%u") " - %s", b, sprint_hex(packetw.data, 4));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4447,19 +4477,23 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) {
|
||||
}
|
||||
|
||||
PrintAndLogEx(INFO, "Please ignore possible transient BCC warnings");
|
||||
|
||||
// read block 2
|
||||
mful_readblock_t packet = {
|
||||
.block_no = 2,
|
||||
mful_readblock_t packetr = {
|
||||
.use_schann = false,
|
||||
.keytype = 0,
|
||||
.keylen = 0,
|
||||
.num_of_blocks = 1,
|
||||
};
|
||||
mful_writeblock_t packetw = {
|
||||
.keytype = 0,
|
||||
.use_schann = false,
|
||||
.keylen = 0,
|
||||
};
|
||||
|
||||
// read block 2
|
||||
packetr.block_no = 2;
|
||||
PacketResponseNG resp;
|
||||
clearCommandBuffer();
|
||||
SendCommandNG(CMD_HF_MIFAREU_READBL, (uint8_t *)&packet, sizeof(packet));
|
||||
SendCommandNG(CMD_HF_MIFAREU_READBL, (uint8_t *)&packetr, sizeof(packetr));
|
||||
if (WaitForResponseTimeout(CMD_HF_MIFAREU_READBL, &resp, 1500) == false) {
|
||||
PrintAndLogEx(WARNING, "Command execute timeout");
|
||||
return PM3_ETIMEOUT;
|
||||
@@ -4485,38 +4519,33 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) {
|
||||
}
|
||||
|
||||
// block 0.
|
||||
uint8_t data[4];
|
||||
data[0] = uid[0];
|
||||
data[1] = uid[1];
|
||||
data[2] = uid[2];
|
||||
data[3] = 0x88 ^ uid[0] ^ uid[1] ^ uid[2];
|
||||
memcpy(packetw.data, uid, 3);
|
||||
packetw.data[3] = 0x88 ^ uid[0] ^ uid[1] ^ uid[2];
|
||||
packetw.block_no = 0;
|
||||
clearCommandBuffer();
|
||||
SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, 0, 0, 0, data, sizeof(data));
|
||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500) == false) {
|
||||
SendCommandNG(CMD_HF_MIFAREU_WRITEBL, (uint8_t *)&packetw, sizeof(packetw));
|
||||
if (WaitForResponseTimeout(CMD_HF_MIFAREU_WRITEBL, &resp, 1500) == false) {
|
||||
PrintAndLogEx(WARNING, "Command execute timeout");
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
|
||||
// block 1.
|
||||
data[0] = uid[3];
|
||||
data[1] = uid[4];
|
||||
data[2] = uid[5];
|
||||
data[3] = uid[6];
|
||||
memcpy(packetw.data, uid+3, 4);
|
||||
packetw.block_no = 1;
|
||||
clearCommandBuffer();
|
||||
SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, 1, 0, 0, data, sizeof(data));
|
||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500) == false) {
|
||||
SendCommandNG(CMD_HF_MIFAREU_WRITEBL, (uint8_t *)&packetw, sizeof(packetw));
|
||||
if (WaitForResponseTimeout(CMD_HF_MIFAREU_WRITEBL, &resp, 1500) == false) {
|
||||
PrintAndLogEx(WARNING, "Command execute timeout");
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
|
||||
// block 2.
|
||||
data[0] = uid[3] ^ uid[4] ^ uid[5] ^ uid[6];
|
||||
data[1] = oldblock2[1];
|
||||
data[2] = oldblock2[2];
|
||||
data[3] = oldblock2[3];
|
||||
packetw.data[0] = uid[3] ^ uid[4] ^ uid[5] ^ uid[6];
|
||||
memcpy(packetw.data+1, oldblock2+1, 3);
|
||||
packetw.block_no = 2;
|
||||
clearCommandBuffer();
|
||||
SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, 2, 0, 0, data, sizeof(data));
|
||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500) == false) {
|
||||
SendCommandNG(CMD_HF_MIFAREU_WRITEBL, (uint8_t *)&packetw, sizeof(packetw));
|
||||
if (WaitForResponseTimeout(CMD_HF_MIFAREU_WRITEBL, &resp, 1500) == false) {
|
||||
PrintAndLogEx(WARNING, "Command execute timeout");
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
@@ -4886,13 +4915,21 @@ static int CmdHF14AMfuOtpTearoff(const char *Cmd) {
|
||||
uint8_t error_retries = 0;
|
||||
|
||||
// read block X
|
||||
mful_readblock_t packet = {
|
||||
mful_readblock_t packetr = {
|
||||
.use_schann = false,
|
||||
.keytype = 0,
|
||||
.keylen = 0,
|
||||
.num_of_blocks = 1,
|
||||
};
|
||||
|
||||
mful_writeblock_t packetw = {
|
||||
.block_no = blockno,
|
||||
.keytype = 0,
|
||||
.use_schann = false,
|
||||
.keylen = 0,
|
||||
};
|
||||
memcpy(packetw.data, data, sizeof(data));
|
||||
|
||||
while ((current <= (end - steps)) && (error_retries < 10)) {
|
||||
|
||||
if (kbd_enter_pressed()) {
|
||||
@@ -4906,39 +4943,25 @@ static int CmdHF14AMfuOtpTearoff(const char *Cmd) {
|
||||
PacketResponseNG resp;
|
||||
|
||||
if (use_data) {
|
||||
SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, blockno, 0, 0, data, d_len);
|
||||
bool got_written = false;
|
||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||
uint8_t isOK = resp.oldarg[0] & 0xff;
|
||||
if (isOK) {
|
||||
got_written = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (got_written == false) {
|
||||
SendCommandNG(CMD_HF_MIFAREU_WRITEBL, (uint8_t *)&packetw, sizeof(packetw));
|
||||
if ((WaitForResponseTimeout(CMD_HF_MIFAREU_WRITEBL, &resp, 1500) == false) ||
|
||||
(resp.status != PM3_SUCCESS)) {
|
||||
PrintAndLogEx(FAILED, "Failed to write block BEFORE");
|
||||
error_retries++;
|
||||
continue; // try again
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
packet.block_no = blockno;
|
||||
SendCommandNG(CMD_HF_MIFAREU_READBL, (uint8_t *)&packet, sizeof(packet));
|
||||
|
||||
bool got_pre = false;
|
||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||
if (resp.status == PM3_SUCCESS) {
|
||||
memcpy(pre, resp.data.asBytes, sizeof(pre));
|
||||
got_pre = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (got_pre == false) {
|
||||
packetr.block_no = blockno;
|
||||
SendCommandNG(CMD_HF_MIFAREU_READBL, (uint8_t *)&packetr, sizeof(packetr));
|
||||
if ((WaitForResponseTimeout(CMD_HF_MIFAREU_READBL, &resp, 1500) == false ) ||
|
||||
(resp.status != PM3_SUCCESS)) {
|
||||
PrintAndLogEx(FAILED, "Failed to read block BEFORE");
|
||||
error_retries++;
|
||||
continue; // try again
|
||||
}
|
||||
memcpy(post, resp.data.asBytes, sizeof(post));
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommandMIX(CMD_HF_MFU_OTP_TEAROFF, blockno, current, 0, teardata, sizeof(teardata));
|
||||
|
||||
@@ -4955,21 +4978,15 @@ static int CmdHF14AMfuOtpTearoff(const char *Cmd) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bool got_post = false;
|
||||
clearCommandBuffer();
|
||||
SendCommandNG(CMD_HF_MIFAREU_READBL, (uint8_t *)&packet, sizeof(packet));
|
||||
if (WaitForResponseTimeout(CMD_HF_MIFAREU_READBL, &resp, 1500)) {
|
||||
if (resp.status == PM3_SUCCESS) {
|
||||
memcpy(post, resp.data.asBytes, sizeof(post));
|
||||
got_post = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (got_post == false) {
|
||||
SendCommandNG(CMD_HF_MIFAREU_READBL, (uint8_t *)&packetr, sizeof(packetr));
|
||||
if ((WaitForResponseTimeout(CMD_HF_MIFAREU_READBL, &resp, 1500) == false ) ||
|
||||
(resp.status != PM3_SUCCESS)) {
|
||||
PrintAndLogEx(FAILED, "Failed to read block BEFORE");
|
||||
error_retries++;
|
||||
continue; // try again
|
||||
}
|
||||
memcpy(post, resp.data.asBytes, sizeof(post));
|
||||
|
||||
error_retries = 0;
|
||||
char prestr[20] = {0};
|
||||
|
||||
Reference in New Issue
Block a user