본문 바로가기
해킹&보안/모바일

모바일 정적분석 #2

AndroidManifest.xml 파일의 보안 설정 분석

1. 서론 

모든 안드로이드 애플리케이션은 루트 디렉터리에 AndroidManifest.xml 파일을 반드시 포함합니다. 이 파일은 앱의 이름, 아이콘, 버전과 같은 기본 정보부터 시작하여, 앱을 구성하는 핵심 컴포넌트의 선언, 그리고 앱이 시스템이나 다른 앱의 기능에 접근하기 위해 필요한 권한 목록까지, 앱의 모든 것을 정의합니다.

정적 분석에서 AndroidManifest.xml 파일을 가장 먼저 살펴보는 이유는 이 파일만으로도 앱의 전체적인 구조를 파악하고 잠재적인 공격 표면을 식별할 수 있기 때문입니다.

InsecureBankv2의 AndroidManifest.xml 파일을 분석하여, 개발 과정에서 흔히 발생하는 주요 보안 설정 오류(과도한 권한 요청, 디버그 모드 활성화, 데이터 백업 허용, 컴포넌트 부적절 노출)를 찾아내고 그 위험성을 분석하는 것을 목표로 합니다.


2. 분석 환경

  • 분석 대상: InsecureBankv2.apk
  • 분석 도구: JADX-GUI 1.4.7

3. 분석 절차 

3.1. AndroidManifest.xml 파일 식별

JADX로 APK 파일을 열면, 좌측 트리 구조의 최상단 Resources 섹션에서 AndroidManifest.xml 파일을 쉽게 찾을 수 있습니다. JADX는 바이너리 형태로 패키징된 XML 파일을 사람이 읽을 수 있는 텍스트 형태로 자동 변환해주므로, 별도의 도구 없이 즉시 내용을 확인할 수 있습니다.

 

3.2. 매니페스트 파일 내용 분석

파일을 열어 <uses-permission>, <application>, 그리고 그 하위 태그들을 중심으로 전체적인 구조와 주요 속성들을 확인합니다.

↓ 코드 ↓

더보기
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="1"
    android:versionName="1.0"
    package="com.android.insecurebankv2"
    platformBuildVersionCode="22"
    platformBuildVersionName="5.1.1-1819727">
    <uses-sdk
        android:minSdkVersion="15"
        android:targetSdkVersion="22"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.SEND_SMS"/>
    <uses-permission android:name="android.permission.USE_CREDENTIALS"/>
    <uses-permission android:name="android.permission.GET_ACCOUNTS"/>
    <uses-permission android:name="android.permission.READ_PROFILE"/>
    <uses-permission android:name="android.permission.READ_CONTACTS"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <uses-permission
        android:name="android.permission.READ_EXTERNAL_STORAGE"
        android:maxSdkVersion="18"/>
    <uses-permission android:name="android.permission.READ_CALL_LOG"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-feature
        android:glEsVersion="0x20000"
        android:required="true"/>
    <application
        android:theme="@android:style/Theme.Holo.Light.DarkActionBar"
        android:label="@string/app_name"
        android:icon="@mipmap/ic_launcher"
        android:debuggable="true"
        android:allowBackup="true">
        <activity
            android:label="@string/app_name"
            android:name="com.android.insecurebankv2.LoginActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <activity
            android:label="@string/title_activity_file_pref"
            android:name="com.android.insecurebankv2.FilePrefActivity"
            android:windowSoftInputMode="adjustNothing|stateVisible"/>
        <activity
            android:label="@string/title_activity_do_login"
            android:name="com.android.insecurebankv2.DoLogin"/>
        <activity
            android:label="@string/title_activity_post_login"
            android:name="com.android.insecurebankv2.PostLogin"
            android:exported="true"/>
        <activity
            android:label="@string/title_activity_wrong_login"
            android:name="com.android.insecurebankv2.WrongLogin"/>
        <activity
            android:label="@string/title_activity_do_transfer"
            android:name="com.android.insecurebankv2.DoTransfer"
            android:exported="true"/>
        <activity
            android:label="@string/title_activity_view_statement"
            android:name="com.android.insecurebankv2.ViewStatement"
            android:exported="true"/>
        <provider
            android:name="com.android.insecurebankv2.TrackUserContentProvider"
            android:exported="true"
            android:authorities="com.android.insecurebankv2.TrackUserContentProvider"/>
        <receiver
            android:name="com.android.insecurebankv2.MyBroadCastReceiver"
            android:exported="true">
            <intent-filter>
                <action android:name="theBroadcast"/>
            </intent-filter>
        </receiver>
        <activity
            android:label="@string/title_activity_change_password"
            android:name="com.android.insecurebankv2.ChangePassword"
            android:exported="true"/>
        <activity
            android:theme="@android:style/Theme.Translucent"
            android:name="com.google.android.gms.ads.AdActivity"
            android:configChanges="smallestScreenSize|screenSize|uiMode|screenLayout|orientation|keyboardHidden|keyboard"/>
        <activity
            android:theme="@style/Theme.IAPTheme"
            android:name="com.google.android.gms.ads.purchase.InAppPurchaseActivity"/>
        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version"/>
        <meta-data
            android:name="com.google.android.gms.wallet.api.enabled"
            android:value="true"/>
        <receiver
            android:name="com.google.android.gms.wallet.EnableWalletOptimizationReceiver"
            android:exported="false">
            <intent-filter>
                <action android:name="com.google.android.gms.wallet.ENABLE_WALLET_OPTIMIZATION"/>
            </intent-filter>
        </receiver>
    </application>
