资讯详情

MASTG-TEST-0325 实战:在 Android 运行时 Hook 检测机制,识别 App 的 Root Detection 逻辑

📅 2026/10/9 5:26:14 | 华诺云谱 👁 阅读
MASTG-TEST-0325 实战:在 Android 运行时 Hook 检测机制,识别 App 的 Root Detection 逻辑
文档教程网络安全【免费下载链接】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 MASTG 仓库中的测试用例 MASTG-TEST-0325Runtime Use of Root Detection Techniques动态/Hook 类测试关联 MASWE-0051讲解如何在 Android 应用的运行时阶段通过 Hook 常见 root 检测 API、追踪系统调用的方式确认 App 是否真正激活了 root 检测逻辑。读完本篇你将掌握静态定位 动态验证的组合测试流程能编写针对性的 Frida Hook 脚本与 strace 追踪命令并准确解读测试结果与常见误报/漏报。1. 测试目标与适用边界MASTG-TEST-0325 的核心目标是验证 App 是否在运行时实现了 root 检测——包括检查 rooted 设备上常见的文件/产物以及调用已知的 root 检测 API 或第三方检测库。该测试的元数据Front Matter明确了它在 MASVS 体系中的位置platform: android type: [dynamic, hooks] maswe: [MASWE-0051] best-practices: [MASTG-BEST-0029, MASTG-BEST-0030] knowledge: [MASTG-KNOW-0027]三个关键定位需要先行说明与静态测试互补而非二选一。文档明确建议将其与 MASTG-TEST-0324References to Root Detection Mechanisms静态分析检测 root 检测引用组合使用两种顺序均可行先静态后动态用 MASTG-TEST-0324 得到潜在的 root 检测机制清单再将动态测试聚焦到这些具体检查点确认它们在运行时被触发先动态后静态先用运行时 Hook 找出实际生效的检测机制再回到静态分析中深入调查其实现与覆盖范围。环境建议但非强制。推荐在已 root 的设备或模拟器上运行本测试以确保 root 检测机制能被触发但即便在未 root 的设备上只要 App 执行了不依赖 root 权限的检查例如检查 root 相关文件是否存在、系统属性等本测试同样可以暴露出 root 检测逻辑。范围边界Out of Scope。本测试不评估root 检测机制的健壮性或有效性——这类评估很难仅靠自动化测试完成可能需要手工逆向与定制插桩。文档将这一点单独标注为 Note并指向 MASTG-BEST-0030Implementing Root Detection。MASTG-BEST-0030 本身也强调root 检测只是提高攻击成本的环境风险信号天然可被绕过通过 Hook、Patch 或隐藏 root 产物应配合完整性校验、反调试信号与服务端强制策略使用且检测点应分散在敏感操作与会话建立处避免单点集中式门控。另外文档给出一个可选的扩展方向借助 MASTG-TECH-0144Bypassing Root Detection尝试绕过 App 的 root 检测并观察结果——若某些检查被成功绕过、或出现检测失败反过来也能说明 root 检测机制的存在。2. 背景知识App 里常见的 Root 检测手段Hook 时要盯住什么测试文档把具体技术细节委托给知识条目 MASTG-KNOW-0027Root Detection。要设计有效的 Hook必须先理解这些检查在代码层面对应哪些 API 调用。按 MASTG-KNOW-0027 的分类常见检测手段及其对应的运行时观测点如下2.1 文件存在性检查File Existence Checks最广泛的程序化检测方式是检查 rooted 设备上典型存在的文件包括常见 rooting 工具的包文件/system/app/Superuser.apk /system/etc/init.d/99SuperSUDaemon /dev/com.koushikdutta.superuser.daemon/ /system/xbin/daemonsu以及在各处探测su二进制与 busybox/sbin/su /system/bin/su /system/bin/failsafe/su /system/xbin/su /system/xbin/busybox /system/sd/xbin/su /data/local/su /data/local/xbin/su /data/local/bin/su典型 Java 实现是遍历PATH环境变量中的目录逐个判断su是否存在public static boolean checkRoot(){ for(String pathDir : System.getenv(PATH).split(:)){ if(new File(pathDir, su).exists()) { return true; } } return false; }从运行时观测的角度看这类检查最终都会落到java.io.File.exists()/access()等调用上——这正是 Hook 的主要切入点。在 Native 层检测代码则通过stat系统调用实现。MASTG-KNOW-0027 给出了一个改编自 rootinspector 的 JNI 示例用stat获取文件信息并在文件存在时返回 1jboolean Java_com_example_statfile(JNIEnv * env, jobject this, jstring filepath) { jboolean fileExists 0; jboolean isCopy; const char * path (*env)-GetStringUTFChars(env, filepath, isCopy); struct stat fileattrib; if (stat(path, fileattrib) 0) { __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, NATIVE: stat error: [%s], strerror(errno)); } else { __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, NATIVE: stat success, access perms: [%d], fileattrib.st_mode); return 1; } return 0; }Native 层的stat/access则对应系统调用stat/newfstatat/faccessat可通过 strace 追踪见 MASTG-TECH-0032 的执行追踪技术。2.2 执行特权命令另一种判断su是否存在的方式是通过Runtime.getRuntime().exec尝试执行它——若su不在 PATH 上会抛出IOException。同一方法也可用于探测 busybox 等程序。运行时观测点java.lang.ProcessBuilder.start()/Runtime.exec()其底层会触发execve系统调用。2.3 检查运行中的进程Supersu 会运行一个名为daemonsu的认证守护进程该进程的存在是另一类 root 特征。枚举进程可用ActivityManager.getRunningAppProcesses、manager.getRunningServices、ps命令或直接遍历/proc目录。示例取自 MASTG-KNOW-0027public boolean checkRunningProcesses() { boolean returnValue false; // Get currently running application processes ListRunningServiceInfo list manager.getRunningServices(300); if(list ! null){ String tempName; for(int i0;ilist.size();i){ tempName list.get(i).process; if(tempName.contains(supersu) || tempName.contains(superuser)){ returnValue true; } } } return returnValue; }运行时观测点ActivityManager相关 API 的返回值。2.4 检查已安装的 Root 管理包用PackageManager探测已知 root 管理器包名例如对特定包名调用getPackageInfoeu.chainfire.supersu com.noshufou.android.su com.koushikdutta.superuser com.topjohnwu.magisk运行时观测点PackageManager.getPackageInfo()。这里 MASTG-KNOW-0027 特别提示了一个 Android 11 的细节包可见性限制package visibility restrictions会影响该检测手段——若目标包已安装但对应用不可见getPackageInfo的表现与包未安装相同抛出PackageManager.NameNotFoundException从而产生漏报。开发者可通过 manifest 中的queries元素声明需要查询的包queries package android:namecom.topjohnwu.magisk / /queries或使用QUERY_ALL_PACKAGES权限受 Google Play 限制约束未必适用于多数场景。2.5 其他检测维度可写分区与系统目录系统/数据目录正常为只读挂载rooted 设备上可能被挂载为读写。检测方式为查找带rw标志挂载的文件系统读/proc/mounts或在 data 目录尝试创建文件——对应openat/creat等系统调用。自定义构建检测检查BUILD.TAGS是否含test-keys通常表明自定义 Android 镜像。MASTG-KNOW-0027 引用的 RootBeer 示例public boolean detectTestKeys() { String buildTags android.os.Build.TAGS; return buildTags ! null buildTags.contains(test-keys); }缺少 Google OTA 证书也是自定义 ROM 的迹象。此外检测也可借助第三方库如 MASTG-TOOL-0146、MASTG-TOOL-0147两者均未获 OWASP 背书这些库以 Java Native 混合实现多种检测以提高绕过难度。2.6 从真实 Demo 印证Native 层 root 检测长什么样仓库中的演示 MASTG-DEMO-0133Root Detection Logic in Native Layer with Insufficient Obfuscation展示了一个把 root 检测下沉到 native 库的示例Java/Kotlin 层加载librootcheck.so并调用findRootArtifactPath()检查常见su路径。该 Demo 用 Radare2 在.rodata中发现明文存储的/system/bin/su、/sbin/su、/system/xbin/su字符串证明检测指标未经编码/加密。这正好印证了 MASTG-KNOW-0027 中 Nativestat检查的思路当 Hook 不到 Java 层的File.exists()时应下沉到 native 层的stat/access与 strace 系统调用层面寻找证据。3. 测试步骤安装、Hook、系统调用追踪与充分操作MASTG-TEST-0325 的 Steps 部分共四步逐条展开如下。3.1 使用 MASTG-TECH-0005 安装 AppMASTG-TECH-0005Installing Apps给出了标准操作adb install ./myApp.apk多设备场景下可用-d已连接物理设备、-e模拟器/TCP 设备或-s serial指定目标adb -d install ./myApp.apk # 物理设备 adb -e install ./myApp.apk # 模拟器 adb devices # 列出所有设备 adb -s 37081JEHN05882 install ./myApp.apk注意安装的是与目标环境匹配的构建若使用 root 设备/模拟器需保证应用签名与调试环境兼容对于重打包签名不一致的包需先adb uninstall package再安装否则会出现INSTALL_FAILED_UPDATE_INCOMPATIBLE。3.2 使用 MASTG-TECH-0043 Hook 相关 API 调用MASTG-TECH-0043Method Hooking介绍了两种主流手段Xposed 模块通过XposedHelpers.findAndHookMethod覆写目标类方法。该技术在 MASTG-TECH-0043 中给出了完整示例——针对遍历/sbin/、/system/bin/等目录查找su的混淆方法com.example.a.b.c()用 Xposed 模块将其返回值强制改为false并打印XposedBridge.log(Caught root check!)。Frida 脚本用Java.perform获取类包装器后覆写方法实现。对本测试而言Hook 的目标是**捕获而非修改**不改变返回值只记录哪些 root 检测 API 被调用。结合第 2 节的观测点清单一个典型的检测存在性探针脚本会 Hook 如下方法并打印调用栈/参数use strict; Java.perform(function () { // 1) 文件存在性检查第 2.1 节File.exists / PATH 遍历 su var File Java.use(java.io.File); File.exists.implementation function () { var path this.getAbsolutePath(); console.log([] File.exists( path )); return this.exists(); }; // 2) 特权命令执行检查第 2.2 节 var Runtime Java.use(java.lang.Runtime); Runtime.exec.overload([Ljava.lang.String;).implementation function (cmd) { console.log([] Runtime.exec( JSON.stringify(cmd) )); return this.exec(cmd); }; // 3) 包名检查第 2.4 节Magisk / SuperSU 等 var PM Java.use(android.app.Application).currentApplication().getPackageManager(); var PackageManager Java.use(android.content.pm.PackageManager); var nameFinder PackageManager.NameNotFoundException.class; try { PM.getPackageInfo(com.topjohnwu.magisk, 0); console.log([] getPackageInfo(com.topjohnwu.magisk): 命中已安装且可见); } catch (e) { console.log([] getPackageInfo(com.topjohnwu.magisk): (e instanceof PackageManager.NameNotFoundException ? NameNotFoundException未安装或不可见 : e)); } // 完整做法应 Hook PackageManager.getPackageInfo 本身并记录所有被查询的包名 // 4) 进程枚举检查第 2.3 节 var ActivityManager Java.use(android.app.ActivityManager); ActivityManager.getRunningAppProcesses.implementation function () { console.log([] ActivityManager.getRunningAppProcesses() 被调用); return this.getRunningAppProcesses(); }; });上面的脚本是对文档hook the relevant API calls要求的具体化示例目标类与方法名需依据 MASTG-TEST-0324 静态分析结果或目标 App 实际代码调整核心原则是保持原始行为不变、仅做记录。Frida 的加载方式在 MASTG-TECH-0043 与 MASTG-TECH-0144 中都有示范如前台启动注入frida -U -f package_name -l root_check_probe.js --no-pauseMASTG-TECH-0144 还提供了一条快速路径objection -n App名 start后执行android root disable它会 Hook 常见 root 检测 API 并返回安全值——若使用该命令前 App 出现退出/拒止行为而执行后正常也可作为 root 检测存在的旁证但按测试要求正式观测仍应以探针式 Hook 的记录输出为准。3.3 使用 MASTG-TECH-0032 追踪相关系统 API 调用Java 层 Hook 不到时检测逻辑在 Native 层如第 2.6 节 Demo 所示下沉到系统调用层。MASTG-TECH-0032Execution Tracing给出的 strace 用法与本测试高度契合——root 检测关注的是文件访问与进程探测类系统调用可按需组合过滤strace -ff -s 2000 -p pgrep -f package_name | head -1 -e traceopenat,access,fstat,newfstatat,readlinkat,execve,ptrace,prctl,mmap,mprotect参数含义引自 MASTG-TECH-0032-ff跟随所有线程及 fork/clone 出的子进程为每个线程/进程写独立输出流-s 2000最多捕获字符串参数 2000 字节这对观察完整路径如/system/bin/failsafe/su与 socket 数据很关键-p指定目标进程 PID示例中用pgrep -f按包名定位-e trace只追踪指定系统调用降低噪音。若只关心文件检查可直接用-e tracefile等价于open,openat,creat,link,unlink,...的组合strace -ff -s 2000 -p pgrep -f package_name | head -1 -e tracefile在输出中搜索第 2 节列出的路径su、magisk、/proc/mounts、busybox等即可确认 Native 层 root 检测正在工作。两点注意事项来自 MASTG-TECH-0032其一strace 依赖ptrace附加一旦目标启用反调试就会失败其二要捕获生命周期早期的行为应开启开发者选项中的Wait for Debugger让应用启动即挂起后再附加或用轮询脚本尽快附加该脚本是近似方案并非真正的启动级追踪。此外若 Java 层追踪不足jdb的trace go methods与 Android Studio Profiler 也可辅助恢复被混淆代码的执行结构rooted 设备上还可考虑 ftrace 等内核级追踪。3.4 充分操作 App 触发尽可能多的流程原文档第 4 步要求Exercise the app extensively to trigger as many flows as possible and enter sensitive data wherever you can. 这是很多检测逻辑被漏检的原因——root 检测点常分布在登录、敏感操作转账、导出、后台服务等路径上而非仅在主界面。结合 MASTG-BEST-0030 中将检查放在敏感操作与会话建立附近的最佳实践反推测试时务必覆盖敏感功能入口包括登录/登出、会话重建、推送唤醒、后台存活等并留意检测是否只在特定进程如:remoteviews、后台服务进程中触发——strace 的-ff与 Frida 的进程枚举spawn后enumerateProcesses能帮助你发现这些额外进程中的检查。4. 观测结果、评估标准与误报分析4.1 Observation期望观测按文档定义输出应包含所有观察到的 root 检测检查实例以及被 Hook 的方法/API。一次合格的观测结果通常长这样Frida 探针输出[] File.exists(/system/xbin/su)、[] Runtime.exec([su,-c,...])、[] getPackageInfo(com.topjohnwu.magisk)等调用记录连同调用时间线与所属线程strace 输出openat(AT_FDCWD, /sbin/su, O_RDONLY) -1 ENOENT (No such file or directory)、newfstatat(..., /system/bin/su, ...)等针对 root 指标路径的系统调用。将两类输出与 MASTG-TEST-0324 的静态清单交叉比对即可形成代码中存在 → 运行时确实触发的完整证据链对动态发现而静态遗漏的机制如混淆/动态加载代码再回到静态分析中补查实现与覆盖范围。4.2 Evaluation评估标准文档的判定规则很明确测试失败条件未观察到任何 root 检测检查实例即 App 未实施 root 检测。结果解读边界本测试的结果应被解读为root 检测逻辑存在的证据而不是对其健壮性/有效性的评估。文档再次指向 MASTG-BEST-0030该最佳实践同时提醒测试方注意检测的固有局限——可通过 Hook、Patch 或隐藏 root 产物被绕过参见 MASTG-TECH-0144 中的重命名二进制、Zygisk/DenyList 隔离、LSPosed 进程过滤、APK 静态 Patch、内核级隐藏等绕过手段清单。4.3 Expected False Negatives预期假阴性文档专门列出假阴性场景这是理解本测试局限的关键Hook/Trace 覆盖不足App 使用的 root 检测手段未被本测试的 Hook 点或系统调用过滤集合覆盖例如自定义的/proc解析逻辑、内存级检查、非典型系统调用路径检测逻辑刻意规避检测通过混淆、动态代码加载DexClassLoader加载运行时下载的检测 dex、反插桩反调试/反 Frida如检测 frida-agent 端口、/proc/self/maps扫描、ptrace保护等手段规避 Hook。因此在无发现时不能据此断言App 没有 root 检测可能需要进一步的手工逆向或定制插桩例如按 MASTG-DEMO-0133 所示对 native 库做字符串/交叉引用分析或对execve前的行为做内核级追踪。5. 小结把 TEST-0325 放进完整的 MASVS-RESILIENCE 测试流知识底座MASTG-KNOW-0027 给出了 root 检测的六大类技术手段文件存在性、特权命令、进程枚举、包名探测、可写分区、自定义构建与具体指标清单是设计 Hook 点与 strace 过滤条件的直接依据测试对偶静态侧 MASTG-TEST-0324 负责找出代码里有哪些检查动态侧 MASTG-TEST-0325本篇负责确认运行时是否真的执行两者循环使用以逼近真实覆盖执行手段安装用 MASTG-TECH-0005Java 层探针用 MASTG-TECH-0043系统调用层用 MASTG-TECH-0032可选绕过验证用 MASTG-TECH-0144结论约束无论正例还是反例结论表述都应落在检测到/未检测到 root 检测逻辑的运行时执行这一层避免外推为该防御有效/无效防御侧的加固与调优诉求请参考 MASTG-BEST-0029Resilience 与 RASP 信号总述与 MASTG-BEST-0030分层防御、检查点分散、多种手段组合、按会话/版本轮换检查项等原则。掌握以上链路后你可以对任意 Android 目标复现本测试静态定位检测面 → 设计探针式 Hook 与 strace 过滤集 → 充分驱动 App 流程 → 以存在性证据口径输出结论并对假阴性场景标注所需的进一步手工分析工作。赞分享文档教程网络安全【免费下载链接】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点击查看免费下载相关推荐MASTG MASTG-TEST-0264用 Frida Hook 在 Android 运行时动态检测 StrictMode API 使用MASTG MASTG TEST 0264用 Frida Hook 在 Android 运行时动态检测 StrictMode API 使用 本篇指南基于 OW文档教程网络安全MASTG Android 静态检测 Root Detection 机制MASTG-TEST-0324 实施指南与源码级验证MASTG Android 静态检测 Root Detection 机制MASTG TEST 0324 实施指南与源码级验证 本篇基于 OWASP MASTG文档教程网络安全Android 强制更新运行时安全测试实战MASTG-TEST-0382 深度解析Android 强制更新运行时安全测试实战MASTG TEST 0382 深度解析 本文围绕 OWASP MASTGMobile Application S文档教程网络安全上一篇DeepSeek-Harness 的 dsh-code-review 技能维护机制基于双评审人适配器的定期人工反馈采纳管线下一篇Podman 多阶段构建阶段标签 --stage-labels 完全指南定位与管理中间镜像创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