AndroidManifest.xml文件安全探索

释放双眼,带上耳机,听听看~!
本文作者:i春秋签约作家——icq8756c1a2最近在做一些apk的安全检测,对AndroidManifest.xml文件进行了研究和探讨,介绍AndroidManifest.xml文件的作用和架构,并研究了AndroidManifest.xml配置文件存在的一些漏洞,在进行安全检测时,可以对症下

本文作者:i春秋签约作家——icq8756c1a2

最近在做一些apk的安全检测,对AndroidManifest.xml文件进行了研究和探讨,介绍AndroidManifest.xml文件的作用和架构,并研究了AndroidManifest.xml配置文件存在的一些漏洞,在进行安全检测时,可以对症下药。

0X00 AndroidManifest.xml文件作用   

AndroidManifest.xml文件的作用非常重要,应该说是缺一不可。在android官方介绍文档中(https://developer.android.com/gu … manifest-intro.html)是这样定义的。每个应用程序必须在其根目录中具有一个AndroidManifest.xml(名字必须一样)文件。Manifest文件提供有关应用程序到Android系统的基本信息,系统必须具有该信息才能运行任何应用程序的代码。换句话说APP是跑在Android系统上,既然要跑在其上,就必须提供信息给Android
System,这些信息就存在AndroidManifest中。AndroidManifest.xml 存放在
app/src/main/ 目录下。在反编译APK文件后,其文件是以乱码格式存在,需要进行转换才能正常查看。

0X01主要功能

1. 命名应用程序Java包,软件包名称作为应用程序的唯一标识符

2. 描述了应用程序的组件,其中包括构成应用程序的活动,服务,广播接收器和内容提供者;它还命名实现每个组件并发布其功能的类,例如Intent可以处理的消息。这些声明通知Android系统的组件及其可以启动的条件。

3. 决定哪些processes主持application

4. 宣告这个App有哪些权限,它声明应用程序必须拥有的权限才能访问API的受保护部分并与其他应用程序交互。它还声明其他人为了与应用程序的组件交互而需要的权限

5.它列出了Instrumentation在应用程序运行时提供概要分析和其他信息的类。这些声明仅在应用程序正在开发中才会存在,并在应用程序发布之前被删除。

6.它声明了应用程序需要的最低级别的Android API。

7.它列出了应用程序必须链接的库。

0X02 Manifest架构  

    允许的元素,蓝字是预设常见的元素,其中的<manifest>与<application>是必要且只能出现一次。每个元素有各自的属性,属性数量不一定,每个属性有其默认值,可视需求进行设定。

1.预设的AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.bmi" 名称空间
    android:versionCode="1"   开发者使用流水版号
    android:versionName="1.0" >  供使用者看的版本号
    <uses-sdk
        android:minSdkVersion="8" 最低兼容SDK版本
        android:targetSdkVersion="21" /> 目标版本,若没设定预设为最低minSdkVersion
    <application
        android:allowBackup="true" 是否允许备份
        android:icon="@drawable/ic_launcher" App Icon
        android:label="@string/app_name" App名称
        android:theme="@style/AppTheme" > App风格
        <activity activity, service, receiver, provider是组成application的4个主要项目
            android:name=".MainActivity" activity名称,可和manifest package串在一起
            android:label="@string/app_name" > APP开启后,显示在画面上方的名称
            <intent-filter> activity操作方式
                <action android:name="android.intent.action.MAIN" /> .MAIN表示activity是APP进入点
                <category android:name="android.intent.category.LAUNCHER" /> 显示在应用程序行表
            </intent-filter>
        </activity>
    </application>
</manifest>

2.标准的AndroidManifest.xml文件样例。

<?xml version="1.0" encoding="utf-8"?>   
<manifest>    
    <!-- 基本配置 --> 
    <uses-permission />  
    <permission />  
    <permission-tree />  
    <permission-group />  
    <instrumentation />  
    <uses-sdk />  
    <uses-configuration />  
    <uses-feature />  
    <supports-screens />  
    <compatible-screens />  
    <supports-gl-texture />        
    <!-- 应用配置 --> 
    <application>            
        <!-- Activity 配置 --> 
        <activity>  
            <intent-filter>  
                <action />  
                <category />  
                <data />  
            </intent-filter>  
            <meta-data />  
        </activity>            
        <activity-alias>  
            <intent-filter> . . . </intent-filter>  
            <meta-data />  
        </activity-alias>  
           <!-- Service 配置 --> 
        <service>  
            <intent-filter> . . . </intent-filter>  
            <meta-data/>  
        </service>  
        <!-- Receiver 配置 --> 
        <receiver>  
            <intent-filter> . . . </intent-filter>  
            <meta-data />  
        </receiver>            
        <!-- Provider 配置 --> 
        <provider>  
            <grant-uri-permission />  
            <meta-data />  
        </provider>            
        <!-- 所需类库配置 --> 
        <uses-library />    
    </application>  
  </manifest>


0×03 文件约定及语法    

从上面的代码中,我们可以看出Android配置文件采用XML作为描述语言,每个XML标签都不同的含义,大部分的配置参数都放在标签的属性中,下面我们便按照以上配置文件样例中的先后顺序来学习Android配置文件中主要元素与标签的用法。

1.元素(Elements)

 
 在所有的元素中只有<manifest>和<application>是必需的,它们各自必须存在,且只能出现一次。如果一个元素包含有其他子元素,必须通过子元素的属性来设置其值。处于同一层次的元素,这些元素的说明是没有顺序的。例如<activity>,<provider>和<service>元素可以以任何顺序混合。这个规则有两个关键的例外:

l 一个<activity-alias> 元素必须遵循 <activity>它是一个别名。

l <application> 元素必须是里面的最后一个元素 <manifest> 的元素。换句话说</application>结束标签必须在</manifest>结束标签之前立即出现。

2.属性

    正常来讲,所有的属性都是可选的,但是有些属性是必须设置的。以便元素可以实现其目的,除了根元素<manifest>的属性之外,所有其他元素属性的名字都是以android:前缀的;

定义类名:所有的元素名都对应其在SDK中的类名,如果你自己定义类名,必须包含类的数据包名,如果类与application处于同一数据包中,可以直接简写为“.”;

3.声明类名

 
 许多元素对应于Java对象,包括应用程序本身(<application>元素)的元素及其主要组件:活动(<activity>),服务<service>),广播接收器(<receiver>)和内容提供者(<provider>))。

