-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathsandbox_inspector.py
115 lines (95 loc) · 5.04 KB
/
sandbox_inspector.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import os
import plistlib
import argparse
import base64
class SandboxInspector:
def __init__(self, home_dir):
self.home_dir = home_dir
def container_exists(self, bundle_id):
# Construct the expected path of the container
container_path = os.path.join(self.home_dir, 'Library', 'Containers', bundle_id)
# Check if the path exists
return os.path.exists(container_path)
@staticmethod
def get_bundle_id(app_path):
# Construct the path to the Info.plist file
info_plist_path = os.path.join(app_path, 'Contents', 'Info.plist')
# Read the Info.plist file to get the bundle identifier
with open(info_plist_path, 'rb') as f:
plist = plistlib.load(f)
return plist.get('CFBundleIdentifier')
def get_metadata(self, bundle_id):
# Construct the path to the metadata plist file
metadata_plist_path = os.path.join(self.home_dir, 'Library', 'Containers', bundle_id, '.com.apple.containermanagerd.metadata.plist')
if os.path.exists(metadata_plist_path):
with open(metadata_plist_path, 'rb') as f:
plist = plistlib.load(f)
return plistlib.dumps(plist, fmt=plistlib.FMT_XML).decode('utf-8')
else:
return None
def get_redirectable_paths(self, bundle_id):
# Construct the path to the metadata plist file
metadata_plist_path = os.path.join(self.home_dir, 'Library', 'Containers', bundle_id, '.com.apple.containermanagerd.metadata.plist')
if os.path.exists(metadata_plist_path):
with open(metadata_plist_path, 'rb') as f:
plist = plistlib.load(f)
redirectable_paths = plist.get('MCMMetadataInfo', {}).get('SandboxProfileDataValidationInfo', {}).get('RedirectablePaths', [])
return redirectable_paths
else:
return None
def get_sandbox_profile_data(self, bundle_id):
# Construct the path to the metadata plist file
metadata_plist_path = os.path.join(self.home_dir, 'Library', 'Containers', bundle_id, '.com.apple.containermanagerd.metadata.plist')
if os.path.exists(metadata_plist_path):
with open(metadata_plist_path, 'rb') as f:
plist = plistlib.load(f)
sandbox_profile_data = plist.get('MCMMetadataInfo', {}).get('SandboxProfileData', None)
return sandbox_profile_data
else:
return None
def parse_sandbox_profile_data(self, sandbox_profile_data):
# Placeholder for actual parsing logic
# This function will take raw bytes and interpret them as Sandbox Profile Language (SBPL)
if sandbox_profile_data:
return sandbox_profile_data# sandbox_profile_data.decode('utf-8', errors='ignore')
return None
def main():
parser = argparse.ArgumentParser(description="Inspect sandbox containers for macOS apps.")
parser.add_argument('-p', '--path', type=str, required=True, help="Path to the application (e.g., /Applications/Notes.app)")
parser.add_argument('-m', '--metadata', action='store_true', help="Print the .com.apple.containermanagerd.metadata.plist contents")
parser.add_argument('-r', '--redirectable', action='store_true', help="Print the redirectable paths")
parser.add_argument('-s', '--sandbox_profile_data', action='store_true', help="Print the SandboxProfileData as base64-encoded bytes")
args = parser.parse_args()
app_path = args.path
inspector = SandboxInspector(os.path.expanduser("~"))
bundle_id = inspector.get_bundle_id(app_path)
if bundle_id:
exists = inspector.container_exists(bundle_id)
# print(f"Container for {bundle_id} exists: {exists}")
if args.metadata:
metadata = inspector.get_metadata(bundle_id)
if metadata:
#print(f"Metadata for {bundle_id}:\n{metadata}")
print(f"{metadata}")
else:
print(f"No metadata plist found for {bundle_id}.")
if args.redirectable:
redirectable_paths = inspector.get_redirectable_paths(bundle_id)
if redirectable_paths:
print(f"Redirectable paths for {bundle_id}:")
for path in redirectable_paths:
print(f"{path}")
else:
print(f"No redirectable paths found for {bundle_id}.")
if args.sandbox_profile_data:
sandbox_profile_data = inspector.get_sandbox_profile_data(bundle_id)
if sandbox_profile_data:
parsed_data = inspector.parse_sandbox_profile_data(sandbox_profile_data)
encoded_data = base64.b64encode(parsed_data).decode('utf-8')
print(f"SandboxProfileData for {bundle_id} (base64-encoded):\n{encoded_data}")
else:
print(f"No SandboxProfileData found for {bundle_id}.")
else:
print("Unable to find the CFBundleIdentifier. Please check the app path.")
if __name__ == "__main__":
main()