Merge branch 'main' into pac-emulation

This commit is contained in:
Kevin Yuan
2026-04-06 16:43:41 +01:00
committed by GitHub
3 changed files with 41 additions and 6 deletions
+2 -1
View File
@@ -3,7 +3,8 @@ 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...
## [unreleased][unreleased]
- Added PAC/Stanley LF protocol support (read, emulate and T55xx clone)
- Added PAC/Stanley LF protocol support: read, emulate and T55xx clone (@kevihiiin, @danieltwagner)
- Fix firmware application USB serial number (@taichunmin)
- Added ioProx LF protocol support (read, emulate and T55xx clone)
- Added commands to dump and clone Mifare tags
- Fix bad missing tools warning (@suut)
+2 -2
View File
@@ -6614,7 +6614,7 @@
#ifndef APP_USBD_STRING_SERIAL_EXTERN
#define APP_USBD_STRING_SERIAL_EXTERN 0
#define APP_USBD_STRING_SERIAL_EXTERN 1
#endif
// <s> APP_USBD_STRING_SERIAL - String descriptor for the serial number.
@@ -6622,7 +6622,7 @@
// <i> Note: This value is not editable in Configuration Wizard.
// <i> Serial number that is defined the same way like in @ref APP_USBD_STRINGS_MANUFACTURER.
#ifndef APP_USBD_STRING_SERIAL
#define APP_USBD_STRING_SERIAL APP_USBD_STRING_DESC("000000000000")
#define APP_USBD_STRING_SERIAL g_extern_serial_number
#endif
// </e>
+37 -3
View File
@@ -2445,9 +2445,43 @@ class HFMFAutopwn(ReaderRequiredUnit):
print(f" {CG}[+]{C0} Some keys found, recovering remaining..")
if nt_level == 2:
print(
f" {CY}[+]{C0} Hardened card — use 'hf mf hardnested' to recover remaining keys"
)
missing_keys = self.find_missing_keys(current_keys_found, total)
hardnested = HFMFHardNested.__new__(HFMFHardNested)
BaseCLIUnit.__init__(hardnested)
hardnested._device_cmd = self.cmd
for missing_key_num, key_type_target in missing_keys.items():
if current_keys_found.get(missing_key_num) is not None:
print(f" {CG}[+]{C0} Key {missing_key_num} found by reuse")
continue
block_known, key_known_bytes, type_known = self.choose_random_known_key(
current_keys_found
)
block_target = (missing_key_num // 2) * 4
hn_key = hardnested.recover_key(
False,
block_known,
type_known,
key_known_bytes,
block_target,
key_type_target,
False,
200,
3,
)
if hn_key is None:
continue
print(f" {CG}[+]{C0} Found key {missing_key_num}: {hn_key.upper()}")
current_keys_found[missing_key_num] = bytes.fromhex(hn_key)
current_keys_found = dict(sorted(current_keys_found.items()))
_, mask_bytes = self.mask_from_keys(missing_keys)
current_keys_found = self.merge_found_sector_keys(
current_keys_found,
self.try_key(bytes.fromhex(hn_key), self.neg_bytes(mask_bytes)),
)
if len(current_keys_found) < total:
current_keys_found = self.run_senested(
current_keys_found, max_sectors_num
)
elif nt_level == 0:
current_keys_found = self.run_senested(current_keys_found, max_sectors_num)
else: