# 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>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hacktricks.xsx.tw/mobile-pentesting/android-app-pentesting/android-applications-basics.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
