Security problems of including cover in Android manifest.xml

Keywords: Android xml SDK encoding

0x00 about Android manifest.xml

Android Manifest.xml is a required file in every Android program. It is located in the root directory of the whole project, and the Manifest file provides basic information about the application to Android System, which is required by the system to run any application code. In other words, app is running on Android System. Since you want to run on it, you must provide information to Android System, which is stored in Android Manifest. Android Manifest.xml is stored in app/src/main /. After decompiling the APK file, the file exists in a garbled format and needs to be converted for normal viewing.

Main functions of Android manifest.xml

  1. Name the application Java package. The package name is the unique identifier of the application;
  2. Describes the components of an application, including the activities, services, broadcast receivers and content providers that make up the application; it also names classes that implement each component and publish its functions, such as messages that Intent can process. These statements inform the components of Android system and the conditions under which they can be started;
  3. Decide which processes host the application;
  4. Declare what permissions the App has, and what permissions the application must have to access the protected part of the API and interact with other applications. It also states the permissions that others need to interact with the components of the application; 5. It lists the classes that Instrumentation provides profiling and other information when the application is running. These statements exist only when the application is under development and are removed before the application is published; 6. It states the lowest level of Android API required by the application; 7. It lists the libraries that the application must link to.
<?xml version="1.0" encoding="utf-8" standalone="no"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.mwr.example.sieve">
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <permission android:label="Allows reading of the Key in Sieve" android:name="com.mwr.example.sieve.READ_KEYS" android:protectionLevel="dangerous"/>
    <permission android:label="Allows editing of the Key in Sieve" android:name="com.mwr.example.sieve.WRITE_KEYS" android:protectionLevel="dangerous"/>
    <application android:allowBackup="true" android:debuggable="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme">
        <activity android:clearTaskOnLaunch="true" android:excludeFromRecents="true" android:exported="true" android:finishOnTaskLaunch="true" android:label="@string/title_activity_file_select" android:name=".FileSelectActivity"/>
        <activity android:excludeFromRecents="true" android:label="@string/app_name" android:launchMode="singleTask" android:name=".MainLoginActivity" android:windowSoftInputMode="adjustResize|stateVisible">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <activity android:clearTaskOnLaunch="true" android:excludeFromRecents="true" android:exported="true" android:finishOnTaskLaunch="true" android:label="@string/title_activity_pwlist" android:name=".PWList"/>
        <activity android:clearTaskOnLaunch="true" android:excludeFromRecents="true" android:finishOnTaskLaunch="true" android:label="@string/title_activity_settings" android:name=".SettingsActivity"/>
        <activity android:clearTaskOnLaunch="true" android:excludeFromRecents="true" android:finishOnTaskLaunch="true" android:label="@string/title_activity_add_entry" android:name=".AddEntryActivity"/>
        <activity android:clearTaskOnLaunch="true" android:excludeFromRecents="true" android:finishOnTaskLaunch="true" android:label="@string/title_activity_short_login" android:name=".ShortLoginActivity"/>
        <activity android:clearTaskOnLaunch="true" android:excludeFromRecents="true" android:finishOnTaskLaunch="true" android:label="@string/title_activity_welcome" android:name=".WelcomeActivity"/>
        <activity android:clearTaskOnLaunch="true" android:excludeFromRecents="true" android:finishOnTaskLaunch="true" android:label="@string/title_activity_pin" android:name=".PINActivity"/>
        <service android:exported="true" android:name=".AuthService" android:process=":remote"/>
        <service android:exported="true" android:name=".CryptoService" android:process=":remote"/>
        <provider android:authorities="com.mwr.example.sieve.DBContentProvider" android:exported="true" android:multiprocess="true" android:name=".DBContentProvider">
            <path-permission android:path="/Keys" android:readPermission="com.mwr.example.sieve.READ_KEYS" android:writePermission="com.mwr.example.sieve.WRITE_KEYS"/>
        </provider>
        <provider android:authorities="com.mwr.example.sieve.FileBackupProvider" android:exported="true" android:multiprocess="true" android:name=".FileBackupProvider"/>
    </application>
</manifest>

0x01 Android manifest.xml risk point analysis

1. Allow backup setup risk

Android API Level 8 (Android 2.1) and above Android systems provide backup and recovery functions for application data. The switch of this function is determined by the value of the allowBackup attribute in the Android manifest.xml file of the application, and its attribute value is true by default. When the property value of allowBackup is not set to false, the attacker can backup and restore the application data through adb backup and adb restore, which may obtain the sensitive information of the user stored in plaintext.

android:allowBackup=["true" | "false"]
$ adb backup -nosystem -noshared -apk -f com.example.demo
$ adb restore com.example.demo
  • -No system means no backup system application
  • -noshared means that the data stored in SD will not be backed up
  • -APK represents the APK installation package of backup application
  • -f represents the path and filename of the. ab file to be backed up, and finally the packageName of the application to be backed up
  • Restore is to restore the backed up data

