mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/mobile-pentesting/android-app-pentesting/android-applic
This commit is contained in:
parent
0cf3dda593
commit
61c4ddd579
@ -11,37 +11,37 @@
|
|||||||
|
|
||||||
### UID Separation
|
### UID Separation
|
||||||
|
|
||||||
**每个应用程序被分配一个特定的用户ID**。这在应用程序安装时完成,因此**该应用程序只能与其用户ID拥有的文件或共享文件进行交互**。因此,只有应用程序本身、操作系统的某些组件和根用户可以访问应用程序的数据。
|
**每个应用程序被分配一个特定的用户ID**。这在应用程序安装时完成,因此**应用程序只能与其用户ID拥有的文件或共享文件进行交互**。因此,只有应用程序本身、操作系统的某些组件和根用户可以访问应用程序的数据。
|
||||||
|
|
||||||
### UID Sharing
|
### UID Sharing
|
||||||
|
|
||||||
**两个应用程序可以配置为使用相同的UID**。这可以用于共享信息,但如果其中一个被攻破,则两个应用程序的数据都会受到影响。这就是为什么这种行为是**不鼓励**的。\
|
**两个应用程序可以配置为使用相同的UID**。这可以用于共享信息,但如果其中一个被攻破,两个应用程序的数据都会受到影响。这就是为什么这种行为**不被鼓励**。\
|
||||||
**要共享相同的UID,应用程序必须在其清单中定义相同的 `android:sharedUserId` 值。**
|
**要共享相同的UID,应用程序必须在其清单中定义相同的 `android:sharedUserId` 值。**
|
||||||
|
|
||||||
### Sandboxing
|
### Sandboxing
|
||||||
|
|
||||||
**Android应用程序沙箱**允许**每个应用程序**作为**在单独用户ID下的单独进程**运行。每个进程都有自己的虚拟机,因此应用程序的代码在与其他应用程序隔离的情况下运行。\
|
**Android应用程序沙箱**允许**每个应用程序**作为**在单独用户ID下的单独进程**运行。每个进程都有自己的虚拟机,因此应用程序的代码与其他应用程序隔离运行。\
|
||||||
从Android 5.0(L)开始,**SELinux**被强制执行。基本上,SELinux拒绝所有进程交互,然后创建策略以**仅允许它们之间的预期交互**。
|
从Android 5.0(L)开始,**SELinux**被强制执行。基本上,SELinux拒绝所有进程交互,然后创建策略以**仅允许它们之间的预期交互**。
|
||||||
|
|
||||||
### Permissions
|
### Permissions
|
||||||
|
|
||||||
当你安装一个**应用程序并请求权限**时,该应用程序是在请求**AndroidManifest.xml**文件中配置的**`uses-permission`**元素中的权限。**uses-permission**元素在**name**属性中指示请求的权限名称。它还有**maxSdkVersion**属性,该属性在版本高于指定版本时停止请求权限。\
|
当你安装一个**应用程序并请求权限**时,应用程序是在请求**AndroidManifest.xml**文件中配置的**`uses-permission`**元素中的权限。**uses-permission**元素在**name**属性中指示请求的权限名称。它还有**maxSdkVersion**属性,该属性在版本高于指定版本时停止请求权限。\
|
||||||
请注意,Android应用程序不需要在开始时请求所有权限,它们也可以**动态请求权限**,但所有权限必须在**清单**中**声明**。
|
请注意,Android应用程序不需要在开始时请求所有权限,它们也可以**动态请求权限**,但所有权限必须在**清单中声明**。
|
||||||
|
|
||||||
当一个应用程序暴露功能时,它可以限制**仅允许具有指定权限的应用程序访问**。\
|
当应用程序暴露功能时,它可以限制**仅允许具有指定权限的应用程序访问**。\
|
||||||
权限元素有三个属性:
|
权限元素有三个属性:
|
||||||
|
|
||||||
- 权限的**名称**
|
- 权限的**名称**
|
||||||
- **permission-group**属性,允许对相关权限进行分组。
|
- **permission-group**属性,允许对相关权限进行分组。
|
||||||
- **protection-level**,指示权限的授予方式。共有四种类型:
|
- **protection-level**,指示权限的授予方式。共有四种类型:
|
||||||
- **Normal**:用于当应用程序**没有已知威胁**时。用户**不需要批准**它。
|
- **Normal**:在没有**已知威胁**的情况下使用。用户**不需要批准**。
|
||||||
- **Dangerous**:指示权限授予请求应用程序某些**提升的访问权限**。**用户被要求批准它们**。
|
- **Dangerous**:指示权限授予请求应用程序某些**提升的访问权限**。**请求用户批准**。
|
||||||
- **Signature**:只有**由与导出组件相同证书签名的应用程序**才能获得权限。这是最强的保护类型。
|
- **Signature**:只有**由与导出组件相同证书签名的应用程序**才能获得权限。这是最强的保护类型。
|
||||||
- **SignatureOrSystem**:只有**由与导出组件相同证书签名的应用程序**或**以系统级访问权限运行的应用程序**才能获得权限。
|
- **SignatureOrSystem**:只有**由与导出组件相同证书签名的应用程序**或**以系统级访问权限运行的应用程序**才能获得权限。
|
||||||
|
|
||||||
## Pre-Installed Applications
|
## Pre-Installed Applications
|
||||||
|
|
||||||
这些应用程序通常位于**`/system/app`**或**`/system/priv-app`**目录中,其中一些是**优化过的**(你可能甚至找不到 `classes.dex` 文件)。这些应用程序值得检查,因为有时它们**运行的权限过多**(作为root)。
|
这些应用程序通常位于**`/system/app`**或**`/system/priv-app`**目录中,其中一些是**优化过的**(你可能甚至找不到`classes.dex`文件)。这些应用程序值得检查,因为有时它们**运行的权限过多**(作为root)。
|
||||||
|
|
||||||
- 随**AOSP**(Android开源项目)**ROM**一起提供的应用程序
|
- 随**AOSP**(Android开源项目)**ROM**一起提供的应用程序
|
||||||
- 由设备**制造商**添加的
|
- 由设备**制造商**添加的
|
||||||
@ -49,8 +49,8 @@
|
|||||||
|
|
||||||
## Rooting
|
## Rooting
|
||||||
|
|
||||||
为了获得对物理Android设备的root访问权限,通常需要**利用**1或2个**漏洞**,这些漏洞通常是**特定**于**设备**和**版本**的。\
|
为了获得物理Android设备的root访问权限,通常需要**利用**1或2个**漏洞**,这些漏洞通常是**特定**于**设备**和**版本**的。\
|
||||||
一旦漏洞成功利用,通常会将Linux `su` 二进制文件复制到用户的PATH环境变量中指定的位置,如`/system/xbin`。
|
一旦利用成功,通常会将Linux `su`二进制文件复制到用户PATH环境变量中指定的位置,如`/system/xbin`。
|
||||||
|
|
||||||
一旦配置了su二进制文件,另一个Android应用程序将用于与`su`二进制文件接口并**处理root访问请求**,如**Superuser**和**SuperSU**(在Google Play商店中可用)。
|
一旦配置了su二进制文件,另一个Android应用程序将用于与`su`二进制文件接口并**处理root访问请求**,如**Superuser**和**SuperSU**(在Google Play商店中可用)。
|
||||||
|
|
||||||
@ -59,14 +59,14 @@
|
|||||||
|
|
||||||
### ROMs
|
### ROMs
|
||||||
|
|
||||||
可以通过**安装自定义固件来替换操作系统**。这样可以扩展旧设备的使用价值,绕过软件限制或获得最新的Android代码。\
|
可以通过**安装自定义固件来替换操作系统**。这样可以扩展旧设备的实用性,绕过软件限制或访问最新的Android代码。\
|
||||||
**OmniROM**和**LineageOS**是两个最流行的固件。
|
**OmniROM**和**LineageOS**是两个最流行的固件。
|
||||||
|
|
||||||
请注意,**并不总是需要root设备**才能安装自定义固件。**一些制造商允许**以良好文档和安全的方式解锁其引导加载程序。
|
请注意,**并不总是需要root设备**才能安装自定义固件。**一些制造商允许**以良好记录和安全的方式解锁其引导加载程序。
|
||||||
|
|
||||||
### Implications
|
### Implications
|
||||||
|
|
||||||
一旦设备被root,任何应用程序都可以请求root访问。如果恶意应用程序获得了它,它将几乎可以访问所有内容,并能够损坏手机。
|
一旦设备被root,任何应用程序都可以请求root访问。如果恶意应用程序获得了它,它几乎可以访问所有内容,并且能够损坏手机。
|
||||||
|
|
||||||
## Android Application Fundamentals <a href="#2-android-application-fundamentals" id="2-android-application-fundamentals"></a>
|
## Android Application Fundamentals <a href="#2-android-application-fundamentals" id="2-android-application-fundamentals"></a>
|
||||||
|
|
||||||
@ -74,7 +74,7 @@
|
|||||||
- APK内容(不详尽)
|
- APK内容(不详尽)
|
||||||
- **AndroidManifest.xml**
|
- **AndroidManifest.xml**
|
||||||
- resources.arsc/strings.xml
|
- resources.arsc/strings.xml
|
||||||
- resources.arsc:包含预编译资源,如二进制XML。
|
- resources.arsc:包含预编译的资源,如二进制XML。
|
||||||
- res/xml/files_paths.xml
|
- res/xml/files_paths.xml
|
||||||
- META-INF/
|
- META-INF/
|
||||||
- 这里是证书所在的位置!
|
- 这里是证书所在的位置!
|
||||||
@ -93,13 +93,13 @@
|
|||||||
|
|
||||||
### **Dalvik & Smali**
|
### **Dalvik & Smali**
|
||||||
|
|
||||||
在Android开发中,**Java或Kotlin**用于创建应用程序。与桌面应用程序使用JVM不同,Android将此代码编译为**Dalvik可执行文件(DEX字节码)**。早期,Dalvik虚拟机处理此字节码,但现在,在较新版本的Android中,Android Runtime(ART)接管。
|
在Android开发中,**Java或Kotlin**用于创建应用程序。与桌面应用程序使用JVM不同,Android将此代码编译为**Dalvik可执行文件(DEX字节码)**。早期,Dalvik虚拟机处理此字节码,但现在,Android Runtime(ART)在较新版本的Android中接管。
|
||||||
|
|
||||||
对于逆向工程,**Smali**变得至关重要。它是DEX字节码的人类可读版本,像汇编语言一样通过将源代码转换为字节码指令。Smali和baksmali在此上下文中指的是汇编和反汇编工具。
|
对于逆向工程,**Smali**变得至关重要。它是DEX字节码的人类可读版本,像汇编语言一样通过将源代码转换为字节码指令。Smali和baksmali在此上下文中指代汇编和反汇编工具。
|
||||||
|
|
||||||
## Intents
|
## Intents
|
||||||
|
|
||||||
Intents是Android应用程序在其组件之间或与其他应用程序之间通信的主要方式。这些消息对象还可以在应用程序或组件之间携带数据,类似于HTTP通信中的GET/POST请求。
|
Intents是Android应用程序在其组件之间或与其他应用程序之间通信的主要方式。这些消息对象还可以在应用程序或组件之间携带数据,类似于HTTP通信中使用的GET/POST请求。
|
||||||
|
|
||||||
因此,Intent基本上是**在组件之间传递的消息**。Intents**可以定向**到特定组件或应用程序,**也可以在没有特定接收者的情况下发送**。\
|
因此,Intent基本上是**在组件之间传递的消息**。Intents**可以定向**到特定组件或应用程序,**也可以在没有特定接收者的情况下发送**。\
|
||||||
简单来说,Intent可以用于:
|
简单来说,Intent可以用于:
|
||||||
@ -114,13 +114,13 @@ Intents是Android应用程序在其组件之间或与其他应用程序之间通
|
|||||||
|
|
||||||
### Intent-Filter
|
### Intent-Filter
|
||||||
|
|
||||||
**Intent过滤器**定义**活动、服务或广播接收器如何与不同类型的Intents交互**。本质上,它们描述了这些组件的能力,例如它们可以执行的操作或可以处理的广播类型。声明这些过滤器的主要位置是在**AndroidManifest.xml文件**中,尽管对于广播接收器,编码它们也是一个选项。
|
**Intent Filters**定义**活动、服务或广播接收器如何与不同类型的Intents交互**。本质上,它们描述了这些组件的能力,例如它们可以执行的操作或可以处理的广播类型。声明这些过滤器的主要位置是在**AndroidManifest.xml文件**中,尽管对于广播接收器,编码它们也是一种选择。
|
||||||
|
|
||||||
Intent过滤器由类别、操作和数据过滤器组成,并可以包含附加元数据。此设置允许组件处理与声明的标准匹配的特定Intents。
|
Intent Filters由类别、操作和数据过滤器组成,并可以包含附加元数据。此设置允许组件处理与声明的标准匹配的特定Intents。
|
||||||
|
|
||||||
Android组件(活动/服务/内容提供者/广播接收器)的一个关键方面是它们的可见性或**公共状态**。如果组件的**`exported`**值为**`true`**,或者在清单中声明了Intent过滤器,则该组件被视为公共的,可以与其他应用程序交互。然而,开发人员可以明确将这些组件保持私有,以确保它们不会与其他应用程序意外交互。这是通过在其清单定义中将**`exported`**属性设置为**`false`**来实现的。
|
Android组件(活动/服务/内容提供者/广播接收器)的一个关键方面是它们的可见性或**公共状态**。如果组件的**`exported`**值为**`true`**,则该组件被视为公共的,可以与其他应用程序交互;如果在清单中声明了Intent Filter,则也是如此。然而,开发人员可以明确将这些组件保持私有,确保它们不会与其他应用程序意外交互。这是通过在其清单定义中将**`exported`**属性设置为**`false`**来实现的。
|
||||||
|
|
||||||
此外,开发人员还有选择进一步保护对这些组件的访问的选项,要求特定权限。**`permission`**属性可以设置为强制要求只有具有指定权限的应用程序才能访问该组件,从而增加了安全性和对谁可以与其交互的控制。
|
此外,开发人员还有选择进一步保护对这些组件的访问的选项,要求特定权限。**`permission`**属性可以设置为强制要求只有具有指定权限的应用程序才能访问该组件,从而增加了安全性和对谁可以与之交互的控制。
|
||||||
```java
|
```java
|
||||||
<activity android:name=".MyActivity" android:exported="false">
|
<activity android:name=".MyActivity" android:exported="false">
|
||||||
<!-- Intent filters go here -->
|
<!-- Intent filters go here -->
|
||||||
@ -128,13 +128,13 @@ Android组件(活动/服务/内容提供者/广播接收器)的一个关键
|
|||||||
```
|
```
|
||||||
### 隐式意图
|
### 隐式意图
|
||||||
|
|
||||||
意图是通过意图构造函数程序化创建的:
|
意图是通过意图构造函数以编程方式创建的:
|
||||||
```java
|
```java
|
||||||
Intent email = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));
|
Intent email = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));
|
||||||
```
|
```
|
||||||
该意图的 **Action** 是 **ACTION_SEND**,**Extra** 是一个 mailto **Uri**(Extra 是意图所期望的额外信息)。
|
**Action** 是之前声明的意图的 **ACTION_SEND**,而 **Extra** 是一个 mailto **Uri**(Extra 是意图所期望的额外信息)。
|
||||||
|
|
||||||
该意图应在清单中声明,如以下示例所示:
|
这个意图应该在清单中声明,如以下示例所示:
|
||||||
```xml
|
```xml
|
||||||
<activity android:name="ShareActivity">
|
<activity android:name="ShareActivity">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
@ -145,15 +145,15 @@ Intent email = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));
|
|||||||
```
|
```
|
||||||
一个 intent-filter 需要匹配 **action**、**data** 和 **category** 才能接收消息。
|
一个 intent-filter 需要匹配 **action**、**data** 和 **category** 才能接收消息。
|
||||||
|
|
||||||
“Intent 解析”过程决定了哪个应用程序应该接收每个消息。这个过程考虑了 **priority attribute**,可以在 **intent-filter declaration** 中设置,**优先级更高的将被选择**。这个优先级可以设置在 -1000 到 1000 之间,应用程序可以使用 `SYSTEM_HIGH_PRIORITY` 值。如果出现 **冲突**,将出现一个“选择器”窗口,以便 **用户可以决定**。
|
“Intent 解析”过程决定了哪个应用程序应该接收每个消息。这个过程考虑了 **priority attribute**,可以在 **intent-filter 声明**中设置,**优先级更高的将被选中**。这个优先级可以设置在 -1000 到 1000 之间,应用程序可以使用 `SYSTEM_HIGH_PRIORITY` 值。如果出现 **冲突**,将出现一个“选择器”窗口,以便 **用户可以决定**。
|
||||||
|
|
||||||
### 显式 Intent
|
### 显式 Intent
|
||||||
|
|
||||||
显式 Intent 指定了它所针对的类名:
|
显式 intent 指定了它所针对的类名:
|
||||||
```java
|
```java
|
||||||
Intent downloadIntent = new (this, DownloadService.class):
|
Intent downloadIntent = new (this, DownloadService.class):
|
||||||
```
|
```
|
||||||
在其他应用程序中,为了访问先前声明的意图,您可以使用:
|
在其他应用程序中,为了访问先前声明的意图,你可以使用:
|
||||||
```java
|
```java
|
||||||
Intent intent = new Intent();
|
Intent intent = new Intent();
|
||||||
intent.setClassName("com.other.app", "com.other.app.ServiceName");
|
intent.setClassName("com.other.app", "com.other.app.ServiceName");
|
||||||
@ -161,18 +161,18 @@ context.startService(intent);
|
|||||||
```
|
```
|
||||||
### Pending Intents
|
### Pending Intents
|
||||||
|
|
||||||
这些允许其他应用程序**代表您的应用程序采取行动**,使用您的应用程序的身份和权限。构造 Pending Intent 时,应该**指定一个意图和要执行的操作**。如果**声明的意图不是显式的**(没有声明哪个意图可以调用它),则**恶意应用程序可能会代表受害者应用程序执行声明的操作**。此外,**如果未指定操作**,恶意应用程序将能够**代表受害者执行任何操作**。
|
这些允许其他应用程序**代表您的应用程序采取行动**,使用您的应用程序的身份和权限。构造 Pending Intent 时,应该**指定一个意图和要执行的操作**。如果**声明的意图不是显式的**(没有声明哪个意图可以调用它),则**恶意应用程序可能会代表受害者应用程序执行声明的操作**。此外,**如果没有指定操作**,恶意应用程序将能够**代表受害者执行任何操作**。
|
||||||
|
|
||||||
### Broadcast Intents
|
### Broadcast Intents
|
||||||
|
|
||||||
与之前的意图不同,后者仅由一个应用程序接收,广播意图**可以被多个应用程序接收**。然而,从 API 版本 14 开始,可以**使用 Intent.setPackage 指定应该接收**消息的应用程序。
|
与之前的意图不同,后者仅由一个应用程序接收,广播意图**可以被多个应用程序接收**。然而,从 API 版本 14 开始,可以**使用 Intent.setPackage 指定应该接收**消息的应用程序。
|
||||||
|
|
||||||
另外,在发送广播时也可以**指定权限**。接收应用程序需要拥有该权限。
|
或者,在发送广播时也可以**指定权限**。接收应用程序需要具有该权限。
|
||||||
|
|
||||||
广播有**两种类型**:**正常**(异步)和**有序**(同步)。**顺序**基于**接收器元素中的配置优先级**。**每个应用程序可以处理、转发或丢弃广播。**
|
广播有**两种类型**:**正常**(异步)和**有序**(同步)。**顺序**基于**接收器**元素中的**配置优先级**。**每个应用程序可以处理、转发或丢弃广播。**
|
||||||
|
|
||||||
可以使用 `Context` 类中的函数 `sendBroadcast(intent, receiverPermission)` 来**发送**一个**广播**。\
|
可以使用 `Context` 类中的函数 `sendBroadcast(intent, receiverPermission)` 来**发送**一个**广播**。\
|
||||||
您还可以使用**`LocalBroadCastManager`**中的函数**`sendBroadcast`**,确保**消息永远不会离开应用程序**。使用此方法,您甚至不需要导出接收器组件。
|
您还可以使用**`LocalBroadCastManager`**中的**`sendBroadcast`**函数,确保**消息永远不会离开应用程序**。使用此方法,您甚至不需要导出接收器组件。
|
||||||
|
|
||||||
### Sticky Broadcasts
|
### Sticky Broadcasts
|
||||||
|
|
||||||
@ -198,7 +198,7 @@ context.startService(intent);
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
[...]
|
[...]
|
||||||
```
|
```
|
||||||
前一个示例中的方案是 `examplescheme://`(还要注意 **`category BROWSABLE`**)
|
该示例中的方案是 `examplescheme://`(还请注意 **`category BROWSABLE`**)
|
||||||
|
|
||||||
然后,在数据字段中,您可以指定 **host** 和 **path**:
|
然后,在数据字段中,您可以指定 **host** 和 **path**:
|
||||||
```xml
|
```xml
|
||||||
@ -206,7 +206,7 @@ context.startService(intent);
|
|||||||
android:host="example"
|
android:host="example"
|
||||||
/>
|
/>
|
||||||
```
|
```
|
||||||
要从网页访问,可以设置一个链接,如:
|
要从网页访问它,可以设置一个链接,如:
|
||||||
```xml
|
```xml
|
||||||
<a href="examplescheme://example/something">click here</a>
|
<a href="examplescheme://example/something">click here</a>
|
||||||
<a href="examplescheme://example/javascript://%250dalert(1)">click here</a>
|
<a href="examplescheme://example/javascript://%250dalert(1)">click here</a>
|
||||||
@ -221,11 +221,11 @@ android:host="example"
|
|||||||
|
|
||||||
### 关键概念
|
### 关键概念
|
||||||
|
|
||||||
- **绑定服务**:这些服务利用AIDL进行IPC,使活动或组件能够绑定到服务,发出请求并接收响应。服务类中的`onBind`方法对于启动交互至关重要,标志着它是安全审查中寻找漏洞的重要领域。
|
- **绑定服务**:这些服务利用AIDL进行IPC,使活动或组件能够绑定到服务,发出请求并接收响应。服务类中的`onBind`方法对于启动交互至关重要,因此在寻找漏洞时是安全审查的重要领域。
|
||||||
|
|
||||||
- **Messenger**:作为绑定服务,Messenger促进IPC,重点处理通过`onBind`方法的数据。必须仔细检查此方法,以发现任何不安全的数据处理或敏感功能的执行。
|
- **Messenger**:作为绑定服务,Messenger促进IPC,重点通过`onBind`方法处理数据。必须仔细检查此方法,以发现任何不安全的数据处理或敏感功能的执行。
|
||||||
|
|
||||||
- **Binder**:尽管由于AIDL的抽象,Binder类的直接使用较少,但了解Binder作为内核级驱动程序在不同进程的内存空间之间促进数据传输是有益的。有关进一步理解的资源可在[https://www.youtube.com/watch?v=O-UHvFjxwZ8](https://www.youtube.com/watch?v=O-UHvFjxwZ8)找到。
|
- **Binder**:尽管由于AIDL的抽象,直接使用Binder类的情况较少,但了解Binder作为内核级驱动程序在不同进程的内存空间之间促进数据传输是有益的。有关进一步理解的资源可在[https://www.youtube.com/watch?v=O-UHvFjxwZ8](https://www.youtube.com/watch?v=O-UHvFjxwZ8)找到。
|
||||||
|
|
||||||
## 组件
|
## 组件
|
||||||
|
|
||||||
@ -294,7 +294,7 @@ super.onCreate();
|
|||||||
|
|
||||||
### 内容提供者
|
### 内容提供者
|
||||||
|
|
||||||
**内容提供者**对于应用之间**共享结构化数据**至关重要,强调实施**权限**以确保数据安全的重要性。它们允许应用访问来自各种来源的数据,包括数据库、文件系统或网络。特定权限,如**`readPermission`**和**`writePermission`**,对于控制访问至关重要。此外,可以通过应用的Manifest中的**`grantUriPermission`**设置授予临时访问,利用`path`、`pathPrefix`和`pathPattern`等属性进行详细的访问控制。
|
**内容提供者**对于**在应用之间共享结构化数据**至关重要,强调实施**权限**以确保数据安全的重要性。它们允许应用访问来自各种来源的数据,包括数据库、文件系统或网络。特定权限,如**`readPermission`**和**`writePermission`**,对于控制访问至关重要。此外,可以通过应用的Manifest中的**`grantUriPermission`**设置授予临时访问,利用`path`、`pathPrefix`和`pathPattern`等属性进行详细的访问控制。
|
||||||
|
|
||||||
输入验证至关重要,以防止漏洞,例如SQL注入。内容提供者支持基本操作:`insert()`、`update()`、`delete()`和`query()`,促进应用之间的数据操作和共享。
|
输入验证至关重要,以防止漏洞,例如SQL注入。内容提供者支持基本操作:`insert()`、`update()`、`delete()`和`query()`,促进应用之间的数据操作和共享。
|
||||||
|
|
||||||
@ -327,12 +327,12 @@ WebViews 就像是 Android 应用中的 **迷你网页浏览器**,从网络或
|
|||||||
|
|
||||||
Android 提供了两种主要的 WebView 类型:
|
Android 提供了两种主要的 WebView 类型:
|
||||||
|
|
||||||
- **WebViewClient** 适合基本的 HTML,但不支持 JavaScript 警告功能,这会影响 XSS 攻击的测试方式。
|
- **WebViewClient** 适合基本的 HTML,但不支持 JavaScript 警告功能,这影响了 XSS 攻击的测试方式。
|
||||||
- **WebChromeClient** 更像是完整的 Chrome 浏览器体验。
|
- **WebChromeClient** 更像是完整的 Chrome 浏览器体验。
|
||||||
|
|
||||||
一个关键点是 WebView 浏览器 **不与设备的主浏览器共享 cookies**。
|
一个关键点是 WebView 浏览器 **不与设备的主浏览器共享 cookies**。
|
||||||
|
|
||||||
对于加载内容,可以使用 `loadUrl`、`loadData` 和 `loadDataWithBaseURL` 等方法。确保这些 URL 或文件是 **安全使用** 的至关重要。安全设置可以通过 `WebSettings` 类进行管理。例如,通过 `setJavaScriptEnabled(false)` 禁用 JavaScript 可以防止 XSS 攻击。
|
在加载内容时,可以使用 `loadUrl`、`loadData` 和 `loadDataWithBaseURL` 等方法。确保这些 URL 或文件是 **安全使用** 的至关重要。安全设置可以通过 `WebSettings` 类进行管理。例如,通过 `setJavaScriptEnabled(false)` 禁用 JavaScript 可以防止 XSS 攻击。
|
||||||
|
|
||||||
JavaScript "Bridge" 允许 Java 对象与 JavaScript 交互,从 Android 4.2 开始,要求方法使用 `@JavascriptInterface` 标记以确保安全。
|
JavaScript "Bridge" 允许 Java 对象与 JavaScript 交互,从 Android 4.2 开始,要求方法使用 `@JavascriptInterface` 标记以确保安全。
|
||||||
|
|
||||||
@ -348,13 +348,13 @@ JavaScript "Bridge" 允许 Java 对象与 JavaScript 交互,从 Android 4.2
|
|||||||
|
|
||||||
- **数字签名** 是 Android 应用的必要条件,确保它们在安装前是 **真实作者**。此过程使用证书进行应用识别,并必须在安装时由设备的包管理器进行验证。应用可以是 **自签名或由外部 CA 认证**,以防止未经授权的访问,并确保应用在传送到设备时保持未被篡改。
|
- **数字签名** 是 Android 应用的必要条件,确保它们在安装前是 **真实作者**。此过程使用证书进行应用识别,并必须在安装时由设备的包管理器进行验证。应用可以是 **自签名或由外部 CA 认证**,以防止未经授权的访问,并确保应用在传送到设备时保持未被篡改。
|
||||||
|
|
||||||
### **增强安全性的应用验证**
|
### **应用验证以增强安全性**
|
||||||
|
|
||||||
- 从 **Android 4.2** 开始,名为 **Verify Apps** 的功能允许用户在安装前检查应用的安全性。此 **验证过程** 可以警告用户潜在有害的应用,甚至阻止特别恶意的应用安装,从而增强用户安全性。
|
- 从 **Android 4.2** 开始,名为 **Verify Apps** 的功能允许用户在安装前检查应用的安全性。此 **验证过程** 可以警告用户潜在有害的应用,甚至阻止特别恶意的应用安装,从而增强用户安全性。
|
||||||
|
|
||||||
### **移动设备管理 (MDM)**
|
### **移动设备管理 (MDM)**
|
||||||
|
|
||||||
- **MDM 解决方案** 通过 **设备管理 API** 提供对移动设备的 **监督和安全**。它们需要安装 Android 应用以有效管理和保护移动设备。主要功能包括 **强制实施密码策略**、**要求存储加密** 和 **允许远程数据擦除**,确保对移动设备的全面控制和安全。
|
- **MDM 解决方案** 通过 **设备管理 API** 提供对移动设备的 **监督和安全**。它们需要安装 Android 应用以有效管理和保护移动设备。主要功能包括 **强制密码策略**、**要求存储加密** 和 **允许远程数据擦除**,确保对移动设备的全面控制和安全。
|
||||||
```java
|
```java
|
||||||
// Example of enforcing a password policy with MDM
|
// Example of enforcing a password policy with MDM
|
||||||
DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
|
DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
|
||||||
@ -365,4 +365,109 @@ if (dpm.isAdminActive(adminComponent)) {
|
|||||||
dpm.setPasswordMinimumLength(adminComponent, 8);
|
dpm.setPasswordMinimumLength(adminComponent, 8);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
## 枚举和利用 AIDL / Binder 服务
|
||||||
|
|
||||||
|
Android *Binder* IPC 暴露了许多 **系统和供应商提供的服务**。当这些服务在没有适当权限检查的情况下被导出时,它们就成为了 **攻击面**(AIDL 层本身 *不* 执行访问控制)。
|
||||||
|
|
||||||
|
### 1. 发现正在运行的服务
|
||||||
|
```bash
|
||||||
|
# from an adb shell (USB or wireless)
|
||||||
|
service list # simple one-liner
|
||||||
|
am list services # identical output, ActivityManager wrapper
|
||||||
|
```
|
||||||
|
1. Android应用程序的基本知识
|
||||||
|
2. Android应用程序的架构
|
||||||
|
3. Android应用程序的组件
|
||||||
|
4. Android应用程序的生命周期
|
||||||
|
5. Android应用程序的安全性
|
||||||
|
6. Android应用程序的权限管理
|
||||||
|
7. Android应用程序的存储机制
|
||||||
|
8. Android应用程序的网络通信
|
||||||
|
9. Android应用程序的调试与测试
|
||||||
|
10. Android应用程序的反编译与分析
|
||||||
|
```
|
||||||
|
145 mtkconnmetrics: [com.mediatek.net.connectivity.IMtkIpConnectivityMetrics]
|
||||||
|
146 wifi : [android.net.wifi.IWifiManager]
|
||||||
|
```
|
||||||
|
* **索引**(第一列)在运行时分配 – ***不要*** 在重启后依赖它。
|
||||||
|
* **Binder 名称**(例如 `mtkconnmetrics`)将被传递给 `service call`。
|
||||||
|
* 括号内的值是生成存根的完全限定 **AIDL 接口**。
|
||||||
|
|
||||||
|
### 2. 获取接口描述符(PING)
|
||||||
|
每个 Binder 存根自动实现 **事务代码 `0x5f4e5446`**(`1598968902` 十进制,ASCII "_NTF")。
|
||||||
|
```bash
|
||||||
|
# "ping" the service
|
||||||
|
service call mtkconnmetrics 1 # 1 == decimal 1598968902 mod 2^32
|
||||||
|
```
|
||||||
|
一个有效的回复返回编码为UTF-16字符串的接口名称,封装在`Parcel`中。
|
||||||
|
|
||||||
|
### 3. 调用事务
|
||||||
|
语法:`service call <name> <code> [type value ...]`
|
||||||
|
|
||||||
|
常见参数说明:
|
||||||
|
* `i32 <int>` – 有符号32位值
|
||||||
|
* `i64 <long>` – 有符号64位值
|
||||||
|
* `s16 <string>` – UTF-16字符串(Android 13+使用`utf16`)
|
||||||
|
|
||||||
|
示例 – 在MediaTek手机上以uid **1**启动网络监控:
|
||||||
|
```bash
|
||||||
|
service call mtkconnmetrics 8 i32 1
|
||||||
|
```
|
||||||
|
### 4. 暴力破解未知方法
|
||||||
|
当头文件不可用时,你可以**迭代代码**,直到错误从:
|
||||||
|
```
|
||||||
|
Result: Parcel(00000000 00000000) # "Not a data message"
|
||||||
|
```
|
||||||
|
到一个正常的 `Parcel` 响应或 `SecurityException`。
|
||||||
|
```bash
|
||||||
|
for i in $(seq 1 50); do
|
||||||
|
printf "[+] %2d -> " $i
|
||||||
|
service call mtkconnmetrics $i 2>/dev/null | head -1
|
||||||
|
done
|
||||||
|
```
|
||||||
|
如果服务是 **使用 proguard 编译的**,则必须猜测映射 – 请参见下一步。
|
||||||
|
|
||||||
|
### 5. 通过 onTransact() 映射代码 ↔ 方法
|
||||||
|
反编译实现接口的 jar/odex(对于 AOSP 存根,请检查 `/system/framework`;OEM 通常使用 `/system_ext` 或 `/vendor`)。
|
||||||
|
搜索 `Stub.onTransact()` – 它包含一个巨大的 `switch(transactionCode)`:
|
||||||
|
```java
|
||||||
|
case TRANSACTION_updateCtaAppStatus: // 5
|
||||||
|
data.enforceInterface(DESCRIPTOR);
|
||||||
|
int appId = data.readInt();
|
||||||
|
boolean ok = data.readInt() != 0;
|
||||||
|
updateCtaAppStatus(appId, ok);
|
||||||
|
reply.writeNoException();
|
||||||
|
return true;
|
||||||
|
```
|
||||||
|
现在原型和**参数类型**非常清晰。
|
||||||
|
|
||||||
|
### 6. 发现缺失的权限检查
|
||||||
|
实现(通常是一个内部的 `Impl` 类)负责授权:
|
||||||
|
```java
|
||||||
|
private void updateCtaAppStatus(int uid, boolean status) {
|
||||||
|
if (!isPermissionAllowed()) {
|
||||||
|
throw new SecurityException("uid " + uid + " rejected");
|
||||||
|
}
|
||||||
|
/* privileged code */
|
||||||
|
}
|
||||||
|
```
|
||||||
|
缺乏这种逻辑或特权 UID 的白名单(例如 `uid == 1000 /*system*/`)是一个 **漏洞指标**。
|
||||||
|
|
||||||
|
案例研究 – *MediaTek* `startMonitorProcessWithUid()`(事务 **8**)在没有任何权限门的情况下完全执行了 Netlink 消息,允许一个无特权的应用与内核的 Netfilter 模块交互并向系统日志发送垃圾信息。
|
||||||
|
|
||||||
|
### 7. 自动化评估
|
||||||
|
加速 Binder 侦察的工具 / 脚本:
|
||||||
|
* [binderfs](https://android.googlesource.com/platform/frameworks/native/+/master/cmds/binderfs/) – 以每个服务节点的形式暴露 `/dev/binderfs`
|
||||||
|
* [`binder-scanner.py`](https://github.com/adenflare/binder-scanner) – 遍历 binder 表并打印 ACL
|
||||||
|
* Frida 快捷方式:`Java.perform(()=>console.log(android.os.ServiceManager.listServices().toArray()))`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 参考文献
|
||||||
|
|
||||||
|
- [Android Services 101 – Pentest Partners](https://www.pentestpartners.com/security-blog/android-services-101/)
|
||||||
|
- [Android Developer Docs – AIDL](https://developer.android.com/guide/components/aidl)
|
||||||
|
- [Android Developer Docs – IBinder](https://developer.android.com/reference/android/os/IBinder)
|
||||||
|
- [Understanding Binder, Talk @ Google](https://www.youtube.com/watch?v=O-UHvFjxwZ8)
|
||||||
|
|
||||||
{{#include ../../banners/hacktricks-training.md}}
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user