)
文档教程网络安全【免费下载链接】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点击查看免费下载本文基于 demos/ios/MASVS-RESILIENCE/MASTG-DEMO-0131 编写。该 Demo 演示了如何构建一个自包含的 iOS 示例应用应用在运行时主动查询设备属性、Metal GPU 可用性以及 Corellium 虚拟化引擎守护进程文件作为虚拟设备virtual device检测指示器测试人员则借助 Frida 插桩捕获这些底层 API 调用与调用栈验证应用是否确实执行了虚拟设备检测逻辑从而通过 MASTG-TEST-0367 动态测试。读完本文你将掌握三类典型 iOS 虚拟设备指示器的实现写法、用 Frida 挂钩 C 函数并记录回溯backtrace的完整流程以及如何依据运行输出判定测试通过与否。一、背景iOS 虚拟设备检测为何重要在反逆向anti-reversing语境下模拟器/虚拟设备检测的目标是提高攻击者在模拟或虚拟化环境中运行应用的难度。当检测被部署后逆向工程师要么必须绕过这些检查要么只能改用物理设备从而限制了大规模设备分析所需的访问途径参见 MASTG-KNOW-0135 的 Overview 部分。所谓虚拟设备是指虚拟化了 iOS 应用所期望的硬件与操作系统环境、且能够直接执行 iOS 设备二进制的环境。它与 iOS Simulator运行模拟器构建产物有本质区别后者属于 MASTG-KNOW-0088 讨论的范畴。自 MASTG-TOOL-0108Corellium 发布以来iOS 虚拟化得以商用化——Corellium 使用真正的 ARM 型 1 型虚拟机监视器type 1 hypervisor其虚拟设备是 ARM 原生的可以在不做代码修改的情况下运行生产代码这让在虚拟设备上开展 iOS 应用的逆向与安全测试成为现实与此同时近期的 vPhone 与 Super Tart 等研究项目也进一步扩展了虚拟设备检测的对抗面见 MASTG-KNOW-0135。检测的核心策略是识别常见虚拟化方案的特性与局限。典型指示器包括硬件能力探测Hardware Capability ProbesCorellium 官方文档明确指出其 iOS 设备缺少 GPU/Metal 支持且当前不支持 NFC 与 Bluetooth。因此可通过MTLCreateSystemDefaultDevice()Metal GPU、NFCReaderSession.readingAvailableNFC、CBCentralManager蓝牙等系统 API 查询硬件存在性设备属性查询Device Properties通过sysctlbyname(hw.machine)获取硬件机型标识再与运行时观察到的硬件能力做交叉校验——一个宣称的机型若与真实应具备的能力不匹配便是虚拟设备的有力线索虚拟化引擎文件存在性Presence of Specific Virtualization Engine FilesCorellium 会在设备中加入名为corelliumd的守护进程其标准路径为/usr/libexec/corelliumd该文件不属于标准 iOS 设备。需要注意的是MASTG-KNOW-0135 同时给出安全警示虚拟设备检测本质上是猫鼠游戏检测方法与绕过手段持续演化有充分时间与资源的攻击者可通过挂钩hooking或修补patching检测逻辑来规避文件类检查也容易被隐藏、重命名、删除或拦截访问。因此这些技术应作为纵深防御defense-in-depth的一部分而非独立解决方案。二、示例应用三类指示器检查的完整实现MASTG-DEMO-0131 的示例应用Swift 实现位于 demos/ios/MASVS-RESILIENCE/MASTG-DEMO-0131/MastgTest.swift。应用执行虚拟设备指示器检查并在 UI 中报告查询值与指示器结果代码中注释为 This sample demonstrates iOS virtual device detection by executing virtual device indicator checks and reporting a final verdict in the UI。2.1 指示器分级模型与结果结构示例先定义了一个四级指示器枚举IndicatorLevelprivate enum IndicatorLevel { case expected // 符合物理设备预期 case suspicious // 可疑 case confirmed // 已确认强证据 case inconclusive // 无法得出结论 }以及承载单条检查结果的结构体IndicatorResult包含检查顺序order、指示器名称name、观测值observed、分级level与原因说明reasonprivate struct IndicatorResult { let order: Int let name: String let observed: String let level: IndicatorLevel let reason: String }2.2 三项检查的逐项解析检测器核心类为VirtualDeviceDetector其run()依次串联三类检查func run() - String { let machineIdentifier currentMachineIdentifier() let results [ machineIndicator(for: machineIdentifier), metalIndicator(), corelliumIndicator() ] return buildReport(from: results) }第一项设备机型标识检查machineIndicator。通过sysctlbyname(hw.machine)查询硬件机型标识private func currentMachineIdentifier() - String { var size: size_t 0 guard sysctlbyname(hw.machine, nil, size, nil, 0) 0, size 1 else { return unknown } var buffer CChar) let result buffer.withUnsafeMutableBufferPointer { pointer in sysctlbyname(hw.machine, pointer.baseAddress, size, nil, 0) } guard result 0 else { return unknown } return String(cString: buffer) }实现采用标准的两段式sysctlbyname调用先传空缓冲区获取所需size同时校验调用成功且size 1再分配缓冲区第二次调用取回 C 字符串。随后machineIndicator(for:)依据返回值分级——若返回unknown判为inconclusiveThe app could not resolve the device model.否则判为expected原因统一为The reported model can be cross-checked against the hardware capabilities observed at runtime.源码中标注PASS: [MASTG-TEST-0367]。第二项Metal GPU 可用性检查metalIndicator。调用MTLCreateSystemDefaultDevice()探测默认 Metal 设备if MTLCreateSystemDefaultDevice() ! nil { return IndicatorResult(order: 2, name: Metal GPU, observed: available, level: .expected, reason: A Metal device is available, which is consistent with a physical iOS device.) } return IndicatorResult(order: 2, name: Metal GPU, observed: missing, level: .suspicious, reason: No Metal device is available, which is unusual for a supported physical iOS device.)逻辑非常直观Metal 设备可用 →expected与物理设备一致不可用 →suspicious受支持的物理 iOS 设备上通常都应有 Metal 设备。这与 MASTG-KNOW-0135 中 Corellium iOS 设备缺乏 GPU/Metal 支持的官方说明相对应。第三项Corellium 守护进程文件检查corelliumIndicator。用stat检查/usr/libexec/corelliumd是否存在private func corelliumDaemonExists() - Bool { var fileInfo stat() return /usr/libexec/corelliumd.withCString { path in stat(path, fileInfo) 0 } }若文件存在则判为confirmed并给出强证据理由The file /usr/libexec/corelliumd exists, which is a strong Corellium indicator.不存在则判为expectedThe file /usr/libexec/corelliumd was not found.。注意 MASTG-KNOW-0135 同时提醒Corellium 也支持创建不带corelliumd守护进程的 iOS 设备因此文件缺失不足以排除 Corellium 虚拟设备——文件类检查只是指示器且易于被绕过。2.3 报告与最终判定buildReportbuildReport(from:)先将结果按order排序再统计confirmed与suspicious结果生成多行文本报告private func buildReport(from results: [IndicatorResult]) - String { let orderedResults results.sorted { $0.order $1.order } let confirmedResults orderedResults.filter { $0.level .confirmed } let suspiciousResults orderedResults.filter { $0.level .suspicious } var lines [ Virtual device detection results:, , Indicators: ] for result in orderedResults { lines.append(- \(result.name): \(result.observed) [\(result.level.label)] - \(result.reason)) } lines.append() lines.append(Verdict:) if !confirmedResults.isEmpty { lines.append(- Likely virtual device.) for result in confirmedResults { lines.append( - \(result.name): \(result.reason)) } } else if !suspiciousResults.isEmpty { lines.append(- No strong virtual-device verdict yet. Review the suspicious indicator below.) for result in suspiciousResults { lines.append( - \(result.name): \(result.reason)) } } else { lines.append(- Likely physical device. No strong virtual-device indicators were observed.) } return lines.joined(separator: \n) }判定逻辑形成三级结论存在confirmed结果 → Likely virtual device.并逐条列出确认依据仅有suspicious→ No strong virtual-device verdict yet.要求人工复核可疑项否则 → Likely physical device.。最后MastgTest.mastgTest(completion:)通过闭包把报告字符串交给 UI 展示。2.4 示例的刻意取舍设计说明原文档明确了两点设计取舍回避 NFC 与蓝牙检查这两类检查可能需要额外的 entitlements、用途描述字符串usage descriptions或依赖用户可控状态如蓝牙开关会削弱 Demo 的确定性determinism回避 App Attest 检查App Attest 需要服务端校验流程破坏 MASTG Demo 自包含self-contained的要求。因此示例聚焦于设备属性、Metal GPU 可用性与 Corellium 文件这三类确定性强、无需额外配置的指示器。三、Frida 插桩如何捕获虚拟设备检测调用示例配套的 Frida 脚本 demos/ios/MASVS-RESILIENCE/MASTG-DEMO-0131/script.js配合 MASTG-TOOL-0039FridaiOS挂钩三个底层 C 函数精确对应示例的三项检查。3.1 通用挂钩基础设施脚本先定义了两块基础设施const BACKTRACE_LIMIT 6; const hookedAddresses new Set(); function printBacktrace(context) { console.log(Backtrace:); const frames Thread.backtrace(context, Backtracer.ACCURATE) .map(DebugSymbol.fromAddress) .slice(0, BACKTRACE_LIMIT); for (const frame of frames) { console.log(frame); } } function logEvent(message, context) { console.log(message); printBacktrace(context); console.log(); } function hookGlobalExport(symbolName, callbacks) { const address Module.findGlobalExportByName(symbolName); if (address null) { console.log([skip] ${symbolName} not found); return; } const addressKey address.toString(); if (hookedAddresses.has(addressKey)) { return; } hookedAddresses.add(addressKey); Interceptor.attach(address, callbacks); }要点Thread.backtraceBacktracer.ACCURATE采集精确调用栈DebugSymbol.fromAddress将地址解析为符号名最多保留前 6 帧BACKTRACE_LIMIThookGlobalExport通过Module.findGlobalExportByName定位全局导出符号并用Set去重避免重复挂钩同一地址。3.2 挂钩MTLCreateSystemDefaultDevicehookGlobalExport(MTLCreateSystemDefaultDevice, { onEnter(args) { this.contextCopy this.context; }, onLeave(retval) { const outcome retval.isNull() ? missing : available; logEvent(MTLCreateSystemDefaultDevice() ${outcome}, this.contextCopy); } });在onEnter中保存上下文副本用于回溯在onLeave中根据返回指针是否为 null 输出available/missing。3.3 挂钩sysctlbyname过滤hw.machinehookGlobalExport(sysctlbyname, { onEnter(args) { this.contextCopy this.context; this.name args[0].readCString(); this.outputPtr args[1]; this.shouldLog this.name hw.machine !this.outputPtr.isNull(); }, onLeave(retval) { if (!this.shouldLog || retval.toInt32() ! 0) { return; } const value this.outputPtr.readCString(); logEvent(sysctlbyname(hw.machine) ${value}, this.contextCopy); } });注意两个过滤条件仅当查询名称为hw.machine且输出缓冲区指针非空即第二次取值调用而非第一次求 size 的调用时记录仅当retval 0调用成功时读取并输出结果。3.4 挂钩stat过滤 Corellium 守护进程路径function hookStatSymbol(symbolName) { hookGlobalExport(symbolName, { onEnter(args) { this.contextCopy this.context; this.path args[0].readCString(); this.shouldLog this.path /usr/libexec/corelliumd; }, onLeave(retval) { if (!this.shouldLog) { return; } const outcome retval.toInt32() 0 ? present : missing; logEvent(${symbolName}(/usr/libexec/corelliumd) ${outcome}, this.contextCopy); } }); } hookStatSymbol(stat);同样用路径过滤只记录目标路径/usr/libexec/corelliumd并以返回值为 0 与否判定present/missing。四、运行步骤与复现原文档给出的运行步骤安装应用见 MASTG-TECH-0056Frida 安装与使用见 MASTG-TOOL-0039在设备上安装应用org.owasp.mastestapp.MASTestApp-iOS确保本机已安装 Frida且设备上已运行frida-server在越狱设备上通过 Sileo 等渠道安装后自动以 root 运行默认仅监听本地 USB 接口可通过frida-ps -U验证连接运行 run.sh 以 Frida 启动应用#!/bin/bash frida -U -f org.owasp.mastestapp.MASTestApp-iOS -l ./script.js -o output.txt-U连接 USB 设备-f以 spawn 方式冷启动目标应用应用启动前即注入-l加载脚本-o将输出写入output.txt点击应用中的Start按钮触发检测流程按CtrlC停止脚本。五、运行输出解读ObservationDemo 仓库附带的 output.txt 记录了真实运行捕获。完整输出为sysctlbyname(hw.machine) iPhone10,6 Backtrace: 0x1c2ac4368 CoreFoundation!___CFGetProductName_block_invoke 0x1c9794780 libdispatch.dylib!_dispatch_client_callout 0x1c9764ddc libdispatch.dylib!_dispatch_once_callout 0x1c2a0fe1c CoreFoundation!_CFBundleInfoPlistProcessInfoDictionary 0x1c2a39e30 CoreFoundation!_CFBundleCopyInfoDictionaryInDirectoryWithVersion 0x1c2a2e588 CoreFoundation!_CFBundleRefreshInfoDictionaryAlreadyLocked sysctlbyname(hw.machine) iPhone10,6 Backtrace: 0x104e29fb0 MASTestApp.debug.dylib!closure #1 in VirtualDeviceDetector.currentMachineIdentifier() 0x104e2a000 MASTestApp.debug.dylib!partial apply for closure #1 in VirtualDeviceDetector.currentMachineIdentifier() 0x104e2a108 MASTestApp.debug.dylib!$sSa30withUnsafeMutableBufferPointeryqd__qd__SryxGzqd_0_YKXEqd_0_YKs5ErrorRd_0_r0_lF 0x104e287cc MASTestApp.debug.dylib!VirtualDeviceDetector.currentMachineIdentifier() 0x104e28090 MASTestApp.debug.dylib!VirtualDeviceDetector.run() 0x104e28040 MASTestApp.debug.dylib!static MastgTest.mastgTest(completion:) MTLCreateSystemDefaultDevice() available Backtrace: 0x104e28b4c MASTestApp.debug.dylib!VirtualDeviceDetector.metalIndicator() 0x104e28104 MASTestApp.debug.dylib!VirtualDeviceDetector.run() 0x104e28040 MASTestApp.debug.dylib!static MastgTest.mastgTest(completion:) 0x104e2d018 MASTestApp.debug.dylib!closure #1 in closure #1 in closure #1 in ContentView.body.getter 0x1c686b35c SwiftUI!0x7d735c (0x18ac6f35c) 0x1c686b844 SwiftUI!0x7d844 (0x18ac6f844) stat(/usr/libexec/corelliumd) missing Backtrace: 0x104e2a5c4 MASTestApp.debug.dylib!closure #1 in VirtualDeviceDetector.corelliumDaemonExists() 0x104e2a5fc MASTestApp.debug.dylib!partial apply for closure #1 in VirtualDeviceDetector.corelliumDaemonExists() 0x1bc937a1c libswiftCore.dylib!String.withCStringA(_:) 0x104e29dec MASTestApp.debug.dylib!VirtualDeviceDetector.corelliumDaemonExists() 0x104e28d60 MASTestApp.debug.dylib!VirtualDeviceDetector.corelliumIndicator() 0x104e28124 MASTestApp.debug.dylib!VirtualDeviceDetector.run()对捕获结果的逐条解读点击Start按钮后触发sysctlbyname(hw.machine)返回iPhone10,6共出现两次调用。第一次的调用栈位于CoreFoundation/libdispatch.dylib属于框架层Framework-level的早期调用___CFGetProductName_block_invoke等第二次的调用栈定位到应用自身即VirtualDeviceDetector.currentMachineIdentifier()及其闭包closure证实示例在运行时查询了设备机型标识MTLCreateSystemDefaultDevice()返回available调用栈清晰显示VirtualDeviceDetector.metalIndicator()→VirtualDeviceDetector.run()→MastgTest.mastgTest(completion:)→ContentView.body.getterSwiftUI 视图证实示例执行了 Metal GPU 可用性检查且当前环境存在 Metal 设备stat(/usr/libexec/corelliumd)返回missing调用栈显示VirtualDeviceDetector.corelliumDaemonExists()内部经String.withCString调用→VirtualDeviceDetector.corelliumIndicator()→VirtualDeviceDetector.run()证实示例检查了 Corellium 守护进程文件且该文件在当前环境不存在。run.sh将脚本输出写入output.txt回传的console.log即上述逐行记录每个事件后都附带了 6 帧以内的符号化回溯足以区分框架自身行为与应用主动调用。六、测试判定MASTG-TEST-0367 通过本 Demo 对应动态测试 tests-beta/ios/MASVS-RESILIENCE/MASTG-TEST-0367.mdRuntime Use of Virtual Device Detection Techniques关联 MASWE-0053。该测试通过尝试挂钩常见虚拟设备检测机制验证应用是否实现了对 iOS 虚拟设备如 Corellium存在性的运行时检测其判定规则为若未观察到任何虚拟设备检测检查实例则测试失败fail。MASTG-DEMO-0131 的测试结果为pass依据是运行输出确认应用在运行时实现了三类检测sysctlbyname(hw.machine)调用设备属性检查应用查询了设备机型标识报告的机型可以与运行时观察到的硬件能力交叉校验cross-checkMTLCreateSystemDefaultDevice()调用硬件能力检查应用检查了是否存在 Metal GPUstat(/usr/libexec/corelliumd)调用虚拟化引擎文件检查应用检查了 Corellium 守护进程文件是否存在。测试边界与预期误报Expected False NegativesMASTG-TEST-0367 明确指出该测试不覆盖检测机制的健壮性与有效性——其效果往往难以仅靠自动化测试评估可能需要手动逆向与自定义插桩相关最佳实践见 MASTG-BEST-0053。同时存在预期误报场景应用使用了未被挂钩/追踪机制覆盖的虚拟设备检测机制检测逻辑通过混淆、动态代码加载或反插桩anti-instrumentation技术规避了追踪。在这些情况下未发现检测行为并不保证应用没有实施虚拟设备检测仍需额外的手动逆向或自定义插桩来识别与分析。七、相关资源示例完整源码MastgTest.swift、script.js、run.sh、output.txt知识背景MASTG-KNOW-0135Virtual Devices Detection关联测试MASTG-TEST-0367相关工具CorelliumMASTG-TOOL-0108、Frida iOSMASTG-TOOL-0039、应用安装MASTG-TECH-0056最佳实践MASTG-BEST-0053如需在真实目标上验证可将 script.js 的挂钩目标sysctlbyname、MTLCreateSystemDefaultDevice、stat与过滤条件替换为目标应用可能使用的检测 API 与文件路径并将run.sh中的应用标识换成目标应用的 Bundle ID即可复现相同的插桩观察流程。赞分享文档教程网络安全【免费下载链接】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-DEMO-0114用 Frida 追踪 Android 应用中的模拟器检测逻辑实战解读 MASTG DEMO 0114用 Frida 追踪 Android 应用中的模拟器检测逻辑 导读 本篇文章围绕 OWASP MASTGMobile文档教程网络安全OWASP MASTG iOS 实战用 Frida 动态检测 LAContext.evaluatePolicy 事件绑定式生物识别认证MASTG-DEMO-0042OWASP MASTG iOS 实战用 Frida 动态检测 LAContext.evaluatePolicy 事件绑定式生物识别认证MASTG DEMO文档教程网络安全OWASP MASTG 实战检测 Android 应用中不校验证书链的 TrustManagerMASTG-DEMO-0054OWASP MASTG 实战检测 Android 应用中不校验证书链的 TrustManagerMASTG DEMO 0054 本篇技术指南以 OWASP文档教程网络安全上一篇免费也能下Steam模组WorkshopDL Steam创意工坊下载器零基础完整指南下一篇魔兽争霸3兼容速修三步解除4MB地图限制、解锁144帧的免费插件实测创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考