This commit is contained in:
iceman1001 2025-06-06 13:27:02 +02:00
commit f41d6fad53
3 changed files with 35 additions and 26 deletions

View file

@ -1805,9 +1805,9 @@ static bool iclass_writeblock_sp(uint8_t blockno, uint8_t *data, uint8_t *mac, b
uint8_t resp[10] = {0};
bool isOK = false;
if(short_delay){
if (short_delay) {
isOK = iclass_send_cmd_with_retries(write, write_len, resp, sizeof(resp), 10, 3, start_time, ICLASS_READER_TIMEOUT_UPDATE_FAST, eof_time, shallow_mod);
}else{
} else {
isOK = iclass_send_cmd_with_retries(write, write_len, resp, sizeof(resp), 10, 3, start_time, ICLASS_READER_TIMEOUT_UPDATE, eof_time, shallow_mod);
}
if (isOK == false) {
@ -2706,7 +2706,7 @@ void iClass_Recover(iclass_recover_req_t *msg) {
}
//Step 0A - The read_check_cc block has to be in AA2, set it by checking the card configuration
read_check_cc[1] = ((uint8_t*)&hdr.conf)[0] + 1; //first block of AA2
read_check_cc[1] = ((uint8_t *)&hdr.conf)[0] + 1; //first block of AA2
//Step1 Authenticate with AA1 using trace
if (card_select) {
@ -2744,7 +2744,7 @@ void iClass_Recover(iclass_recover_req_t *msg) {
} else {
interrupted = true;
}
if(msg->fast){
if (msg->fast) {
goto fast_restore;
}
goto out;
@ -2823,10 +2823,10 @@ void iClass_Recover(iclass_recover_req_t *msg) {
memcpy(genkeyblock, zero_key, PICOPASS_BLOCK_SIZE);
}
if(msg->fast){//if we're skipping restoring the original key to gain speed, xor the new index key with the previous index key and update the difference and track restore values differently
if(index > 0 && loops > 1){
generate_single_key_block_inverted_opt(zero_key, index -1, fast_previous_key);
}else{
if (msg->fast) { //if we're skipping restoring the original key to gain speed, xor the new index key with the previous index key and update the difference and track restore values differently
if (index > 0 && loops > 1) {
generate_single_key_block_inverted_opt(zero_key, index - 1, fast_previous_key);
} else {
memcpy(fast_previous_key, zero_key, PICOPASS_BLOCK_SIZE);
}
for (int i = 0; i < PICOPASS_BLOCK_SIZE; i++) {
@ -2850,7 +2850,7 @@ void iClass_Recover(iclass_recover_req_t *msg) {
if (iclass_writeblock_sp(blockno, genkeyblock, mac2, shallow_mod, &start_time, &eof_time, short_delay)) {
status_message = 4; //wrote new key on the card - unverified
}
if(!msg->fast){ //if we're going slow we check at every write that the write actually happened
if (!msg->fast) { //if we're going slow we check at every write that the write actually happened
//Reset cypher state
start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
iclass_send_as_reader(read_check_cc2, sizeof(read_check_cc2), &start_time, &eof_time, shallow_mod);
@ -2877,7 +2877,7 @@ void iClass_Recover(iclass_recover_req_t *msg) {
written = true;
}
}
}else{ //if we're going fast we can skip the above checks as we're just xorring the key over and over
} else { //if we're going fast we can skip the above checks as we're just xorring the key over and over
status_message = 5;
written = true;
}
@ -2900,11 +2900,11 @@ void iClass_Recover(iclass_recover_req_t *msg) {
bool reverted = false;
uint8_t revert_retries = 0;
if(msg->fast){ //if we're going fast only restore the original key at the end
if(recovered){
if (msg->fast) { //if we're going fast only restore the original key at the end
if (recovered) {
goto fast_restore;
}
}else{
} else {
//if we're NOT going fast, regardless of bits being found, restore the original key and verify it
while (!reverted) {
//Regain privilege escalation with a readcheck
@ -3018,9 +3018,9 @@ fast_restore:
Dbhexdump(8, fast_restore_key, false);
Dbprintf(_RED_("Attempted to restore original key for %3d times and failed. Stopping. Card is likely unusable."), revert_retries);
}
if(recovered){
if (recovered) {
goto restore;
}else{
} else {
goto out;
}
}
@ -3030,9 +3030,9 @@ restore:
uint8_t partialkey[PICOPASS_BLOCK_SIZE] = {0};
for (int i = 0; i < PICOPASS_BLOCK_SIZE; i++) {
if(msg->fast){
if (msg->fast) {
partialkey[i] = fast_restore_key[i] ^ bits_found;
}else{
} else {
partialkey[i] = genkeyblock[i] ^ bits_found;
}
}

View file

@ -4634,11 +4634,15 @@ typedef struct {
// HF iClass legbrute - Brute-force worker thread
static void *brute_thread(void *args_void) {
thread_args_t *args = (thread_args_t *)args_void;
uint8_t div_key[8], mac[4], verification_mac[4];
uint8_t div_key[8];
uint8_t mac[4];
uint8_t verification_mac[4];
uint64_t index = args->index_start;
while (!*(args->found)) {
generate_key_block_inverted(args->startingKey, index, div_key);
doMAC(args->CCNR1, div_key, mac);
@ -4659,8 +4663,8 @@ static void *brute_thread(void *args_void) {
if (index % 1000000 == 0 && !*(args->found)) {
pthread_mutex_lock(args->log_lock);
if(args->thread_id == 0){
PrintAndLogEx(INPLACE, "Tested "_YELLOW_("%" PRIu64 )" million keys, using "_YELLOW_("%d")" threads - Index: "_YELLOW_("%" PRIu64 )" - Last key on Thread[0]: %s", (index / 1000000) * args->thread_count, args->thread_count, index / 1000000, sprint_hex(div_key, 8));
if (args->thread_id == 0) {
PrintAndLogEx(INPLACE, "Tested "_YELLOW_("%" PRIu64)" million keys, using "_YELLOW_("%d")" threads - Index: "_YELLOW_("%" PRIu64)" - Last key on Thread[0]: %s", (index / 1000000) * args->thread_count, args->thread_count, index / 1000000, sprint_hex(div_key, 8));
}
pthread_mutex_unlock(args->log_lock);
}
@ -4720,7 +4724,9 @@ static int CmdHFiClassLegBrute_MT(uint8_t epurse[8], uint8_t macs[8], uint8_t ma
static int CmdHFiClassLegBrute(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf iclass legbrute",
"This command takes sniffed trace data and a partial raw key and bruteforces the remaining 40 bits of the raw key.",
"This command takes sniffed trace data and a partial raw key and bruteforces the remaining 40 bits of the raw key.\n"
"Complete 40 bit keyspace is 1'099'511'627'776 and command is lockdown to max 16 threads currently.\n"
"A possible worst case scenario on 16 threads estimates XXX days YYY hours MMM minutes.",
"hf iclass legbrute --epurse feffffffffffffff --macs1 1306cad9b6c24466 --macs2 f0bf905e35f97923 --pk B4F12AADC5301225");
void *argtable[] = {

View file

@ -3493,7 +3493,7 @@
},
"hf iclass legbrute": {
"command": "hf iclass legbrute",
"description": "This command take sniffed trace data and partial raw key and bruteforces the remaining 40 bits of the raw key.",
"description": "This command takes sniffed trace data and a partial raw key and bruteforces the remaining 40 bits of the raw key. Complete 40 bit keyspace is 1'099'511'627'776 and command is lockdown to max 16 threads currently. A possible worst case scenario on 16 threads estimates XXX days YYY hours MMM minutes.",
"notes": [
"hf iclass legbrute --epurse feffffffffffffff --macs1 1306cad9b6c24466 --macs2 f0bf905e35f97923 --pk B4F12AADC5301225"
],
@ -3504,9 +3504,10 @@
"--macs1 <hex> MACs captured from the reader",
"--macs2 <hex> MACs captured from the reader, different than the first set (with the same csn and epurse value)",
"--pk <hex> Partial Key from legrec or starting key of keyblock from legbrute",
"--index <dec> Where to start from to retrieve the key, default 0 - value in millions e.g. 1 is 1 million"
"--index <dec> Where to start from to retrieve the key, default 0 - value in millions e.g. 1 is 1 million",
"--threads <dec> Number of threads to use, by default it uses the cpu's max threads (max 16)."
],
"usage": "hf iclass legbrute [-h] --epurse <hex> --macs1 <hex> --macs2 <hex> --pk <hex> [--index <dec>]"
"usage": "hf iclass legbrute [-h] --epurse <hex> --macs1 <hex> --macs2 <hex> --pk <hex> [--index <dec>] [--threads <dec>]"
},
"hf iclass legrec": {
"command": "hf iclass legrec",
@ -3524,9 +3525,11 @@
"--debug Re-enables tracing for debugging. Limits cycles to 1.",
"--notest Perform real writes on the card!",
"--allnight Loops the loop for 10 times, recommended loop value of 5000.",
"--fast Increases the speed (4.6->7.4 key updates/second), higher risk to brick the card.",
"--sl Lower card comms delay times, further speeds increases, may cause more errors.",
"--est Estimates the key updates based on the card's CSN assuming standard key."
],
"usage": "hf iclass legrec [-h] --macs <hex> [--index <dec>] [--loop <dec>] [--debug] [--notest] [--allnight] [--est]"
"usage": "hf iclass legrec [-h] --macs <hex> [--index <dec>] [--loop <dec>] [--debug] [--notest] [--allnight] [--fast] [--sl] [--est]"
},
"hf iclass loclass": {
"command": "hf iclass loclass",
@ -13372,6 +13375,6 @@
"metadata": {
"commands_extracted": 768,
"extracted_by": "PM3Help2JSON v1.00",
"extracted_on": "2025-06-04T16:02:17"
"extracted_on": "2025-06-06T11:25:04"
}
}