우선 Content Provider에 대해서 간단하게 살펴보자.
[Content Provider]
- Content Provider는 애플리케이션이 자체적으로 저장한 데이터나 다른 애플리케이션의 데이터를 관리하고, 이를 다른 애플리케이션과 안전하게 공유할 수 있도록 돕는 표준 인터페이스다.
- 앱 데이터를 다른 앱에서 사용할 수 있는 통로를 제공한다고 생각하면 된다.
- Content Provider의 주소 URI는 "content://authority/path"와 같은 형식으로 구성된다.
++ 추가적으로 새롭게 알게된 내용!!
UriMatcher를 사용하면 ContentProvider에서 여러 URI 패턴을 처리할 수 있게 되는데, 이러한 패턴은 ContentProvider 내부의 URI 매핑 테이블에 등록되고, 이 테이블을 통해 어떤 URI 요청이 들어왔을 때 해당 요청을 어떤 방식으로 처리할지 결정된다.
만약 앱의 ContentProvider가 UriMatcher를 사용하고 있고, 그 ContentProvider가 exported=true로 설정되어 있다면, 외부 애플리케이션이 해당 URI에 접근할 수 있다. 이때, URI를 정확히 알아내기 위해서는 UriMatcher에서 사용된 패턴을 이해하고, 해당 패턴에 맞는 URI를 시도해보는 것이 중요하다.
일반적으로 UriMatcher는 아래와 같은 형태로 설정된다:
UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
matcher.addURI("authority", "path", SOME_CONSTANT);
matcher.addURI("authority", "path/#", ANOTHER_CONSTANT);
여기서 path나 path/#와 같은 패턴을 외부에서 유추할 수 있으면, adb shell content query --uri content://authority/path와 같은 명령어로 해당 ContentProvider에 접근하여 데이터를 쿼리할 수 있다.
따라서 취약점 점검 시에는 단순히 URI를 바로 사용하는 경우뿐만 아니라, UriMatcher를 통해서 유추할 수 있는 URI 패턴까지도 시도해볼 수 있다.
Insecurebankv2에서 취약한 Content Provider를 살펴보면 다음과 같이 진단해볼 수 있다.
Analysis
1. Androidmanifest.xml에서 선언된 Content Provider의 exported=true의 유무
아래와 같이 "TrackUserContentProvider" 이름의 provider의 exported=true를 확인할 수 있다.
<provider
android:name="com.android.insecurebankv2.TrackUserContentProvider"
android:exported="true"
android:authorities="com.android.insecurebankv2.TrackUserContentProvider"/>
2. content:// 확인
jadx의 검색기능을 통해 아래와 같이 com.android.insecurebankv2.TrackUserContentProvider 파일에서
uri 전체 주소를 확인할 수 있다.

3. 취약점 확인
확인된 uri 전체 주소를 갖고,
adb shell content query --uri [확인된 URI 전체 주소] 를 통해서 아래와 같이 사용자가 로그인한 내역을 확인할 수 있다.

추가적으로 Drozer를 사용해서 쉽게 Content Provider 공격 가능한 URI를 확인해볼 수 있었는데 그에 대한 방법은 아래와 같다. 우선 Drozer 설치 및 환경 구축은 이전 게시글인 https://benkyoblog.tistory.com/12 에서 참고하면 된다.
1. Content Provider URI 검색
run scanner.provider.finduris -a com.android.insecurebankv2 명령어를 통해서 아래와 같이 접근 가능한 목록이 출력되는 것을 확인할 수 있다.
scanner.provider.finduris -a package_name 명령어는 Content Provider의 URI 주소를 검색해서 접근 가능한 목록들을 찾아주고, Unable to Query와 Able to Query로 구분해서 실질적으로 Accessible한 content URI들의 목록까지 출력해준다.

2. 데이터 확인
run app.provider.query [Accessible한 URI 주소] 를 통해서 아래와 같이 adb를 통해 확인한 정보와 동일한 결과가 출력되는 것을 확인해볼 수 있다.

Content Provider는 대상 앱의 데이터베이스, 데이터 등 확인할 수 있기 때문에 Drozer를 통해 SQL Injection, 경로 탐색 등 진단도 가능하다.
Drozer로 SQL Injection을 아래와 같이 시도해보았다.
우선 싱글 쿼터를 사용해서 run app.provider.query [URI 주소] --projection "'" 명령어를 통해 취약점 존재를 아래와 같이 확인해보았고,

테이블 목록을 확인해보기 위해서, run app.provider.query [URI 주소] --projection "* from SQLITE_MASTER where type='table';--" 명령어를 통해서 SQLITE에 존재하는 테이블들을 확인했다.

이제 확인된 테이블들을 run app.provider.query [URI 주소] "* from [확인하고자 하는 테이블 이름];--" 명령어를 통해서 아래와 같이 모두 확인해볼 수 있었다.

Mitigation
- Content Provider를 통해서 앱 데이터 유출을 막기 위해 Androidmanifest.xml에서 Content Provider 선언시, exported를 true가 아닌 false로 선언한다. 이렇게 하면, 권한이 없다는 메세지와 함께 결과 출력이 되지 않는다.
- 같은 회사에서 여러 앱 서비스를 제공하고 해당 앱들간 데이터를 주고 받는 상황에서 해당 exported가 false로 선언이 되어 있다면, 데이터의 연결통로가 막히게 되므로 사용자의 편의성에 있어서 단점으로 발생할 수 있다. 취약점 진단시, 이런 부분들을 고려해서 확인해 볼 수 있을거 같다는 생각이든다.
'Hacker > APP' 카테고리의 다른 글
| Diva 풀이 9~11번 (Access Control Issues - Part 1~3) (0) | 2024.09.16 |
|---|---|
| Diva 풀이 7~8번 (Input Validation Issues Part 1~2) (0) | 2024.09.15 |
| drozer 환경 구축 (0) | 2024.08.20 |
| Insecurebankv2 - Local Encryption issues, Hardcoded secret, Weak Cryptography implementation (0) | 2024.08.12 |
| Diva 풀이 4~6번 (Insecure Data Storage - Part 2 ~ 4) (0) | 2024.08.09 |