mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-20 05:13:46 -07:00
fm11rf08s_recovery: initial fchk with default keys
This commit is contained in:
parent
c401359a4e
commit
fe3901b69b
1 changed files with 56 additions and 16 deletions
|
@ -20,6 +20,8 @@ from output_grabber import OutputGrabber
|
||||||
|
|
||||||
BACKDOOR_RF08S = "A396EFA4E24F"
|
BACKDOOR_RF08S = "A396EFA4E24F"
|
||||||
NUM_SECTORS = 16
|
NUM_SECTORS = 16
|
||||||
|
# Run an initial check with the default keys
|
||||||
|
INITIAL_CHECK = True
|
||||||
# Run a final check with the found keys, mostly for validation
|
# Run a final check with the found keys, mostly for validation
|
||||||
FINAL_CHECK = True
|
FINAL_CHECK = True
|
||||||
|
|
||||||
|
@ -55,6 +57,22 @@ if uid is None:
|
||||||
exit()
|
exit()
|
||||||
print(f"UID: {uid:08X}")
|
print(f"UID: {uid:08X}")
|
||||||
|
|
||||||
|
found_keys = [["", ""] for _ in range(NUM_SECTORS)]
|
||||||
|
if INITIAL_CHECK:
|
||||||
|
print("Checking default keys...")
|
||||||
|
with out:
|
||||||
|
p.console("hf mf fchk")
|
||||||
|
for line in out.captured_output.split('\n'):
|
||||||
|
if "[+] 0" in line:
|
||||||
|
res = [x.strip() for x in line.split('|')]
|
||||||
|
sec = int(res[0][4:])
|
||||||
|
if res[3] == '1':
|
||||||
|
found_keys[sec][0] = res[2]
|
||||||
|
print(f"Sector {sec:2} keyA = {found_keys[sec][0]}")
|
||||||
|
if res[5] == '1':
|
||||||
|
found_keys[sec][1] = res[4]
|
||||||
|
print(f"Sector {sec:2} keyB = {found_keys[sec][1]}")
|
||||||
|
|
||||||
nt = [["", ""] for _ in range(NUM_SECTORS)]
|
nt = [["", ""] for _ in range(NUM_SECTORS)]
|
||||||
nt_enc = [["", ""] for _ in range(NUM_SECTORS)]
|
nt_enc = [["", ""] for _ in range(NUM_SECTORS)]
|
||||||
par_err = [["", ""] for _ in range(NUM_SECTORS)]
|
par_err = [["", ""] for _ in range(NUM_SECTORS)]
|
||||||
|
@ -62,9 +80,13 @@ print("Getting nonces...")
|
||||||
with out:
|
with out:
|
||||||
for sec in range(NUM_SECTORS):
|
for sec in range(NUM_SECTORS):
|
||||||
blk = sec * 4
|
blk = sec * 4
|
||||||
for key_type in [0, 1]:
|
if found_keys[sec][0] == "" or found_keys[sec][1] == "":
|
||||||
p.console(f"hf mf isen -n1 --blk {blk} -c {key_type+4} --key {BACKDOOR_RF08S}")
|
# Even if one key already found, we'll need both nt
|
||||||
p.console(f"hf mf isen -n1 --blk {blk} -c {key_type+4} --key {BACKDOOR_RF08S} --c2 {key_type}")
|
for key_type in [0, 1]:
|
||||||
|
cmd = f"hf mf isen -n1 --blk {blk} -c {key_type+4} --key {BACKDOOR_RF08S}"
|
||||||
|
p.console(cmd)
|
||||||
|
cmd += f" --c2 {key_type}"
|
||||||
|
p.console(cmd)
|
||||||
print("Processing traces...")
|
print("Processing traces...")
|
||||||
for line in out.captured_output.split('\n'):
|
for line in out.captured_output.split('\n'):
|
||||||
if "nested cmd: 64" in line or "nested cmd: 65" in line:
|
if "nested cmd: 64" in line or "nested cmd: 65" in line:
|
||||||
|
@ -84,8 +106,12 @@ print("Running staticnested_1nt & 2x1nt when doable...")
|
||||||
keys = [[set(), set()] for _ in range(NUM_SECTORS)]
|
keys = [[set(), set()] for _ in range(NUM_SECTORS)]
|
||||||
all_keys = set()
|
all_keys = set()
|
||||||
duplicates = set()
|
duplicates = set()
|
||||||
|
# Availability of filtered dicts
|
||||||
|
filtered_dicts = [[False, False] for _ in range(NUM_SECTORS)]
|
||||||
for sec in range(NUM_SECTORS):
|
for sec in range(NUM_SECTORS):
|
||||||
if nt[sec][0] != nt[sec][1]:
|
if found_keys[sec][0] != "" and found_keys[sec][1] != "":
|
||||||
|
continue
|
||||||
|
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 = [STATICNESTED_1NT, f"{uid:08X}", f"{sec}",
|
cmd = [STATICNESTED_1NT, f"{uid:08X}", f"{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]]
|
||||||
|
@ -97,6 +123,7 @@ for sec in range(NUM_SECTORS):
|
||||||
if DEBUG:
|
if 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
|
||||||
for key_type in [0, 1]:
|
for key_type in [0, 1]:
|
||||||
with (open(f"keys_{uid:08x}_{sec:02}_{nt[sec][key_type]}_filtered.dic")) as f:
|
with (open(f"keys_{uid:08x}_{sec:02}_{nt[sec][key_type]}_filtered.dic")) as f:
|
||||||
keys_set = set()
|
keys_set = set()
|
||||||
|
@ -106,8 +133,11 @@ for sec in range(NUM_SECTORS):
|
||||||
keys[sec][key_type] = keys_set
|
keys[sec][key_type] = keys_set
|
||||||
duplicates.update(all_keys.intersection(keys_set))
|
duplicates.update(all_keys.intersection(keys_set))
|
||||||
all_keys.update(keys_set)
|
all_keys.update(keys_set)
|
||||||
else:
|
else: # one key not found or both identical
|
||||||
key_type = 0
|
if found_keys[sec][0] == "":
|
||||||
|
key_type = 0
|
||||||
|
else:
|
||||||
|
key_type = 1
|
||||||
cmd = [STATICNESTED_1NT, f"{uid:08X}", f"{sec}",
|
cmd = [STATICNESTED_1NT, f"{uid:08X}", f"{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 DEBUG:
|
if DEBUG:
|
||||||
|
@ -129,9 +159,12 @@ for dup in duplicates:
|
||||||
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)
|
||||||
if nt[sec][0] == nt[sec][1] and key_type == 0 and keys[sec][1] == set():
|
if nt[sec][0] == nt[sec][1] and key_type == 0 and keys[sec][1] == set() and found_keys[sec][1] == "":
|
||||||
keys_filtered[sec][1].add(dup)
|
keys_filtered[sec][1].add(dup)
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Availability of duplicates dicts
|
||||||
|
duplicates_dicts = [[False, False] for _ in range(NUM_SECTORS)]
|
||||||
first = True
|
first = True
|
||||||
for sec in range(NUM_SECTORS):
|
for sec in range(NUM_SECTORS):
|
||||||
for key_type in [0, 1]:
|
for key_type in [0, 1]:
|
||||||
|
@ -142,14 +175,16 @@ for sec in range(NUM_SECTORS):
|
||||||
with (open(f"keys_{uid:08x}_{sec:02}_{nt[sec][key_type]}_duplicates.dic", "w")) as f:
|
with (open(f"keys_{uid:08x}_{sec:02}_{nt[sec][key_type]}_duplicates.dic", "w")) as f:
|
||||||
for k in keys_filtered[sec][key_type]:
|
for k in keys_filtered[sec][key_type]:
|
||||||
f.write(f"{k}\n")
|
f.write(f"{k}\n")
|
||||||
|
duplicates_dicts[sec][key_type] = True
|
||||||
|
|
||||||
abort = False
|
abort = False
|
||||||
print("Brute-forcing keys... Press any key to interrupt")
|
print("Brute-forcing keys... Press any key to interrupt")
|
||||||
found_keys = [["", ""] for _ in range(NUM_SECTORS)]
|
|
||||||
for sec in range(NUM_SECTORS):
|
for sec in range(NUM_SECTORS):
|
||||||
for key_type in [0, 1]:
|
for key_type in [0, 1]:
|
||||||
# If we have a duplicates dict
|
# If we have a duplicates dict
|
||||||
if found_keys[sec][0] == "" and found_keys[sec][1] == "" and len(keys_filtered[sec][key_type]) > 0:
|
# note: we skip if we already know one key
|
||||||
|
# as using 2x1nt1key later will be faster
|
||||||
|
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}_{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 {sec * 4} -{kt} -f {dic} --no-default"
|
||||||
|
@ -174,7 +209,10 @@ for sec in range(NUM_SECTORS):
|
||||||
break
|
break
|
||||||
|
|
||||||
for key_type in [0, 1]:
|
for key_type in [0, 1]:
|
||||||
if found_keys[sec][0] == "" and found_keys[sec][1] == "" and nt[sec][0] != nt[sec][1]:
|
# If we have a filtered dict
|
||||||
|
# note: we skip if we already know one key
|
||||||
|
# as using 2x1nt1key later will be faster
|
||||||
|
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}_{sec:02}_{nt[sec][key_type]}_filtered.dic"
|
||||||
|
@ -195,6 +233,7 @@ for sec in range(NUM_SECTORS):
|
||||||
if abort:
|
if abort:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
# If one common key for the sector
|
||||||
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]:
|
||||||
key_type = 0
|
key_type = 0
|
||||||
# Use regular dict
|
# Use regular dict
|
||||||
|
@ -216,20 +255,21 @@ for sec in range(NUM_SECTORS):
|
||||||
if abort:
|
if abort:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
# If one key is missing, use the other one with 2x1nt1key
|
||||||
if ((found_keys[sec][0] == "") ^ (found_keys[sec][1] == "")) and nt[sec][0] != nt[sec][1]:
|
if ((found_keys[sec][0] == "") ^ (found_keys[sec][1] == "")) and nt[sec][0] != nt[sec][1]:
|
||||||
# use 2x1nt1key
|
|
||||||
if (found_keys[sec][0] == ""):
|
if (found_keys[sec][0] == ""):
|
||||||
key_type_source = 1
|
key_type_source = 1
|
||||||
key_type_target = 0
|
key_type_target = 0
|
||||||
else:
|
else:
|
||||||
key_type_source = 0
|
key_type_source = 0
|
||||||
key_type_target = 1
|
key_type_target = 1
|
||||||
if len(keys_filtered[sec][key_type_target]) > 0:
|
if duplicates_dicts[sec][key_type_target]:
|
||||||
cmd = [STATICNESTED_2X1NT1KEY, nt[sec][key_type_source], found_keys[sec][key_type_source],
|
dic = f"keys_{uid:08x}_{sec:02}_{nt[sec][key_type_target]}_duplicates.dic"
|
||||||
f"keys_{uid:08x}_{sec:02}_{nt[sec][key_type_target]}_duplicates.dic"]
|
elif filtered_dicts[sec][key_type_target]:
|
||||||
|
dic = f"keys_{uid:08x}_{sec:02}_{nt[sec][key_type_target]}_filtered.dic"
|
||||||
else:
|
else:
|
||||||
cmd = [STATICNESTED_2X1NT1KEY, nt[sec][key_type_source], found_keys[sec][key_type_source],
|
dic = f"keys_{uid:08x}_{sec:02}_{nt[sec][key_type_target]}.dic"
|
||||||
f"keys_{uid:08x}_{sec:02}_{nt[sec][key_type_target]}_filtered.dic"]
|
cmd = [STATICNESTED_2X1NT1KEY, nt[sec][key_type_source], found_keys[sec][key_type_source], dic]
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
print(' '.join(cmd))
|
print(' '.join(cmd))
|
||||||
result = subprocess.run(cmd, capture_output=True, text=True).stdout
|
result = subprocess.run(cmd, capture_output=True, text=True).stdout
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue