Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save righettod/c71681d834d2967fddbfc1967d92f200 to your computer and use it in GitHub Desktop.
Save righettod/c71681d834d2967fddbfc1967d92f200 to your computer and use it in GitHub Desktop.
Python3 script to find common entries in 2 export of a iOS device keychain performed via objection.
import json
import binascii
import hashlib
import argparse
from tabulate import tabulate
"""
Python3 script to find common entries in 2 export of a iOS device keychain performed via objection.
The objective is to help performing the following test of the OWASP MSTG:
https://github.com/OWASP/owasp-mstg/blob/master/Document/0x06d-Testing-Data-Storage.md#keychain-data-persistence
Dependencies:
pip install tabulate
"""
def search_entry(data_hex, entries):
"""
Search for a keychain entry in the JSON export of the keychain obtained after
the reinstall of the application. Search is performed based on HEX data.
"""
entry_found_data = None
raw_data = binascii.unhexlify(data_hex.strip())
hash_data = hashlib.sha256(raw_data).hexdigest()
for entry in entries:
entry_hex_data = entry["dataHex"].strip()
if len(entry_hex_data) > 0:
entry_raw_data = binascii.unhexlify(entry_hex_data)
entry_hash_data = hashlib.sha256(entry_raw_data).hexdigest()
if entry_hash_data == hash_data:
entry_found_data = entry
break
return entry_found_data
parser = argparse.ArgumentParser(description="Script to find common entries in 2 export of a iOS device keychain performed via objection.")
parser.add_argument("--keychain-before", action="store", dest="keychain_export_file_initial_install", help="JSON export of the keychain from the intial installation of the application.", required=True)
parser.add_argument("--keychain-after", action="store", dest="keychain_export_file_after_reinstall", help="JSON export of the keychain after the reinstallation of the application.", required=True)
args = parser.parse_args()
print("[+] Load keychains files...")
with open(args.keychain_export_file_initial_install) as json_file:
keychain_export_json_initial_install = json.load(json_file)
with open(args.keychain_export_file_after_reinstall) as json_file:
keychain_export_json_after_reinstall = json.load(json_file)
print(f"{args.keychain_export_file_initial_install}: {len(keychain_export_json_initial_install)} entries")
print(f"{args.keychain_export_file_after_reinstall}: {len(keychain_export_json_after_reinstall)} entries")
print("[+] Search for keychain entries from initial install still present after app reinstall...")
common_entries_found = []
for entry in keychain_export_json_initial_install:
entry_in_new_keychain = search_entry(entry["dataHex"], keychain_export_json_after_reinstall)
if entry_in_new_keychain is not None:
common_entries_found.append(entry_in_new_keychain)
if len(common_entries_found) == 0:
print("[!] No common entries found.")
else:
print("[+] Common entries found:")
table_headers = ["Account", "DataHex[:20]", "CreateDate", "ModificationDate", "AccessibleAttribute", "ItemClass", "EntitlementGroup"]
table_rows = []
for entry in common_entries_found:
table_rows.append([entry["account"], entry["dataHex"][:20], entry["create_date"].replace("+0000",""), entry["modification_date"].replace("+0000",""), entry["accessible_attribute"],
entry["item_class"], entry["entitlement_group"] ])
print(tabulate(table_rows, headers=table_headers))
@righettod
Copy link
Author

righettod commented Jul 21, 2020

Call example:

$ python keychain_data_persistence_mstg_check.py --help
usage: keychain_data_persistence_mstg_check.py [-h] --keychain-before KEYCHAIN_EXPORT_FILE_INITIAL_INSTALL --keychain-after KEYCHAIN_EXPORT_FILE_AFTER_REINSTALL

Script to find common entries in 2 export of a iOS device keychain performed via objection.

optional arguments:
  -h, --help            show this help message and exit
  --keychain-before KEYCHAIN_EXPORT_FILE_INITIAL_INSTALL
                        JSON export of the keychain from the intial
                        installation of the application.
  --keychain-after KEYCHAIN_EXPORT_FILE_AFTER_REINSTALL
                        JSON export of the keychain after the reinstallation
                        of the application.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment