《Android安全攻防权威指南》 阅读学习

2 Android的安全设计与架构

Android 的总体架构由 5 个主要层次上的组件构成,这 5 层是:

  • Android 应用层
    • 允许开发者无须修改底层代码就对设备的功能进行扩展和提升
  • Android 框架层
    • 为开发者提供了用来访问 Android 设备各种必需设备的 API
    • 充当 应用层 与 Dalvik 虚拟机层 之间的“粘合剂”
  • Dalvik 虚拟机层
    • 为底层操作系统提供一个高效的抽象层
  • 用户空间原生代码层
    • 包括系统服务(如 vold 和 DBus)、网络服务(如 dhcpd 和 wpa_supplicant)和程序库(如 bionic libc、WebKit 和 OpenSSL)
  • Linux 内核层
    assets/Android安全攻防权威指南/file-20250327094813741.png

API 中包含各种构件(building block)以允许开发者执行通用任务,比如管理 UI 元素、访问共享数据存储,以及在应用组件间传递信息等

2.2 理解安全边界和安全策略执行

安全边界,是系统中分隔不同信任级别的特殊区域
一个最直接的例子就是内核空间用户空间之间的边界

  • 内核空间中的代码可以对硬件操作访问所有的虚拟和物理内存
  • 用户空间中的代码则无法访问所有内存

Android 的双权限模型

  1. Linux 内核层权限模型
    • 基于 用户/用户组 控制文件系统和资源访问(继承自 Linux)。
    • 实现 Android 沙箱,隔离应用进程。
  2. Android 运行时权限模型
    • 由 Dalvik/ART 虚拟机 和框架实现,安装时向用户声明。
    • 通过权限限制应用能力(如摄像头、位置访问)。
    • 映射关系:部分权限直接关联底层 Linux 用户组或权能(如 NET_ADMIN 对应 net_raw 组)。

2.2.1 Android 沙箱

Android 基于 Linux 的 进程隔离最小权限原则 构建沙箱,核心机制包括:

  1. Linux 进程隔离
    • 每个进程运行在独立的用户环境,无法直接访问其他进程内存或发送信号
  2. 唯一用户标识(UID)
    • 大多数应用进程分配唯一 UID,实现权限隔离。
  3. 文件系统权限控制
    • 严格限制文件访问权限(基于 Linux 的 UID/GID 模型)。

Android 特有实现

Android 沙箱通过 UID 隔离文件权限控制 实现进程级安全,结合 AID 机制适配移动端需求,确保应用间资源隔离与系统稳定性

AID(Android ID)

  • 沿用了 Linux 的 UID/GID(用户组ID)权限模型
  • 没有使用传统 Linux passwd/group 文件,而是定义了从名称到独特标识符 Android ID (AID) 的映射表
  • 映射表中包含了一些与特权用户及系统关键用户(如 system用户/用户组) 对应的静态保留条目
  • 保留特定 AID 范围用于系统服务(如 AID_SYSTEM=1000)和隔离进程(如 Chrome 沙箱)。

示例(简化 AID 定义)

#define AID_ROOT     0   // 传统的unix根用户
#define AID_SYSTEM   1000 // 系统服务器
#define AID_APP      10000 // 第一个应用用户

2.2.2 Android 权限模型

Android 权限分为三类,相互关联且可能映射到底层系统权能:

  1. API 权限:API权限用于控制访问高层次的功能,如控制访问=应用访问敏感功能=(如摄像头、位置)。
    1. 一个使用API权限的常见例子是READ_PHONE_STATE---->允许“对手机状态的只读访问,应用若申请该权限,随后就会授予该权限,从而可以调用关于查询手机信息的多种方法
    2. 由于一些API权限与内核级的安全实施机制相对应,例如,被授予INTERNET权限,意味着申请权限应用的UID将会被添加到 inet用户组(GID 3003)的成员中
  2. 文件系统权限:基于 Linux 用户/组控制文件访问。
    1. 应用的唯一 UID 和 GID 都只能访问文件系统上相应的数据存储路径
    2. 相应地,由这些应用创建的文件也会拥有相应的权限设置
    3. 特定的辅助用户组 GID 用于访问共享资源,如 SD卡或其他外部存储器
  3. IPC 权限:限制跨应用或跨进程的组件访问(如禁止外部应用启动私有 Service)。
    1. 用于控制应用组件(如 ActivityService)及系统级 IPC 的交互安全
    2. 与 API 权限的重叠:部分 API 权限(如 INTERNET)可能隐含 IPC 权限需求

