experimental restoring app bundles

This commit is contained in:
leminlimez
2025-03-13 09:45:55 -04:00
parent 5f84ce79a4
commit 6ccac7bd09
3 changed files with 38 additions and 6 deletions

View File

@@ -108,10 +108,17 @@ class SymbolicLink(BackupFile):
flags=4,
properties=[]
)
@dataclass
class AppBundle:
identifier: str
path: str
version: str = 804
@dataclass
class Backup:
files: list[BackupFile]
apps: list[AppBundle]
def write_to_directory(self, directory: Path):
for file in self.files:
@@ -150,7 +157,7 @@ class Backup:
})
def generate_manifest(self) -> bytes: # Manifest.plist
return plistlib.dumps({
plist = {
"BackupKeyBag": b64decode("""
VkVSUwAAAAQAAAAFVFlQRQAAAAQAAAABVVVJRAAAABDud41d1b9NBICR1BH9JfVtSE1D
SwAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAV1JBUAAA
@@ -182,4 +189,15 @@ class Backup:
"Lockdown": {},
"SystemDomainsVersion": "20.0",
"Version": "9.1"
})
}
# add the apps
if len(self.apps) > 0:
plist["Applications"] = {}
for app in self.apps:
appInfo = {
"CFBundleIdentifier": app.identifier,
"CFBundleVersion": app.version,
"Path": app.path
}
plist["Applications"][app.identifier] = appInfo
return plistlib.dumps(plist)

View File

@@ -10,6 +10,12 @@ class FileToRestore:
self.owner = owner
self.group = group
class AppBundleToRestore(FileToRestore):
def __init__(self, contents: str, bundle_id: str, bundle_version: str, bundle_path: str):
super().__init__(contents=contents, restore_path=bundle_path, domain=f"AppDomain-{bundle_id}")
self.bundle_id = bundle_id
self.bundle_version = bundle_version
def concat_exploit_file(file: FileToRestore, files_list: list[FileToRestore], last_domain: str) -> str:
base_path = "/var/backup"
# set it to work in the separate volumes (prevents a bootloop)
@@ -83,13 +89,21 @@ def restore_files(files: list, reboot: bool = False, lockdown_client: LockdownCl
# create the files to be backed up
files_list = [
]
apps_list = []
sorted_files = sorted(files, key=lambda x: x.restore_path, reverse=False)
# add the file paths
last_domain = ""
last_path = ""
exploit_only = True
for file in sorted_files:
if file.domain == None:
if isinstance(file, AppBundleToRestore):
# add bundle id to the manifest
apps_list.append(backup.AppBundle(
identifier=file.bundle_id,
path=file.restore_path,
version=file.bundle_version
))
elif file.domain == None:
last_domain = concat_exploit_file(file, files_list, last_domain)
else:
last_domain, last_path = concat_regular_file(file, files_list, last_domain, last_path)
@@ -100,7 +114,7 @@ def restore_files(files: list, reboot: bool = False, lockdown_client: LockdownCl
files_list.append(backup.ConcreteFile("", "SysContainerDomain-../../../../../../../.." + "/crash_on_purpose", contents=b""))
# create the backup
back = backup.Backup(files=files_list)
back = backup.Backup(files=files_list, apps=apps_list)
perform_restore(backup=back, reboot=reboot, lockdown_client=lockdown_client)