diff --git a/client/pyscripts/des_talk.py b/client/pyscripts/des_talk.py index 5624f592d..97d7d5e72 100644 --- a/client/pyscripts/des_talk.py +++ b/client/pyscripts/des_talk.py @@ -28,6 +28,7 @@ Full license text: import subprocess import time +import sys import os import re @@ -100,24 +101,33 @@ def send_proxmark_command(command): def authenticate_and_menu(): + com_mode = input("Enter communication mode (PLAIN, MAC, ENCRYPT) (Default: PLAIN): ").strip() or "plain" key_type = input("Enter key type (DES, 2TDEA, 3TDEA, AES): ").strip() - key = input("Enter 8, 16, 24 or 32-byte hex key (no spaces): ").strip() + key = input("Enter 8, 16, or 24-byte hex key (no spaces): ").strip() # Authenticate - auth_command = f"hf mfdes auth -t {key_type} -k {key}" + auth_command = f"hf mfdes auth -t {key_type} -k {key} -m {com_mode}" auth_response = send_proxmark_command(auth_command) print(auth_response) + # print("DEBUG: Raw Proxmark response:\n", repr(auth_response)) # Check for Proxmark failure messages if "error" in auth_response.lower() or "must have" in auth_response.lower(): - print("❌ Authentication failed. Check your connection, key, and key type.") + print("❌ Authentication failed. Check your connection, mode, key type, and key.") return while True: - # Get AIDs - aids_command = f"hf mfdes getaids -n 0 -t {key_type} -k {key}" + aids_command = f"hf mfdes getaids -n 0 -t {key_type} -k {key} -m {com_mode}" aids_response = send_proxmark_command(aids_command) + + # Check for communication mode errors + com_mode_error_match = re.search(r"Wrong communication mode", aids_response) + crc_error_match = re.search(r"CRC32 error", aids_response) + if com_mode_error_match or crc_error_match: + print("❌ Incorrect communication mode.\n") + return + print(aids_response) # Regex to match valid 6-character hex AIDs @@ -144,7 +154,8 @@ def authenticate_and_menu(): print("3. Delete an AID") print("4. Format PICC") print("5. Show free memory") - print("6. Exit") + print("6. Change keys") + print("7. Exit") choice = input("Enter your choice: ").strip() @@ -157,32 +168,39 @@ def authenticate_and_menu(): selected_aid = aids[selected_index] print(f"\nSelecting AID: {selected_aid}") - select_command = f"hf mfdes selectapp --aid {selected_aid} -t {key_type} -k {key}" + select_command = f"hf mfdes selectapp --aid {selected_aid} -t {key_type} -k {key} -m {com_mode}" select_response = send_proxmark_command(select_command) print(select_response) + # Retrieve AID key 0 + aid_key_type = input(f"Enter AID encryption algorithm (DES, 2TDEA, 3TDEA, AES) (Default: {key_type.upper()}): ").strip() or key_type + aid_key = input(f"Enter AID key (Default: {key}): ").strip() or key + # Show file menu - aid_file_menu(selected_aid, key_type, key) + aid_file_menu(selected_aid, key_type, key, com_mode, aid_key_type, aid_key) elif choice == "2": - create_aid(key_type, key) + create_aid(key_type, key, com_mode) elif choice == "3": - delete_aid(key_type, key) + delete_aid(key_type, key, com_mode) elif choice == "4": - format_picc(key_type, key) + format_picc(key_type, key, com_mode) elif choice == "5": - free_memory(key_type, key) + free_memory(key_type, key, com_mode) elif choice == "6": + change_key(key_type, key, com_mode) + + elif choice == "7": print("Exiting...") break else: print("Invalid choice, please try again.") -def aid_file_menu(selected_aid, key_type, key): +def aid_file_menu(selected_aid, key_type, key, com_mode, aid_key_type, aid_key): while True: print(f"\n[ AID {selected_aid} is open ]") @@ -191,50 +209,52 @@ def aid_file_menu(selected_aid, key_type, key): print("2. Read a File") print("3. Create a File") print("4. Write to a File") - print("5. Delete a File") - print("6. Exit") + print("5. Edit File Restrictions") + print("6. Delete a File") + print("7. Back") choice = input("Enter your choice: ").strip() if choice == "1": - list_files(selected_aid, key_type, key) + list_files(selected_aid, key_type, key, com_mode, aid_key_type, aid_key) elif choice == "2": - read_file(selected_aid, key_type, key) + read_file(selected_aid, key_type, key, com_mode, aid_key_type, aid_key) elif choice == "3": - create_file(selected_aid, key_type, key) + create_file(selected_aid, key_type, key, com_mode, aid_key_type, aid_key) elif choice == "4": - write_to_file(selected_aid, key_type, key) + write_to_file(selected_aid, key_type, key, com_mode, aid_key_type, aid_key) elif choice == "5": - delete_file(selected_aid, key_type, key) + edit_file_restriction(selected_aid, key_type, key, com_mode, aid_key_type, aid_key) elif choice == "6": + delete_file(selected_aid, key_type, key, com_mode, aid_key_type, aid_key) + elif choice == "7": print("Returning to AID selection...") break else: print("Invalid choice, please try again.") -def create_aid(key_type, key): +def create_aid(key_type, key, com_mode): aid = input("Enter new AID (6 hex characters, e.g., 112233): ").strip() iso_fid = input("Enter ISO File ID (4 hex characters, e.g., 1234): ").strip() - dstalgo = input("Enter encryption algorithm (DES, 2TDEA, 3TDEA, AES): ").strip().upper() - - create_command = f"hf mfdes createapp -n 0 --aid {aid} --fid {iso_fid} --dstalgo {dstalgo} -t {key_type} -k {key} -a" + dstalgo = input(f"Enter encryption algorithm (DES, 2TDEA, 3TDEA, AES) (Default: {key_type.upper()}): ").strip() or key_type + create_command = f"hf mfdes createapp -n 0 --aid {aid} --fid {iso_fid} --dstalgo {dstalgo} -t {key_type} -k {key} -m {com_mode} -a" response = send_proxmark_command(create_command) print(response) -def delete_aid(key_type, key): +def delete_aid(key_type, key, com_mode): aid = input("Enter AID to delete (6 hex characters): ").strip() - delete_command = f"hf mfdes deleteapp --aid {aid} -n 0 -t {key_type} -k {key}" + delete_command = f"hf mfdes deleteapp --aid {aid} -n 0 -t {key_type} -k {key} -m {com_mode}" response = send_proxmark_command(delete_command) print(response) -def format_picc(key_type, key): +def format_picc(key_type, key, com_mode): confirm = input("Are you sure you want to format the PICC? This will erase all data. (y/n): ").strip().lower() if confirm == "y": - format_command = f"hf mfdes formatpicc -t {key_type} -k {key} -v" + format_command = f"hf mfdes formatpicc -t {key_type} -k {key} -m {com_mode} -v" response = send_proxmark_command(format_command) print(response) elif confirm == "n": @@ -242,9 +262,9 @@ def format_picc(key_type, key): else: print("Invalid input. Please enter 'y' or 'n'.") -def free_memory(key_type, key): +def free_memory(key_type, key, com_mode): - memory_command = f"hf mfdes freemem -t {key_type} -k {key}" + memory_command = f"hf mfdes freemem -t {key_type} -k {key} -m {com_mode}" response = send_proxmark_command(memory_command) for line in response.splitlines(): @@ -254,10 +274,54 @@ def free_memory(key_type, key): print("❌ Unable to retrieve free memory information.") -def list_files(aid, key_type, key): +def change_key(key_type, key, com_mode): + print("\nChange Key - Choose Target:") + print("1. PICC (Card Master Key)") + print("2. Application Key") + target = input("Change key for (1/2)? (Default: 1): ").strip() or "1" + aid = "" + + if target == "2": + aid = input("Enter 6-digit AID (e.g., 010203): ").strip() + + print("\n!! Verify and securely store the new key !!") + print("Key length guide:") + print(" DES : 8 bytes (16 hex chars)") + print(" 2TDEA : 16 bytes (32 hex chars)") + print(" 3TDEA : 24 bytes (48 hex chars)") + print(" AES : 16 bytes (32 hex chars)") + + newalgo = input(f"Enter new key encryption algorithm (DES, 2TDEA, 3TDEA, AES) " + f"(Default: {key_type.upper()}): ").strip() or key_type + newkey = input(f"Enter new 8, 16, or 24-byte hex key (no spaces) (Default: {key}): ").strip() or key + + confirm = input("Are you sure you want to change the key? (Key 0) (y or n): ").strip().lower() + + if confirm == "y": + changekey_command = f"hf mfdes changekey -n 0 -t {key_type} -k {key} -m {com_mode} " \ + f"--newalgo {newalgo} --newkey {newkey} --newver 00 -v" + if aid: + app_key_type = input(f"Enter original application encryption algorithm (DES, 2TDEA, 3TDEA, AES) " + f"(Default: DES): ").strip() or "DES" + app_key = input(f"Enter original application key " + f"(Default: 0000000000000000): ").strip() or "0000000000000000" + changekey_command = f"hf mfdes changekey -n 0 -t {app_key_type} -k {app_key} -m {com_mode} " \ + f"--newalgo {newalgo} --newkey {newkey} --newver 00 --aid {aid} -v" + + response = send_proxmark_command(changekey_command) + print(response) + print("\nReauthenticate with the master key.") + sys.exit() + + elif confirm == "n": + print("Cancelled.") + else: + print("Invalid input. Please enter 'y' or 'n'.") + +def list_files(aid, key_type, key, com_mode, aid_key_type, aid_key): print("\nFetching file list...") - command = f"hf mfdes getfileids --aid {aid} -t {key_type} -k {key}" + command = f"hf mfdes getfileids --aid {aid} -t {aid_key_type} -k {aid_key} -m {com_mode}" response = send_proxmark_command(command) # Extract file IDs by looking for "File ID:" regex @@ -276,7 +340,7 @@ def list_files(aid, key_type, key): print("No files found in this AID.") return [] -def read_file(aid, key_type, key): +def read_file(aid, key_type, key, com_mode, aid_key_type, aid_key): file_id = input("Enter file ID to read: ").strip() @@ -288,7 +352,8 @@ def read_file(aid, key_type, key): length_input = input("Enter length to read (e.g., 16 for 16 bytes, 64 for 64 bytes, default full read): ").strip() or "0" length_hex = format(int(length_input), '06X') # Convert to 3-byte hex - read_command = f"hf mfdes read --aid {aid} --fid {file_id} -t {key_type} -k {key} --offset {offset_hex} --length {length_hex}" + read_command = f"hf mfdes read --aid {aid} --fid {file_id} -t {aid_key_type} -k {aid_key} " \ + f"--offset {offset_hex} --length {length_hex} -m {com_mode}" response = send_proxmark_command(read_command) # Extract and display file content @@ -299,7 +364,7 @@ def read_file(aid, key_type, key): return response -def create_file(aid, key_type, key): +def create_file(aid, key_type, key, com_mode, aid_key_type, aid_key): # Prompt for file ID in hex format file_id = input("Enter file ID (2 hex characters, e.g., 01, 02): ").strip() @@ -332,16 +397,17 @@ def create_file(aid, key_type, key): print(f"Invalid file size: {e}") return - create_command = f"hf mfdes createfile --aid {aid} --fid {file_id} --isofid {iso_file_id} --size {file_size_hex} -t {key_type} -k {key}" + create_command = f"hf mfdes createfile --aid {aid} --fid {file_id} --isofid {iso_file_id} " \ + f"--size {file_size_hex} -t {aid_key_type} -k {aid_key} -m {com_mode}" response = send_proxmark_command(create_command) print(response) -def write_to_file(aid, key_type, key): +def write_to_file(aid, key_type, key, com_mode, aid_key_type, aid_key): file_id = input("Enter file ID to write to: ").strip() # Get file size - file_size_command = f"hf mfdes getfilesettings --aid {aid} --fid {file_id} -t {key_type} -k {key}" + file_size_command = f"hf mfdes getfilesettings --aid {aid} --fid {file_id} -t {aid_key_type} -k {aid_key} -m {com_mode}" response = send_proxmark_command(file_size_command) # Extract the file size from the response @@ -376,15 +442,49 @@ def write_to_file(aid, key_type, key): else: print("❌ Invalid choice. Please choose 1 for text or 2 for hex.") - write_command = f"hf mfdes write --aid {aid} --fid {file_id} -t {key_type} -k {key} -d {write_data_hex}" + write_command = f"hf mfdes write --aid {aid} --fid {file_id} -t {aid_key_type} -k {aid_key} -d {write_data_hex} -m {com_mode}" response = send_proxmark_command(write_command) print(response) -def delete_file(aid, key_type, key): +def edit_file_restriction(aid, key_type, key, com_mode, aid_key_type, aid_key): + while True: + print("\nNOTE: This only works if you have changed the default keys.") + print("The Proxmark3 and other tools will automatically attempt to read files using DESFire default keys.") + print("\nWould you like to apply or remove a key from the file?") + print("1. Apply key 0 (Requires authentication for access)") + print("2. Remove key (Make file freely accessible)") + print("3. Back") + + choice = input("Enter your choice (1, 2, or 3): ").strip() + + if choice == "3": + print("Returning to the previous menu.") + break + + file_id = input("Enter file ID to update: ").strip() + + if choice == "1": + edit_file_command = f"hf mfdes chfilesettings --rawrights 0000 --aid {aid} --fid {file_id} -t {aid_key_type} -k {aid_key} -m {com_mode}" + print("Applying key 0 for read, write, and change access. This ensures authentication is required to access the file.") + + elif choice == "2": + # Must use encrypt communications mode to remove restrictions + edit_file_command = f"hf mfdes chfilesettings --rawrights EEEE --aid {aid} --fid {file_id} -t {aid_key_type} -k {aid_key} -m encrypt" + print("Removing key restrictions. File will be freely accessible.") + + else: + print("❌ Invalid choice. Please enter 1, 2, or 3.") + continue + + response = send_proxmark_command(edit_file_command) + print(response) + break + +def delete_file(aid, key_type, key, com_mode, aid_key_type, aid_key): file_id = input("Enter file ID to delete: ").strip() - delete_command = f"hf mfdes deletefile --aid {aid} --fid {file_id} -t {key_type} -k {key}" + delete_command = f"hf mfdes deletefile --aid {aid} --fid {file_id} -t {aid_key_type} -k {aid_key} -m {com_mode}" response = send_proxmark_command(delete_command) print(response)