Translated ['src/mobile-pentesting/android-app-pentesting/android-task-h

This commit is contained in:
Translator 2025-02-25 22:34:57 +00:00
parent 1dda85f4a2
commit 3ba46fbb54
5 changed files with 77 additions and 24 deletions

View File

@ -1,4 +1,4 @@
# Android 任务劫持 # Android Task Hijacking
{{#include ../../banners/hacktricks-training.md}} {{#include ../../banners/hacktricks-training.md}}
@ -8,7 +8,7 @@
以下是活动转换的快速概述: 以下是活动转换的快速概述:
- **活动 1** 作为前台的唯一活动开始 - **活动 1** 开始时是前台的唯一活动
- 启动 **活动 2****活动 1** 推入后栈,使 **活动 2** 进入前台。 - 启动 **活动 2****活动 1** 推入后栈,使 **活动 2** 进入前台。
- 启动 **活动 3****活动 1****活动 2** 进一步推入栈中,**活动 3** 现在在前面。 - 启动 **活动 3****活动 1****活动 2** 进一步推入栈中,**活动 3** 现在在前面。
- 关闭 **活动 3****活动 2** 重新带回前台,展示了 Android 的简化任务导航机制。 - 关闭 **活动 3****活动 2** 重新带回前台,展示了 Android 的简化任务导航机制。
@ -19,25 +19,31 @@
### 任务亲和力和启动模式概述 ### 任务亲和力和启动模式概述
在 Android 应用中,**任务亲和力** 指定活动的首选任务,通常与应用的包名对齐。这个设置在制作攻击的概念验证 (PoC) 应用时至关重要。 在 Android 应用中,**任务亲和力** 指定活动的首选任务,通常与应用的包名对齐。这个设置在制作证明概念 (PoC) 应用以演示攻击时至关重要。
### 启动模式 ### 启动模式
`launchMode` 属性指导活动实例在任务中的处理。**singleTask** 模式对该攻击至关重要,根据现有活动实例和任务亲和力匹配情况,规定了三种场景。该漏洞依赖于攻击者的应用能够模仿目标应用的任务亲和力,误导 Android 系统启动攻击者的应用而不是预期的目标。 `launchMode` 属性指导活动实例在任务中的处理。**singleTask** 模式对该攻击至关重要,根据现有活动实例和任务亲和力匹配情况,规定了三种场景。该漏洞利用攻击者的应用模仿目标应用的任务亲和力,误导 Android 系统启动攻击者的应用而不是预期的目标。
### 详细攻击步骤 ### 详细攻击步骤
1. **恶意应用安装**:受害者在其设备上安装攻击者的应用。 1. **恶意应用安装**:受害者在其设备上安装攻击者的应用。
2. **初始激活**:受害者首次打开恶意应用,为攻击做好准备。 2. **初始激活**:受害者首次打开恶意应用,为攻击做好准备。
3. **目标应用启动尝试**:受害者尝试打开目标应用。 3. **目标应用启动尝试**:受害者尝试打开目标应用。
4. **劫持执行**:由于任务亲和力匹配,恶意应用被启动,取代目标应用。 4. **劫持执行**在某个时刻,应用尝试打开 **singleTask** 视图。由于任务亲和力匹配,恶意应用被启动,取代目标应用。
5. **欺骗**:恶意应用展示一个假登录界面,类似于目标应用,欺骗用户输入敏感信息。 5. **欺骗**:恶意应用展示一个假登录界面,类似于目标应用,欺骗用户输入敏感信息。
有关此攻击的实际实施,请参考 GitHub 上的任务劫持 Strandhogg 存储库:[Task Hijacking Strandhogg](https://github.com/az0mb13/Task_Hijacking_Strandhogg)。 > [!TIP]
> 请注意,为了使此攻击有效,易受攻击的视图 **不需要将 exported 设置为 true**,也不需要是主活动。
有关此攻击的实际实现,请参阅 GitHub 上的 Task Hijacking Strandhogg 存储库:[Task Hijacking Strandhogg](https://github.com/az0mb13/Task_Hijacking_Strandhogg)。
### 预防措施 ### 预防措施
为了防止此类攻击,开发者可以将 `taskAffinity` 设置为空字符串,并选择 `singleInstance` 启动模式,确保其应用与其他应用隔离。自定义 `onBackPressed()` 函数提供了额外的保护,以防止任务劫持。 为了防止此类攻击,开发人员可以:
- 将 **`**taskAffinity`** 的 **singleTask** 视图设置为空字符串 (`android:taskAffinity=""`)
- 选择 **`singleInstance`** 启动模式,确保其应用与其他应用隔离。
- 自定义 **`onBackPressed()`** 函数,提供额外的保护以防止任务劫持。
## **参考文献** ## **参考文献**

View File

@ -6,34 +6,76 @@
1. 将 APK 文件重命名为 zip 扩展名,并使用命令 `cp com.example.apk example-apk.zip``unzip -qq example-apk.zip -d ReactNative` 将其提取到新文件夹中。 1. 将 APK 文件重命名为 zip 扩展名,并使用命令 `cp com.example.apk example-apk.zip``unzip -qq example-apk.zip -d ReactNative` 将其提取到新文件夹中。
2. 导航到新创建的 ReactNative 文件夹,找到 assets 文件夹。在此文件夹中,您应该找到文件 `index.android.bundle`,该文件包含以压缩格式编写的 React JavaScript。 2. 导航到新创建的 ReactNative 文件夹,找到 assets 文件夹。在此文件夹中,您应该找到文件 `index.android.bundle`,该文件以压缩格式包含 React JavaScript。
3. 使用命令 `find . -print | grep -i ".bundle$"` 搜索 JavaScript 文件。 3. 使用命令 `find . -print | grep -i ".bundle$"` 搜索 JavaScript 文件。
要进一步分析 JavaScript 代码,请在同一目录中创建一个名为 `index.html` 的文件,内容如下: ## Javascript 代码
如果检查 `index.android.bundle` 的内容时发现应用程序的 JavaScript 代码(即使是压缩的),您可以 **分析它以查找敏感信息和漏洞**
由于该包实际上包含了应用程序的所有 JS 代码,因此可以 **将其分割成不同的文件**(可能使其逆向工程更容易),使用 **工具 [react-native-decompiler](https://github.com/numandev1/react-native-decompiler)**
### Webpack
要进一步分析 JavaScript 代码,您可以将文件上传到 [https://spaceraccoon.github.io/webpack-exploder/](https://spaceraccoon.github.io/webpack-exploder/) 或按照以下步骤操作:
1. 在同一目录中创建一个名为 `index.html` 的文件,内容如下:
```html ```html
<script src="./index.android.bundle"></script> <script src="./index.android.bundle"></script>
``` ```
您可以将文件上传到 [https://spaceraccoon.github.io/webpack-exploder/](https://spaceraccoon.github.io/webpack-exploder/) 或按照以下步骤操作: 2. 在 Google Chrome 中打开 `index.html` 文件。
1. 在 Google Chrome 中打开 `index.html` 文件。 3. 通过按 **Command+Option+J for OS X****Control+Shift+J for Windows** 打开开发者工具栏
2. 按 **Command+Option+J for OS X****Control+Shift+J for Windows** 打开开发者工具栏。 4. 在开发者工具栏中点击 "Sources"。你应该会看到一个 JavaScript 文件,它被分成文件夹和文件,构成了主包
3. 在开发者工具栏中点击“Sources”。您应该会看到一个分成文件夹和文件的 JavaScript 文件,构成主要的捆绑包。 如果你找到一个名为 `index.android.bundle.map` 的文件,你将能够以未压缩的格式分析源代码。映射文件包含源映射,这允许你映射压缩的标识符。
如果您找到一个名为 `index.android.bundle.map` 的文件,您将能够以未压缩的格式分析源代码。映射文件包含源映射,这使您能够映射压缩的标识符。
要搜索敏感凭证和端点,请按照以下步骤操作: 要搜索敏感凭证和端点,请按照以下步骤操作:
1. 确定敏感关键词以分析 JavaScript 代码。React Native 应用程序通常使用第三方服务,如 Firebase、AWS S3 服务端点、私钥等。 1. 确定敏感关键词以分析 JavaScript 代码。React Native 应用程序通常使用第三方服务,如 Firebase、AWS S3 服务端点、私钥等。
2. 在这种特定情况下,观察到该应用程序使用了 Dialogflow 服务。搜索与其配置相关的模式。 2. 在这个特定案例中,观察到该应用程序使用了 Dialogflow 服务。搜索与其配置相关的模式。
3. 幸运的是,在侦查过程中在 JavaScript 代码中发现了敏感的硬编码凭证。 3. 幸运的是,在侦查过程中在 JavaScript 代码中发现了敏感的硬编码凭证。
### 更改 JS 代码并重建
在这种情况下,更改代码很简单。你只需将应用程序重命名为使用扩展名 `.zip` 并提取它。然后你可以 **修改这个包中的 JS 代码并重建应用程序**。这应该足以让你 **注入代码** 以进行测试。
## Hermes 字节码
如果包包含 **Hermes 字节码**,你 **将无法访问应用程序的 JavaScript 代码**(甚至无法访问压缩版本)。
你可以通过运行以下命令检查包是否包含 Hermes 字节码:
```bash
file index.android.bundle
index.android.bundle: Hermes JavaScript bytecode, version 96
```
然而,您可以使用工具 **[hbctool](https://github.com/bongtrop/hbctool)**、**[hermes-dec](https://github.com/P1sec/hermes-dec)** 或 **[hermes_rs](https://github.com/Pilfer/hermes_rs)** 来 **反汇编字节码**,并且还可以 **将其反编译为一些伪 JS 代码**。要做到这一点,例如可以使用以下命令:
```bash
hbc-disassembler ./index.android.bundle /tmp/my_output_file.hasm
hbc-decompiler ./index.android.bundle /tmp/my_output_file.js
```
### 修改代码并重建
理想情况下,您应该能够修改反汇编的代码(更改比较、值或您需要修改的任何内容),然后**重建字节码**,再重建应用程序。
工具**[hbctool](https://github.com/bongtrop/hbctool)**支持反汇编包并在进行更改后重新构建,但它**仅支持旧版本**的Hermes字节码。
工具**[hermes-dec](https://github.com/P1sec/hermes-dec)**不支持重建字节码。
工具**[hermes_rs](https://github.com/Pilfer/hermes_rs)**支持重建字节码但它实际上是一个库而不是CLI工具。
## 动态分析
您可以尝试动态分析应用程序使用Frida启用React应用的开发者模式并使用**`react-native-debugger`**进行附加。然而,显然您需要应用程序的源代码。您可以在[https://newsroom.bedefended.com/hooking-react-native-applications-with-frida/](https://newsroom.bedefended.com/hooking-react-native-applications-with-frida/)找到更多信息。
## 参考文献 ## 参考文献
- [https://medium.com/bugbountywriteup/lets-know-how-i-have-explored-the-buried-secrets-in-react-native-application-6236728198f7](https://medium.com/bugbountywriteup/lets-know-how-i-have-explored-the-buried-secrets-in-react-native-application-6236728198f7) - [https://medium.com/bugbountywriteup/lets-know-how-i-have-explored-the-buried-secrets-in-react-native-application-6236728198f7](https://medium.com/bugbountywriteup/lets-know-how-i-have-explored-the-buried-secrets-in-react-native-application-6236728198f7)
- [https://www.assetnote.io/resources/research/expanding-the-attack-surface-react-native-android-applications](https://www.assetnote.io/resources/research/expanding-the-attack-surface-react-native-android-applications)
- [https://payatu.com/wp-content/uploads/2023/02/Mastering-React-Native-Application-Pentesting-A-Practical-Guide-2.pdf](https://payatu.com/wp-content/uploads/2023/02/Mastering-React-Native-Application-Pentesting-A-Practical-Guide-2.pdf)
{{#include ../../banners/hacktricks-training.md}} {{#include ../../banners/hacktricks-training.md}}

View File

@ -9,21 +9,23 @@
### 检测 ### 检测
为了检测易受此攻击的应用程序,您应该在 Android 清单中搜索 **导出活动**(请注意,带有意图过滤器的活动默认情况下会自动导出)。一旦找到导出活动,**检查它们是否需要任何权限**。这是因为 **恶意应用程序也需要该权限** 为了检测易受此攻击的应用程序,您应该在 android manifest 中搜索 **导出活动**(请注意,带有 intent-filter 的活动默认情况下会自动导出)。一旦找到导出活动,**检查它们是否需要任何权限**。这是因为 **恶意应用程序也需要该权限**
您还可以检查应用程序的最低 SDK 版本,检查 **`android:minSdkVersion`** 在 **`AndroidManifest.xml`** 文件中的值。如果该值 **低于 30**,则该应用程序易受 Tapjacking 攻击。
### 保护 ### 保护
#### Android 12 (API 31,32) 及更高版本 #### Android 12 (API 31,32) 及更高版本
[**根据这个来源**](https://www.geeksforgeeks.org/tapjacking-in-android/)**** 从 Android 12 (API 31 & 30) 及更高版本开始Android 会自动防止 tapjacking 攻击。因此,即使应用程序存在漏洞,您 **也无法利用它** [**根据这个来源**](https://www.geeksforgeeks.org/tapjacking-in-android/)**** 从 Android 12 (API 31 & 30) 及更高版本开始Android 会自动防止 tapjacking 攻击。因此,即使应用程序易受攻击,您 **也无法利用它**
#### `filterTouchesWhenObscured` #### `filterTouchesWhenObscured`
如果 **`android:filterTouchesWhenObscured`** 设置为 **`true`**,则 `View` 在视图窗口被另一个可见窗口遮挡时将不会接收触摸。 如果 **`android:filterTouchesWhenObscured`** 设置为 **`true`**,则当视图的窗口被另一个可见窗口遮挡时,`View` 将不会接收触摸。
#### **`setFilterTouchesWhenObscured`** #### **`setFilterTouchesWhenObscured`**
如果 Android 版本较低,属性 **`setFilterTouchesWhenObscured`** 设置为 true 也可以防止利用此漏洞。\ 如果将属性 **`setFilterTouchesWhenObscured`** 设置为 true也可以防止在 Android 版本较低时利用此漏洞。\
例如,如果设置为 **`true`**,则按钮在被遮挡时可以自动 **禁用** 例如,如果设置为 **`true`**,则按钮在被遮挡时可以自动 **禁用**
```xml ```xml
<Button android:text="Button" <Button android:text="Button"
@ -50,12 +52,13 @@ android:filterTouchesWhenObscured="true">
> [!CAUTION] > [!CAUTION]
> 看起来这个项目现在不再维护,这个功能也不再正常工作 > 看起来这个项目现在不再维护,这个功能也不再正常工作
你可以使用 [**qark**](https://github.com/linkedin/qark) 和 `--exploit-apk` --sdk-path `/Users/username/Library/Android/sdk` 参数来创建一个恶意应用程序,以测试可能的 **Tapjacking** 漏洞。 你可以使用 [**qark**](https://github.com/linkedin/qark) 和 `--exploit-apk` --sdk-path `/Users/username/Library/Android/sdk` 参数来创建一个恶意应用程序,以测试可能的 **Tapjacking** 漏洞。\
缓解措施相对简单,因为开发者可以选择在视图被其他视图覆盖时不接收触摸事件。使用 [Android 开发者参考](https://developer.android.com/reference/android/view/View#security): 缓解措施相对简单,因为开发者可以选择在视图被其他视图覆盖时不接收触摸事件。使用 [Android 开发者参考](https://developer.android.com/reference/android/view/View#security):
> 有时,应用程序能够验证某个操作是在用户充分了解和同意的情况下进行的,这一点至关重要,例如授予权限请求、进行购买或点击广告。不幸的是,恶意应用程序可能会试图欺骗用户在不知情的情况下执行这些操作,通过隐藏视图的预期目的。作为补救措施,框架提供了一种触摸过滤机制,可以用来提高提供敏感功能访问的视图的安全性。 > 有时,应用程序能够验证某个操作是在用户的完全知情和同意下执行的,这一点至关重要,例如授予权限请求、进行购买或点击广告。不幸的是,恶意应用程序可能会试图欺骗用户执行这些操作,而用户却对此毫不知情,因为它隐藏了视图的预期目的。作为补救措施,框架提供了一种触摸过滤机制,可以用来提高提供敏感功能访问的视图的安全性。
> >
> 要启用触摸过滤,请调用 [`setFilterTouchesWhenObscured(boolean)`](https://developer.android.com/reference/android/view/View#setFilterTouchesWhenObscured%28boolean%29) 或将 android:filterTouchesWhenObscured 布局属性设置为 true。当启用时框架将丢弃在视图的窗口被另一个可见窗口遮挡时接收到的触摸。因此当 toast、对话框或其他窗口出现在视图的窗口上方时视图将不会接收到触摸。 > 要启用触摸过滤,请调用 [`setFilterTouchesWhenObscured(boolean)`](https://developer.android.com/reference/android/view/View#setFilterTouchesWhenObscured%28boolean%29) 或将 android:filterTouchesWhenObscured 布局属性设置为 true。当启用时框架将丢弃在视图的窗口被另一个可见窗口遮挡时接收到的触摸。因此当 toast、对话框或其他窗口出现在视图的窗口上方时视图将不会接收到触摸。
{{#include ../../banners/hacktricks-training.md}} {{#include ../../banners/hacktricks-training.md}}

View File

@ -471,12 +471,13 @@ window.search = window.search || {};
showResults(true); showResults(true);
} }
fetch(path_to_root + 'searchindex.json') var branch = lang === "en" ? "master" : lang
fetch(`https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/refs/heads/${branch}/searchindex.json`)
.then(response => response.json()) .then(response => response.json())
.then(json => init(json)) .then(json => init(json))
.catch(error => { // Try to load searchindex.js if fetch failed .catch(error => { // Try to load searchindex.js if fetch failed
var script = document.createElement('script'); var script = document.createElement('script');
script.src = path_to_root + 'searchindex.js'; script.src = `https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/refs/heads/${branch}/searchindex.js`;
script.onload = () => init(window.search); script.onload = () => init(window.search);
document.head.appendChild(script); document.head.appendChild(script);
}); });

View File

@ -55,6 +55,7 @@
<!-- Provide site root to javascript --> <!-- Provide site root to javascript -->
<script> <script>
var path_to_root = "{{ path_to_root }}"; var path_to_root = "{{ path_to_root }}";
var lang = "{{ language }}";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "{{ preferred_dark_theme }}" : "{{ default_theme }}"; var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "{{ preferred_dark_theme }}" : "{{ default_theme }}";
</script> </script>
<!-- Start loading toc.js asap --> <!-- Start loading toc.js asap -->