ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

OWASP MASTG 深度解析:Android Activity 组件、Intent 访问控制与攻击面评估

OWASP MASTG 深度解析:Android Activity 组件、Intent 访问控制与攻击面评估 文档教程网络安全【免费下载链接】mastgThe OWASP Mobile Application Security Testing Guide (MASTG) is a comprehensive manual for mobile app security testing and reverse engineering. It describes technical processes for verifying the OWASP Mobile Security Weakness Enumeration (MASWE) weaknesses, which are in alignment with the OWASP MASVS.项目地址https://gitcode.com/gh_mirrors/ow/mastg点击查看免费下载本指南基于 OWASP MASTGMobile Application Security Testing Guide知识库中的 Android Activities 专题MASTG-KNOW-0132系统讲解 Activity 的声明方式、生命周期、显式/隐式 Intent 启动机制、intent-filter解析规则以及以android:exported和android:permission为核心的组件访问控制模型。文中结合 MASTG 仓库中的测试用例MASTG-TEST-0364、技术条目MASTG-TECH-0160、最佳实践MASTG-BEST-0052与静态分析规则semgrep YAML 规则说明安全测试人员如何枚举导出 Activity、识别敏感功能暴露风险并验证加固措施。读完本文你将掌握 Activity 作为 IPC 入口点的完整安全评估方法并能在实际项目中正确配置组件可见性。Activity 是什么一个屏幕也是 IPC 入口点Activity 是 Android 应用组件app component之一它提供一个带有用户界面的独立屏幕。一个应用通常为每个屏幕实现一个 Activity——例如一个三屏应用就实现三个 Activity。每个 Activity 都继承自Activity类或其子类如AppCompatActivity并在其中承载该屏幕的界面元素包括 Fragment、View 与布局。从安全视角看Activity 的独特之处在于它是进程间通信IPC的入口点之一。MASTG 的 IPC 模型条目 MASTG-KNOW-0020 明确指出Android 中有四类组件充当 IPC 入口点Activities提供可由其他应用启动的 UI 屏幕Services运行其他应用可启动或绑定的后台任务Broadcast Receivers响应来自其他应用与系统的广播消息Content Providers通过基于 URI 的接口暴露结构化数据。所有组件都在AndroidManifest.xml中声明其对外可见性由android:exported属性及可选的权限属性控制。其他应用或系统可以通过发送Intent来启动 Activity但这种启动受到清单访问控制如android:exported和android:permission的约束——这正是 Activity 可见性与应用攻击面直接相关的根本原因。声明不声明的 Activity 无法被显示每个 Activity 必须在AndroidManifest.xml中用application内嵌套的activity元素声明activity android:name.MainActivity /关键约束未在清单中声明的 Activity 无法被显示尝试启动它会抛出异常。系统在 Activity 启动时才实例化它并将用户交互与生命周期事件路由给它。安全测试的第一步静态分析通常就是检查清单确认应用中到底声明了哪些 Activity——详见后文枚举导出的 Activity一节。生命周期系统管理的状态机Activity 的生命周期由 Android 系统管理。一个 Activity 可以处于多种状态之一created、started、resumed、paused、stopped、destroyed 等并在状态迁移时收到对应的回调。最常见的回调包括onCreate初始化 Activity通常在此构建用户界面onStart、onResumeActivity 变为可见随后变为可交互onPause、onStopActivity 失去焦点随后失去可见性onDestroyActivity 正在被销毁在此释放资源onSaveInstanceState与onRestoreInstanceState持久化并恢复瞬态 UI 状态如旋转屏幕时的输入内容。完整流程参见 The activity lifecycle。对安全测试而言生命周期回调是定位敏感操作发生点的重要锚点例如深链处理代码常写在onCreate中见 MASTG-DEMO-0152 的DeepLinkActivity.onCreate而onNewIntent则处理应用已在前台运行时再次收到 Intent 的情况。启动 Activity显式 Intent 与隐式 Intent一个 Activity 通过向startActivity传递Intent来启动当需要返回值时使用 Activity Result APIs显式 IntentExplicit通过目标组件的类名或包名指名道姓地指定目标组件。典型场景是启动应用内部组件因为调用方明确知道目标 Activity/Service 的类Intent downloadIntent new Intent(this, DownloadActivity.class); downloadIntent.setAction(android.intent.action.GET_CONTENT); startActivityForResult(downloadIntent);显式 Intent 也可以跨应用启动已导出的组件在访问控制允许的前提下。隐式 IntentImplicit不指定目标组件只声明一个 action以及可选的 data 与 categories由系统根据已安装应用声明的intent-filter解析由哪个组件处理。例如调用方可以用隐式 Intent 在地图上显示某个位置而不必指定具体的某个地图应用Intent downloadIntent new Intent(); downloadIntent.setAction(android.intent.action.GET_CONTENT); startActivityForResult(downloadIntent);Intent 解析算法系统收到隐式 Intent 后会将 Intent 与所有已安装组件声明的intent-filter进行比对intent resolution algorithm评估以下匹配准则Actionfilter 必须声明与 Intent 相同的 action 字符串CategoryIntent 中的所有 category 都必须出现在 filter 中filter 可以额外声明更多 categoryDataURI 的 scheme、host、path 与 MIME type 必须满足 filter 中data的约束。如果解析出多个匹配组件系统可能弹出 chooser/消歧对话框让用户选择如果只有一个匹配组件则直接路由。两个重要的平台行为值得安全测试人员注意隐式 Intent 默认附加CATEGORY_DEFAULT对于隐式启动 Activityfilter 通常需要声明CATEGORY_DEFAULT类别因为startActivity会像隐式 Intent 已包含该类别一样处理它。Android 14 收紧隐式 Intent 到内部组件如果应用 targetSdk 为 Android 14API level 34或更高隐式 Intent永远不会被发送到内部组件见 Android 14 behavior changes。这强制开发者对内部通信使用显式 Intent。包级限定解析Intent.setPackage可以把解析范围限制在指定包内同时仍保留基于 action 的匹配语义——这是半显式的常用折中方案val intent Intent(com.example.app.INTERNAL_ACTION).apply { setPackage(com.example.app) } startActivity(intent)MASTG 仓库为此提供了对应的静态分析规则 mastg-android-implicit-intent-internal-communication.yml通过 semgrep 模式检测用隐式 Intent 做内部组件通信的写法new Intent(...)setAction(...)startActivity(...)并在缺少setPackage(...)/setComponent(...)时告警消息内容为[MASVS-CODE-4]内部组件通信应使用显式 Intent。Intent Filters活动能力声明而非安全边界intent-filter声明一个 Activity 能够响应的 actions、categories 与 data。最典型的例子是 launcher activity启动入口它声明MAINaction 与LAUNCHERcategoryactivity android:name.MainActivity android:exportedtrue intent-filter action android:nameandroid.intent.action.MAIN / category android:nameandroid.intent.category.LAUNCHER / /intent-filter /activity一个 Activity 只有在声明了匹配的 intent filter 时才能被隐式 Intent 启动。但必须强调 MASTG 知识库中的安全要点Intent filters 不是访问控制机制——要控制哪些外部调用方可以启动 Activity应使用android:exported和权限permissions。Deep Links 是 intent filter 的一种特殊用例它将 Web URI 或自定义 URI 映射到 Activity参见 MASTG-KNOW-0019。一个可浏览的 Web 深链通常组合了android.intent.action.VIEWaction、android.intent.category.DEFAULT与android.intent.category.BROWSABLE类别以及一个或多个定义scheme、host、path的data元素。同一条intent-filter内的多个data元素会按属性组合全部合并。深链安全的核心风险是deep link collision深链冲突设备上任意其他应用都能声明与目标应用完全相同的深链导致系统弹出消歧对话框用户可能误选恶意应用。Android App Links基于http/https且经 Digital Asset Links 验证可缓解此问题但自定义 URL scheme如myapp://不受系统验证。MASTG 还提供了规则 mastg-android-custom-deeplink-scheme.yml 定位自定义 scheme 声明以及 mastg-android-deeplink-unvalidated-parameter.yml 定位getIntent().getData()/getQueryParameter(...)这类深链入口与参数读取点。访问控制android:exported 与 android:permission其他应用能否启动某个 Activity由清单属性决定。MASTG-KNOW-0132 将其归纳为三个要素属性/元素作用关键语义android:exported是否允许其他应用启动为true时其他应用的组件可以启动该 Activity除非android:permission等机制阻止调用方为false时只有同应用、共享同一 user ID 的应用或特权系统组件可以启动。默认值为false当 Activity 没有 intent filter 时。intent-filter声明 Activity 能接收的隐式 Intent历史上声明了 intent filter 且未显式设置android:exported的 Activity在较老的 target SDK 版本上可能被其他应用触达。依赖默认值是被明确劝阻的targetSdk 为 Android 12API level 31或更高 的应用凡带有 intent filter 的 Activity 必须显式声明android:exported否则应用无法安装。android:permission要求调用方持有特定权限调用方未持有该权限时Intent 不会投递给 Activity。结合自定义权限与合适的android:protectionLevel例如signature可将可交互的应用限制到特定集合。关于权限保护级别与自定义权限的完整模型normal、signature、signatureOrSystem、dangerous、appop等参见 MASTG-KNOW-0017关于导出组件基于权限的访问控制官方说明参见 Permission-based access control to exported components。最佳实践默认不导出导出必有权限MASTG 最佳实践 MASTG-BEST-0052Restrict Access to Android App Components给出了落地准则仅在另一应用确实需要交互时才导出组件。每个导出组件都是设备上其他应用可能调用的入口点默认保持私有可缩小攻击面。显式设置android:exportedfalse不要依赖默认值——默认值在不同 Android 版本和组件类型间变化过且 intent filter 历史上会让组件被导出。自 Android 12API level 31起任何带 intent filter 的 Activity/Service/Receiver 都必须显式声明android:exported。仅内部使用的组件应移除intent-filter改用显式 Intent 触达需要被另一个受信任应用访问时用android:exportedtrue配合合适权限通常为signature。不要把android:permission的存在当作充分条件normal或dangerous这类可广泛授予的保护级别仍可能让不可信应用调用敏感组件。自定义权限的声明示例定义在组件拥有方或其他可信包的清单中permission android:namecom.example.app.permission.SEND_INTERNAL_BROADCAST android:protectionLevelsignature /安全测试实践枚举导出的 Activity从安全测试角度第一步是确定应用的可触达面——即哪些 Activity 被导出。MASTG 技术条目 MASTG-TECH-0160Enumerating Activities系统给出了四种方法建议优先做清单静态分析无需设备且精确反映声明内容需要确认运行时行为时再结合设备工具。1. 直接分析 AndroidManifest提取并解码AndroidManifest.xml参见 MASTG-TECH-0117后查找activity与activity-alias元素记录其android:name、android:exported、android:permission和 intent filter。注意activity alias 有自己的android:exported、android:permission与 intent filter需要与目标 Activity 分开审查。用xmlstarlet可以一次性列出每个 Activity/别名及其关键属性xmlstarlet sel -t -m //activity | //activity-alias -v name() -o name -v android:name -o exported -v android:exported -o permission -v android:permission -o intent_filters -v count(intent-filter) -n AndroidManifest.xml解读android:exported时必须结合 intent filter、target SDK、Android 版本与关联权限targetSdk 为 Android 11 或更低的应用任何声明了intent-filter且未设android:exportedfalse的 Activity 都可能被其他应用触达targetSdk 为 Android 12API level 31或更高的应用则必须显式声明否则无法安装。2. 使用 aapt2 快速查看aapt2无需解码完整 XML 即可打印清单中声明的组件aapt2 d xmltree app.apk --file AndroidManifest.xml | grep -A20 -E E: activity|E: activity-alias逐块检查每个 activity 的android:name、android:exported、android:permission及嵌套的intent-filter。在原始输出中android:exportedtrue显示为0xffffffff。嵌套的intent-filter只是需要结合 target SDK 与版本规则解读的信号本身并不直接证明组件已导出。3. 使用 adb 查询运行时状态在装有应用的设备或模拟器上可以查询包管理器的解析表adb shell dumpsys package package_name | awk /^Activity Resolver Table:/{show1} /^Receiver Resolver Table:/{show0} show adb shell cmd package query-activities --components -p package_name -a android.intent.action.MAIN -c android.intent.category.LAUNCHERdumpsys package可查看 activity resolver table 及其关联的permission值cmd package query-activities适合快速分诊但它只是针对给定包、action、category 的 intent 解析视图不能枚举包声明的所有 Activity。启动导出的 Activity 并观察其行为# 按组件名启动 adb shell am start -n package_name/activity_name # 指定 action 与 category 启动 adb shell am start -n package_name/activity_name -a android.intent.action.MAIN -c android.intent.category.LAUNCHER历史测试用例 MASTG-TEST-0029已废弃被 MASTG-TEST-0364 等覆盖曾以脆弱密码管理器 Sieve 演示其.PWList与.FileSelectActivity均带android:exportedtrue可直接用adb shell am start -n com.mwr.example.sieve/.PWList启动从而绕过MainLoginActivity的登录验证直接访问密码数据——这是导出 Activity 绕过认证的典型利用链。4. 使用 drozer 兜底当清单与 adb 检查不足时drozer 可以枚举导出 Activity 及其权限并提供构造 Intent 的辅助命令run app.activity.info -a package_name run app.activity.start --component package_name activity_name测试用例视角导出且未受保护的敏感 ActivityMASTG 的 V2 测试用例 MASTG-TEST-0364Exported And Unprotected Activities That Expose Sensitive Functionality对应 MASWE-0018将该主题固化为可重复执行的测试流程步骤先用 MASTG-TECH-0013 逆向应用 → 用 MASTG-TECH-0117 获取AndroidManifest.xml→ 用 MASTG-TECH-0160 列出导出 Activity 及其android:permission→ 用 MASTG-TECH-0014 检查每个导出 Activity 的代码实现。判定失败条件任一导出 Activity 未受合适的android:permission保护、且暴露或执行敏感功能例如显示或返回敏感数据账户详情、消息、存储的密钥执行安全相关操作修改设置或凭据直接启动可绕过应用其他路径依赖的认证步骤如登录或 PIN 屏。进一步验证使用 MASTG-TECH-0023 深入审查判断该 Activity 是否有正当理由被第三方应用启动——如果没有就不应导出如果确实需要外部访问则判断android:permission或其他等效控制是否与功能敏感度及允许的调用方集合匹配并验证权限在该信任边界内是否真正有效例如使用signature保护级别或其他不会被不可信应用广泛获取的控制。与之呼应的还有 V2 测试 MASTG-TEST-0355 与 MASTG-TEST-0356覆盖原 MASTG-TEST-0007 的存储数据经 IPC 泄露检查涵盖 Provider 与 FileProvider 场景以及深链参数校验测试 MASTG-TEST-0394。仓库实证深链处理器的未校验参数案例MASTG 仓库的演示用例 MASTG-DEMO-0152 完整演示了自定义 URL scheme 未校验参数的失败样本应用在DeepLinkActivity上注册自定义 schememastestapp://transfer设备上任意应用都能打开它例如mastestapp://transfer?amount9999999。该 Activity 的入口DeepLinkActivity.onCreate通过getIntent().getData()读取 URI随后在MastgTest中用getQueryParameter(amount)提取amount参数并直接以原始String传入processTransfer()全程没有toLong()转换或范围检查String amount data.getQueryParameter(amount); // raw String from the URI ... return processTransfer(amount); // used as-is ... private final String processTransfer(String amount) { return Transferring amount units; // no toLong(), no bounds check }配合 semgrep 规则 mastg-android-deeplink-unvalidated-parameter.yml匹配$INTENT.getData()与$URI.getQueryParameter(...)静态扫描即可定位深链入口与参数读取点再结合 MASTG-TECH-0023 人工确认参数是否被验证。该用例与本文的关联在于任何应用都能发送匹配导出 intent filter 的 Intent——与 iOS 不同Android 没有内建机制让深链处理器识别发送方应用iOS 可通过sourceApplication获取调用方 bundle identifier因此深链参数必须视为不可信输入。总结Activity 安全评估清单结合原知识条目与仓库内测试、规则、最佳实践可将 Android Activity 的安全评估浓缩为以下可操作清单声明检查在AndroidManifest.xml中列出全部activity与activity-alias用xmlstarlet或aapt2确认是否存在未声明组件。导出状态显式化每个带intent-filter的 Activity 显式声明android:exported仅内部使用的组件移除 filter 并用显式 Intent 触达targetSdk ≥ 31 时这是安装硬性要求。权限配套确实需要导出的 Activity评估android:permissionprotectionLevel优先signature是否与功能敏感度匹配警惕normal/dangerous级别可被广泛授予的问题。运行时验证用adb shell am start直接启动导出 Activity确认是否存在绕过认证、泄露数据或执行敏感操作的可能参见 MASTG-TEST-0364 的评估标准。深链单独审查对声明了 VIEW action BROWSABLE category 的 Activity检查深链参数getQueryParameter等是否经过类型转换、边界检查或白名单验证警惕 deep link collision参见 MASTG-DEMO-0152。Activity 既是应用功能的最小组成单元也是攻击面暴露的最常见载体。将默认不导出、导出必有权限、入口必校验三条原则落地配合 MASTG 提供的测试用例与 semgrep 规则做持续集成检查即可系统性地控制这一 IPC 入口点的风险。赞分享文档教程网络安全【免费下载链接】mastgThe OWASP Mobile Application Security Testing Guide (MASTG) is a comprehensive manual for mobile app security testing and reverse engineering. It describes technical processes for verifying the OWASP Mobile Security Weakness Enumeration (MASWE) weaknesses, which are in alignment with the OWASP MASVS.项目地址https://gitcode.com/gh_mirrors/ow/mastg点击查看免费下载相关推荐Android IPC 机制全面解析Binder、Intent 与四大组件入口基于 OWASP MASTGAndroid IPC 机制全面解析Binder、Intent 与四大组件入口基于 OWASP MASTG Android 的每个进程都运行在独立沙箱地址文档教程网络安全OWASP MASTG 深度解析Android 显式与隐式 IntentExplicit vs Implicit Intents原理、解析机制与安全实践OWASP MASTG 深度解析Android 显式与隐式 IntentExplicit vs Implicit Intents原理、解析机制与安全实践文档教程网络安全OWASP MASTG 实战Android 覆盖层攻击Overlay / Tapjacking防护机制解析与验证OWASP MASTG 实战Android 覆盖层攻击Overlay / Tapjacking防护机制解析与验证 覆盖层攻击Overlay Attack文档教程网络安全创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表