TCC Update

This commit is contained in:
Karmaz95
2024-11-12 19:53:42 +01:00
parent 6c9db3e455
commit a75925c3c9
2 changed files with 552 additions and 125 deletions
+284 -6
View File
@@ -16,6 +16,7 @@ import struct
import threading
import time
import xattr
import sqlite3
### --- APP BUNDLE EXTENSION --- ###
class SnakeHatchery:
@@ -3121,16 +3122,278 @@ class TCCProcessor:
pass
def process(self, args):
if args.test: #
snake_instance.test()
if args.tcc:
snake_instance.printPermissions()
if args.tcc_fda:
snake_instance.printFDAStatus()
if args.tcc_automation:
snake_instance.printTCCAutomation()
if args.tcc_sysadmin:
snake_instance.printSysAdminFilesStatus()
if args.tcc_desktop:
snake_instance.printDesktopAccessStatus()
if args.tcc_documents:
snake_instance.printDocumentsAccessStatus()
if args.tcc_downloads:
snake_instance.printDownloadsAccessStatus()
if args.tcc_photos:
snake_instance.printPhotosAccessStatus()
if args.tcc_contacts:
snake_instance.printContactsAccessStatus()
if args.tcc_calendar:
snake_instance.printCalendarAccessStatus()
if args.tcc_camera:
snake_instance.printCameraAccessStatus()
if args.tcc_microphone:
snake_instance.printMicrophoneAccessStatus()
if args.tcc_location:
snake_instance.printLocationAccessStatus()
if args.tcc_recording:
snake_instance.printScreenRecordingAccessStatus()
if args.tcc_accessibility:
snake_instance.printAccessibilityAccessStatus()
if args.tcc_icloud:
snake_instance.printICloudAccessStatus()
class SnakeIX(SnakeVIII):
def __init__(self, binaries, file_path):
super().__init__(binaries, file_path)
# Paths for TCC databases and location plist
self.TCC_DB_PATHS = [
"/Library/Application Support/com.apple.TCC/TCC.db",
os.path.expanduser("~/Library/Application Support/com.apple.TCC/TCC.db")
]
self.LOCATION_PLIST_PATH = "/var/db/locationd/clients.plist"
def test(self):
''' test '''
print('test')
def prepareDataForTCCQuery(self):
''' Prepare binary path and bundle ID for TCC queries. '''
binary_path = os.path.abspath(self.file_path).lower()
bundle_id = bundle_processor.getBundleId().lower() if bundle_processor else None
return binary_path, bundle_id
def getPermissionsFromDB(self, db_path, binary_path, bundle_id):
''' Retrieve all permissions from a given TCC database for the binary. '''
permissions = []
try:
conn = sqlite3.connect(db_path)
conn.create_function("lower", 1, lambda x: x.lower())
cursor = conn.cursor()
cursor.execute('''
SELECT * FROM access
WHERE lower(client) IN (lower(?), lower(?));
''', (binary_path, bundle_id or binary_path))
columns = [col[0] for col in cursor.description]
permissions = [dict(zip(columns, row)) for row in cursor.fetchall()]
except sqlite3.Error as e:
print(f"Error accessing {db_path}: {e}")
finally:
if 'conn' in locals() and conn:
conn.close()
return permissions
def getPermissions(self, binary_path, bundle_id):
''' Retrieve all permissions from all TCC databases. '''
permissions = {}
for db_path in self.TCC_DB_PATHS:
if self.checkIfPathExists(db_path):
db_permissions = self.getPermissionsFromDB(db_path, binary_path, bundle_id)
for permission in db_permissions:
service = permission.get('service')
if service not in permissions:
permissions[service] = permission.get('auth_value')
return permissions
def getLocationPermission(self, binary_path, bundle_id):
''' Check location services permission for the given binary from the plist. '''
if not os.path.exists(self.LOCATION_PLIST_PATH):
print(f"Error accessing {self.LOCATION_PLIST_PATH}: File not found or inaccessible from current user (run as root)")
return {}
with open(self.LOCATION_PLIST_PATH, 'rb') as plist_file:
plist_data = plistlib.load(plist_file)
for key, value in plist_data.items():
if isinstance(value, dict):
executable_match = 'Executable' in value and binary_path.lower() in value['Executable'].lower()
bundle_match = bundle_id and 'BundleId' in value and bundle_id.lower() in value['BundleId'].lower()
if executable_match or bundle_match:
return {'Location Services': 2 if value.get('Authorized', 0) == 1 else 0}
return {}
def parseTCCPermissions(self, location_check=False):
''' Consolidate permissions from TCC databases and location plist. '''
binary_path, bundle_id = self.prepareDataForTCCQuery()
permissions = self.getPermissions(binary_path, bundle_id)
if location_check:
permissions.update(self.getLocationPermission(binary_path, bundle_id))
return permissions
def printPermissions(self):
''' Print permissions from TCC databases and location plist in a readable format. '''
results = self.parseTCCPermissions(True)
for service in sorted(results.keys()):
auth_value = results[service]
status = self.getAuthValueStatus(auth_value)
print(f"{service}: {status} ({auth_value})")
def getAuthValueStatus(self, auth_value):
''' Get human-readable status for a given auth value. '''
return {
0: "No Access",
1: "Unknown",
2: "Access Granted",
3: "Limited"
}.get(auth_value, "Unknown Status")
def checkFDA(self):
''' Check if the binary has Full Disk Access (FDA) by looking for specific permissions. '''
return self.parseTCCPermissions().get('kTCCServiceSystemPolicyAllFiles') == 2
def printFDAStatus(self):
''' Print the Full Disk Access (FDA) status. '''
print(f"FDA: {'True' if self.checkFDA() else 'False'}")
def getAppleEventsPermissions(self, binary_path, bundle_id):
''' Retrieve permissions related to "kTCCServiceAppleEvents". '''
permissions = []
for db_path in self.TCC_DB_PATHS:
if self.checkIfPathExists(db_path):
db_permissions = self.getPermissionsFromDB(db_path, binary_path, bundle_id)
permissions.extend([
{
'service': perm['service'],
'auth_value': perm['auth_value'],
'indirect_object_identifier': perm['indirect_object_identifier']
}
for perm in db_permissions if perm['service'] == "kTCCServiceAppleEvents"
])
return permissions
def printTCCAutomation(self):
''' Print automation access details for "kTCCServiceAppleEvents". '''
binary_path, bundle_id = self.prepareDataForTCCQuery()
apple_events_permissions = self.getAppleEventsPermissions(binary_path, bundle_id)
if not apple_events_permissions:
print("TCC Automation: False")
else:
print("TCC Automation: True")
for permission in apple_events_permissions:
status = self.getAuthValueStatus(permission['auth_value'])
print(f"Target: {permission['indirect_object_identifier']}, Status: {status} ({permission['auth_value']})")
def checkSysAdminFilesAccess(self):
''' Check if the binary has System Policy SysAdmin Files access by looking for specific permissions. '''
return self.parseTCCPermissions().get('kTCCServiceSystemPolicySysAdminFiles') == 2
def printSysAdminFilesStatus(self):
''' Print the System Policy SysAdmin Files access status. '''
print(f"SysAdmin Files Access: {'True' if self.checkSysAdminFilesAccess() else 'False'}")
def checkDesktopAccess(self):
''' Check if the binary has Desktop Folder access by looking for specific permissions. '''
return self.parseTCCPermissions().get('kTCCServiceSystemPolicyDesktopFolder') == 2
def printDesktopAccessStatus(self):
''' Print the Desktop Folder access status. '''
print(f"Desktop Folder Access: {'True' if self.checkDesktopAccess() else 'False'}")
def checkDocumentsAccess(self):
''' Check if the binary has Documents Folder access by looking for specific permissions. '''
return self.parseTCCPermissions().get('kTCCServiceSystemPolicyDocumentsFolder') == 2
def printDocumentsAccessStatus(self):
''' Print the Documents Folder access status. '''
print(f"Documents Folder Access: {'True' if self.checkDocumentsAccess() else 'False'}")
def checkDownloadsAccess(self):
''' Check if the binary has Downloads Folder access by looking for specific permissions. '''
return self.parseTCCPermissions().get('kTCCServiceSystemPolicyDownloadsFolder') == 2
def printDownloadsAccessStatus(self):
''' Print the Downloads Folder access status. '''
print(f"Downloads Folder Access: {'True' if self.checkDownloadsAccess() else 'False'}")
def checkPhotosAccess(self):
''' Check if the binary has Photos Library access by looking for specific permissions. '''
return self.parseTCCPermissions().get('kTCCServicePhotos') == 2
def printPhotosAccessStatus(self):
''' Print the Photos Library access status. '''
print(f"Photos Library Access: {'True' if self.checkPhotosAccess() else 'False'}")
def checkContactsAccess(self):
''' Check if the binary has Contacts access by looking for specific permissions. '''
return self.parseTCCPermissions().get('kTCCServiceAddressBook') == 2
def printContactsAccessStatus(self):
''' Print the Contacts access status. '''
print(f"Contacts Access: {'True' if self.checkContactsAccess() else 'False'}")
def checkCalendarAccess(self):
''' Check if the binary has Calendar access by looking for specific permissions. '''
return self.parseTCCPermissions().get('kTCCServiceCalendar') == 2
def printCalendarAccessStatus(self):
''' Print the Calendar access status. '''
print(f"Calendar Access: {'True' if self.checkCalendarAccess() else 'False'}")
def checkCameraAccess(self):
''' Check if the binary has Camera access by looking for specific permissions. '''
return self.parseTCCPermissions().get('kTCCServiceCamera') == 2
def printCameraAccessStatus(self):
''' Print the Camera access status. '''
print(f"Camera Access: {'True' if self.checkCameraAccess() else 'False'}")
def checkMicrophoneAccess(self):
''' Check if the binary has Microphone access by looking for specific permissions. '''
return self.parseTCCPermissions().get('kTCCServiceMicrophone') == 2
def printMicrophoneAccessStatus(self):
''' Print the Microphone access status. '''
print(f"Microphone Access: {'True' if self.checkMicrophoneAccess() else 'False'}")
def checkScreenRecordingAccess(self):
''' Check if the binary has Screen Recording access by looking for specific permissions. '''
return self.parseTCCPermissions().get('kTCCServiceScreenCapture') == 2
def printScreenRecordingAccessStatus(self):
''' Print the Screen Recording access status. '''
print(f"Screen Recording Access: {'True' if self.checkScreenRecordingAccess() else 'False'}")
def checkAccessibilityAccess(self):
''' Check if the binary has Accessibility access by looking for specific permissions. '''
return self.parseTCCPermissions().get('kTCCServiceAccessibility') == 2
def printAccessibilityAccessStatus(self):
''' Print the Accessibility access status. '''
print(f"Accessibility Access: {'True' if self.checkAccessibilityAccess() else 'False'}")
def checkICloudAccess(self):
''' Check if the binary has iCloud (Ubiquity) access by looking for specific permissions. '''
return self.parseTCCPermissions().get('kTCCServiceUbiquity') == 2
def printICloudAccessStatus(self):
''' Print the iCloud (Ubiquity) access status. '''
print(f"iCloud Access: {'True' if self.checkICloudAccess() else 'False'}")
### --- ARGUMENT PARSER --- ###
@@ -3299,7 +3562,22 @@ class ArgumentParser:
def addTCCArgs(self):
tcc_group = self.parser.add_argument_group('TCC ARGS')
tcc_group.add_argument('--test', action='store_true', help="test")
tcc_group.add_argument('--tcc', action='store_true', help="Print TCC permissions of the binary")
tcc_group.add_argument('--tcc_fda', action='store_true', help="Check Full Disk Access (FDA) TCC permission for the binary")
tcc_group.add_argument('--tcc_automation', action='store_true', help="Check Automation TCC permission for the binary")
tcc_group.add_argument('--tcc_sysadmin', action='store_true', help="Check System Policy SysAdmin Files TCC permission for the binary")
tcc_group.add_argument('--tcc_desktop', action='store_true', help="Check Desktop Folder TCC permission for the binary")
tcc_group.add_argument('--tcc_documents', action='store_true', help="Check Documents Folder TCC permission for the binary")
tcc_group.add_argument('--tcc_downloads', action='store_true', help="Check Downloads Folder TCC permission for the binary")
tcc_group.add_argument('--tcc_photos', action='store_true', help="Check Photos Library TCC permission for the binary")
tcc_group.add_argument('--tcc_contacts', action='store_true', help="Check Contacts TCC permission for the binary")
tcc_group.add_argument('--tcc_calendar', action='store_true', help="Check Calendar TCC permission for the binary")
tcc_group.add_argument('--tcc_camera', action='store_true', help="Check Camera TCC permission for the binary")
tcc_group.add_argument('--tcc_microphone', action='store_true', help="Check Microphone TCC permission for the binary")
tcc_group.add_argument('--tcc_location', action='store_true', help="Check Location Services TCC permission for the binary")
tcc_group.add_argument('--tcc_recording', action='store_true', help="Check Screen Recording TCC permission for the binary")
tcc_group.add_argument('--tcc_accessibility', action='store_true', help="Check Accessibility TCC permission for the binary")
tcc_group.add_argument('--tcc_icloud', action='store_true', help="Check iCloud (Ubiquity) TCC permission for the binary")
def parseArgs(self):
args = self.parser.parse_args()
+268 -119
View File
@@ -56,37 +56,68 @@ The table of contents showing links to all articles is below:
Core program resulting from the Snake&Apple article series for binary analysis. You may find older versions of this script in each article directory in this repository.
* Usage
```console
usage: CrimsonUroboros [-h] [-p PATH] [-b BUNDLE] [--bundle_structure] [--bundle_info]
[--bundle_info_syntax_check] [--bundle_frameworks] [--bundle_plugins] [--bundle_id]
[--file_type] [--header_flags] [--endian] [--header] [--load_commands] [--has_cmd LC_MAIN]
[--segments] [--has_segment __SEGMENT] [--sections] [--has_section __SEGMENT,__section]
[--symbols] [--imports] [--exports] [--imported_symbols] [--chained_fixups]
[--exports_trie] [--uuid] [--main] [--encryption_info [(optional) save_path.bytes]]
[--strings_section] [--all_strings] [--save_strings all_strings.txt] [--info]
[--dump_data [offset,size,output_path]] [--calc_offset vm_offset] [--constructors]
[--dump_section __SEGMENT,__section] [--dump_binary output_path] [--verify_signature]
[--cd_info] [--cd_requirements] [--entitlements [human|xml|var]]
[--extract_cms cms_signature.der] [--extract_certificates certificate_name]
[--remove_sig unsigned_binary] [--sign_binary [adhoc|identity]] [--cs_offset] [--cs_flags]
[--verify_bundle_signature] [--remove_sig_from_bundle] [--has_pie] [--has_arc]
[--is_stripped] [--has_canary] [--has_nx_stack] [--has_nx_heap] [--has_xn] [--is_notarized]
[--is_encrypted] [--is_restricted] [--is_hr] [--is_as] [--is_fort] [--has_rpath] [--has_lv]
[--checksec] [--dylibs] [--rpaths] [--rpaths_u] [--dylibs_paths] [--dylibs_paths_u]
[--broken_relative_paths] [--dylibtree [cache_path,output_path,is_extracted]] [--dylib_id]
[--reexport_paths] [--hijack_sec] [--dylib_hijacking [(optional) cache_path]]
[--dylib_hijacking_a [cache_path]] [--prepare_dylib [(optional) target_dylib_name]]
[--is_built_for_sim] [--get_dyld_env] [--compiled_with_dyld_env] [--has_interposing]
[--interposing_symbols] [--dump_prelink_info [(optional) out_name]]
[--dump_prelink_text [(optional) out_name]] [--dump_prelink_kext [kext_name]]
[--kext_prelinkinfo [kext_name]] [--kmod_info kext_name] [--kext_entry kext_name]
[--kext_exit kext_name] [--mig] [--has_suid] [--has_sgid] [--has_sticky]
[--injectable_dyld] [--test_insert_dylib] [--test_prune_dyld] [--test_dyld_print_to_file]
[--test_dyld_SLC] [--xattr] [--xattr_value xattr_name] [--xattr_all] [--has_quarantine]
[--remove_quarantine] [--add_quarantine] [--sandbox_container_path]
[--sandbox_container_metadata] [--sandbox_redirectable_paths] [--sandbox_parameters]
[--sandbox_entitlements] [--sandbox_build_uuid] [--sandbox_redirected_paths]
[--sandbox_system_images] [--sandbox_system_profiles] [--sandbox_content_protection]
[--sandbox_profile_data] [--dump_kext kext_name] [--extract_sandbox_operations]
usage: CrimsonUroboros [-h] [-p PATH] [-b BUNDLE] [--bundle_structure]
[--bundle_info] [--bundle_info_syntax_check]
[--bundle_frameworks] [--bundle_plugins] [--bundle_id]
[--file_type] [--header_flags] [--endian] [--header]
[--load_commands] [--has_cmd LC_MAIN] [--segments]
[--has_segment __SEGMENT] [--sections]
[--has_section __SEGMENT,__section] [--symbols]
[--imports] [--exports] [--imported_symbols]
[--chained_fixups] [--exports_trie] [--uuid] [--main]
[--encryption_info [(optional) save_path.bytes]]
[--strings_section] [--all_strings]
[--save_strings all_strings.txt] [--info]
[--dump_data [offset,size,output_path]]
[--calc_offset vm_offset] [--constructors]
[--dump_section __SEGMENT,__section]
[--dump_binary output_path] [--verify_signature]
[--cd_info] [--cd_requirements]
[--entitlements [human|xml|var]]
[--extract_cms cms_signature.der]
[--extract_certificates certificate_name]
[--remove_sig unsigned_binary]
[--sign_binary [adhoc|identity]] [--cs_offset]
[--cs_flags] [--verify_bundle_signature]
[--remove_sig_from_bundle] [--has_pie] [--has_arc]
[--is_stripped] [--has_canary] [--has_nx_stack]
[--has_nx_heap] [--has_xn] [--is_notarized]
[--is_encrypted] [--is_restricted] [--is_hr] [--is_as]
[--is_fort] [--has_rpath] [--has_lv] [--checksec]
[--dylibs] [--rpaths] [--rpaths_u] [--dylibs_paths]
[--dylibs_paths_u] [--broken_relative_paths]
[--dylibtree [cache_path,output_path,is_extracted]]
[--dylib_id] [--reexport_paths] [--hijack_sec]
[--dylib_hijacking [(optional) cache_path]]
[--dylib_hijacking_a [cache_path]]
[--prepare_dylib [(optional) target_dylib_name]]
[--is_built_for_sim] [--get_dyld_env]
[--compiled_with_dyld_env] [--has_interposing]
[--interposing_symbols]
[--dump_prelink_info [(optional) out_name]]
[--dump_prelink_text [(optional) out_name]]
[--dump_prelink_kext [kext_name]]
[--kext_prelinkinfo [kext_name]]
[--kmod_info kext_name] [--kext_entry kext_name]
[--kext_exit kext_name] [--mig] [--has_suid]
[--has_sgid] [--has_sticky] [--injectable_dyld]
[--test_insert_dylib] [--test_prune_dyld]
[--test_dyld_print_to_file] [--test_dyld_SLC] [--xattr]
[--xattr_value xattr_name] [--xattr_all]
[--has_quarantine] [--remove_quarantine]
[--add_quarantine] [--sandbox_container_path]
[--sandbox_container_metadata]
[--sandbox_redirectable_paths] [--sandbox_parameters]
[--sandbox_entitlements] [--sandbox_build_uuid]
[--sandbox_redirected_paths] [--sandbox_system_images]
[--sandbox_system_profiles]
[--sandbox_content_protection] [--sandbox_profile_data]
[--dump_kext kext_name] [--extract_sandbox_operations]
[--tcc] [--tcc_fda] [--tcc_automation] [--tcc_sysadmin]
[--tcc_desktop] [--tcc_documents] [--tcc_downloads]
[--tcc_photos] [--tcc_contacts] [--tcc_calendar]
[--tcc_camera] [--tcc_microphone] [--tcc_location]
[--tcc_recording] [--tcc_accessibility] [--tcc_icloud]
Mach-O files parser for binary analysis
@@ -94,19 +125,21 @@ options:
-h, --help show this help message and exit
GENERAL ARGS:
-p PATH, --path PATH Path to the Mach-O file
-b BUNDLE, --bundle BUNDLE
Path to the App Bundle (can be used with -p to change path of binary which is by default
set to: /target.app/Contents/MacOS/target)
-p, --path PATH Path to the Mach-O file
-b, --bundle BUNDLE Path to the App Bundle (can be used with -p to change
path of binary which is by default set to:
/target.app/Contents/MacOS/target)
BUNDLE ARGS:
--bundle_structure Print the structure of the app bundle
--bundle_info Print the Info.plist content of the app bundle (JSON format)
--bundle_info Print the Info.plist content of the app bundle (JSON
format)
--bundle_info_syntax_check
Check if bundle info syntax is valid
--bundle_frameworks Print the list of frameworks in the bundle
--bundle_plugins Print the list of plugins in the bundle
--bundle_id Print the CFBundleIdentifier value from the Info.plist file if it exists
--bundle_id Print the CFBundleIdentifier value from the Info.plist
file if it exists
MACH-O ARGS:
--file_type Print binary file type
@@ -124,147 +157,192 @@ MACH-O ARGS:
--symbols Print all binary symbols
--imports Print imported symbols
--exports Print exported symbols
--imported_symbols Print symbols imported from external libraries with dylib names
--imported_symbols Print symbols imported from external libraries with
dylib names
--chained_fixups Print Chained Fixups information
--exports_trie Print Export Trie information
--uuid Print UUID
--main Print entry point and stack size
--encryption_info [(optional) save_path.bytes]
Print encryption info if any. Optionally specify an output path to dump the encrypted data
(if cryptid=0, data will be in plain text)
Print encryption info if any. Optionally specify an
output path to dump the encrypted data (if cryptid=0,
data will be in plain text)
--strings_section Print strings from __cstring section
--all_strings Print strings from all sections
--save_strings all_strings.txt
Parse all sections, detect strings, and save them to a file
--info Print header, load commands, segments, sections, symbols, and strings
Parse all sections, detect strings, and save them to a
file
--info Print header, load commands, segments, sections,
symbols, and strings
--dump_data [offset,size,output_path]
Dump {size} bytes starting from {offset} to a given {filename} (e.g.
'0x1234,0x1000,out.bin')
Dump {size} bytes starting from {offset} to a given
{filename} (e.g. '0x1234,0x1000,out.bin')
--calc_offset vm_offset
Calculate the real address (file on disk) of the given Virtual Memory {vm_offset} (e.g.
0xfffffe000748f580)
Calculate the real address (file on disk) of the given
Virtual Memory {vm_offset} (e.g. 0xfffffe000748f580)
--constructors Print binary constructors
--dump_section __SEGMENT,__section
Dump '__SEGMENT,__section' to standard output as a raw bytes
Dump '__SEGMENT,__section' to standard output as a raw
bytes
--dump_binary output_path
Dump arm64 binary to a given file
CODE SIGNING ARGS:
--verify_signature Code Signature verification (if the contents of the binary have been modified)
--verify_signature Code Signature verification (if the contents of the
binary have been modified)
--cd_info Print Code Signature information
--cd_requirements Print Code Signature Requirements
--entitlements [human|xml|var]
Print Entitlements in a human-readable, XML, or DER format (default: human)
Print Entitlements in a human-readable, XML, or DER
format (default: human)
--extract_cms cms_signature.der
Extract CMS Signature from the Code Signature and save it to a given file
Extract CMS Signature from the Code Signature and save
it to a given file
--extract_certificates certificate_name
Extract Certificates and save them to a given file. To each filename will be added an
index at the end: _0 for signing, _1 for intermediate, and _2 for root CA certificate
Extract Certificates and save them to a given file. To
each filename will be added an index at the end: _0
for signing, _1 for intermediate, and _2 for root CA
certificate
--remove_sig unsigned_binary
Save the new file on a disk with removed signature
--sign_binary [adhoc|identity]
Sign binary using specified identity - use : 'security find-identity -v -p codesigning' to
get the identity (default: adhoc)
Sign binary using specified identity - use : 'security
find-identity -v -p codesigning' to get the identity
(default: adhoc)
--cs_offset Print Code Signature file offset
--cs_flags Print Code Signature flags
--verify_bundle_signature
Code Signature verification (if the contents of the bundle have been modified)
Code Signature verification (if the contents of the
bundle have been modified)
--remove_sig_from_bundle
Remove Code Signature from the bundle
CHECKSEC ARGS:
--has_pie Check if Position-Independent Executable (PIE) is set
--has_arc Check if Automatic Reference Counting (ARC) is in use (can be false positive)
--has_arc Check if Automatic Reference Counting (ARC) is in use
(can be false positive)
--is_stripped Check if binary is stripped
--has_canary Check if Stack Canary is in use (can be false positive)
--has_canary Check if Stack Canary is in use (can be false
positive)
--has_nx_stack Check if stack is non-executable (NX stack)
--has_nx_heap Check if heap is non-executable (NX heap)
--has_xn Check if binary is protected by eXecute Never (XN) ARM protection
--is_notarized Check if the application is notarized and can pass the Gatekeeper verification
--is_encrypted Check if the application is encrypted (has LC_ENCRYPTION_INFO(_64) and cryptid set to 1)
--is_restricted Check if binary has __RESTRICT segment or CS_RESTRICT flag set
--has_xn Check if binary is protected by eXecute Never (XN) ARM
protection
--is_notarized Check if the application is notarized and can pass the
Gatekeeper verification
--is_encrypted Check if the application is encrypted (has
LC_ENCRYPTION_INFO(_64) and cryptid set to 1)
--is_restricted Check if binary has __RESTRICT segment or CS_RESTRICT
flag set
--is_hr Check if the Hardened Runtime is in use
--is_as Check if the App Sandbox is in use
--is_fort Check if the binary is fortified
--has_rpath Check if the binary utilise any @rpath variables
--has_lv Check if the binary has Library Validation (protection against Dylib Hijacking)
--has_lv Check if the binary has Library Validation (protection
against Dylib Hijacking)
--checksec Run all checksec module options on the binary
DYLIBS ARGS:
--dylibs Print shared libraries used by specified binary with compatibility and the current version
(loading paths unresolved, like @rpath/example.dylib)
--rpaths Print all paths (resolved) that @rpath can be resolved to
--rpaths_u Print all paths (unresolved) that @rpath can be resolved to
--dylibs_paths Print absolute dylib loading paths (resolved @rpath|@executable_path|@loader_path) in
order they are searched for
--dylibs Print shared libraries used by specified binary with
compatibility and the current version (loading paths
unresolved, like @rpath/example.dylib)
--rpaths Print all paths (resolved) that @rpath can be resolved
to
--rpaths_u Print all paths (unresolved) that @rpath can be
resolved to
--dylibs_paths Print absolute dylib loading paths (resolved
@rpath|@executable_path|@loader_path) in order they
are searched for
--dylibs_paths_u Print unresolved dylib loading paths.
--broken_relative_paths
Print 'broken' relative paths from the binary (cases where the dylib source is specified
for an executable directory without @executable_path)
Print 'broken' relative paths from the binary (cases
where the dylib source is specified for an executable
directory without @executable_path)
--dylibtree [cache_path,output_path,is_extracted]
Print the dynamic dependencies of a Mach-O binary recursively. You can specify the Dyld
Shared Cache path in the first argument, the output directory as the 2nd argument, and if
you have already extracted DSC in the 3rd argument (0 or 1). The output_path will be used
as a base for dylibtree. For example, to not extract DSC, use: --dylibs ",,1", or to
extract from default to default use just --dylibs or --dylibs ",,0" which will extract DSC
to extracted_dyld_share_cache/ in the current directory
Print the dynamic dependencies of a Mach-O binary
recursively. You can specify the Dyld Shared Cache
path in the first argument, the output directory as
the 2nd argument, and if you have already extracted
DSC in the 3rd argument (0 or 1). The output_path will
be used as a base for dylibtree. For example, to not
extract DSC, use: --dylibs ",,1", or to extract from
default to default use just --dylibs or --dylibs ",,0"
which will extract DSC to extracted_dyld_share_cache/
in the current directory
--dylib_id Print path from LC_ID_DYLIB
--reexport_paths Print paths from LC_REEXPORT_DLIB
--hijack_sec Check if binary is protected against Dylib Hijacking
--dylib_hijacking [(optional) cache_path]
Check for possible Direct and Indirect Dylib Hijacking loading paths. The output is
printed to console and saved in JSON format to /tmp/dylib_hijacking_log.json(append mode).
Check for possible Direct and Indirect Dylib Hijacking
loading paths. The output is printed to console and
saved in JSON format to
/tmp/dylib_hijacking_log.json(append mode).
Optionally, specify the path to the Dyld Shared Cache
--dylib_hijacking_a [cache_path]
Like --dylib_hijacking, but shows only possible vectors (without protected binaries)
Like --dylib_hijacking, but shows only possible
vectors (without protected binaries)
--prepare_dylib [(optional) target_dylib_name]
Compile rogue dylib. Optionally, specify target_dylib_path, it will search for the
imported symbols from it in the dylib specified in the --path argument and automatically
add it to the source code of the rogue lib. Example: --path lib1.dylib --prepare_dylib
/path/to/lib2.dylib
Compile rogue dylib. Optionally, specify
target_dylib_path, it will search for the imported
symbols from it in the dylib specified in the --path
argument and automatically add it to the source code
of the rogue lib. Example: --path lib1.dylib
--prepare_dylib /path/to/lib2.dylib
DYLD ARGS:
--is_built_for_sim Check if binary is built for simulator platform.
--get_dyld_env Extract Dyld environment variables from the loader binary.
--get_dyld_env Extract Dyld environment variables from the loader
binary.
--compiled_with_dyld_env
Check if binary was compiled with -dyld_env flag and print the environment variables and
its values.
Check if binary was compiled with -dyld_env flag and
print the environment variables and its values.
--has_interposing Check if binary has interposing sections.
--interposing_symbols
Print interposing symbols if any.
AMFI ARGS:
--dump_prelink_info [(optional) out_name]
Dump "__PRELINK_INFO,__info" to a given file (default: "PRELINK_info.txt")
Dump "__PRELINK_INFO,__info" to a given file (default:
"PRELINK_info.txt")
--dump_prelink_text [(optional) out_name]
Dump "__PRELINK_TEXT,__text" to a given file (default: "PRELINK_text.txt")
Dump "__PRELINK_TEXT,__text" to a given file (default:
"PRELINK_text.txt")
--dump_prelink_kext [kext_name]
Dump prelinked KEXT {kext_name} from decompressed Kernel Cache PRELINK_TEXT segment to a
file named: prelinked_{kext_name}.bin
Dump prelinked KEXT {kext_name} from decompressed
Kernel Cache PRELINK_TEXT segment to a file named:
prelinked_{kext_name}.bin
--kext_prelinkinfo [kext_name]
Print _Prelink properties from PRELINK_INFO,__info for a give {kext_name}
Print _Prelink properties from PRELINK_INFO,__info for
a give {kext_name}
--kmod_info kext_name
Parse kmod_info structure for the given {kext_name} from Kernel Cache
Parse kmod_info structure for the given {kext_name}
from Kernel Cache
--kext_entry kext_name
Calculate the virtual memory address of the __start (entrypoint) for the given {kext_name}
Kernel Extension
Calculate the virtual memory address of the __start
(entrypoint) for the given {kext_name} Kernel
Extension
--kext_exit kext_name
Calculate the virtual memory address of the __stop (exitpoint) for the given {kext_name}
Kernel Extension
Calculate the virtual memory address of the __stop
(exitpoint) for the given {kext_name} Kernel Extension
--mig Search for MIG subsystem and prints message handlers
--has_suid Check if the file has SetUID bit set
--has_sgid Check if the file has SetGID bit set
--has_sticky Check if the file has sticky bit set
--injectable_dyld Check if the binary is injectable using DYLD_INSERT_LIBRARIES
--test_insert_dylib Check if it is possible to inject dylib using DYLD_INSERT_LIBRARIES (INVASIVE - the binary
is executed)
--test_prune_dyld Check if Dyld Environment Variables are cleared (using DYLD_PRINT_INITIALIZERS=1)
(INVASIVE - the binary is executed)
--test_dyld_print_to_file
Check if DYLD_PRINT_TO_FILE Dyld Environment Variables works (INVASIVE - the binary is
--injectable_dyld Check if the binary is injectable using
DYLD_INSERT_LIBRARIES
--test_insert_dylib Check if it is possible to inject dylib using
DYLD_INSERT_LIBRARIES (INVASIVE - the binary is
executed)
--test_prune_dyld Check if Dyld Environment Variables are cleared (using
DYLD_PRINT_INITIALIZERS=1) (INVASIVE - the binary is
executed)
--test_dyld_print_to_file
Check if DYLD_PRINT_TO_FILE Dyld Environment Variables
works (INVASIVE - the binary is executed)
--test_dyld_SLC Check if DYLD_SHARED_REGION=private Dyld Environment
Variables works and code can be injected using
DYLD_SHARED_CACHE_DIR (INVASIVE - the binary is
executed)
--test_dyld_SLC Check if DYLD_SHARED_REGION=private Dyld Environment Variables works and code can be
injected using DYLD_SHARED_CACHE_DIR (INVASIVE - the binary is executed)
ANTIVIRUS ARGS:
--xattr Print all extended attributes names
@@ -272,35 +350,67 @@ ANTIVIRUS ARGS:
Print single extended attribute value
--xattr_all Print all extended attributes names and their values
--has_quarantine Check if the file has quarantine extended attribute
--remove_quarantine Remove com.apple.quarantine extended attribute from the file
--add_quarantine Add com.apple.quarantine extended attribute to the file
--remove_quarantine Remove com.apple.quarantine extended attribute from
the file
--add_quarantine Add com.apple.quarantine extended attribute to the
file
SANDBOX ARGS:
--sandbox_container_path
Print the sandbox container path
--sandbox_container_metadata
Print the .com.apple.containermanagerd.metadata.plist contents for the given bundlein XML
format
Print the .com.apple.containermanagerd.metadata.plist
contents for the given bundlein XML format
--sandbox_redirectable_paths
Print the redirectable paths from the sandbox container metadata as list
--sandbox_parameters Print the parameters from the sandbox container metadata as key-value pairs
Print the redirectable paths from the sandbox
container metadata as list
--sandbox_parameters Print the parameters from the sandbox container
metadata as key-value pairs
--sandbox_entitlements
Print the entitlements from the sandbox container metadata in JSON format
--sandbox_build_uuid Print the sandbox build UUID from the sandbox container metadata
Print the entitlements from the sandbox container
metadata in JSON format
--sandbox_build_uuid Print the sandbox build UUID from the sandbox
container metadata
--sandbox_redirected_paths
Print the redirected paths from the sandbox container metadata as list
Print the redirected paths from the sandbox container
metadata as list
--sandbox_system_images
Print the system images from the sandbox container metadata as key-value pairs
Print the system images from the sandbox container
metadata as key-value pairs
--sandbox_system_profiles
Print the system profile from the sandbox container metadata in JSON format
Print the system profile from the sandbox container
metadata in JSON format
--sandbox_content_protection
Print the content protection from the sandbox container metadata
Print the content protection from the sandbox
container metadata
--sandbox_profile_data
Print raw bytes ofthe sandbox profile data from the sandbox container metadata
Print raw bytes ofthe sandbox profile data from the
sandbox container metadata
--dump_kext kext_name
Dump the kernel extension binary from the kernelcache.decompressed file
Dump the kernel extension binary from the
kernelcache.decompressed file
--extract_sandbox_operations
Extract sandbox operations from the Sandbox.kext file
TCC ARGS:
--tcc Print TCC permissions of the binary
--tcc_fda Check Full Disk Access (FDA) TCC permission for the
binary
--tcc_automation Check Automation TCC permission for the binary
--tcc_sysadmin Check System Policy SysAdmin Files TCC permission for
the binary
--tcc_desktop Check Desktop Folder TCC permission for the binary
--tcc_documents Check Documents Folder TCC permission for the binary
--tcc_downloads Check Downloads Folder TCC permission for the binary
--tcc_photos Check Photos Library TCC permission for the binary
--tcc_contacts Check Contacts TCC permission for the binary
--tcc_calendar Check Calendar TCC permission for the binary
--tcc_camera Check Camera TCC permission for the binary
--tcc_microphone Check Microphone TCC permission for the binary
--tcc_location Check Location Services TCC permission for the binary
--tcc_recording Check Screen Recording TCC permission for the binary
--tcc_accessibility Check Accessibility TCC permission for the binary
--tcc_icloud Check iCloud (Ubiquity) TCC permission for the binary
```
* Example:
```bash
@@ -586,6 +696,45 @@ Notes:
- When using --list, each path should be on a new line in the list file
- The tool automatically converts relative paths to absolute paths
```
### [TCCParser](IX.%20TCC/python/TCCParser.py)
A tool for querying macOS TCC (Transparency, Consent, and Control) databases.
It was introduced in the article [](todo)
```bash
usage: TCCParser [-h] [-p PATH] [-t] [-a] [-l]
Parse TCC Database for Permissions Information
options:
-h, --help Show this help message and exit
-p PATH, --path PATH Path to TCC.db file to analyze
-t, --table Output results in table format
-a, --all Automatically query all available TCC databases on the system
-l, --list_db List all available TCC databases on the system
Examples:
---------
1. List all available TCC databases on the system:
--list_db
-l
2. Query a specific TCC database:
--path /path/to/TCC.db
-p /path/to/TCC.db
3. Display the query results in a formatted table:
--path /path/to/TCC.db --table
-p /path/to/TCC.db -t
4. Automatically query all known TCC databases:
--all
-a
Notes:
------
- The tool retrieves details such as client, service, and authorization status for each entry in the TCC database.
- The `--list_db` option helps users locate all known TCC databases on the system, sourced from `REG.db`.
```
## INSTALL
```