2. debuggable setting risk

This property is used to specify whether the application can be debugged, even when running in user mode on the device, if it is set to true, it can be debugged; however, the default debuggable property value of Android version is false, so it is recommended to use the default configuration.

android:debuggable=["true" | "false"]

3. Component export risk

Four components

  • Activity
  • Broadcast Receive
  • Service
  • Content Provider

The exportable components can be called arbitrarily by the third party APP, which leads to the leakage of sensitive information, and may be used to bypass authentication, malicious code injection, sql injection, denial of service and other attacks;

Default value of exported in Activity

  1. If there is no intent filter, it defaults to false
  2. true by default when there is an intent filter

The content filter label represents the primary Activity, and each APP will have a primary Activity. Therefore, when the application's Activity does not need to be exported, or the content filter label is configured, it is recommended to display and set android:exported="false". If the component must be exported to other applications, it is recommended to control the permissions of the component.

The default values of Broadcast Receive and Service are the same as those of Activity.

Default value of exported in Content Provider

  1. true by default when minSdkVersion or targetSdkVersion is less than 16
  2. If it is greater than 17, it defaults to false

4. Custom permission risk

In the security model of Android system, by default, an application can not perform any operation that has a negative impact on other applications, systems or users. If the application needs to perform some operations, it needs to declare the permission corresponding to the operation. That is to say, add the < uses Permission > tag in the Android manifest.xml file. Of course, you can also customize your own permission. However, if the authority is not properly controlled, it may lead to a variety of security problems such as ultra vires.

<uses-permission android:name="android.permission.INTERNET"/>
<permission android:label="Allows reading of the Key in Sieve" android:name="com.mwr.example.sieve.READ_KEYS" android:protectionLevel="dangerous"/>
android:protectionLevel=["normal" | "dangerous" | "signature" | "signatureOrSystem"]
  1. normal: This is the lowest risk permission. If the application declares this permission, the system will directly default that the application has this permission and will not prompt the user who installed the application to authorize it;
  2. dangerous: the system will prompt the user when installing the application with such permission declaration, but all apps can access and share this permission;
  3. Signature: this permission level is called advanced permission or system permission. Only when the application sending the request and the application receiving the request use the same signature file, and the permission is declared, it will be authorized by default, and the user will not be prompted for authorization
  4. Signature or system: this permission should be avoided as much as possible, and it is system level

0x02 AndroidManifest.xml structure

<?xmlversion="1.0"encoding="utf-8"?>

<manifest>
    <application>
       <activity>
           <intent-filter>
               <action/>
               <category/>
           </intent-filter>
      </activity>
       <activity-alias>
           <intent-filter></intent-filter>
           <meta-data/>
      </activity-alias>
       <service>
           <intent-filter></intent-filter>
           <meta-data/>
       </service>
       <receiver>
           <intent-filter></intent-filter>
           <meta-data/>
       </receiver>
       <provider>
           <grant-uri-permission/>
           <meta-data/>
       </provider>
       <uses-library/>
    </application>
    <uses-permission/>
    <permission/>
    <permission-tree/>
    <permission-group/>
    <instrumentation/>
    <uses-sdk/>
    <uses-configuration/>
    <uses-feature/>
    <supports-screens/>
</manifest>

0x03 introduction to Android manifest.xml

1,manifest

<manifest  xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.woody.test"
          android:sharedUserId="string"
          android:sharedUserLabel="string resource"
          android:versionCode="integer"
          android:versionName="string"
          android:installLocation=["auto" | "internalOnly" | "preferExternal"] >
</manifest>

2,application

<application  android:allowClearUserData=["true" | "false"]
             android:allowTaskReparenting=["true" | "false"]
             android:backupAgent="string"
             android:debuggable=["true" | "false"]
             android:description="string resource"
             android:enabled=["true" | "false"]
             android:hasCode=["true" | "false"]
             android:icon="drawable resource"
             android:killAfterRestore=["true" | "false"]
             android:label="string resource"
             android:manageSpaceActivity="string"
             android:name="string"
             android:permission="string"
             android:persistent=["true" | "false"]
             android:process="string"
             android:restoreAnyVersion=["true" | "false"]
             android:taskAffinity="string"
             android:theme="resource or theme" >
</application>

3,activity

