minor text

This commit is contained in:
iceman1001 2024-11-07 21:36:02 +01:00
parent 27fee07090
commit 32028fd53f
3 changed files with 52 additions and 49 deletions

View file

@ -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...
## [unreleased][unreleased]
- Fixed `intertic.py` - missing comma in array (@iceman1001)
- Added improved algorithm for `hf iclass legrec` leveraging reduced entropy from hash0 constraints (@antiklesys)
- Fixed `hf iclass configcard` when generating elite or keyroll elite configcards for Rev.C legacy readers (@antiklesys)
- Changed `hf mf c*` - now accepts a --gdm flag to write using uscuid/gdm 20/23 alt magic wakeup (@nvx)

View file

@ -13,12 +13,7 @@ import json
from fm11rf08s_recovery import recovery
# ------------------------------------------------------------------------------
# Revision log & Licence
# ------------------------------------------------------------------------------
'''
1.2.0 - BC - Proxmark3 Submission
'''
author = "@csBlueChip"
script_ver = "1.2.0"
# Copyright @csBlueChip
@ -123,7 +118,7 @@ globals:
# No logfile name yet
lprint("Fudan FM11RF08[S] full card recovery")
lprint(f"\nDump folder: {dpath}")
lprint(f"\nDump folder... " + color(f"{dpath}", fg="yellow"))
# FIXME: script is announced as for RF08 and for RF08S but it comprises RF32N key
# and if RF08 is supported, all other NXP/Infineon with same backdoor can be treated
@ -143,7 +138,8 @@ globals:
# Currently loadKeys is hardcoded for RF08S
if args.force or (key := loadKeys(keyfile)) is None:
if args.recover is False:
lprint("* Keys not loaded, use --recover to run recovery script [slow]")
s = color("--recover", fg="yellow")
lprint(f"Keys not loaded, use {s} to run recovery script [slow]")
else:
# FIXME: recovery() is only for RF08S. TODO for the other ones with a "darknested" attack
keyfile = recoverKeys()
@ -153,7 +149,8 @@ globals:
ret, mad, key = verifyKeys(key)
if ret is False:
if args.nokeys is False:
lprint("! Use --nokeys to keep going past this point")
s = color("--nokeys", fg="yellow")
lprint(f"Use {s} to keep going past this point")
return
# FIXME: nr of blocks depend on the tag. RF32 is 256, RF08 is 64, RF08S is 64+8
@ -375,7 +372,7 @@ If keys cannot be loaded AND --recover is specified, then run key recovery
"""
key = [[b'' for _ in range(2)] for _ in range(17)] # create a fresh array
lprint(f"\nLoad Keys from file: |{keyfile}|")
lprint(f"\n Load keys from file... " + color(f"{keyfile}", fg="yellow"))
try:
with (open(keyfile, "rb")) as fh:
@ -434,7 +431,7 @@ globals:
badk = 0
mad = False
lprint("Check keys...")
lprint("Checking keys...")
for sec in range(0, 16+1): # 16 normal, 1 dark
sn = sec
@ -450,11 +447,13 @@ globals:
lprint(f" `{cmd}`", end='', flush=True)
res = p.console(cmd, capture=False)
lprint(" " * (3-len(str(bn))), end="", prompt='')
lprint(" " * (3-len(str(bn))), end='', prompt='')
if res == 0:
lprint(" ... PASS", end="", prompt='')
s = color("ok", fg="green")
lprint(f" ( {s} )", end='', prompt='')
else:
lprint(" ... FAIL", end="", prompt='')
s = color("fail", fg="red")
lprint(f" ( {s} )", end='', prompt='')
badk += 1
key[sec][ab] = b''
@ -467,8 +466,9 @@ globals:
lprint("", prompt='')
if badk > 0:
lprint(f"! {badk} bad key", end='')
lprint("s exist" if badk != 1 else " exists")
s = color(f'{badk}', fg="red")
e = "s exist" if badk != 1 else " exists"
lprint(f" {s} bad key{e}", prompt='[!]')
rv = False, mad, key
else:
@ -920,9 +920,9 @@ def dumpAcl(data):
def diskDump(data, uid, dpath):
"""Full Dump"""
dump18 = f"{dpath}hf-mf-{uid.hex().upper()}-dump18.bin"
dump18 = color(f"{dpath}hf-mf-{uid.hex().upper()}-dump18.bin", fg="yellow")
lprint(f"\nDump Card Data to file: {dump18}")
lprint(f"\nDump Card Data to file... {dump18}")
bad = False
with open(dump18, 'wb') as f:

View file

@ -90,11 +90,11 @@ def Describe_Usage_1(Usage, ContractMediumEndDate, Certificate):
unk = Usage.nom_bits(65)
EventValidityTimeFirstStamp = Usage.nom(11)
print(' EventDateStamp : {} ({})'.format(EventDateStamp, (datetime(1997, 1, 1) + timedelta(days = ContractMediumEndDate - EventDateStamp)).strftime('%Y-%m-%d')));
print(' EventDateStamp : {} ({})'.format(EventDateStamp, (datetime(1997, 1, 1) + timedelta(days = ContractMediumEndDate - EventDateStamp)).strftime('%Y-%m-%d')))
print(' EventTimeStamp : {} ({:02d}:{:02d})'. format(EventTimeStamp, EventTimeStamp // 60, EventTimeStamp % 60))
print(' unk1... :', unk);
print(' unk1... :', unk)
print(' EventValidityTimeFirstStamp: {} ({:02d}:{:02d})'. format(EventValidityTimeFirstStamp, EventValidityTimeFirstStamp // 60, EventValidityTimeFirstStamp % 60))
print(' left... :', Usage.nom_bits_left());
print(' left... :', Usage.nom_bits_left())
print(' [CER] Usage : {:04x}'.format(Certificate.nom(16)))
def Describe_Usage_1_1(Usage, ContractMediumEndDate, Certificate):
@ -110,18 +110,18 @@ def Describe_Usage_1_1(Usage, ContractMediumEndDate, Certificate):
EventCountPassengers_mb = Usage.nom(4)
EventValidityTimeFirstStamp = Usage.nom(11)
print(' DateStamp : {} ({})'.format(EventDateStamp, (datetime(1997, 1, 1) + timedelta(days = ContractMediumEndDate - EventDateStamp)).strftime('%Y-%m-%d')));
print(' DateStamp : {} ({})'.format(EventDateStamp, (datetime(1997, 1, 1) + timedelta(days = ContractMediumEndDate - EventDateStamp)).strftime('%Y-%m-%d')))
print(' TimeStamp : {} ({:02d}:{:02d})'. format(EventTimeStamp, EventTimeStamp // 60, EventTimeStamp % 60))
print(' unk0... :', unk0);
print(' unk0... :', unk0)
print(' Code/Nature : 0x{:x} ({})'.format(EventCode_Nature, TYPE_EventCode_Nature.get(EventCode_Nature, '?')))
print(' Code/Type : 0x{:x} ({})'.format(EventCode_Type, TYPE_EventCode_Type.get(EventCode_Type, '?')))
print(' unk1... :', unk1);
print(' unk1... :', unk1)
print(' GeoVehicleId : {}'. format(EventGeoVehicleId))
print(' GeoRouteId : {}'. format(EventGeoRouteId))
print(' Direction : {} ({})'. format(EventGeoRoute_Direction, TYPE_EventGeoRoute_Direction.get(EventGeoRoute_Direction, '?')))
print(' Passengers(?) : {}'. format(EventCountPassengers_mb))
print(' ValidityTimeFirstStamp: {} ({:02d}:{:02d})'. format(EventValidityTimeFirstStamp, EventValidityTimeFirstStamp // 60, EventValidityTimeFirstStamp % 60))
print(' left... :', Usage.nom_bits_left());
print(' left... :', Usage.nom_bits_left())
print(' [CER] Usage : {:04x}'.format(Certificate.nom(16)))
def Describe_Usage_1_2(Usage, ContractMediumEndDate, Certificate):
@ -143,19 +143,19 @@ def Describe_Usage_1_2(Usage, ContractMediumEndDate, Certificate):
0x1: 'tramway',
}
print(' DateStamp : {} ({})'.format(EventDateStamp, (datetime(1997, 1, 1) + timedelta(days = ContractMediumEndDate - EventDateStamp)).strftime('%Y-%m-%d')));
print(' DateStamp : {} ({})'.format(EventDateStamp, (datetime(1997, 1, 1) + timedelta(days = ContractMediumEndDate - EventDateStamp)).strftime('%Y-%m-%d')))
print(' TimeStamp : {} ({:02d}:{:02d})'. format(EventTimeStamp, EventTimeStamp // 60, EventTimeStamp % 60))
print(' Count(?) : {}'. format(EventCount_mb))
print(' unk0... :', unk0);
print(' unk0... :', unk0)
print(' Code/Nature(?) : 0x{:x} ({})'.format(EventCode_Nature_mb, TYPE_EventCode_Nature_Reims.get(EventCode_Nature_mb, '?')))
print(' Code/Type(?) : 0x{:x} ({})'.format(EventCode_Type_mb, TYPE_EventCode_Type.get(EventCode_Type_mb, '?')))
print(' unk1... :', unk1);
print(' unk1... :', unk1)
print(' GeoVehicleId : {}'. format(EventGeoVehicleId))
print(' GeoRouteId : {}'. format(EventGeoRouteId))
print(' Direction : {} ({})'. format(EventGeoRoute_Direction, TYPE_EventGeoRoute_Direction.get(EventGeoRoute_Direction, '?')))
print(' Passengers(?) : {}'. format(EventCountPassengers_mb))
print(' ValidityTimeFirstStamp: {} ({:02d}:{:02d})'. format(EventValidityTimeFirstStamp, EventValidityTimeFirstStamp // 60, EventValidityTimeFirstStamp % 60))
print(' left... :', Usage.nom_bits_left());
print(' left... :', Usage.nom_bits_left())
print(' [CER] Usage : {:04x}'.format(Certificate.nom(16)))
@ -171,17 +171,17 @@ def Describe_Usage_2(Usage, ContractMediumEndDate, Certificate):
EventCountPassengers_mb = Usage.nom(4)
EventValidityTimeFirstStamp = Usage.nom(11)
print(' DateStamp : {} ({})'.format(EventDateStamp, (datetime(1997, 1, 1) + timedelta(days = ContractMediumEndDate - EventDateStamp)).strftime('%Y-%m-%d')));
print(' DateStamp : {} ({})'.format(EventDateStamp, (datetime(1997, 1, 1) + timedelta(days = ContractMediumEndDate - EventDateStamp)).strftime('%Y-%m-%d')))
print(' TimeStamp : {} ({:02d}:{:02d})'. format(EventTimeStamp, EventTimeStamp // 60, EventTimeStamp % 60))
print(' unk0... :', unk0);
print(' unk0... :', unk0)
print(' Code/Nature : 0x{:x} ({})'.format(EventCode_Nature, TYPE_EventCode_Nature.get(EventCode_Nature, '?')))
print(' Code/Type : 0x{:x} ({})'.format(EventCode_Type, TYPE_EventCode_Type.get(EventCode_Type, '?')))
print(' unk1... :', unk1);
print(' unk1... :', unk1)
print(' GeoRouteId : {}'. format(EventGeoRouteId))
print(' Direction : {} ({})'. format(EventGeoRoute_Direction, TYPE_EventGeoRoute_Direction.get(EventGeoRoute_Direction, '?')))
print(' Passengers(?) : {}'. format(EventCountPassengers_mb))
print(' ValidityTimeFirstStamp: {} ({:02d}:{:02d})'. format(EventValidityTimeFirstStamp, EventValidityTimeFirstStamp // 60, EventValidityTimeFirstStamp % 60))
print(' left... :', Usage.nom_bits_left());
print(' left... :', Usage.nom_bits_left())
print(' [CER] Usage : {:04x}'.format(Certificate.nom(16)))
def Describe_Usage_3(Usage, ContractMediumEndDate, Certificate):
@ -190,11 +190,11 @@ def Describe_Usage_3(Usage, ContractMediumEndDate, Certificate):
unk = Usage.nom_bits(27)
EventValidityTimeFirstStamp = Usage.nom(11)
print(' EventDateStamp : {} ({})'.format(EventDateStamp, (datetime(1997, 1, 1) + timedelta(days = ContractMediumEndDate - EventDateStamp)).strftime('%Y-%m-%d')));
print(' EventDateStamp : {} ({})'.format(EventDateStamp, (datetime(1997, 1, 1) + timedelta(days = ContractMediumEndDate - EventDateStamp)).strftime('%Y-%m-%d')))
print(' EventTimeStamp : {} ({:02d}:{:02d})'. format(EventTimeStamp, EventTimeStamp // 60, EventTimeStamp % 60))
print(' unk1... :', unk);
print(' unk1... :', unk)
print(' EventValidityTimeFirstStamp: {} ({:02d}:{:02d})'. format(EventValidityTimeFirstStamp, EventValidityTimeFirstStamp // 60, EventValidityTimeFirstStamp % 60))
print(' left... :', Usage.nom_bits_left());
print(' left... :', Usage.nom_bits_left())
print(' [CER] Usage : {:04x}'.format(Certificate.nom(16)))
def Describe_Usage_4(Usage, ContractMediumEndDate, Certificate):
@ -203,16 +203,16 @@ def Describe_Usage_4(Usage, ContractMediumEndDate, Certificate):
unk = Usage.nom_bits(63)
EventValidityTimeFirstStamp = Usage.nom(11)
print(' EventDateStamp : {} ({})'.format(EventDateStamp, (datetime(1997, 1, 1) + timedelta(days = ContractMediumEndDate - EventDateStamp)).strftime('%Y-%m-%d')));
print(' EventDateStamp : {} ({})'.format(EventDateStamp, (datetime(1997, 1, 1) + timedelta(days = ContractMediumEndDate - EventDateStamp)).strftime('%Y-%m-%d')))
print(' EventTimeStamp : {} ({:02d}:{:02d})'. format(EventTimeStamp, EventTimeStamp // 60, EventTimeStamp % 60))
print(' unk1... :', unk);
print(' unk1... :', unk)
print(' EventValidityTimeFirstStamp: {} ({:02d}:{:02d})'. format(EventValidityTimeFirstStamp, EventValidityTimeFirstStamp // 60, EventValidityTimeFirstStamp % 60))
print(' left... :', Usage.nom_bits_left());
print(' left... :', Usage.nom_bits_left())
print(' [CER] Usage : {:04x}'.format(Certificate.nom(16)))
def Describe_Usage_Generic(Usage, ContractMediumEndDate, Certificate):
print(' !!! GENERIC DUMP - please provide full file dump to benjamin@gentilkiwi.com - especially if NOT empty !!!')
print(' left... :', Usage.nom_bits_left());
print(' left... :', Usage.nom_bits_left())
print(' [CER] Usage : {:04x}'.format(Certificate.nom(16)))
print(' !!! Trying Usage_1 (the most common) !!!')
Usage.reset()
@ -241,7 +241,7 @@ FRA_OrganizationalAuthority_Contract_Provider = {
},
0x013: {
1: InterticHelper('Avignon', 'Orizo'),
}
},
0x021: {
1: InterticHelper('Bordeaux', 'TBM / Keolis', Describe_Usage_1_1),
},
@ -378,7 +378,7 @@ def main():
return 3
print('PID (product): 0x{:02x} (flipflop?: {})'.format(PID, (PID & 0x10) != 0));
print('PID (product): 0x{:02x} (flipflop?: {})'.format(PID, (PID & 0x10) != 0))
print('KeyId : 0x{:1x}'.format(KeyId))
print()
@ -401,10 +401,11 @@ def main():
Distribution_left = Distribution_Data.nom_bits_left()
print('DISTRIBUTION')
print(' CountryCode : {:03x} - {}'.format(CountryCode, ISO_Countries.get(CountryCode, '?')));
print(' OrganizationalAuthority : {:03x}'.format(OrganizationalAuthority));
print(' ContractApplicationVersionNumber:', ContractApplicationVersionNumber);
print(' ContractProvider :', ContractProvider);
print(' CountryCode : {:03x} - {}'.format(CountryCode, ISO_Countries.get(CountryCode, '?')))
print(' OrganizationalAuthority : {:03x}'.format(OrganizationalAuthority))
print(' ContractApplicationVersionNumber:', ContractApplicationVersionNumber)
print(' ContractProvider :', ContractProvider)
if (CountryCode == 0x250):
oa = FRA_OrganizationalAuthority_Contract_Provider.get(OrganizationalAuthority)
if (oa is not None):
@ -412,9 +413,10 @@ def main():
if (s is not None):
print(' ~ Authority & Provider ~ : {} ({})'.format(s.OrganizationalAuthority, s.ContractProvider))
Describe_Usage = s.UsageDescribeFunction
print(' ContractTariff :', ContractTariff);
print(' ContractMediumEndDate : {} ({})'.format(ContractMediumEndDate, (datetime(1997, 1, 1) + timedelta(days = ContractMediumEndDate)).strftime('%Y-%m-%d')));
print(' left... :', Distribution_left);
print(' ContractTariff :', ContractTariff)
print(' ContractMediumEndDate : {} ({})'.format(ContractMediumEndDate, (datetime(1997, 1, 1) + timedelta(days = ContractMediumEndDate)).strftime('%Y-%m-%d')))
print(' left... :', Distribution_left)
print(' [CER] Distribution : {:08x}'.format(Distribution_Cer.nom(32)))
print()