mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 13:53:55 -07:00
Merge branch 'RfidResearchGroup:master' into master
This commit is contained in:
commit
09bdb0c566
6 changed files with 69 additions and 43 deletions
|
@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file.
|
||||||
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
||||||
|
|
||||||
## [unreleased][unreleased]
|
## [unreleased][unreleased]
|
||||||
|
- Changed `hf iclass wrbl` - replay behavior to use privilege escalation if the macs field is not passed empty(@antiklesys)
|
||||||
- Changed `hf iclass restore` - it now supports privilege escalation to restore card content using replay (@antiklesys)
|
- Changed `hf iclass restore` - it now supports privilege escalation to restore card content using replay (@antiklesys)
|
||||||
- Fixed `hf 15 dump` - now reads sysinfo response correct (@iceman1001)
|
- Fixed `hf 15 dump` - now reads sysinfo response correct (@iceman1001)
|
||||||
- Changed `make clean` - it now removes all __pycache__ folders (@iceman1001)
|
- Changed `make clean` - it now removes all __pycache__ folders (@iceman1001)
|
||||||
|
|
|
@ -1857,8 +1857,39 @@ static bool iclass_writeblock_sp(uint8_t blockno, uint8_t *data, uint8_t *mac, b
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t credit_key[8] = {0xFD, 0xCB, 0x5A, 0x52, 0xEA, 0x8F, 0x30, 0x90};
|
||||||
|
|
||||||
|
static bool do_privilege_escalation(uint8_t *read_check_cc, size_t cc_len, uint32_t *eof_time) {
|
||||||
|
|
||||||
|
int priv_esc_tries = 5;
|
||||||
|
|
||||||
|
while (priv_esc_tries--) {
|
||||||
|
|
||||||
|
uint16_t resp_len = 0;
|
||||||
|
uint8_t resp[10] = {0};
|
||||||
|
//The privilege escalation is done with a readcheck and not just a normal read!
|
||||||
|
uint32_t start_time = *eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
||||||
|
|
||||||
|
iclass_send_as_reader(read_check_cc, cc_len, &start_time, eof_time, false);
|
||||||
|
// expect a 8-byte response here
|
||||||
|
int res = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_OTHERS, eof_time, false, true, &resp_len);
|
||||||
|
if (res == PM3_SUCCESS && resp_len == 8) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_dbglevel == DBG_INFO) {
|
||||||
|
DbpString("");
|
||||||
|
DbpString(_RED_("Unable to complete privilege escalation! Stopping."));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// turn off afterwards
|
// turn off afterwards
|
||||||
void iClass_WriteBlock(uint8_t *msg) {
|
void iClass_WriteBlock(uint8_t *msg) {
|
||||||
|
bool priv_esc = false;
|
||||||
|
uint8_t read_check_cc[] = { 0x10 | ICLASS_CMD_READCHECK, 0x18 };
|
||||||
|
uint8_t div_cc[8] = {0};
|
||||||
|
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
|
|
||||||
|
@ -1878,6 +1909,9 @@ void iClass_WriteBlock(uint8_t *msg) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
iclass_calc_div_key(hdr.csn, credit_key, div_cc, false);
|
||||||
|
read_check_cc[1] = hdr.conf.app_limit + 1; //first block of AA2
|
||||||
|
|
||||||
uint32_t start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
uint32_t start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
||||||
|
|
||||||
uint8_t mac[4] = {0};
|
uint8_t mac[4] = {0};
|
||||||
|
@ -1904,7 +1938,7 @@ void iClass_WriteBlock(uint8_t *msg) {
|
||||||
write_len -= 2;
|
write_len -= 2;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (payload->req.use_replay) {
|
if (payload->req.use_replay && (memcmp(payload->mac, "\x00\x00\x00\x00", 4) != 0)) {
|
||||||
memcpy(write + 10, payload->mac, sizeof(payload->mac));
|
memcpy(write + 10, payload->mac, sizeof(payload->mac));
|
||||||
} else {
|
} else {
|
||||||
// Secure tags uses MAC
|
// Secure tags uses MAC
|
||||||
|
@ -1912,10 +1946,17 @@ void iClass_WriteBlock(uint8_t *msg) {
|
||||||
wb[0] = payload->req.blockno;
|
wb[0] = payload->req.blockno;
|
||||||
memcpy(wb + 1, payload->data, PICOPASS_BLOCK_SIZE);
|
memcpy(wb + 1, payload->data, PICOPASS_BLOCK_SIZE);
|
||||||
|
|
||||||
if (payload->req.use_credit_key)
|
if (payload->req.use_credit_key) {
|
||||||
doMAC_N(wb, sizeof(wb), hdr.key_c, mac);
|
doMAC_N(wb, sizeof(wb), hdr.key_c, mac);
|
||||||
else
|
} else if (payload->req.use_replay) {
|
||||||
|
priv_esc = do_privilege_escalation(read_check_cc, sizeof(read_check_cc), &eof_time);
|
||||||
|
if (priv_esc == false) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
doMAC_N(wb, sizeof(wb), div_cc, mac);
|
||||||
|
} else {
|
||||||
doMAC_N(wb, sizeof(wb), hdr.key_d, mac);
|
doMAC_N(wb, sizeof(wb), hdr.key_d, mac);
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(write + 10, mac, sizeof(mac));
|
memcpy(write + 10, mac, sizeof(mac));
|
||||||
}
|
}
|
||||||
|
@ -2552,36 +2593,9 @@ out:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool do_privilege_escalation(uint8_t *read_check_cc, size_t cc_len, uint32_t *eof_time) {
|
|
||||||
|
|
||||||
int priv_esc_tries = 5;
|
|
||||||
|
|
||||||
while (priv_esc_tries--) {
|
|
||||||
|
|
||||||
uint16_t resp_len = 0;
|
|
||||||
uint8_t resp[10] = {0};
|
|
||||||
//The privilege escalation is done with a readcheck and not just a normal read!
|
|
||||||
uint32_t start_time = *eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
|
|
||||||
|
|
||||||
iclass_send_as_reader(read_check_cc, cc_len, &start_time, eof_time, false);
|
|
||||||
// expect a 8-byte response here
|
|
||||||
int res = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_OTHERS, eof_time, false, true, &resp_len);
|
|
||||||
if (res == PM3_SUCCESS && resp_len == 8) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_dbglevel == DBG_INFO) {
|
|
||||||
DbpString("");
|
|
||||||
DbpString(_RED_("Unable to complete privilege escalation! Stopping."));
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void iClass_Restore(iclass_restore_req_t *msg) {
|
void iClass_Restore(iclass_restore_req_t *msg) {
|
||||||
bool priv_esc = false;
|
bool priv_esc = false;
|
||||||
uint8_t read_check_cc[] = { 0x10 | ICLASS_CMD_READCHECK, 0x18 };
|
uint8_t read_check_cc[] = { 0x10 | ICLASS_CMD_READCHECK, 0x18 };
|
||||||
uint8_t credit_key[8] = {0xFD, 0xCB, 0x5A, 0x52, 0xEA, 0x8F, 0x30, 0x90};
|
|
||||||
uint8_t div_cc[8] = {0};
|
uint8_t div_cc[8] = {0};
|
||||||
|
|
||||||
// sanitation
|
// sanitation
|
||||||
|
@ -2626,13 +2640,6 @@ void iClass_Restore(iclass_restore_req_t *msg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg->req.use_replay) {
|
|
||||||
priv_esc = do_privilege_escalation(read_check_cc, sizeof(read_check_cc), &eof_time);
|
|
||||||
if (priv_esc == false) {
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// main loop
|
// main loop
|
||||||
bool use_mac;
|
bool use_mac;
|
||||||
for (uint8_t i = 0; i < msg->item_cnt; i++) {
|
for (uint8_t i = 0; i < msg->item_cnt; i++) {
|
||||||
|
@ -2653,6 +2660,10 @@ void iClass_Restore(iclass_restore_req_t *msg) {
|
||||||
if (msg->req.use_credit_key) {
|
if (msg->req.use_credit_key) {
|
||||||
doMAC_N(wb, sizeof(wb), hdr.key_c, mac);
|
doMAC_N(wb, sizeof(wb), hdr.key_c, mac);
|
||||||
} else if (msg->req.use_replay) {
|
} else if (msg->req.use_replay) {
|
||||||
|
priv_esc = do_privilege_escalation(read_check_cc, sizeof(read_check_cc), &eof_time);
|
||||||
|
if (priv_esc == false) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
doMAC_N(wb, sizeof(wb), div_cc, mac);
|
doMAC_N(wb, sizeof(wb), div_cc, mac);
|
||||||
} else {
|
} else {
|
||||||
doMAC_N(wb, sizeof(wb), hdr.key_d, mac);
|
doMAC_N(wb, sizeof(wb), hdr.key_d, mac);
|
||||||
|
|
|
@ -2329,7 +2329,7 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) {
|
||||||
arg_lit0(NULL, "credit", "key is assumed to be the credit key"),
|
arg_lit0(NULL, "credit", "key is assumed to be the credit key"),
|
||||||
arg_lit0(NULL, "elite", "elite computations applied to key"),
|
arg_lit0(NULL, "elite", "elite computations applied to key"),
|
||||||
arg_lit0(NULL, "raw", "no computations applied to key"),
|
arg_lit0(NULL, "raw", "no computations applied to key"),
|
||||||
arg_lit0(NULL, "nr", "replay of NR/MAC"),
|
arg_lit0(NULL, "nr", "replay of NR/MAC block write or use privilege escalation if mac is empty"),
|
||||||
arg_lit0("v", "verbose", "verbose output"),
|
arg_lit0("v", "verbose", "verbose output"),
|
||||||
arg_lit0(NULL, "shallow", "use shallow (ASK) reader modulation instead of OOK"),
|
arg_lit0(NULL, "shallow", "use shallow (ASK) reader modulation instead of OOK"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
|
|
|
@ -267,7 +267,7 @@ static void ParseAndPrintSaflokData(const sector_t *sector0_info, const sector_t
|
||||||
uint16_t property_id = ((decodedBA[14] & 0x0F) << 8) | decodedBA[15];
|
uint16_t property_id = ((decodedBA[14] & 0x0F) << 8) | decodedBA[15];
|
||||||
|
|
||||||
// Bytes 11-13: Creation date since SAFLOK_YEAR_OFFSET Jan 1st
|
// Bytes 11-13: Creation date since SAFLOK_YEAR_OFFSET Jan 1st
|
||||||
uint16_t creation_year = (((decodedBA[11] & 0xF0) >> 4) + SAFLOK_YEAR_OFFSET) | creation_year_high_bits;
|
uint16_t creation_year = (creation_year_high_bits | (decodedBA[11] >> 4)) + SAFLOK_YEAR_OFFSET;
|
||||||
uint8_t creation_month = decodedBA[11] & 0x0F;
|
uint8_t creation_month = decodedBA[11] & 0x0F;
|
||||||
uint8_t creation_day = (decodedBA[12] >> 3) & 0x1F;
|
uint8_t creation_day = (decodedBA[12] >> 3) & 0x1F;
|
||||||
uint8_t creation_hour = ((decodedBA[12] & 0x07) << 2) | ((decodedBA[13] & 0xC0) >> 6);
|
uint8_t creation_hour = ((decodedBA[12] & 0x07) << 2) | ((decodedBA[13] & 0xC0) >> 6);
|
||||||
|
@ -329,7 +329,7 @@ static void ParseAndPrintSaflokData(const sector_t *sector0_info, const sector_t
|
||||||
bool checksum_valid = (checksum_calculated == checksum);
|
bool checksum_valid = (checksum_calculated == checksum);
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(INFO, "--- " _CYAN_("SAFLOK details"));
|
PrintAndLogEx(INFO, "--- " _CYAN_("Saflok details"));
|
||||||
PrintAndLogEx(SUCCESS, "Key Level............. %u (%s)", saflok_key_levels[key_level].level_num, saflok_key_levels[key_level].level_name);
|
PrintAndLogEx(SUCCESS, "Key Level............. %u (%s)", saflok_key_levels[key_level].level_num, saflok_key_levels[key_level].level_name);
|
||||||
PrintAndLogEx(SUCCESS, "LED Warning........... %s", led_warning ? "Yes" : "No");
|
PrintAndLogEx(SUCCESS, "LED Warning........... %s", led_warning ? "Yes" : "No");
|
||||||
PrintAndLogEx(SUCCESS, "Key ID................ %u (0x%02X)", key_id, key_id);
|
PrintAndLogEx(SUCCESS, "Key ID................ %u (0x%02X)", key_id, key_id);
|
||||||
|
|
|
@ -698,8 +698,13 @@ int flash_write(flash_file_t *ctx) {
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, " 0x%08x..0x%08x [0x%x / %u blocks]", seg->start, end - 1, length, blocks);
|
PrintAndLogEx(SUCCESS, " 0x%08x..0x%08x [0x%x / %u blocks]", seg->start, end - 1, length, blocks);
|
||||||
if (is_loaded) {
|
if (is_loaded) {
|
||||||
|
if (blocks < 50) {
|
||||||
|
PrintAndLogEx(SUCCESS, "" NOLF);
|
||||||
|
} else {
|
||||||
fprintf(stdout, "\n\n");
|
fprintf(stdout, "\n\n");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
int block = 0;
|
int block = 0;
|
||||||
uint8_t *data = seg->data;
|
uint8_t *data = seg->data;
|
||||||
|
@ -721,6 +726,15 @@ int flash_write(flash_file_t *ctx) {
|
||||||
length -= block_size;
|
length -= block_size;
|
||||||
block++;
|
block++;
|
||||||
|
|
||||||
|
// small files, like bootrom
|
||||||
|
if (blocks < 50) {
|
||||||
|
fprintf(stdout, ".");
|
||||||
|
len++;
|
||||||
|
fflush(stdout);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// large fullimage write
|
||||||
if (is_loaded) {
|
if (is_loaded) {
|
||||||
if (len < ice3len) {
|
if (len < ice3len) {
|
||||||
fprintf(stdout, "%c", ice3[len++]);
|
fprintf(stdout, "%c", ice3[len++]);
|
||||||
|
|
|
@ -3810,7 +3810,7 @@
|
||||||
"--credit key is assumed to be the credit key",
|
"--credit key is assumed to be the credit key",
|
||||||
"--elite elite computations applied to key",
|
"--elite elite computations applied to key",
|
||||||
"--raw no computations applied to key",
|
"--raw no computations applied to key",
|
||||||
"--nr replay of NR/MAC",
|
"--nr replay of NR/MAC block write or use privilege escalation if mac is empty",
|
||||||
"-v, --verbose verbose output",
|
"-v, --verbose verbose output",
|
||||||
"--shallow use shallow (ASK) reader modulation instead of OOK"
|
"--shallow use shallow (ASK) reader modulation instead of OOK"
|
||||||
],
|
],
|
||||||
|
@ -13377,6 +13377,6 @@
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"commands_extracted": 768,
|
"commands_extracted": 768,
|
||||||
"extracted_by": "PM3Help2JSON v1.00",
|
"extracted_by": "PM3Help2JSON v1.00",
|
||||||
"extracted_on": "2025-07-04T10:19:21"
|
"extracted_on": "2025-07-06T18:10:18"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue