> For the complete documentation index, see [llms.txt](https://hacktricks.xsx.tw/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hacktricks.xsx.tw/mobile-pentesting/android-app-pentesting/android-applications-basics.md).

# Android Applications Basics

<details>

<summary><strong>从零开始学习AWS黑客技术，成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE（HackTricks AWS红队专家）</strong></a><strong>！</strong></summary>

支持HackTricks的其他方式：

* 如果您想看到您的**公司在HackTricks中做广告**或**下载PDF格式的HackTricks**，请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取[**官方PEASS和HackTricks周边产品**](https://peass.creator-spring.com)
* 探索[**PEASS家族**](https://opensea.io/collection/the-peass-family)，我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)
* **加入** 💬 [**Discord群**](https://discord.gg/hRep4RUj7f) 或 [**电报群**](https://t.me/peass) 或在**Twitter**上关注我们 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**。**
* **通过向** [**HackTricks**](https://github.com/carlospolop/hacktricks) 和 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) **github仓库提交PR来分享您的黑客技巧。**

</details>

**Try Hard Security Group**

<figure><img src="/files/Kw46fTSYxPIOMyKySfL5" alt=""><figcaption></figcaption></figure>

{% embed url="<https://discord.gg/tryhardsecurity>" %}

***

## Android安全模型

**有两个层次：**

* **操作系统（OS）**，将安装的应用程序相互隔离。
* **应用程序本身**，允许开发人员**公开某些功能**并配置应用程序功能。

### UID分离

**每个应用程序被分配一个特定的用户ID**。这是在应用程序安装期间完成的，因此**应用程序只能与其用户ID拥有的文件或共享文件进行交互**。因此，只有应用程序本身、操作系统的某些组件和根用户可以访问应用程序的数据。

### UID共享

**两个应用程序可以配置为使用相同的UID**。这可能有助于共享信息，但如果其中一个受到损害，则两个应用程序的数据将受到损害。这就是为什么**不鼓励**这种行为。\
**要共享相同的UID，应用程序必须在其清单中定义相同的`android:sharedUserId`值。**

### 沙箱

**Android应用程序沙箱**允许将**每个应用程序**作为**单独的进程在单独的用户ID下运行**。每个进程都有自己的虚拟机，因此应用程序的代码在与其他应用程序隔离的环境中运行。\
从Android 5.0（L）开始，**SELinux**被强制执行。基本上，SELinux拒绝了所有进程交互，然后创建策略**仅允许它们之间的预期交互**。

### 权限

当您安装一个**应用程序并请求权限**时，该应用程序正在请求在**AndroidManifest.xml**文件中配置的\*\*`uses-permission`**元素中配置的权限。uses-permission元素指示请求的权限的名称在**name\*\* **属性**中。它还具有**maxSdkVersion**属性，该属性在高于指定版本的版本上停止请求权限。\
请注意，Android应用程序不需要一开始就请求所有权限，它们也可以**动态请求权限**，但所有权限必须在**清单中声明**。

当应用程序公开功能时，它可以限制**仅允许具有指定权限的应用程序访问**。\
权限元素具有三个属性：

* 权限的**名称**
* **permission-group**属性，允许对相关权限进行分组。
* **protection-level**，指示权限如何授予。有四种类型：
* **Normal**：当应用程序**没有已知威胁**时使用。用户**无需批准**。
* **Dangerous**：指示权限授予请求应用程序一些**提升的访问权限**。**用户被要求批准**。
* **Signature**：只有**由与导出组件相同的证书签名的应用程序**可以被授予权限。这是最强大的保护类型。
* **SignatureOrSystem**：只有**由与导出组件相同的证书签名的应用程序**或**以系统级访问权限运行的应用程序**可以被授予权限。

## 预安装应用程序

这些应用程序通常位于\*\*`/system/app`**或**`/system/priv-app`**目录中，其中一些应用程序是**经过优化的\*\*（您可能甚至找不到`classes.dex`文件）。这些应用程序值得检查，因为有时它们以**root权限运行**。

* 与**AOSP**（Android开源项目）**ROM**一起提供的应用程序
* 设备**制造商**添加的应用程序
* 手机提供商添加的应用程序（如果从他们那里购买）

## Rooting

为了在物理Android设备上获得root访问权限，通常需要**利用**1或2个**漏洞**，这些漏洞通常是**特定于**设备和**版本**的。\
一旦利用成功，通常会将Linux `su`二进制文件复制到用户的PATH环境变量中指定的位置，如`/system/xbin`。

配置su二进制文件后，另一个Android应用程序用于与`su`二进制文件进行交互，并**处理对root访问的请求**，如**Superuser**和**SuperSU**（在Google Play商店中可用）。

{% hint style="danger" %}
请注意，root过程非常危险，可能会严重损坏设备
{% endhint %}

### ROM

可以通过**安装自定义固件**来**替换操作系统**。这样做可以扩展旧设备的用途，绕过软件限制或访问最新的Android代码。\
**OmniROM**和**LineageOS**是两种最受欢迎的固件。

请注意，**并非总是需要对设备进行root处理**才能安装自定义固件。**一些制造商允许**以文件记录和安全的方式解锁其引导加载程序。

### 影响

一旦设备被root，任何应用程序都可以请求以root权限访问。如果恶意应用程序获得了这一权限，它将可以访问几乎所有内容，并且可以损坏手机。

## Android应用程序基础知识 <a href="#id-2-android-application-fundamentals" id="id-2-android-application-fundamentals"></a>

* Android应用程序的格式称为\_APK文件格式\_。它本质上是一个**ZIP文件**（通过将文件扩展名更改为.zip，可以提取和查看内容）。
* APK内容（不详尽）
* **AndroidManifest.xml**
* resources.arsc/strings.xml
* resources.arsc：包含预编译资源，如二进制XML。
* res/xml/files\_paths.xml
* META-INF/
* 这是证书的位置！
* **classes.dex**
* 包含Dalvik字节码，表示应用程序默认执行的编译Java（或Kotlin）代码。
* lib/
* 包含本机库，按CPU架构在子目录中分隔。
* `armeabi`：用于基于ARM的处理器的代码
* `armeabi-v7a`：用于基于ARMv7及更高版本的处理器的代码
* `x86`：用于X86处理器的代码
* `mips`：仅用于MIPS处理器的代码
* assets/
* 存储应用程序需要的各种文件，可能包括其他本机库或DEX文件，有时被恶意软件作者用于隐藏其他代码。
* res/
* 包含未编译为resources.arsc的资源

### **Dalvik & Smali**

在Android开发中，使用**Java或Kotlin**来创建应用程序。Android将此代码编译为**Dalvik Executable (DEX) bytecode**，而不是像桌面应用程序那样使用JVM。以前，Dalvik虚拟机处理这些字节码，但现在，在较新的Android版本中，Android Runtime (ART)接管了这一任务。

对于逆向工程，**Smali**变得至关重要。它是DEX bytecode的可读版本，类似于汇编语言，通过将源代码转换为字节码指令来实现。在这个上下文中，Smali和baksmali是指汇编和反汇编工具。

## 意图

意图是Android应用程序在其组件之间或与其他应用程序之间进行通信的主要手段。这些消息对象还可以在应用程序或组件之间传递数据，类似于HTTP通信中使用GET/POST请求的方式。

因此，Intent基本上是**在组件之间传递的消息**。Intent **可以定向**到特定组件或应用程序，**也可以发送给没有特定接收方的情况**。\
简单来说，Intent可以用于：

* 启动Activity，通常打开应用程序的用户界面
* 作为广播通知系统和应用程序的更改
* 启动、停止和与后台服务通信
* 通过ContentProviders访问数据
* 作为回调来处理事件

如果存在漏洞，**Intent可以用于执行各种攻击**。

### 意图过滤器

**Intent Filters**定义了**活动、服务或广播接收器如何与不同类型的Intent交互**。本质上，它们描述了这些组件的功能，例如它们可以执行哪些操作或可以处理哪些广播。声明这些过滤器的主要位置是在**AndroidManifest.xml文件**中，尽管对于广播接收器，也可以通过编码来实现。

Intent Filters由类别、操作和数据过滤器组成，并可以包含附加元数据。这种设置允许组件处理符合声明标准的特定Intent。

Android组件（活动/服务/内容提供程序/广播接收器）的一个关键方面是它们的可见性或**公共状态**。如果组件被设置为\*\*`exported`**且值为**`true`**，或者在清单中为其声明了Intent Filter，那么该组件被视为公共组件，可以与其他应用程序进行交互。然而，开发人员可以通过在其清单定义中将**`exported`**属性设置为**`false`\*\*来明确将这些组件保持私有，确保它们不会无意中与其他应用程序交互。

此外，开发人员可以通过要求特定权限来进一步保护对这些组件的访问。\*\*`permission`\*\*属性可以设置为强制只有具有指定权限的应用程序才能访问组件，从而增加一层安全性和控制，以确定谁可以与其交互。

```java
<activity android:name=".MyActivity" android:exported="false">
<!-- Intent filters go here -->
</activity>
```

### 隐式意图

意图是使用 Intent 构造函数在程序中创建的：

```java
Intent email = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));
```

**Action**之前声明的意图是**ACTION\_SEND**，**Extra**是一个mailto **Uri**（Extra是意图期望的额外信息）。

这个意图应该在清单文件中声明，就像以下示例中所示：

```xml
<activity android:name="ShareActivity">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
```

一个 intent-filter 需要匹配 **action**、**data** 和 **category** 才能接收消息。

"Intent resolution" 过程确定哪个应用程序应该接收每条消息。此过程考虑 **priority attribute**，该属性可以在 **intent-filter declaration** 中设置，**优先级较高的将被选择**。此优先级可以设置在 -1000 到 1000 之间，应用程序可以使用 `SYSTEM_HIGH_PRIORITY` 值。如果出现 **冲突**，将出现一个“选择器”窗口，以便 **用户可以决定**。

### 显式 Intent

显式 intent 指定了它所针对的类名：

```java
Intent downloadIntent = new (this, DownloadService.class):
```

在其他应用程序中，为了访问先前声明的意图，您可以使用：

```java
Intent intent = new Intent();
intent.setClassName("com.other.app", "com.other.app.ServiceName");
context.startService(intent);
```

### 挂起意图

这允许其他应用程序**代表您的应用程序执行操作**，使用您应用程序的身份和权限。构造挂起意图时，应该**指定一个意图和要执行的操作**。如果**声明的意图不是显式的**（没有声明哪个意图可以调用它），**恶意应用程序可以代表受害者应用程序执行声明的操作**。此外，**如果未指定操作**，恶意应用程序将能够**代表受害者执行任何操作**。

### 广播意图

与之前的意图不同，广播意图**可以被多个应用程序接收**。但是，从 API 版本 14 开始，可以使用 Intent.set Package 来**指定应该接收消息的应用程序**。

另外，**在发送广播时也可以指定权限**。接收应用程序将需要拥有该权限。

有**两种**广播：**普通**（异步）和**有序**（同步）。**顺序**基于**接收器内配置的优先级**。**每个应用程序可以处理、中继或丢弃广播**。

可以使用 `Context` 类中的 `sendBroadcast(intent, receiverPermission)` 函数**发送**广播。\
您还可以使用\*\*`LocalBroadCastManager`**中的**`sendBroadcast`**函数，确保**消息永远不会离开应用程序\*\*。使用这种方式，甚至不需要导出接收器组件。

### 粘性广播

这种广播**可以在发送后很长时间后访问**。\
这在 API 级别 21 中已被弃用，建议**不要使用它们**。\
**它们允许任何应用程序嗅探数据，但也可以修改数据**。

如果发现包含单词“粘性”的函数，如\*\*`sendStickyBroadcast`**或**`sendStickyBroadcastAsUser`\*\*，**检查影响并尝试删除它们**。

## 深层链接 / URL 方案

在 Android 应用程序中，**深层链接**用于通过 URL 直接启动操作（意图）。这是通过在活动中声明特定的**URL 方案**来完成的。当 Android 设备尝试**访问具有此方案的 URL**时，将启动应用程序中指定的活动。

该方案必须在\*\*`AndroidManifest.xml`\*\*文件中声明：

```xml
[...]
<activity android:name=".MyActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="examplescheme" />
</intent-filter>
[...]
```

前面示例中的scheme是`exampleapp://`（还要注意\*\*`category BROWSABLE`\*\*）

然后，在数据字段中，您可以指定**主机**和**路径**：

```xml
<data android:scheme="examplescheme"
android:host="example"
/>
```

要从网络访问它，可以设置一个链接，如下所示：

```xml
<a href="examplescheme://example/something">click here</a>
<a href="examplescheme://example/javascript://%250dalert(1)">click here</a>
```

要找到在应用程序中将执行的**代码**，请转到由深度链接调用的活动，并搜索函数\*\*`onNewIntent`\*\*。

了解如何[在不使用HTML页面的情况下调用深度链接](/mobile-pentesting/android-app-pentesting.md#exploiting-schemes-deep-links)。

## AIDL - Android接口定义语言

**Android接口定义语言（AIDL）旨在通过进程间通信**（IPC）在Android应用程序中促进客户端和服务之间的通信。由于在Android上不允许直接访问另一个进程的内存，AIDL通过将对象编组成操作系统理解的格式来简化该过程，从而简化了跨不同进程的通信。

### 关键概念

* **绑定服务**：这些服务利用AIDL进行IPC，使活动或组件能够绑定到服务，发出请求并接收响应。服务类中的`onBind`方法对于启动交互至关重要，因此在寻找漏洞时，这是一个重要的安全审查领域。
* **Messenger**：作为绑定服务运行，Messenger便于通过`onBind`方法处理数据的IPC。必须仔细检查此方法，以查找任何不安全的数据处理或执行敏感功能。
* **Binder**：尽管由于AIDL的抽象性，直接使用Binder类较少见，但了解Binder充当内核级驱动程序，促进不同进程的内存空间之间的数据传输是有益的。为了进一步了解，可以参考<https://www.youtube.com/watch?v=O-UHvFjxwZ8>。

## 组件

这些包括：**活动、服务、广播接收器和提供程序。**

### 启动器活动和其他活动

在Android应用中，**活动**就像屏幕，显示应用程序用户界面的不同部分。一个应用可以有许多活动，每个活动向用户呈现一个独特的屏幕。

**启动器活动**是应用程序的主要入口，当您点击应用程序图标时启动。它在应用程序清单文件中定义，具有特定的MAIN和LAUNCHER意图：

```markup
<activity android:name=".LauncherActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
```

并非所有应用程序都需要启动器活动，特别是那些没有用户界面的后台服务。

通过在清单中将活动标记为“exported”，可以使其对其他应用程序或进程可用。此设置允许其他应用程序启动此活动：

```markdown
<service android:name=".ExampleExportedService" android:exported="true"/>
```

然而，从另一个应用访问活动并不总是安全风险。如果敏感数据被不当共享，可能会导致信息泄露。

活动的生命周期**始于onCreate方法**，设置用户界面并准备与用户交互的活动。

### 应用程序子类

在Android开发中，应用程序有选项创建[Application](https://developer.android.com/reference/android/app/Application)类的**子类**，尽管这并非强制要求。当定义了这样的子类时，它将成为应用程序中首个被实例化的类。如果在此子类中实现了\*\*`attachBaseContext`**方法，则会在**`onCreate`\*\*方法之前执行。这种设置允许在应用程序的其余部分启动之前进行早期初始化。

```java
public class MyApp extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
// Initialization code here
}

@Override
public void onCreate() {
super.onCreate();
// More initialization code
}
}
```

### 服务

[服务](https://developer.android.com/guide/components/services)是能够在没有用户界面的情况下执行任务的**后台操作者**。这些任务可以在用户切换到不同应用程序时继续运行，因此服务对于**长时间运行的操作**至关重要。

服务具有多种用途；它们可以通过各种方式启动，其中\*\*意图（Intents）\*\*是启动服务的主要方法，作为应用程序的入口点。一旦使用`startService`方法启动服务，其`onStart`方法就会开始运行，并持续运行，直到显式调用`stopService`方法。或者，如果服务的作用取决于活动客户端连接，则使用`bindService`方法将客户端绑定到服务，通过`onBind`方法进行数据传递。

服务的一个有趣应用包括在后台播放音乐或获取网络数据，而不会影响用户与应用程序的交互。此外，服务可以通过**导出**使其他设备上的进程可以访问。这不是默认行为，需要在Android清单文件中进行显式配置：

```xml
<service android:name=".ExampleExportedService" android:exported="true"/>
```

### 广播接收器

**广播接收器** 在消息系统中充当监听器，允许多个应用程序响应来自系统的相同消息。应用程序可以通过应用程序的**清单**或通过\*\*`registerReceiver`\*\* API在应用程序代码中**动态注册接收器**的**两种主要方式**来**注册接收器**。在清单中，广播通过权限进行过滤，而动态注册的接收器在注册时也可以指定权限。

**意图过滤器** 在两种注册方法中都至关重要，确定哪些广播会触发接收器。一旦发送匹配的广播，接收器的\*\*`onReceive`\*\*方法将被调用，使应用程序能够做出相应反应，例如根据低电量警报调整行为。

广播可以是**异步**的，无序地到达所有接收器，也可以是**同步**的，其中接收器根据设置的优先级获取广播。然而，需要注意潜在的安全风险，因为任何应用程序都可以将自己优先级提高以拦截广播。

要了解接收器的功能，请查找其类中的\*\*`onReceive`**方法。该方法的代码可以操作接收到的意图，突出了接收器进行数据验证的必要性，特别是在**有序广播\*\*中，这种广播可以修改或丢弃意图。

### 内容提供程序

**内容提供程序** 对于在应用程序之间**共享结构化数据**至关重要，强调了实施**权限**以确保数据安全的重要性。它们允许应用程序从各种来源访问数据，包括数据库、文件系统或网络。控制访问的关键权限，如\*\*`readPermission`**和**`writePermission`**至关重要。此外，可以通过应用程序清单中的**`grantUriPermission`\*\*设置临时访问权限，利用`path`、`pathPrefix`和`pathPattern`等属性进行详细的访问控制。

输入验证至关重要，以防止漏洞，如SQL注入。内容提供程序支持基本操作：`insert()`、`update()`、`delete()`和`query()`，促进数据操作和在应用程序之间共享数据。

**FileProvider**，一种专门的内容提供程序，专注于安全共享文件。它在应用程序的清单中定义，具有特定属性来控制对文件夹的访问，由`android:exported`和`android:resource`指向文件夹配置。在共享目录时要谨慎，以避免意外暴露敏感数据。

FileProvider的示例清单声明：

```xml
<provider android:name="androidx.core.content.FileProvider"
android:authorities="com.example.myapp.fileprovider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
```

并在 `filepaths.xml` 中指定共享文件夹的示例：

```xml
<paths>
<files-path path="images/" name="myimages" />
</paths>
```

## WebViews

WebViews就像Android应用内的**迷你浏览器**，可以从网络或本地文件中获取内容。它们面临与常规浏览器类似的风险，但可以通过特定的**设置**来**减少这些风险**。

Android提供了两种主要的WebView类型：

* **WebViewClient**非常适合基本的HTML，但不支持JavaScript警报功能，影响了XSS攻击的测试方式。
* **WebChromeClient**更像完整的Chrome浏览器体验。

一个关键点是，WebView浏览器**不会与设备的主要浏览器共享cookie**。

用于加载内容的方法包括`loadUrl`, `loadData`, 和 `loadDataWithBaseURL`。确保这些URL或文件**安全可用**至关重要。安全设置可以通过`WebSettings`类进行管理。例如，使用`setJavaScriptEnabled(false)`禁用JavaScript可以防止XSS攻击。

JavaScript“桥梁”允许Java对象与JavaScript交互，需要在Android 4.2及更高版本中使用`@JavascriptInterface`标记方法以确保安全性。

允许内容访问（`setAllowContentAccess(true)`）允许WebViews访问内容提供程序，这可能存在风险，除非内容URL经过验证为安全。

控制文件访问：

* 禁用文件访问（`setAllowFileAccess(false)`）限制对文件系统的访问，某些资产除外，确保它们仅用于非敏感内容。

## 其他应用组件和移动设备管理

### **应用程序的数字签名**

* 对于Android应用程序，**数字签名**是必不可少的，确保在安装之前它们是**真实授权**的。这个过程使用应用程序标识的证书，并且必须在设备的包管理器上安装时进行验证。应用程序可以是**自签名的或由外部CA认证**，防止未经授权的访问，并确保应用程序在传递到设备过程中保持不被篡改。

### **增强安全性的应用程序验证**

* 从**Android 4.2**开始，一个名为**验证应用程序**的功能允许用户在安装之前检查应用程序的安全性。这个**验证过程**可以警告用户可能有害的应用程序，甚至阻止特别恶意应用程序的安装，增强用户安全性。

### **移动设备管理（MDM）**

* **MDM解决方案**通过**设备管理API**为移动设备提供**监督和安全性**。它们需要安装一个Android应用程序来有效管理和保护移动设备。关键功能包括**强制密码策略**，**强制存储加密**，和**允许远程数据擦除**，确保对移动设备拥有全面的控制和安全性。

```java
// Example of enforcing a password policy with MDM
DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
ComponentName adminComponent = new ComponentName(context, AdminReceiver.class);

if (dpm.isAdminActive(adminComponent)) {
// Set minimum password length
dpm.setPasswordMinimumLength(adminComponent, 8);
}
```

**尝试困难安全团队**

<figure><img src="/files/Kw46fTSYxPIOMyKySfL5" alt=""><figcaption></figcaption></figure>

{% embed url="<https://discord.gg/tryhardsecurity>" %}

<details>

<summary><strong>从零开始学习AWS黑客技术，成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE（HackTricks AWS红队专家）</strong></a><strong>！</strong></summary>

支持HackTricks的其他方式：

* 如果您想在HackTricks中看到您的**公司广告**或**下载PDF格式的HackTricks**，请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取[**官方PEASS & HackTricks周边产品**](https://peass.creator-spring.com)
* 发现[**PEASS家族**](https://opensea.io/collection/the-peass-family)，我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)收藏品
* **加入** 💬 [**Discord团队**](https://discord.gg/hRep4RUj7f) 或 [**telegram团队**](https://t.me/peass) 或在**Twitter**上关注我们 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**。**
* 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。

</details>