</manifest>

a

분석 결과, 여러 항목에서 보안상 고려해야 할 설정들을 발견할 수 있습니다.


4. 취약점 분석 및 영향

4.1. 과도한 권한 요청

취약점 코드: <uses-permission android:name="android.permission.SEND_SMS"/>, <uses-permission android:name="android.permission.READ_CONTACTS"/>

위험도: 정보 노출  ~  높음 

상세 설명: 이 앱은 금융 앱의 핵심 기능과 직접적인 관련이 없어 보이는 SMS 전송, 연락처 읽기, 통화 기록 읽기 등 민감한 권한을 다수 요청하고 있습니다. 만약 앱의 다른 취약점과 연계될 경우에 공격자는 이 권한들을 악용하여 사용자 몰래 SMS를 보내거나 개인 정보를 탈취하는 등 심각한 피해를 유발할 수 있습니다.

 

4.2. 디버그 모드 활성화

취약점 코드: <application android:debuggable="true" ... >

위험도: 높음

상세 설명: android:debuggable="true" 설정은 공격자가 ADB를 통해 앱 프로세스에 자유롭게 접근하여 메모리 덤프, 코드 실행, 변수 조작 등을 가능하게 합니다. 이는 앱의 모든 내부 로직을 분석하고 우회할 수 있는 문을 열어주는 것과 같으므로, 상용 앱에서는 절대 허용되어서는 안 됩니다.

 

4.3. 데이터 백업 허용

취약점 코드: <application android:allowBackup="true" ... >

위험도: 중간 (Medium)

상세 설명: android:allowBackup="true" 설정은 adb backup 명령어를 통해 앱의 내부 데이터를 백업할 수 있도록 허용합니다. 공격자가 루팅되지 않은 기기라도 물리적 접근만 가능하다면, 앱이 저장하는 모든 설정, 계정 정보, 데이터베이스 파일 등을 PC로 추출하여 분석할 수 있습니다.

 

4.4. 부적절한 컴포넌트 노출 

취약점 코드: <activity android:exported="true"/>, <provider android:exported="true"/>, <receiver android:exported="true"/>

위험도: 높음 (High)

상세 설명: InsecureBankv2는 다수의 Activity뿐만 아니라, TrackUserContentProviderMyBroadCastReceiver 컴포넌트까지 android:exported="true"로 설정하여 외부에 노출시키고 있습니다.

  • Activity: 로그인 후에만 접근해야 할 PostLogin, DoTransfer 화면이 노출되어 인증 우회 공격에 취약합니다.
  • Content Provider: TrackUserContentProvider가 노출되어 있어, 악성 앱이 해당 Provider에 접근하여 사용자의 데이터를 조회하거나 변조할 수 있는 위험이 있습니다.
  • Broadcast Receiver: MyBroadCastReceiver가 노출되어 있어, 악성 앱이 theBroadcast 액션을 포함한 인텐트를 전송하여 해당 리시버를 비정상적으로 트리거하고 의도치 않은 동작을 유발할 수 있습니다. (일명 Intent Spoofing 공격)

5. 결론 및 대응 방안

AndroidManifest.xml 파일은 간단한 설정 값만으로도 앱의 보안 수준을 크게 좌우할 수 있는 중요한 파일입니다. 권한은 최소한으로 요청하고, 개발 단계의 편의를 위해 설정했던 값들은 상용 버전에 포함되지 않도록 철저히 관리해야 합니다.

 

안전한 설정 방안

권한 관리: 앱 기능에 필수적인 최소한의 권한만 요청합니다.

android:debuggable: 상용 빌드에서는 반드시 false로 설정합니다.

android:allowBackup: 민감 정보를 다룬다면 명시적으로 false로 설정하여 백업을 비활성화합니다.

android:exported: 다른 앱과의 연동이 명시적으로 필요한 경우가 아니라면 모든 컴포넌트에 false로 설정을 원칙으로 합니다.

'해킹&보안 > 모바일' 카테고리의 다른 글

모바일 정적분석 #6  (0) 2025.10.18
모바일 정적분석 #5  (0) 2025.10.18
모바일 정적분석 #4  (0) 2025.10.17
모바일 정적분석 #3  (0) 2025.10.17
모바일 정적분석 #1  (0) 2025.10.16