
CVE-2026-28576에 대한 PoC 및 레드팀 앱으로, Android Contacts Provider의 제로 권한 SQL 인젝션을 통해 전체 연락처 데이터베이스 유출이 가능합니다.
CVE-2026-28576은 Android Contacts Provider 프레임워크(ContactsProvider2.queryLocal())의 치명적인 접근 제어 취약점입니다. 이 결함은 선언된 권한이 전혀 없는 로컬에 설치된 비특권 애플리케이션이 전체 이름, 전화번호, 우편 주소, 이메일 주소를 포함한 기기의 전체 연락처 데이터베이스를 유출할 수 있게 합니다.
| 속성 | 값 |
|---|---|
| CVE ID | CVE-2026-28576 |
| GHSA ID | GHSA-ph86-9mcx-3p6r |
| Android Bug ID | A-488593616 |
| CWE | CWE-89: SQL 명령에 사용되는 특수 요소의 부적절한 중화('SQL 인젝션') |
| CVSS v4.0 | 10.0 (치명적) - AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H |
| EPSS 점수 | 0.148% (4번째 백분위수) |
| 게시일 | 2026년 6월 17일 |
| 구성 요소 | Android Contacts Provider (ContactsProvider2) |
| 공격 벡터 | 로컬 (제로 권한 앱) |
| 사용자 상호작용 | 필요 없음 |
이 취약점은 Android Contacts Provider 프레임워크(packages/providers/ContactsProvider) 내 ContactsProvider2.queryLocal() 메서드에 존재합니다. 이 메서드는 ContentResolver.query()를 통해 전달된 selection 및 selectionArgs 매개변수를 사용하여 정제되지 않은 사용자 제어 입력으로 SQL 쿼리를 구성하여 SQL 인젝션을 허용합니다.
ContentResolver.query()
→ ContactsProvider2.query()
→ ContactsProvider2.queryLocal() [취약]
→ SQLiteQueryBuilder.buildQuery()
→ 정제되지 않은 입력으로 원시 SQL 실행
selection (String): 매개변수화되지 않은 WHERE 절selectionArgs (String[]): 부적절하게 이스케이프된 인수uri (Uri): content://com.android.contacts/...를 대상으로 하는 콘텐츠 URIREAD_CONTACTS, READ_PRIVILEGED_PHONE_STATE 또는 기타 위험한 권한 불필요queryLocal() 메서드는 selection 매개변수를 적절한 매개변수화 없이 SQL WHERE 절에 직접 연결하여 처리합니다:
// ContactsProvider2.java의 단순화된 취약 패턴
public Cursor queryLocal(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(Tables.CONTACTS);
// 취약: selection이 SQL에 직접 보간됨
String whereClause = buildWhereClause(selection, selectionArgs);
Cursor c = qb.query(db, projection, whereClause, null, null, null, sortOrder);
return c;
}
공격자는 다음과 같은 악성 selection 매개변수를 구성합니다:
"1=1) UNION SELECT _id, display_name, phone_number, email_address, postal_address FROM raw_contacts--"
이는 의도된 쿼리 로직을 우회하고 모든 연락처 필드를 추출합니다.
graph TD
A[악성 앱 설치됨] --> B[ContentResolver.query 요청]
B --> C[SQL 인젝션 페이로드 구성]
C --> D[content://com.android.contacts/data 대상]
D --> E[ContactsProvider2.queryLocal]
E --> F[정제되지 않은 selection 매개변수]
F --> G[SQL 인젝션 실행됨]
G --> H[전체 연락처 DB 반환됨]
H --> I[네트워크/로그를 통한 유출]UNION/UPDATE 인젝션을 통한 잠재적 연락처 데이터 조작| Android 버전 | 상태 |
|---|---|
| Android 14 (U) | 취약 |
| Android 15 (V) | 취약 |
| Android 16 (W) | 취약 |
| Android 17 (2026년 6월+) | 패치됨 |
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() 제한selection 매개변수에 대한 ContactsProvider 쿼리 로그 감사READ_CONTACTS 권한 없이 content://com.android.contacts URI 사용을 앱에서 스캔CVE-2026-28576 연구 저장소를 위해 생성된 문서 최종 업데이트: 2025년 9월
| 데이터 범주 | 노출된 필드 |
|---|
| 신원 | display_name, phonetic_name, nickname, company, title |
| 전화번호 | number, type (휴대폰, 집, 직장, 팩스 등), label |
| 이메일 주소 | address, type (집, 직장, 기타), label |
| 우편 주소 | street, city, region, postcode, country, type |
| 구조화된 데이터 | mimetype, data1–data15, sync1–sync4 |
| 메타데이터 | contact_id, raw_contact_id, version, dirty, deleted |