如果你定义一个子类,如同你总是会为组件类(Activity,Service, BroadcastReceiver和ContentProvider)子类是通过name属性来声明,该名称必须包括完整的包装名称。例如,一个Service子类可能被声明如下:

<manifest . . . >

    <application . . . >

        <service android:name=”com.example.project.SecretService” . . . >

            . . .

        </service>

        . . .

    </application>

</manifest>      

4.多个值

   如果某个元素有超过一个数值,这个元素必须通过重复的方式来说明其某个属性具有多个数值项,且不能将多个数值项一次性说明在一个属性中;例如一个intent-filter 可以保护多个action:

<intent-filter . . . >

    <action android:name=”android.intent.action.EDIT” />

    <action android:name=”android.intent.action.INSERT” />

    <action android:name=”android.intent.action.DELETE” />

    . . .

</intent-filter>

5.资源值

    某些属性具有可显示给用户的值,例如一个活动的标签和图标。这些属性的值应该从资源或主题进行本地化和设置。资源值以下列格式表示:

@[package:]type/name

如果资源与应用程序在同一个软件包中,则可以省略软件包名称。该类型是一种资源,例如字符串或可画的对象,名称是特定资源的标识名称。例如:

<activity android:icon="@drawable/smallPic" . . . >

主题的值使用类似地表达,但以初始值“? ”代替“@”:

?[package:]type/name

注意:资源或主题包的值必须是“android”或应用程序包的名称。

6.字符串值

在属性值为字符串的地方,必须使用双反斜杠(\\)来转义字符,例如\\n换行符或\\uxxxx 表示Unicode字符。

7.意图过滤器

 
 应用程序的核心组件,如活动,服务和广播接收器由意图(Intent)激活。意图是Intent描述所需动作的一组信息(对象),包括要执行的数据,应该执行该操作的组件的类别以及其他相关指令。Android系统找到一个可以响应意图的适当组件,如果需要,则启动组件的新实例,并将其传递给 Intent对象。

