
PoC y aplicación de red team para CVE-2026-28576, una inyección SQL sin permisos en el Android Contacts Provider que permite la exfiltración completa de la base de datos de contactos.
CVE-2026-28576 es una vulnerabilidad crítica de control de acceso en el framework Android Contacts Provider (ContactsProvider2.queryLocal()). El fallo permite que una aplicación sin privilegios instalada localmente con cero permisos declarados exfiltre toda la base de datos de contactos de un dispositivo, incluidos nombres completos, números de teléfono, direcciones postales y direcciones de correo electrónico.
| Atributo | Valor |
|---|---|
| ID CVE | CVE-2026-28576 |
| ID GHSA | GHSA-ph86-9mcx-3p6r |
| ID de bug de Android | A-488593616 |
| CWE | CWE-89: Neutralización incorrecta de elementos especiales utilizados en un comando SQL ('Inyección SQL') |
| CVSS v4.0 | 10.0 (Crítico) - AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H |
| Puntuación EPSS | 0.148% (percentil 4) |
| Publicado | 17 de junio de 2026 |
| Componente | Android Contacts Provider (ContactsProvider2) |
| Vector de ataque | Local (aplicación sin permisos) |
| Interacción del usuario | No se requiere |
La vulnerabilidad existe en el método ContactsProvider2.queryLocal() dentro del framework Android Contacts Provider (packages/providers/ContactsProvider). El método construye consultas SQL utilizando entrada controlada por el usuario no saneada, lo que permite la inyección SQL a través de los parámetros selection y selectionArgs pasados mediante ContentResolver.query().
ContentResolver.query()
→ ContactsProvider2.query()
→ ContactsProvider2.queryLocal() [VULNERABLE]
→ SQLiteQueryBuilder.buildQuery()
→ Raw SQL execution with unsanitized input
selection (String): Cláusula WHERE sin parametrizaciónselectionArgs (String[]): Argumentos que se escapan incorrectamenteuri (Uri): URI de contenido dirigida a content://com.android.contacts/...READ_CONTACTS, READ_PRIVILEGED_PHONE_STATE ni ningún permiso peligrosoEl método queryLocal() procesa el parámetro selection concatenándolo directamente en la cláusula WHERE de SQL sin la parametrización adecuada:
// Simplified vulnerable pattern in ContactsProvider2.java
public Cursor queryLocal(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(Tables.CONTACTS);
// VULNERABLE: selection directly interpolated into SQL
String whereClause = buildWhereClause(selection, selectionArgs);
Cursor c = qb.query(db, projection, whereClause, null, null, null, sortOrder);
return c;
}
Un atacante elabora un parámetro selection malicioso como:
"1=1) UNION SELECT _id, display_name, phone_number, email_address, postal_address FROM raw_contacts--"
Esto elude la lógica de consulta prevista y extrae todos los campos de contactos.
graph TD
A[Malicious App Installed] --> B[Request ContentResolver.query]
B --> C[Craft SQL Injection Payload]
C --> D[Target content://com.android.contacts/data]
D --> E[ContactsProvider2.queryLocal]
E --> F[Unsanitized selection parameter]
F --> G[SQL Injection Executed]
G --> H[Full Contacts DB Returned]
H --> I[Exfiltrate via Network/Logs]UNION/UPDATE| Versión de Android | Estado |
|---|---|
| Android 14 (U) | Vulnerable |
| Android 15 (V) | Vulnerable |
| Android 16 (W) | Vulnerable |
| Android 17 (junio de 2026+) | Parcheado |
rule Android_ContactsProvider_SQLi_CVE_2026_28576 {
meta:
description = "Detects SQL injection payloads targeting ContactsProvider"
cve = "CVE-2026-28576"
severity = "critical"
strings:
$s1 = "content://com.android.contacts" nocase
$s2 = "UNION SELECT" nocase
$s3 = "raw_contacts" nocase
$s4 = "data1" nocase
$s5 = "1=1" nocase
condition:
$s1 and 2 of ($s2, $s3, $s4, $s5)
}
alert http any any -> any any (
msg:"CVE-2026-28576 Contacts Exfiltration";
flow:established,to_server;
content:"contacts";
http.uri;
pcre:"/UNION.*SELECT.*raw_contacts/i";
classtype:web-application-attack;
sid:202628576;
rev:1;
)
ContentResolver.query() mediante política SELinuxContactsProvider en busca de parámetros selection anómaloscontent://com.android.contacts sin permiso READ_CONTACTSDocumento generado para el repositorio de investigación CVE-2026-28576 Última actualización: septiembre de 2025
| Categoría de datos | Campos expuestos |
|---|
| Identidad | display_name, phonetic_name, nickname, company, title |
| Números de teléfono | number, type (móvil, casa, trabajo, fax, etc.), label |
| Direcciones de correo electrónico | address, type (casa, trabajo, otro), label |
| Direcciones postales | street, city, region, postcode, country, type |
| Datos estructurados | mimetype, data1–data15, sync1–sync4 |
| Metadatos | contact_id, raw_contact_id, version, dirty, deleted |