权限管理机制

  • 声明:权限在 AndroidManifest.xml 中定义(如 <uses-permission>)。
  • 存储:安装时由 PackageManager 提取权限,记录到 /data/system/packages.xml
  • 应用:进程启动时根据 packages.xml 设置 UID/GID,授予对应权限。

示例packages.xml 中的 Chrome 权限配置):

<package name="com.android.chrome" uid="10086">  
    <uses-permission name="android.permission.INTERNET"/>  
    <uses-permission name="android.permission.ACCESS_NETWORK_STATE"/>  
</package>  

2.3 深入理解各个层次

2.3.1 Android 应用层

Android 应用层通过 签名机制组件化设计 实现安全隔离,预装应用与用户应用权限差异显著,四大组件的 IPC 端点是安全分析的关键切入点。

应用分类

  1. 预装应用
    • 路径:/system/app
    • 来源:谷歌/OEM/运营商(如日历、浏览器)
    • 特点:可能拥有高权限(如 system 用户权限)
  2. 用户安装应用
    • 路径:/data/app
    • 来源:应用市场或手动安装(adb install
    • 签名:开发者私钥签名,防止篡改

密钥与签名

  • 平台密钥:签署预装应用,赋予 system 权限。
  • 开发者密钥:签署第三方应用,确保更新合法性。

主要的应用组件

AndroidManifest.xml
  1. 基础信息
    • 包名(如 com.example.app)、版本号
    • 应用图标、安装位置等配置
  2. 组件声明
    • ActivityServiceBroadcastReceiverContentProvider
  3. 权限管理
    • 声明所需权限(如 <uses-permission>
    • 定义自定义权限(如 <permission>
  4. 共享 UID 机制
    • 相同签名的应用可通过 sharedUserId 共享 UID,实现数据互通
  5. 构建处理
    • 开发工具(如 Android Studio)生成明文 XML,编译时转为二进制格式

IPC通信端点

Intent

Intent 是 Android 组件通信的枢纽,需结合权限与 IntentFilter 设计安全的交互逻辑。

  • 本质
    • 消息对象,用于组件间通信(跨应用/进程),类似轻量级 IPC/RPC。
  • 关键属性
    • 动作(Action):如 ACTION_VIEWACTION_SEND
    • 目标组件(可选)显式指定(包名+类名)或隐式匹配(通过 IntentFilter)。
    • 附加数据键值对形式传递参数(如链接、文本内容)。
  • 权限控制
    • 发送/接收方可声明权限(如 <activity android:permission="com.example.PRIVATE_ACCESS">)。
    • 系统作为参考监视器,在传递时校验权限。
  • 隐式 Intent 匹配
    • 通过 IntentFilter 声明组件能力(如处理 http:// 链接)。
    • 示例:
<activity android:name=".InstallWidgetActivity"  
 android:permission="com.wiley.permission.INSTALL_WIDGET">  
 <intent-filter>  
	 <action android:name="android.intent.action.INSTALL_WIDGET" />  
 </intent-filter>  
</activity>  
Activity
  • 本质
    • 用户界面(UI)组件继承自 Activity 基类,包含窗口和交互元素。
    • ActivityManagerService 统一管理生命周期和调用逻辑。
  • 关键配置(Manifest 声明)
    • launchMode:控制实例化行为(如 singleTask 保证全局唯一实例)。
    • 其他属性:屏幕方向、主题等 UI 相关配置。
  • 安全实践
    • 显式设置 exported 属性(避免未授权外部调用)。
    • 敏感 Activity 应添加权限限制(如 android:permission)。
BroadcastReceiver

BroadcastReceiver 通过权限和注册机制实现安全的广播通信,静态注册适用于持久监听,动态注册提供灵活性但需管理生命周期。

  • 功能
    • 接收系统或应用广播(如短信、电量变化),作为 IPC 端点
  • 注册方式
    • 静态注册:在 AndroidManifest.xml 声明,长期监听(如开机启动)。
    <receiver android:name=".SmsReceiver"  
        android:permission="android.permission.BROADCAST_SMS">  
        <intent-filter>  
            <action android:name="android.provider.Telephony.SMS_RECEIVED" />  
        </intent-filter>  
    </receiver>  
    
    • 动态注册:代码中通过 registerReceiver() 临时监听(需注意生命周期)。
  • 权限控制
    • 发送方限制:通过 sendBroadcast(Intent, String) 指定接收方所需权限。
    • 接收方限制:在 BroadcastReceiver 声明中设置 android:permission
Service

Service 是后台任务和 IPC 的核心组件,通过 IntentBinder 提供功能,需注意生命周期和权限控制以保障安全。

  1. 功能

    • 后台执行任务(无UI),如播放音乐、下载文件。
    • 支持跨进程通信(IPC),通过 IntentBinder 交互。
  2. 声明方式(Manifest)

    <service  
        android:name=".MyService"  
        android:exported="false">  
        <intent-filter>  
            <action android:name="com.example.START_SERVICE" />  
        </intent-filter>  
    </service>  
    
    • exported:控制是否允许外部应用访问(默认值依赖 IntentFilter 存在性)。
  3. 启动方式

    • startService():启动后独立运行(需手动停止)。
    • bindService():绑定后通过 Binder IPC 交互(生命周期与调用方绑定)。
Content Provider

Content Provider 是 Android 数据共享的安全网关,通过权限和 URI 机制控制访问,需结合加密与最小权限原则设计。

  1. 功能

    • 结构化数据共享接口(如联系人、媒体文件),基于 SQLite 或文件系统。
  2. 权限控制

    <provider  
        android:name=".MyProvider"  
        android:authorities="com.example.data"  
        android:readPermission="com.example.READ_DATA"  
        android:writePermission="com.example.WRITE_DATA" />  
    
    • 读写分离:通过 readPermission/writePermission 精细化授权。
    • URI 格式content://[authority]/[path](如 content://com.example.data/contacts)。

2.3.2 Android 框架层

Android 框架层通过系统服务封装核心功能,为应用提供标准化接口,其安全设计基于 权限控制进程隔离,确保资源访问受控。

  • 定位与作用

    • 纽带角色连接应用层与运行时(Dalvik/ART),提供通用功能支持
    • 核心组成
      • 基础类库android.*(如 android.content)、java.*javax.*
      • 第三方库:Apache HTTP 客户端、SAX 解析器等。
  • 关键系统服务(由 system_server 管理)

服务名称 核心功能
Activity管理器 管理应用生命周期、Intent 解析与跳转(如启动 Activity)。
视图系统 控制 UI 渲染与交互(如布局、控件事件)。
程序包管理器 处理应用安装、卸载及权限管理(读取 AndroidManifest.xml)。
电话管理器 提供通话状态、网络信号等蜂窝网络功能接口。
资源管理器 加载非代码资源(如图片、字符串、布局文件)。
位置管理器 集成 GPS/Wi-Fi/基站定位,提供经纬度数据。
通知管理器 管理状态栏通知(声音、震动、LED 提示等)。
  • 安全关联
    • 权限依赖:如位置管理器需 ACCESS_FINE_LOCATION 权限。
    • 进程隔离:服务运行于 system_server,通过 Binder IPC 与应用交互。

DalvikVM 与 Zygote 机制

DalvikVM 通过寄存器架构DEX 优化提升性能
Zygote 通过预加载和 ==fork() ==加速应用启动
二者共同构成 Android 运行时基础,但共享机制可能引入安全风险。

DalvikVM
  1. 与 Java 的区别

    • 基于寄存器架构(非栈式),专为嵌入式设备优化(内存/CPU 受限)。
    • 开发流程:
      Java语法 → .class文件 → Dalvik字节码 → 合并为DEX → 解释执行  
      
    • DEX 优化首次运行时生成 ODEX 文件(设备/版本依赖,不可移植)。
  2. 执行机制

    • 使用约 64,000 个虚拟寄存器(常用前 16-256 个),模拟物理寄存器功能。
    • 通过 JNI 与原生代码交互(如 C/C++)。
Zygote
  1. 启动与优化

    • 设备启动时首个加载的进程,预加载框架核心库(如 android.*)。
    • 进程孵化:通过 fork() 快速派生新进程(如应用进程),共享只读内存,减少重复加载开销。
  2. 关键服务

    • 启动 system_server 进程(运行系统服务,如 ActivityManagerService)。
    • 终止 system_server 会导致 Dalvik 子系统重启(类似软重启)。
  3. 安全影响

    • 共享内存机制可能引发跨进程数据泄露

2.3.4 用户空间原生代码层

这一层主要由两大类组件构成:程序库和核心系统服务。

1. 程序库

Android的底层功能通过共享程序库实现,分为厂商特定库/vendor/lib)和系统通用库/system/lib),主要特点包括:

  • 开源库集成:如SQLite(本地存储)、WebKit(浏览器引擎)、FreeType(字体渲染)等,复用类Unix系统的成熟项目。
  • 关键自定义库
    • Bionic:Android专属的C运行时库,优化内存占用并规避GPL授权问题,但功能较GNU libc更精简,包含自定义动态链接器和线程API。
    • 硬件支持库:如蓝牙(libbluetooth)、音频(libaudioalsa)、XML解析(libexpat)等,通过JNI供上层调用。
  • 安全风险:原生代码开发的库易出现内存破坏漏洞,是安全研究的重点目标。

2. 核心服务

核心服务是Android用户空间的基础,主要包括以下关键组件:

(1)init进程

  • 功能:通过解析/init.rc和硬件特定的/init.[hw].rc文件,初始化用户空间环境,包括:
    • 启动守护进程(如adbddebuggerd)。
    • 设置系统属性和用户权限。
    • 响应事件(如文件系统挂载)。

(2)Property服务

  • 作用:提供持久化的键值对配置存储,影响网络、安全等核心功能。
  • 访问方式
    • 命令行工具:getprop/setprop
    • 编程接口:libcutils原生函数或Java的SystemProperties类。

(3)无线接口层(RIL)

  • 功能管理蜂窝通信(通话、短信、移动数据),是智能手机的核心服务。

(4)调试与崩溃处理

  • debuggerd:捕获原生代码崩溃并生成报告,通过信号处理机制与链接器协作。
  • ADB(Android调试桥)
    • 包含设备端守护进程adbd和主机端服务,支持Shell访问、应用调试、文件传输等。
    • 默认监听5037端口,是开发与逆向分析的关键工具。

(5)Volume守护进程(vold)

  • 功能管理存储设备(如SD卡)的挂载/卸载,处理加密容器(ASEC/OBB)。
  • 风险:以root权限运行,历史上是特权提升漏洞的高发点。

(6)其他服务

  • 厂商定制服务:如HTC、三星等设备的特有服务,代码质量参差不齐,可能引入额外攻击面。

2.3.5 Android内核

Android基于Linux内核,但进行了多项关键修改以适配移动设备需求,包括IPC机制内存管理安全增强。以下是核心变更点:

1. Binder IPC机制

  • 作用:Android的核心IPC框架,支持跨进程通信(如应用与系统服务交互)。
  • 关键特性
    • 客户端-服务器模型:抽象为本地方法调用(类似RPC)。
    • 权限控制:通过Binder.getCallingUid()checkCallingPermission()验证调用方身份。
    • AIDL接口:定义标准化IPC接口(示例:IRemoteService)。
  • 安全意义:权限检查依赖调用方UID,漏洞可能导致越权访问(如ACCESS_SURFACE_FLINGER权限滥用)。

2. 内存管理驱动

  • ashmem(匿名共享内存)
    • 功能:提供基于文件的共享内存,支持动态回收(低内存时自动释放)。
    • 应用场景:Surface Flinger、AudioFlinger等核心组件。
  • pmem(物理连续内存)
    • 用途分配大块物理连续内存(供GPU等硬件使用)。
    • 限制:需显式管理文件描述符生命周期。

3. 日志系统(Logger驱动)

  • 多缓冲区设计
    • main(应用日志)、system(系统事件)、radio(基带模块)、events(低层事件)。
  • 访问方式
    • 应用层:通过android.util.Log类记录(如Log.i())。
    • 命令行adb logcat或直接运行logcat
  • 安全用途:监控系统行为,但敏感信息可能泄露(需过滤日志输出)。

4. 网络访问控制(Paranoid Networking)

  • 机制:基于GID限制网络操作,权限与Manifest声明绑定:
    • 例如:INTERNET权限映射到GID 3003(AID_INET)。
  • 配置文件
    • 内核头文件:include/linux/androidaid.h
    • AOSP定义:android_filesystem_config.h

进一步阅读

  • AOSP文档(system/core/include/
  • Linux内核源码(drivers/staging/android/

3 ROOT

  • 在Android设备上获得超级用户权限的过程通常被称为root
  • 这个特殊账号拥有对类UNIX系统上所有文件与程序的权限,能够对操作系统进行完全控制。
  • root设备还允许用户卸载预装应用,执行完整的系统备份和恢复,或安装定制内核映像与模块
  • 此外,有一类应用需要 root权限才能运行,这些应用通常称为 root app。包括基于 IPTables 的防火墙软件、广告拦截软件、超频软件及支持设置上网热点(Tethering)的应用等
  • root设备将会损害设备的安全性。一个原因是所有用户数据都将暴露给被授予root权限的应用

3.1 理解 Android 分区布局

1. 分区定义与作用

分区是设备持久性存储中的逻辑存储单元,布局定义了分区的顺序、偏移量和尺寸。
不同设备的分区布局因硬件平台和厂商定制存在差异,但核心分区具有通用性


2. 核心分区详解

(1) Bootloader 分区

  • 作用存储引导加载程序(如 U-Boot),负责硬件初始化内核加载启动模式选择(如 fastboot、recovery)。
  • 特点:厂商通常加密此分区,若损坏可能导致设备变砖。

(2) Boot 分区

  • 内容:包含 Linux 内核(zImage 或 Image)和初始 RAM 磁盘(initrd),用于启动 Android 主系统
  • 动态变化:Android 13 引入 init_boot 分区,分离通用 ramdisk,优化启动流程。

(3) Recovery 分区

  • 功能:独立的最小化 Android 系统,用于系统恢复OTA 升级工厂重置。支持自定义 Recovery(如 TWRP)。

(4) System 分区

  • 内容存放 Android 框架、系统应用和核心库(如 /system/app, /system/lib)。
  • 动态分区化:Android 10+ 中可能被纳入 super 动态分区,支持灵活调整大小。

(5) Data 分区

  • 作用:存储用户数据(应用、媒体文件)和动态配置(如 /data/app, /data/data)。
  • 加密机制:支持 FBE(基于文件的加密)和 FDE(全盘加密)。

(6) Cache 分区

  • 用途:==临时存储 ==OTA 包、日志等,可擦除且不影响系统功能。动态分区设备中可能被弱化。

(7) Vendor 分区

  • 内容厂商专有组件(如 HAL 驱动、闭源固件),与芯片硬件强关联。
  • 模块化:与 odm(设备制造商定制)和 product(产品线定制)分区协同,实现分层解耦。

(8) Radio 分区

  • 功能:存储基带固件(Modem),管理通信模块(如 4G/5G、Wi-Fi)。仅存在于支持通话的设备。

3. 扩展分区与新技术

(1) 动态分区(Super 分区)

  • 机制:Android 10+ 引入,将 systemvendor 等分区整合为逻辑子分区,支持 OTA 时动态调整大小
  • 优势:消除预留空间浪费,提升存储利用率。

(2) Metadata 分区

  • 作用:存储动态分区的元数据(lp_metadata)和加密密钥。大小为 16MB+,未加密但受 AVB 保护。

(3) Virtual A/B 分区

  • 特点:Android 11+ 支持,实现无缝更新,通过共享数据块减少空间占用,升级过程对用户透明。

(4) Misc 分区

  • 用途存储 Bootloader 控制块(BCB),决定启动模式(主系统或 Recovery)。

4. 分区布局管理

  • Bootloader 主导:多数设备由 Bootloader 解析分区表(如 GPT)。
  • 内核参与:动态分区通过 Linux device-mapper 驱动实现逻辑映射,用户空间工具(如 lpmake)生成 super.img
  • 厂商定制:通过 BoardConfig.mk 定义分区大小和类型(如 BOARD_SYSTEMIMAGE_PARTITION_SIZE)。

3.2 理解 Android 引导过程

1. 引导加载程序(Bootloader)的核心功能

引导加载程序是设备开机后运行的首个代码模块,负责底层硬件初始化启动操作系统。其核心功能包括:

  • 硬件初始化:设置时钟、RAM、存储介质等基础硬件(如通过BootROM加载Bootloader);
  • 操作系统引导:从存储介质中加载Android内核和initrd到RAM,并移交控制权;
  • 模式切换支持:支持进入下载模式(如fastboot/ODIN)、恢复模式等特殊启动模式;
  • 安全验证:通过签名验证(Secure Boot)确保固件合法性,防止恶意篡改。

厂商差异:不同厂商的Bootloader实现不同。例如:

  • 高通设备通过fastboot flashing unlock解锁;
  • 三星使用ODIN协议刷机;
  • 联发科(MTK)通过音量键进入强制下载模式。

2. 内核启动与初始化流程

Linux内核启动后完成以下关键任务:

  • 硬件驱动加载初始化CPU调度器、内存管理、中断控制器等;
  • 文件系统挂载临时挂载initrd为可写根文件系统(如tmpfsproc);
  • 启动init进程作为用户空间首个进程(PID=1),执行/system/core/init/main.cppmain()入口。

关键阶段

  1. FirstStageMain:创建基础目录(如/dev/proc),挂载临时文件系统;
  2. SetupSelinux:初始化安全策略;
  3. SecondStageMain:加载属性服务、解析init.rc脚本。

3. init进程与init.rc脚本解析

(1) init.rc的核心结构

  • Action:定义触发条件(如on booton property:ro.debuggable=1)及执行命令;
  • Service:启动守护进程(如zygoteservicemanager),配置重启策略(如oneshotdisabled);
  • Command:包含文件操作(mountchmod)、服务管理(startstop)等指令。

(2) 关键服务启动顺序

  1. Zygote:通过service zygote启动,预加载Java类库,孵化应用进程
  2. System Server由Zygote fork而来,启动AMS、PMS等核心服务;
  3. SurfaceFlinger/MediaServer:处理图形渲染与多媒体功能。

4. 系统启动完成与广播事件

  • BOOT_COMPLETED广播通知应用系统启动完成,需在Manifest中声明RECEIVE_BOOT_COMPLETED权限;
  • 用户空间初始化:完成Launcher启动、后台服务加载后进入交互状态。

5. 下载模式与刷机协议

(1) 进入下载模式的方法

  • 按键组合:如三星长按音量下+电源进入ODIN模式,小米音量下+电源进入fastboot;
  • ADB命令adb reboot bootloader或厂商专用指令(如高通adb reboot edl)。

(2) 刷机协议类型

  • Fastboot:通用协议,通过fastboot flash刷入分区镜像;
  • ODIN:三星专有协议,支持.tar格式固件包;
  • SPRD/UFS:展讯平台专用模式,需短接特定GPIO。

安全限制:多数厂商默认锁定Bootloader,需官方工具解锁(如小米需开发者账号审核)。


6. 动态分区与fastbootd(Android 10+)

  • Super分区:整合systemvendor等逻辑分区,支持OTA动态调整大小;
  • fastbootd:在Recovery中实现用户态刷机,复用系统驱动提升兼容性。
posted @ 2025-04-24 14:45  方北七  阅读(195)  评论(0)    收藏  举报