import sys import subprocess import time import json import requests import random def collect_nonces(target_key_names): uid = None while uid is None: output = subprocess.check_output( "nfc-list", shell=True).decode('utf-8') for line in output.split('\n'): if 'UID (NFCID1):' in line: uid = line.split(':')[1].strip().replace(' ', '') break if uid is None: print(output) time.sleep(1) print(f"Call API for getting known keys of {uid}...") response = requests.get(f'https://holycard.pinlin.me/card/{uid}') if response.status_code == 404: raise Exception("Card not found") card = json.loads(response.text) key_names = set(target_key_names) for sector in card['sectors']: index = sector['index'] if sector['keyA'] is not None and f'{index}A' in key_names: key_names.remove(f'{index}A') if sector['keyB'] is not None and f'{index}B' in key_names: key_names.remove(f'{index}B') print("Collect nonces for these keys:", list(key_names)) known_sector = random.choice(card['sectors']) known_block_index = int(known_sector['index']) * 4 known_block_key_type = 'A' if known_sector['keyA'] is not None else 'B' known_block_key = known_sector['keyA'] if known_block_key_type == 'A' else known_sector['keyB'] executed_key_names = [] for key_name in key_names: block_index = int(key_name[:-1]) * 4 block_key_type = key_name[-1] cmd = f'crypto1_bs/holycard_collect {known_block_key} {known_block_index} {known_block_key_type} {block_index} {block_key_type}' proc = subprocess.Popen( cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=1, universal_newlines=True) for line in proc.stdout: print(line, end='') for line in proc.stderr: print(line, end='', file=sys.stderr) print() executed_key_names.append(key_name) return executed_key_names if __name__ == '__main__': executed_key_names = collect_nonces(['2A', '7A', '8A', '11A']) print(f"Executed key_names: {list(executed_key_names)}")