<activity android:allowTaskReparenting=["true" | "false"]
          android:alwaysRetainTaskState=["true" | "false"]
          android:clearTaskOnLaunch=["true" | "false"]
          android:configChanges=["mcc", "mnc", "locale",
                                 "touchscreen", "keyboard", "keyboardHidden",
                                 "navigation", "orientation", "screenLayout",
                                 "fontScale", "uiMode"]
          android:enabled=["true" | "false"]
          android:excludeFromRecents=["true" | "false"]
          android:exported=["true" | "false"]
          android:finishOnTaskLaunch=["true" | "false"]
          android:icon="drawable resource"
          android:label="string resource"
          android:launchMode=["multiple" | "singleTop" |
                              "singleTask" | "singleInstance"]
          android:multiprocess=["true" | "false"]
          android:name="string"
          android:noHistory=["true" | "false"]
          android:permission="string"
          android:process="string"
          android:screenOrientation=["unspecified" | "user" | "behind" |
                                     "landscape" | "portrait" |
                                     "sensor" | "nosensor"]
          android:stateNotNeeded=["true" | "false"]
          android:taskAffinity="string"
          android:theme="resource or theme"
          android:windowSoftInputMode=["stateUnspecified",
                                       "stateUnchanged", "stateHidden",
                                       "stateAlwaysHidden", "stateVisible",
                                       "stateAlwaysVisible", "adjustUnspecified",
                                       "adjustResize", "adjustPan"] > 
</activity>

4,intent-filter

<intent-filter  android:icon="drawable resource"
               android:label="string resource"
               android:priority="integer" >

<action />

<category />

<data />

</intent-filter>

5,meta-data

<meta-data android:name="string"
           android:resource="resource specification"
           android:value="string"/>

6,activity-alias

<activity-alias android:enabled=["true" | "false"]
                android:exported=["true" | "false"]
                android:icon="drawable resource"
                android:label="string resource"
                android:name="string"
                android:permission="string"
                android:targetActivity="string">

<intent-filter/>
<meta-data/>
</activity-alias>

7,service

<service android:enabled=["true" | "false"]
android:exported[="true" | "false"]
android:icon="drawable resource"
android:label="string resource"
android:name="string"
android:permission="string"
android:process="string">
</service>

8,receiver

9,provider

<provider android:authorities="list"
android:enabled=["true" | "false"]
android:exported=["true" | "false"]
android:grantUriPermissions=["true" | "false"]
android:icon="drawable resource"
android:initOrder="integer"
android:label="string resource"
android:multiprocess=["true" | "false"]
android:name="string"
android:permission="string"
android:process="string"
android:readPermission="string"
android:syncable=["true" | "false"]
android:writePermission="string">
<grant-uri-permission/>
<meta-data/>
</provider>

10,uses-library

11,supports-screens

<supports-screens  android:smallScreens=["true" | "false"]
                  android:normalScreens=["true" | "false"]
                  android:largeScreens=["true" | "false"]
                  android:anyDensity=["true" | "false"] />

12. Uses configuration and uses feature

<uses-configuration  android:reqFiveWayNav=["true" | "false"]
                    android:reqHardKeyboard=["true" | "false"]
                    android:reqKeyboardType=["undefined" | "nokeys" | "qwerty" |   "twelvekey"]
                    android:reqNavigation=["undefined" | "nonav" | "dpad" |  "trackball" | "wheel"]
                    android:reqTouchScreen=["undefined" | "notouch" | "stylus" | "finger"] />

<uses-feature android:glEsVersion="integer"
              android:name="string"
              android:required=["true" | "false"] />

13,uses-sdk

<uses-sdk android:minSdkVersion="integer"
          android:targetSdkVersion="integer"
          android:maxSdkVersion="integer"/>

14,instrumentation

<instrumentation android:functionalTest=["true" | "false"]
                 android:handleProfiling=["true" | "false"]
                 android:icon="drawable resource"
                 android:label="string resource"
                 android:name="string"
                 android:targetPackage="string"/>

15. Differences between < Permission >, < uses Permission >, < permission tree / > and < permission group / >

The most commonly used is < uses Permission >. When we need to obtain a permission, we must declare it in our manifest file. This < uses Permission > is the same as < Application >. For the specific permission list, please see here

Usually we don't need to declare a permission for our own application, unless you provide code or data for other applications to call. At this time, you need to use the < Permission > tag. Obviously this tag allows us to declare our rights. For example:

<permission android:name="com.teleca.project.MY_SECURITY" . . . />

Then you can declare the custom permission in activity, such as:

<application . . .>
        <activity android:name="XXX" . . . >
                  android:permission="com.teleca.project.MY_SECURITY"> </activity>
 </application>

Of course, you can't use the permission declared by yourself at will, or you need to use < uses Permission > to declare that you need the permission < permission group > is to declare a label, which represents a set of permissions, while < permission tree > is to declare a namespace for a set of permissions. These two tags can be seen in the previous series.

Published 10 original articles, won praise 0, visited 248
Private letter follow

Posted by varasurf on Mon, 16 Mar 2020 06:39:38 -0700