组件通过意图过滤器通知他们可以响应的意图类型。由于Android系统必须了解组件在启动组件之前可以处理的意图,因此在清单中将intent过滤器指定为 <intent-filter> 元素。组件可以具有任意数量的过滤器,每个过滤器描述不同的功能。显式命名目标组件的意图激活该组件,因此过滤器不起作用。没有通过名称指定目标的意图可以仅在组件可以通过组件的过滤器之一时激活组件。

8.图标和标签

      
许多元素都有图标和标签属性,可以向用户显示一个小图标和文本。一些还有一个更长的描述属性,也可以在屏幕上显示。例如,该 <permission> 元素具有所有这三个属性,以便当询问用户是否授予已请求它的应用程序的权限时,一个图标代表权限,许可的名称以及它所需要的描述都会呈现给用户。

      
在每种情况下,在包含元素中设置的图标和标签将成为所有容器的子元素的默认值 icon和label设置。因此, <application>元素中设置的图标和标签是每个应用程序组件的默认图标和标签。类似地,为组件(如<activity> 元素)设置的图标和标签是每个组件<intent-filter> 元素的默认设置

。如果一个 <application> 元素设置了一个标签,但是一个活动和它的意图过滤器没有,应用程序标签将被视为活动和意图过滤器的标签。

       
为意图过滤器设置的图标和标签表示当组件呈现给用户并满足由过滤器发布的功能时的组件。例如,带有android.intent.action.MAIN和 android.intent.category.LAUNCHER设置的过滤器将活动通告为启动应用程序的活动。也就是说,应该在应用程序启动器中显示。在过滤器中设置的图标和标签显示在启动器中。

9.权限

        权限是限制的代码的一部分,或者在设备上的数据的访问的限制。限制是为了保护可能被误用以扭曲或损坏用户体验的关键数据和代码。

每个权限都由唯一标签标识。标签通常表示限制的动作。以下是Android定义的一些权限:

android.permission.CALL_EMERGENCY_NUMBERS

android.permission.READ_OWNER_DATA

android.permission.SET_WALLPAPER

android.permission.DEVICE_POWER

      
功能只能通过一个权限来保护。如果应用程序需要访问受权限保护的功能,则它必须声明它需要使用<uses-permission>
清单中的元素的权限
。当应用程序安装在设备上时,安装程序将通过检查签署应用程序证书的机构以及在某些情况下询问用户来确定是否授予所请求的权限。如果许可被授予,应用程序就可以使用受保护的功能。如果没有,则尝试访问这些功能失败,而不通知用户。

 
 应用程序也可以通过权限保护自己的组件。它可以使用由Android定义的任何权限,如android.Manifest.permission由其他应用程序列出
或声明的。它也可以自己定义。<permission> 元素声明了新的权限 。例如,活动可以如下保护:

<manifest . . . >

    <permission android:name=”com.example.project.DEBIT_ACCT” . . . />

    <uses-permission android:name=”com.example.project.DEBIT_ACCT” />

    . . .

    <application . . .>

        <activity android:name=”com.example.project.FreneticActivity”

                  android:permission=”com.example.project.DEBIT_ACCT”

                  . . . >

            . . .

        </activity>

    </application>

</manifest>   

请注意,在这个例子中,DEBIT_ACCT权限不仅仅是使用<permission> 元素来声明的
,所以它也使用了 <uses-permission> 元素。为了启动受保护的活动,您必须要求使用该应用程序的其他组件,即使应用程序本身也施加了保护。

0×04权限属性值意义

ACCESS_CHECKIN_PROPERTIES:允许对checkin数据库中的表“properties”进行读/写访问,以更改上传的值。

ACCESS_COARSE_LOCATION:允许应用访问大概位置。

ACCESS_FINE_LOCATION:允许应用访问精确位置。

ACCESS_LOCATION_EXTRA_COMMANDS:允许应用程序访问额外的位置提供程序命令。

ACCESS_NETWORK_STATE:允许应用程序访问有关网络的信息。

ACCESS_NOTIFICATION_POLICY:希望访问通知政策的应用程序的标记权限。

ACCESS_WIFI_STATE:允许应用程序访问有关Wi-Fi网络的信息。

ACCOUNT