mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 13:53:55 -07:00
fm11rf08s: get advanced verification sector keys as well
This commit is contained in:
parent
846b273583
commit
69d7a7e0c3
3 changed files with 98 additions and 69 deletions
|
@ -1045,8 +1045,8 @@ void MifareAcquireStaticEncryptedNonces(uint32_t flags, uint8_t *key) {
|
||||||
uint8_t uid[10] = {0x00};
|
uint8_t uid[10] = {0x00};
|
||||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00};
|
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00};
|
||||||
uint8_t par_enc[1] = {0x00};
|
uint8_t par_enc[1] = {0x00};
|
||||||
uint8_t buf[PM3_CMD_DATA_SIZE] = {0x00};
|
// ((MIFARE_1K_MAXSECTOR + 1) * 2) * 9 < PM3_CMD_DATA_SIZE
|
||||||
|
uint8_t buf[((MIFARE_1K_MAXSECTOR + 1) * 2) * 9] = {0x00};
|
||||||
uint64_t ui64Key = bytes_to_num(key, 6);
|
uint64_t ui64Key = bytes_to_num(key, 6);
|
||||||
bool with_data = flags & 1;
|
bool with_data = flags & 1;
|
||||||
uint32_t cuid = 0;
|
uint32_t cuid = 0;
|
||||||
|
@ -1054,7 +1054,6 @@ void MifareAcquireStaticEncryptedNonces(uint32_t flags, uint8_t *key) {
|
||||||
uint16_t num_nonces = 0;
|
uint16_t num_nonces = 0;
|
||||||
uint8_t cascade_levels = 0;
|
uint8_t cascade_levels = 0;
|
||||||
bool have_uid = false;
|
bool have_uid = false;
|
||||||
uint8_t num_sectors = 16;
|
|
||||||
|
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
LED_C_OFF();
|
LED_C_OFF();
|
||||||
|
@ -1068,8 +1067,13 @@ void MifareAcquireStaticEncryptedNonces(uint32_t flags, uint8_t *key) {
|
||||||
|
|
||||||
LED_C_ON();
|
LED_C_ON();
|
||||||
|
|
||||||
for (uint16_t sec = 0; sec < num_sectors; sec++) {
|
for (uint16_t sec = 0; sec < MIFARE_1K_MAXSECTOR + 1; sec++) {
|
||||||
uint8_t blockNo = sec * 4;
|
uint16_t sec_gap = sec;
|
||||||
|
if (sec >= MIFARE_1K_MAXSECTOR) {
|
||||||
|
// gap between user blocks and advanced verification method blocks
|
||||||
|
sec_gap += 16;
|
||||||
|
}
|
||||||
|
uint16_t blockNo = sec_gap * 4;
|
||||||
for (uint8_t keyType = 0; keyType < 2; keyType++) {
|
for (uint8_t keyType = 0; keyType < 2; keyType++) {
|
||||||
// Test if the action was cancelled
|
// Test if the action was cancelled
|
||||||
if (BUTTON_PRESS()) {
|
if (BUTTON_PRESS()) {
|
||||||
|
@ -1110,19 +1114,20 @@ void MifareAcquireStaticEncryptedNonces(uint32_t flags, uint8_t *key) {
|
||||||
goto out;
|
goto out;
|
||||||
};
|
};
|
||||||
if (with_data) {
|
if (with_data) {
|
||||||
uint8_t data[16];
|
if (blockNo < MIFARE_1K_MAXSECTOR * 4) {
|
||||||
for (uint16_t tb = blockNo; tb < blockNo + 4; tb++) {
|
uint8_t data[16];
|
||||||
memset(data, 0x00, sizeof(data));
|
for (uint16_t tb = blockNo; tb < blockNo + 4; tb++) {
|
||||||
int res = mifare_classic_readblock(pcs, tb, data);
|
memset(data, 0x00, sizeof(data));
|
||||||
if (res == 1) {
|
int res = mifare_classic_readblock(pcs, tb, data);
|
||||||
if (g_dbglevel >= DBG_ERROR) Dbprintf("AcquireStaticEncryptedNonces: Read error");
|
if (res == 1) {
|
||||||
isOK = PM3_ESOFT;
|
if (g_dbglevel >= DBG_ERROR) Dbprintf("AcquireStaticEncryptedNonces: Read error");
|
||||||
goto out;
|
isOK = PM3_ESOFT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
emlSetMem_xt(data, tb, 1, 16);
|
||||||
}
|
}
|
||||||
emlSetMem_xt(data, tb, 1, 16);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// nested authentication
|
// nested authentication
|
||||||
uint16_t len = mifare_sendcmd_short(pcs, AUTH_NESTED, MIFARE_AUTH_KEYA + keyType + 4, blockNo, receivedAnswer, sizeof(receivedAnswer), par_enc, NULL);
|
uint16_t len = mifare_sendcmd_short(pcs, AUTH_NESTED, MIFARE_AUTH_KEYA + keyType + 4, blockNo, receivedAnswer, sizeof(receivedAnswer), par_enc, NULL);
|
||||||
if (len != 4) {
|
if (len != 4) {
|
||||||
|
|
|
@ -31,6 +31,7 @@ except ModuleNotFoundError:
|
||||||
|
|
||||||
BACKDOOR_RF08S = "A396EFA4E24F"
|
BACKDOOR_RF08S = "A396EFA4E24F"
|
||||||
NUM_SECTORS = 16
|
NUM_SECTORS = 16
|
||||||
|
NUM_EXTRA_SECTORS = 1
|
||||||
DICT_DEF = "mfc_default_keys.dic"
|
DICT_DEF = "mfc_default_keys.dic"
|
||||||
DEFAULT_KEYS = set()
|
DEFAULT_KEYS = set()
|
||||||
if os.path.basename(os.path.dirname(os.path.dirname(sys.argv[0]))) == 'client':
|
if os.path.basename(os.path.dirname(os.path.dirname(sys.argv[0]))) == 'client':
|
||||||
|
@ -87,7 +88,7 @@ def print_key(sec, key_type, key):
|
||||||
print(f"Sector {sec:2} key{kt} = " + color(key, fg="green"))
|
print(f"Sector {sec:2} key{kt} = " + color(key, fg="green"))
|
||||||
|
|
||||||
|
|
||||||
found_keys = [["", ""] for _ in range(NUM_SECTORS)]
|
found_keys = [["", ""] for _ in range(NUM_SECTORS + NUM_EXTRA_SECTORS)]
|
||||||
if args.init_check:
|
if args.init_check:
|
||||||
print("Checking default keys...")
|
print("Checking default keys...")
|
||||||
p.console("hf mf fchk")
|
p.console("hf mf fchk")
|
||||||
|
@ -144,31 +145,34 @@ else:
|
||||||
print(f"Warning, {DICT_DEF} not found.")
|
print(f"Warning, {DICT_DEF} not found.")
|
||||||
|
|
||||||
print("Running staticnested_1nt & 2x1nt when doable...")
|
print("Running staticnested_1nt & 2x1nt when doable...")
|
||||||
keys = [[set(), set()] for _ in range(NUM_SECTORS)]
|
keys = [[set(), set()] for _ in range(NUM_SECTORS + NUM_EXTRA_SECTORS)]
|
||||||
all_keys = set()
|
all_keys = set()
|
||||||
duplicates = set()
|
duplicates = set()
|
||||||
# Availability of filtered dicts
|
# Availability of filtered dicts
|
||||||
filtered_dicts = [[False, False] for _ in range(NUM_SECTORS)]
|
filtered_dicts = [[False, False] for _ in range(NUM_SECTORS + NUM_EXTRA_SECTORS)]
|
||||||
found_default = [[False, False] for _ in range(NUM_SECTORS)]
|
found_default = [[False, False] for _ in range(NUM_SECTORS + NUM_EXTRA_SECTORS)]
|
||||||
for sec in range(NUM_SECTORS):
|
for sec in range(NUM_SECTORS + NUM_EXTRA_SECTORS):
|
||||||
|
real_sec = sec
|
||||||
|
if sec >= NUM_SECTORS:
|
||||||
|
real_sec += 16
|
||||||
if found_keys[sec][0] != "" and found_keys[sec][1] != "":
|
if found_keys[sec][0] != "" and found_keys[sec][1] != "":
|
||||||
continue
|
continue
|
||||||
if found_keys[sec][0] == "" and found_keys[sec][1] == "" and nt[sec][0] != nt[sec][1]:
|
if found_keys[sec][0] == "" and found_keys[sec][1] == "" and nt[sec][0] != nt[sec][1]:
|
||||||
for key_type in [0, 1]:
|
for key_type in [0, 1]:
|
||||||
cmd = [tools["staticnested_1nt"], f"{uid:08X}", f"{sec}",
|
cmd = [tools["staticnested_1nt"], f"{uid:08X}", f"{real_sec}",
|
||||||
nt[sec][key_type], nt_enc[sec][key_type], par_err[sec][key_type]]
|
nt[sec][key_type], nt_enc[sec][key_type], par_err[sec][key_type]]
|
||||||
if args.debug:
|
if args.debug:
|
||||||
print(' '.join(cmd))
|
print(' '.join(cmd))
|
||||||
subprocess.run(cmd, capture_output=True)
|
subprocess.run(cmd, capture_output=True)
|
||||||
cmd = [tools["staticnested_2x1nt"],
|
cmd = [tools["staticnested_2x1nt"],
|
||||||
f"keys_{uid:08x}_{sec:02}_{nt[sec][0]}.dic", f"keys_{uid:08x}_{sec:02}_{nt[sec][1]}.dic"]
|
f"keys_{uid:08x}_{real_sec:02}_{nt[sec][0]}.dic", f"keys_{uid:08x}_{real_sec:02}_{nt[sec][1]}.dic"]
|
||||||
if args.debug:
|
if args.debug:
|
||||||
print(' '.join(cmd))
|
print(' '.join(cmd))
|
||||||
subprocess.run(cmd, capture_output=True)
|
subprocess.run(cmd, capture_output=True)
|
||||||
filtered_dicts[sec][key_type] = True
|
filtered_dicts[sec][key_type] = True
|
||||||
for key_type in [0, 1]:
|
for key_type in [0, 1]:
|
||||||
keys_set = set()
|
keys_set = set()
|
||||||
with (open(f"keys_{uid:08x}_{sec:02}_{nt[sec][key_type]}_filtered.dic")) as f:
|
with (open(f"keys_{uid:08x}_{real_sec:02}_{nt[sec][key_type]}_filtered.dic")) as f:
|
||||||
while line := f.readline().rstrip():
|
while line := f.readline().rstrip():
|
||||||
keys_set.add(line)
|
keys_set.add(line)
|
||||||
keys[sec][key_type] = keys_set.copy()
|
keys[sec][key_type] = keys_set.copy()
|
||||||
|
@ -177,9 +181,14 @@ for sec in range(NUM_SECTORS):
|
||||||
# Prioritize default keys
|
# Prioritize default keys
|
||||||
keys_def_set = DEFAULT_KEYS.intersection(keys_set)
|
keys_def_set = DEFAULT_KEYS.intersection(keys_set)
|
||||||
keys_set.difference_update(DEFAULT_KEYS)
|
keys_set.difference_update(DEFAULT_KEYS)
|
||||||
|
# Prioritize sector 32 keyB starting with 0000
|
||||||
|
if real_sec == 32:
|
||||||
|
keyb32cands = set(x for x in keys_set if x.startswith("0000"))
|
||||||
|
keys_def_set.update(keyb32cands)
|
||||||
|
keys_set.difference_update(keyb32cands)
|
||||||
if len(keys_def_set) > 0:
|
if len(keys_def_set) > 0:
|
||||||
found_default[sec][key_type] = True
|
found_default[sec][key_type] = True
|
||||||
with (open(f"keys_{uid:08x}_{sec:02}_{nt[sec][key_type]}_filtered.dic", "w")) as f:
|
with (open(f"keys_{uid:08x}_{real_sec:02}_{nt[sec][key_type]}_filtered.dic", "w")) as f:
|
||||||
for k in keys_def_set:
|
for k in keys_def_set:
|
||||||
f.write(f"{k}\n")
|
f.write(f"{k}\n")
|
||||||
for k in keys_set:
|
for k in keys_set:
|
||||||
|
@ -189,13 +198,13 @@ for sec in range(NUM_SECTORS):
|
||||||
key_type = 0
|
key_type = 0
|
||||||
else:
|
else:
|
||||||
key_type = 1
|
key_type = 1
|
||||||
cmd = [tools["staticnested_1nt"], f"{uid:08X}", f"{sec}",
|
cmd = [tools["staticnested_1nt"], f"{uid:08X}", f"{real_sec}",
|
||||||
nt[sec][key_type], nt_enc[sec][key_type], par_err[sec][key_type]]
|
nt[sec][key_type], nt_enc[sec][key_type], par_err[sec][key_type]]
|
||||||
if args.debug:
|
if args.debug:
|
||||||
print(' '.join(cmd))
|
print(' '.join(cmd))
|
||||||
subprocess.run(cmd, capture_output=True)
|
subprocess.run(cmd, capture_output=True)
|
||||||
keys_set = set()
|
keys_set = set()
|
||||||
with (open(f"keys_{uid:08x}_{sec:02}_{nt[sec][key_type]}.dic")) as f:
|
with (open(f"keys_{uid:08x}_{real_sec:02}_{nt[sec][key_type]}.dic")) as f:
|
||||||
while line := f.readline().rstrip():
|
while line := f.readline().rstrip():
|
||||||
keys_set.add(line)
|
keys_set.add(line)
|
||||||
keys[sec][key_type] = keys_set.copy()
|
keys[sec][key_type] = keys_set.copy()
|
||||||
|
@ -206,30 +215,33 @@ for sec in range(NUM_SECTORS):
|
||||||
keys_set.difference_update(DEFAULT_KEYS)
|
keys_set.difference_update(DEFAULT_KEYS)
|
||||||
if len(keys_def_set) > 0:
|
if len(keys_def_set) > 0:
|
||||||
found_default[sec][key_type] = True
|
found_default[sec][key_type] = True
|
||||||
with (open(f"keys_{uid:08x}_{sec:02}_{nt[sec][key_type]}.dic", "w")) as f:
|
with (open(f"keys_{uid:08x}_{real_sec:02}_{nt[sec][key_type]}.dic", "w")) as f:
|
||||||
for k in keys_def_set:
|
for k in keys_def_set:
|
||||||
f.write(f"{k}\n")
|
f.write(f"{k}\n")
|
||||||
for k in keys_set:
|
for k in keys_set:
|
||||||
f.write(f"{k}\n")
|
f.write(f"{k}\n")
|
||||||
|
|
||||||
print("Looking for common keys across sectors...")
|
print("Looking for common keys across sectors...")
|
||||||
keys_filtered = [[set(), set()] for _ in range(NUM_SECTORS)]
|
keys_filtered = [[set(), set()] for _ in range(NUM_SECTORS + NUM_EXTRA_SECTORS)]
|
||||||
for dup in duplicates:
|
for dup in duplicates:
|
||||||
for sec in range(NUM_SECTORS):
|
for sec in range(NUM_SECTORS + NUM_EXTRA_SECTORS):
|
||||||
for key_type in [0, 1]:
|
for key_type in [0, 1]:
|
||||||
if dup in keys[sec][key_type]:
|
if dup in keys[sec][key_type]:
|
||||||
keys_filtered[sec][key_type].add(dup)
|
keys_filtered[sec][key_type].add(dup)
|
||||||
|
|
||||||
# Availability of duplicates dicts
|
# Availability of duplicates dicts
|
||||||
duplicates_dicts = [[False, False] for _ in range(NUM_SECTORS)]
|
duplicates_dicts = [[False, False] for _ in range(NUM_SECTORS + NUM_EXTRA_SECTORS)]
|
||||||
first = True
|
first = True
|
||||||
for sec in range(NUM_SECTORS):
|
for sec in range(NUM_SECTORS + NUM_EXTRA_SECTORS):
|
||||||
|
real_sec = sec
|
||||||
|
if sec >= NUM_SECTORS:
|
||||||
|
real_sec += 16
|
||||||
for key_type in [0, 1]:
|
for key_type in [0, 1]:
|
||||||
if len(keys_filtered[sec][key_type]) > 0:
|
if len(keys_filtered[sec][key_type]) > 0:
|
||||||
if first:
|
if first:
|
||||||
print("Saving duplicates dicts...")
|
print("Saving duplicates dicts...")
|
||||||
first = False
|
first = False
|
||||||
with (open(f"keys_{uid:08x}_{sec:02}_{nt[sec][key_type]}_duplicates.dic", "w")) as f:
|
with (open(f"keys_{uid:08x}_{real_sec:02}_{nt[sec][key_type]}_duplicates.dic", "w")) as f:
|
||||||
keys_set = keys_filtered[sec][key_type].copy()
|
keys_set = keys_filtered[sec][key_type].copy()
|
||||||
keys_def_set = DEFAULT_KEYS.intersection(keys_set)
|
keys_def_set = DEFAULT_KEYS.intersection(keys_set)
|
||||||
keys_set.difference_update(DEFAULT_KEYS)
|
keys_set.difference_update(DEFAULT_KEYS)
|
||||||
|
@ -240,12 +252,15 @@ for sec in range(NUM_SECTORS):
|
||||||
duplicates_dicts[sec][key_type] = True
|
duplicates_dicts[sec][key_type] = True
|
||||||
|
|
||||||
print("Computing needed time for attack...")
|
print("Computing needed time for attack...")
|
||||||
candidates = [[0, 0] for _ in range(NUM_SECTORS)]
|
candidates = [[0, 0] for _ in range(NUM_SECTORS + NUM_EXTRA_SECTORS)]
|
||||||
for sec in range(NUM_SECTORS):
|
for sec in range(NUM_SECTORS + NUM_EXTRA_SECTORS):
|
||||||
|
real_sec = sec
|
||||||
|
if sec >= NUM_SECTORS:
|
||||||
|
real_sec += 16
|
||||||
for key_type in [0, 1]:
|
for key_type in [0, 1]:
|
||||||
if found_keys[sec][0] == "" and found_keys[sec][1] == "" and duplicates_dicts[sec][key_type]:
|
if found_keys[sec][0] == "" and found_keys[sec][1] == "" and duplicates_dicts[sec][key_type]:
|
||||||
kt = ['a', 'b'][key_type]
|
kt = ['a', 'b'][key_type]
|
||||||
dic = f"keys_{uid:08x}_{sec:02}_{nt[sec][key_type]}_duplicates.dic"
|
dic = f"keys_{uid:08x}_{real_sec:02}_{nt[sec][key_type]}_duplicates.dic"
|
||||||
with open(dic, 'r') as file:
|
with open(dic, 'r') as file:
|
||||||
count = sum(1 for _ in file)
|
count = sum(1 for _ in file)
|
||||||
# print(f"dic {dic} size {count}")
|
# print(f"dic {dic} size {count}")
|
||||||
|
@ -259,7 +274,7 @@ for sec in range(NUM_SECTORS):
|
||||||
candidates[sec][key_type] = 1
|
candidates[sec][key_type] = 1
|
||||||
else:
|
else:
|
||||||
kt = ['a', 'b'][key_type]
|
kt = ['a', 'b'][key_type]
|
||||||
dic = f"keys_{uid:08x}_{sec:02}_{nt[sec][key_type]}_filtered.dic"
|
dic = f"keys_{uid:08x}_{real_sec:02}_{nt[sec][key_type]}_filtered.dic"
|
||||||
with open(dic, 'r') as file:
|
with open(dic, 'r') as file:
|
||||||
count = sum(1 for _ in file)
|
count = sum(1 for _ in file)
|
||||||
# print(f"dic {dic} size {count}")
|
# print(f"dic {dic} size {count}")
|
||||||
|
@ -272,7 +287,7 @@ for sec in range(NUM_SECTORS):
|
||||||
else:
|
else:
|
||||||
key_type = 0
|
key_type = 0
|
||||||
kt = ['a', 'b'][key_type]
|
kt = ['a', 'b'][key_type]
|
||||||
dic = f"keys_{uid:08x}_{sec:02}_{nt[sec][key_type]}.dic"
|
dic = f"keys_{uid:08x}_{real_sec:02}_{nt[sec][key_type]}.dic"
|
||||||
with open(dic, 'r') as file:
|
with open(dic, 'r') as file:
|
||||||
count = sum(1 for _ in file)
|
count = sum(1 for _ in file)
|
||||||
# print(f"dic {dic} size {count}")
|
# print(f"dic {dic} size {count}")
|
||||||
|
@ -280,9 +295,12 @@ for sec in range(NUM_SECTORS):
|
||||||
candidates[sec][1] = 1
|
candidates[sec][1] = 1
|
||||||
|
|
||||||
if args.debug:
|
if args.debug:
|
||||||
for sec in range(NUM_SECTORS):
|
for sec in range(NUM_SECTORS + NUM_EXTRA_SECTORS):
|
||||||
print(f" {sec:03} | {sec*4+3:03} | {candidates[sec][0]:6} | {candidates[sec][1]:6} ")
|
real_sec = sec
|
||||||
total_candidates = sum(candidates[sec][0] + candidates[sec][1] for sec in range(NUM_SECTORS))
|
if sec >= NUM_SECTORS:
|
||||||
|
real_sec += 16
|
||||||
|
print(f" {real_sec:03} | {real_sec*4+3:03} | {candidates[sec][0]:6} | {candidates[sec][1]:6} ")
|
||||||
|
total_candidates = sum(candidates[sec][0] + candidates[sec][1] for sec in range(NUM_SECTORS + NUM_EXTRA_SECTORS))
|
||||||
|
|
||||||
elapsed_time2 = time.time() - start_time - elapsed_time1
|
elapsed_time2 = time.time() - start_time - elapsed_time1
|
||||||
minutes = int(elapsed_time2 // 60)
|
minutes = int(elapsed_time2 // 60)
|
||||||
|
@ -300,15 +318,18 @@ print("Still about " + color(f"{minutes:2}", fg="yellow") + " minutes " +
|
||||||
|
|
||||||
abort = False
|
abort = False
|
||||||
print("Brute-forcing keys... Press any key to interrupt")
|
print("Brute-forcing keys... Press any key to interrupt")
|
||||||
for sec in range(NUM_SECTORS):
|
for sec in range(NUM_SECTORS + NUM_EXTRA_SECTORS):
|
||||||
|
real_sec = sec
|
||||||
|
if sec >= NUM_SECTORS:
|
||||||
|
real_sec += 16
|
||||||
for key_type in [0, 1]:
|
for key_type in [0, 1]:
|
||||||
# If we have a duplicates dict
|
# If we have a duplicates dict
|
||||||
# note: we skip if we already know one key
|
# note: we skip if we already know one key
|
||||||
# as using 2x1nt1key later will be faster
|
# as using 2x1nt1key later will be faster
|
||||||
if found_keys[sec][0] == "" and found_keys[sec][1] == "" and duplicates_dicts[sec][key_type]:
|
if found_keys[sec][0] == "" and found_keys[sec][1] == "" and duplicates_dicts[sec][key_type]:
|
||||||
kt = ['a', 'b'][key_type]
|
kt = ['a', 'b'][key_type]
|
||||||
dic = f"keys_{uid:08x}_{sec:02}_{nt[sec][key_type]}_duplicates.dic"
|
dic = f"keys_{uid:08x}_{real_sec:02}_{nt[sec][key_type]}_duplicates.dic"
|
||||||
cmd = f"hf mf fchk --blk {sec * 4} -{kt} -f {dic} --no-default"
|
cmd = f"hf mf fchk --blk {real_sec * 4} -{kt} -f {dic} --no-default"
|
||||||
if args.debug:
|
if args.debug:
|
||||||
print(cmd)
|
print(cmd)
|
||||||
p.console(cmd)
|
p.console(cmd)
|
||||||
|
@ -316,11 +337,11 @@ for sec in range(NUM_SECTORS):
|
||||||
if "aborted via keyboard" in line:
|
if "aborted via keyboard" in line:
|
||||||
abort = True
|
abort = True
|
||||||
if "found:" in line:
|
if "found:" in line:
|
||||||
found_keys[sec][key_type] = line[30:]
|
found_keys[sec][key_type] = line[30:].strip()
|
||||||
print_key(sec, key_type, found_keys[sec][key_type])
|
print_key(real_sec, key_type, found_keys[sec][key_type])
|
||||||
if nt[sec][0] == nt[sec][1] and found_keys[sec][key_type ^ 1] == "":
|
if nt[sec][0] == nt[sec][1] and found_keys[sec][key_type ^ 1] == "":
|
||||||
found_keys[sec][key_type ^ 1] = found_keys[sec][key_type]
|
found_keys[sec][key_type ^ 1] = found_keys[sec][key_type]
|
||||||
print_key(sec, key_type ^ 1, found_keys[sec][key_type ^ 1])
|
print_key(real_sec, key_type ^ 1, found_keys[sec][key_type ^ 1])
|
||||||
if abort:
|
if abort:
|
||||||
break
|
break
|
||||||
if abort:
|
if abort:
|
||||||
|
@ -333,8 +354,8 @@ for sec in range(NUM_SECTORS):
|
||||||
if found_keys[sec][0] == "" and found_keys[sec][1] == "" and filtered_dicts[sec][key_type]:
|
if found_keys[sec][0] == "" and found_keys[sec][1] == "" and filtered_dicts[sec][key_type]:
|
||||||
# Use filtered dict
|
# Use filtered dict
|
||||||
kt = ['a', 'b'][key_type]
|
kt = ['a', 'b'][key_type]
|
||||||
dic = f"keys_{uid:08x}_{sec:02}_{nt[sec][key_type]}_filtered.dic"
|
dic = f"keys_{uid:08x}_{real_sec:02}_{nt[sec][key_type]}_filtered.dic"
|
||||||
cmd = f"hf mf fchk --blk {sec * 4} -{kt} -f {dic} --no-default"
|
cmd = f"hf mf fchk --blk {real_sec * 4} -{kt} -f {dic} --no-default"
|
||||||
if args.debug:
|
if args.debug:
|
||||||
print(cmd)
|
print(cmd)
|
||||||
p.console(cmd)
|
p.console(cmd)
|
||||||
|
@ -342,8 +363,8 @@ for sec in range(NUM_SECTORS):
|
||||||
if "aborted via keyboard" in line:
|
if "aborted via keyboard" in line:
|
||||||
abort = True
|
abort = True
|
||||||
if "found:" in line:
|
if "found:" in line:
|
||||||
found_keys[sec][key_type] = line[30:]
|
found_keys[sec][key_type] = line[30:].strip()
|
||||||
print_key(sec, key_type, found_keys[sec][key_type])
|
print_key(real_sec, key_type, found_keys[sec][key_type])
|
||||||
if abort:
|
if abort:
|
||||||
break
|
break
|
||||||
if abort:
|
if abort:
|
||||||
|
@ -354,8 +375,8 @@ for sec in range(NUM_SECTORS):
|
||||||
key_type = 0
|
key_type = 0
|
||||||
# Use regular dict
|
# Use regular dict
|
||||||
kt = ['a', 'b'][key_type]
|
kt = ['a', 'b'][key_type]
|
||||||
dic = f"keys_{uid:08x}_{sec:02}_{nt[sec][key_type]}.dic"
|
dic = f"keys_{uid:08x}_{real_sec:02}_{nt[sec][key_type]}.dic"
|
||||||
cmd = f"hf mf fchk --blk {sec * 4} -{kt} -f {dic} --no-default"
|
cmd = f"hf mf fchk --blk {real_sec * 4} -{kt} -f {dic} --no-default"
|
||||||
if args.debug:
|
if args.debug:
|
||||||
print(cmd)
|
print(cmd)
|
||||||
p.console(cmd)
|
p.console(cmd)
|
||||||
|
@ -363,10 +384,10 @@ for sec in range(NUM_SECTORS):
|
||||||
if "aborted via keyboard" in line:
|
if "aborted via keyboard" in line:
|
||||||
abort = True
|
abort = True
|
||||||
if "found:" in line:
|
if "found:" in line:
|
||||||
found_keys[sec][0] = line[30:]
|
found_keys[sec][0] = line[30:].strip()
|
||||||
found_keys[sec][1] = line[30:]
|
found_keys[sec][1] = line[30:].strip()
|
||||||
print_key(sec, 0, found_keys[sec][key_type])
|
print_key(real_sec, 0, found_keys[sec][key_type])
|
||||||
print_key(sec, 1, found_keys[sec][key_type])
|
print_key(real_sec, 1, found_keys[sec][key_type])
|
||||||
if abort:
|
if abort:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
@ -379,11 +400,11 @@ for sec in range(NUM_SECTORS):
|
||||||
key_type_source = 0
|
key_type_source = 0
|
||||||
key_type_target = 1
|
key_type_target = 1
|
||||||
if duplicates_dicts[sec][key_type_target]:
|
if duplicates_dicts[sec][key_type_target]:
|
||||||
dic = f"keys_{uid:08x}_{sec:02}_{nt[sec][key_type_target]}_duplicates.dic"
|
dic = f"keys_{uid:08x}_{real_sec:02}_{nt[sec][key_type_target]}_duplicates.dic"
|
||||||
elif filtered_dicts[sec][key_type_target]:
|
elif filtered_dicts[sec][key_type_target]:
|
||||||
dic = f"keys_{uid:08x}_{sec:02}_{nt[sec][key_type_target]}_filtered.dic"
|
dic = f"keys_{uid:08x}_{real_sec:02}_{nt[sec][key_type_target]}_filtered.dic"
|
||||||
else:
|
else:
|
||||||
dic = f"keys_{uid:08x}_{sec:02}_{nt[sec][key_type_target]}.dic"
|
dic = f"keys_{uid:08x}_{real_sec:02}_{nt[sec][key_type_target]}.dic"
|
||||||
cmd = [tools["staticnested_2x1nt1key"], nt[sec][key_type_source], found_keys[sec][key_type_source], dic]
|
cmd = [tools["staticnested_2x1nt1key"], nt[sec][key_type_source], found_keys[sec][key_type_source], dic]
|
||||||
if args.debug:
|
if args.debug:
|
||||||
print(' '.join(cmd))
|
print(' '.join(cmd))
|
||||||
|
@ -394,7 +415,7 @@ for sec in range(NUM_SECTORS):
|
||||||
keys.add(line[12:])
|
keys.add(line[12:])
|
||||||
if len(keys) > 1:
|
if len(keys) > 1:
|
||||||
kt = ['a', 'b'][key_type_target]
|
kt = ['a', 'b'][key_type_target]
|
||||||
cmd = f"hf mf fchk --blk {sec * 4} -{kt} --no-default"
|
cmd = f"hf mf fchk --blk {real_sec * 4} -{kt} --no-default"
|
||||||
for k in keys:
|
for k in keys:
|
||||||
cmd += f" -k {k}"
|
cmd += f" -k {k}"
|
||||||
if args.debug:
|
if args.debug:
|
||||||
|
@ -404,11 +425,11 @@ for sec in range(NUM_SECTORS):
|
||||||
if "aborted via keyboard" in line:
|
if "aborted via keyboard" in line:
|
||||||
abort = True
|
abort = True
|
||||||
if "found:" in line:
|
if "found:" in line:
|
||||||
found_keys[sec][key_type_target] = line[30:]
|
found_keys[sec][key_type_target] = line[30:].strip()
|
||||||
elif len(keys) == 1:
|
elif len(keys) == 1:
|
||||||
found_keys[sec][key_type_target] = keys.pop()
|
found_keys[sec][key_type_target] = keys.pop()
|
||||||
if found_keys[sec][key_type_target] != "":
|
if found_keys[sec][key_type_target] != "":
|
||||||
print_key(sec, key_type_target, found_keys[sec][key_type_target])
|
print_key(real_sec, key_type_target, found_keys[sec][key_type_target])
|
||||||
if abort:
|
if abort:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
@ -434,14 +455,17 @@ else:
|
||||||
print(plus + "-----+-----+--------------+---+--------------+----")
|
print(plus + "-----+-----+--------------+---+--------------+----")
|
||||||
print(plus + " Sec | Blk | key A |res| key B |res")
|
print(plus + " Sec | Blk | key A |res| key B |res")
|
||||||
print(plus + "-----+-----+--------------+---+--------------+----")
|
print(plus + "-----+-----+--------------+---+--------------+----")
|
||||||
for sec in range(NUM_SECTORS):
|
for sec in range(NUM_SECTORS + NUM_EXTRA_SECTORS):
|
||||||
|
real_sec = sec
|
||||||
|
if sec >= NUM_SECTORS:
|
||||||
|
real_sec += 16
|
||||||
keys = [["", 0], ["", 0]]
|
keys = [["", 0], ["", 0]]
|
||||||
for key_type in [0, 1]:
|
for key_type in [0, 1]:
|
||||||
if found_keys[sec][key_type] == "":
|
if found_keys[sec][key_type] == "":
|
||||||
keys[key_type] = [color("------------", fg="red"), color("0", fg="red")]
|
keys[key_type] = [color("------------", fg="red"), color("0", fg="red")]
|
||||||
else:
|
else:
|
||||||
keys[key_type] = [color(found_keys[sec][key_type], fg="green"), color("1", fg="green")]
|
keys[key_type] = [color(found_keys[sec][key_type], fg="green"), color("1", fg="green")]
|
||||||
print(plus + f" {sec:03} | {sec*4+3:03} | {keys[0][0]} | {keys[0][1]} | {keys[1][0]} | {keys[1][1]} ")
|
print(plus + f" {real_sec:03} | {real_sec*4+3:03} | {keys[0][0]} | {keys[0][1]} | {keys[1][0]} | {keys[1][1]} ")
|
||||||
print(plus + "-----+-----+--------------+---+--------------+----")
|
print(plus + "-----+-----+--------------+---+--------------+----")
|
||||||
print(plus + "( " + color("0", fg="red") + ":Failed / " +
|
print(plus + "( " + color("0", fg="red") + ":Failed / " +
|
||||||
color("1", fg="green") + ":Success )")
|
color("1", fg="green") + ":Success )")
|
||||||
|
@ -451,7 +475,7 @@ else:
|
||||||
unknown = False
|
unknown = False
|
||||||
with (open(keyfile, "wb")) as f:
|
with (open(keyfile, "wb")) as f:
|
||||||
for key_type in [0, 1]:
|
for key_type in [0, 1]:
|
||||||
for sec in range(NUM_SECTORS):
|
for sec in range(NUM_SECTORS + NUM_EXTRA_SECTORS):
|
||||||
k = found_keys[sec][key_type]
|
k = found_keys[sec][key_type]
|
||||||
if k == "":
|
if k == "":
|
||||||
k = "FFFFFFFFFFFF"
|
k = "FFFFFFFFFFFF"
|
||||||
|
|
|
@ -9863,7 +9863,7 @@ static int CmdHF14AMfISEN(const char *Cmd) {
|
||||||
return NONCE_FAIL;
|
return NONCE_FAIL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uint8_t num_sectors = 16;
|
uint8_t num_sectors = MIFARE_1K_MAXSECTOR + 1;
|
||||||
PrintAndLogEx(NORMAL, "[\n [");
|
PrintAndLogEx(NORMAL, "[\n [");
|
||||||
for (uint8_t sec = 0; sec < num_sectors; sec++) {
|
for (uint8_t sec = 0; sec < num_sectors; sec++) {
|
||||||
PrintAndLogEx(NORMAL, " [\"%08x\", \"%08x\"]%s",
|
PrintAndLogEx(NORMAL, " [\"%08x\", \"%08x\"]%s",
|
||||||
|
@ -9889,7 +9889,7 @@ static int CmdHF14AMfISEN(const char *Cmd) {
|
||||||
}
|
}
|
||||||
if (collect_fm11rf08s_with_data) {
|
if (collect_fm11rf08s_with_data) {
|
||||||
PrintAndLogEx(NORMAL, " ],\n [");
|
PrintAndLogEx(NORMAL, " ],\n [");
|
||||||
int bytes = num_sectors * 4 * 16;
|
int bytes = MIFARE_1K_MAXSECTOR * 4 * 16;
|
||||||
|
|
||||||
uint8_t *dump = calloc(bytes, sizeof(uint8_t));
|
uint8_t *dump = calloc(bytes, sizeof(uint8_t));
|
||||||
if (dump == NULL) {
|
if (dump == NULL) {
|
||||||
|
@ -9901,11 +9901,11 @@ static int CmdHF14AMfISEN(const char *Cmd) {
|
||||||
free(dump);
|
free(dump);
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
for (uint8_t sec = 0; sec < num_sectors; sec++) {
|
for (uint8_t sec = 0; sec < MIFARE_1K_MAXSECTOR; sec++) {
|
||||||
for (uint8_t b = 0; b < 4; b++) {
|
for (uint8_t b = 0; b < 4; b++) {
|
||||||
PrintAndLogEx(NORMAL, " \"%s\"%s",
|
PrintAndLogEx(NORMAL, " \"%s\"%s",
|
||||||
sprint_hex_inrow(dump + ((sec * 4) + b) * 16, 16),
|
sprint_hex_inrow(dump + ((sec * 4) + b) * 16, 16),
|
||||||
(sec == num_sectors - 1) && (b == 3) ? "" : ",");
|
(sec == MIFARE_1K_MAXSECTOR - 1) && (b == 3) ? "" : ",");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(dump);
|
free(dump);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue