Android安全实战:基于InsecureBankv2的渗透测试工具开发指南

📅 2026/7/3 23:55:10 👁️ 阅读次数 📝 编程学习
Android安全实战:基于InsecureBankv2的渗透测试工具开发指南

1. 项目概述:为什么选择InsecureBankv2作为你的Android安全“训练场”?

如果你对移动安全、渗透测试或者Android应用漏洞挖掘感兴趣,那么InsecureBankv2这个名字你一定不陌生。它不是一个真实的银行应用,而是一个由安全专家Dinesh Shetty精心设计的、故意内置了多种安全漏洞的Android应用。你可以把它理解为一个“漏洞游乐场”或者“安全实验室”,专门用来学习和实践Android渗透测试技术。我最初接触它,是为了给团队的新人找一个能上手实操、又不会惹麻烦的靶场,结果发现,围绕它来构建一套自己的漏洞利用工具链,是提升实战能力最快的方式。

为什么这么说?因为真实的渗透测试环境往往复杂且敏感,直接上手风险高、法律边界模糊。而InsecureBankv2提供了一个绝对安全、可控的环境。它模拟了一个银行应用的核心功能——登录、查看余额、转账——却在这些功能里埋下了诸如不安全的组件暴露、硬编码凭证、逻辑缺陷、不安全的通信等经典漏洞。你的任务不是搞破坏,而是像一个安全研究员或白帽黑客那样,去发现、分析并验证这些漏洞。这个过程,恰恰是构建一个有效渗透测试工具的核心:你需要理解漏洞原理,设计检测逻辑,编写利用代码,最后验证结果。通过这个项目,你不仅能深入理解Android安全机制,更能掌握从漏洞分析到工具开发的完整闭环,这对于从事移动应用安全评估、红队演练或者漏洞研究来说,是极其宝贵的经验。

2. 环境搭建与靶场部署:打造你的专属移动安全实验室

工欲善其事,必先利其器。在开始“拆解”InsecureBankv2之前,我们需要一个稳定、隔离的测试环境。这不仅能保证测试过程的安全可控,也能让你更专注于技术本身,避免被各种环境问题干扰。

2.1 核心测试平台选择:模拟器 vs 真机

首先,你需要一个运行Android系统的设备。主流选择有两个:Android模拟器和物理真机。

对于InsecureBankv2这类学习型靶场,我强烈推荐使用Android Studio自带的官方模拟器。原因有三:第一,兼容性最好,尤其是涉及到需要特定系统镜像或Google Play服务的场景;第二,快照(Snapshot)功能可以让你随时保存一个干净的测试状态,一键还原,非常适合反复进行漏洞利用尝试;第三,网络配置和文件传输非常方便。当然,如果你有一台专门用于测试的备用安卓手机,并且已经解锁了Bootloader、刷入了可调试的系统镜像(如LineageOS),那也是一个不错的选择,能接触到更真实的硬件环境。但对于绝大多数初学者和以学习为目的的从业者,模拟器是最高效、最稳妥的起点。

注意:切勿在你日常使用的主力手机或包含个人敏感数据的设备上进行渗透测试练习,即使是对InsecureBankv2这样的无害应用。一些测试操作可能会修改系统设置或安装证书,存在潜在风险。

2.2 靶场应用InsecureBankv2的获取与安装

InsecureBankv2的官方源码和APK文件托管在GitHub上。最直接的方式是下载其预编译的APK文件进行安装。

  1. 下载APK:访问项目的GitHub仓库(通常搜索“InsecureBankv2”即可找到),在Release页面或根目录找到名为InsecureBankv2.apk的文件并下载到你的电脑。
  2. 安装到模拟器:启动你的Android模拟器(建议使用Android 8.0或9.0的镜像,兼容性较好)。打开命令行终端,使用ADB(Android Debug Bridge)工具进行安装。ADB工具通常包含在Android SDK的platform-tools目录下。安装命令非常简单:
    adb install /path/to/your/InsecureBankv2.apk
    如果看到“Success”字样,说明安装成功。你可以在模拟器的应用列表中找到名为“InsecureBankv2”的应用图标。
  3. 初始配置:首次运行InsecureBankv2,应用可能会要求你配置一个“服务器地址”。这里通常使用模拟器环回地址的变体10.0.2.2(这是Android模拟器中专指宿主电脑本地IP的特殊地址)。如果应用有配套的服务器端(某些漏洞需要),你可能还需要在电脑上运行一个简单的Python HTTP服务器。但就客户端漏洞挖掘而言,很多测试可以直接进行。

2.3 渗透测试工具链准备:你的“瑞士军刀”

仅仅有靶场还不够,你需要一套趁手的工具。下面是我在Android渗透测试中最常用、也最适合配合InsecureBankv2使用的工具组合,它们覆盖了静态分析、动态分析、流量抓包和漏洞利用各个阶段。

  • 静态分析工具

    • JADX-GUI:这是我的首选反编译工具。它可以直接打开APK文件,将Dex字节码反编译成可读性非常高的Java代码。对于分析InsecureBankv2的硬编码密码、逻辑判断、组件定义等静态漏洞至关重要。相比apktool只进行反汇编,JADX提供的代码视图更利于快速理解应用逻辑。
    • APKTool:虽然反编译代码可读性不如JADX,但apktool在解包资源文件(如图片、XML布局、AndroidManifest.xml)、以及重打包APK方面不可替代。当你需要修改Smali代码(Android的汇编语言)进行深度漏洞验证或制作PoC时,就必须用到它。
  • 动态分析工具

    • Frida:动态插桩框架的王者。它允许你在应用运行时注入JavaScript脚本,来Hook Java方法和Native函数,实时监控、修改参数和返回值。对于分析InsecureBankv2的运行时行为、绕过客户端校验、动态提取内存中的敏感数据(如解密后的密钥)来说,Frida是神器。你需要先在测试设备上安装Frida Server,然后在电脑上通过Python脚本进行控制。
    • Objection:一个基于Frida的命令行工具,它封装了许多常见的移动端安全测试任务,比如绕过SSL Pinning、枚举可用的Activity和Service、搜索内存中的敏感数据等。对于快速评估和初步探索,Objection能极大提升效率。
  • 流量分析工具

    • Burp SuiteOWASP ZAP:拦截和修改HTTP/HTTPS流量是Web和移动端测试的核心。你需要将测试设备(模拟器或手机)的代理设置为运行Burp Suite的电脑IP和端口(通常是8080)。对于模拟器,还需要在设备上安装Burp的CA证书,以解密HTTPS流量。InsecureBankv2中关于不安全的API通信、传输数据未加密等漏洞,都需要通过抓包来验证。
  • ADB (Android Debug Bridge):这不是一个独立的图形化工具,但它是所有工作的基础。文件推送拉取、安装卸载应用、端口转发、启动组件、获取日志(logcat)都离不开它。确保你的ADB版本较新,并且能稳定连接到测试设备。

准备好这些,你的移动安全实验室就算初步搭建完成了。接下来,我们就可以开始对InsecureBankv2进行“体检”,并在这个过程中,思考如何将我们的发现工具化。

3. 漏洞深度剖析与工具化思路:从发现到自动化

InsecureBankv2包含了OWASP Mobile Top 10中提到的多种典型漏洞。我们不仅仅要找到它们,更要思考:如果我要写一个工具来自动检测这类漏洞,我该怎么做?这个思维转换,就是从“测试者”到“工具开发者”的关键一步。

3.1 漏洞一:暴露的组件与Intent嗅探

漏洞原理:Android应用通过四大组件(Activity, Service, BroadcastReceiver, ContentProvider)与系统或其他应用交互。如果组件在AndroidManifest.xml中被错误地导出(android:exported=”true”或未显式声明但包含Intent Filter),那么任何其他应用,甚至用户通过ADB,都可以直接启动它并传递数据。这可能导致权限提升、敏感信息泄露或拒绝服务。

在InsecureBankv2中的体现:使用JADX打开APK,查看AndroidManifest.xml。你很可能会发现一些本不该对外暴露的组件被设置为导出。例如,一个用于内部处理转账的Activity,或者一个包含敏感操作的BroadcastReceiver。

手动验证:通过ADB,你可以使用am(activity manager)命令来启动一个导出的Activity:

adb shell am start -n com.android.insecurebankv2/.PostLogin –es username “attacker” –es password “guess”

这个命令尝试以“attacker”身份启动PostLogin活动,如果该Activity没有进行充分的权限校验,就可能绕过登录。

工具化思路(构建SniffIntents类工具)

  1. 静态分析模块:编写一个脚本(可以用Python),使用apktool或直接解析APK,提取AndroidManifest.xml。分析所有组件的exported属性和<intent-filter>,标识出所有导出的组件。这是工具的基础信息收集阶段。
  2. 动态探测模块:这是核心。工具需要能自动构造并发送测试Intent到这些导出组件。对于Activity/Service,工具可以模拟am start命令;对于BroadcastReceiver,工具可以发送有序和无序广播。关键在于构造什么样的Intent数据(Action、Category、Extras)。
    • 策略:可以内置一个“Payload”字典,包含常见的敏感参数名,如username,password,token,url,command等,以及一些测试值或路径遍历字符串(如../../../etc/passwd)。
    • 监控:发送Intent的同时,工具需要监控目标应用的反应。这可以通过ADBlogcat来捕获应用日志,寻找错误信息、崩溃堆栈或意外的成功响应。更高级的工具可以结合Frida,在目标应用内部Hook关键方法,直接观察Intent的处理流程和数据流向。
  3. 结果报告模块:将成功触发异常行为(如崩溃、数据返回、权限绕过)的组件、使用的Payload以及观察到的现象整理成报告输出。

实操心得:在构建这类工具时,最大的挑战是降低误报率。不是所有导出的组件都是漏洞,很多是应用正常功能所需。工具需要一定的“智能”去判断组件的敏感性(例如,通过分析组件名称、所属包路径、或尝试从反编译代码中推断其功能),并设计更精巧的Payload,而不仅仅是盲目轰炸。

3.2 漏洞二:硬编码的敏感信息

漏洞原理:将密码、API密钥、加密密钥、后端服务器地址等敏感信息直接以明文形式写在源代码或资源文件中。攻击者一旦反编译应用,这些信息就一览无余。

在InsecureBankv2中的体现:用JADX全局搜索诸如password,key,secret,admin等关键词。你很可能会在某个Java类的静态变量中,或者res/values/strings.xml文件里,找到像superSecretPassword123这样的硬编码凭证。

手动验证:找到这些字符串后,尝试在应用界面中使用它们。例如,如果找到了一个疑似后台管理员密码的字符串,就尝试在登录界面使用它。或者,如果找到了一个加密密钥,尝试用它去解密应用本地存储的加密数据。

工具化思路(构建CredentialHunter类工具)

  1. 字符串提取与模式匹配:工具首先需要解包APK,并遍历所有.dex.jar(如果有)、.so(Native库)以及资源文件(如strings.xml,*.properties)。提取所有可打印的字符串。
  2. 启发式规则引擎:这是工具准确性的核心。不能只靠简单关键词匹配。需要定义一系列复杂的正则表达式和规则:
    • 格式匹配:匹配AWS/Azure/GCP的API密钥格式、数据库连接字符串、JWT令牌格式、加密密钥的常见编码(Base64, Hex)。
    • 上下文分析:在反编译的Java代码中,寻找字符串被赋值给变量名包含PASSWORDKEYSECRETTOKEN的语句。
    • 熵值计算:对于长字符串,计算其信息熵。高熵的随机字符串很可能是加密密钥或令牌,而不是普通的UI文本。
  3. 风险评级与验证:工具应对发现的潜在凭证进行风险评级。例如,一个在LoginActivity中赋值给defaultPassword的字符串,风险等级为“高”。更进一步,工具可以尝试进行简单的验证,比如用发现的URL去发起一个HTTP HEAD请求,看是否能连通;或者用发现的密钥尝试解密一段已知的密文(如果上下文能提供)。

注意事项:这种工具容易产生大量误报,比如将UI中的提示文本“请输入密码”也标记出来。因此,后期的人工审核仍然必不可少。工具的价值在于从海量代码中快速缩小审查范围。

3.3 漏洞三:不安全的通信与证书绑定绕过

漏洞原理:应用使用HTTP明文传输数据,或者虽然使用了HTTPS,但证书验证逻辑存在缺陷(如接受任意证书、证书域名不匹配、未正确实现证书绑定),导致中间人攻击成为可能。

在InsecureBankv2中的体现:使用Burp Suite设置代理并拦截应用流量。你可能会发现某些请求直接使用了http://开头的URL。或者,在配置了Burp的CA证书后,能成功解密HTTPS流量,这说明应用没有启用或正确实现SSL Pinning(证书绑定)。

手动验证:配置好代理和证书后,尝试进行登录、转账等操作。在Burp中观察请求和响应,看敏感数据是否明文传输,或者是否能被成功拦截和修改。

工具化思路(构建通信安全评估工具)

  1. 流量捕获与协议识别:工具需要能启动一个代理服务器(或与现有代理如Burp协作),引导测试应用的流量通过它。然后分析捕获到的所有网络请求,识别出使用的是HTTP还是HTTPS,以及具体的URL端点。
  2. HTTPS深度检测
    • 证书验证测试:工具模拟一个恶意的CA,签发一个用于目标域名的假证书,然后尝试与应用建立HTTPS连接。如果连接成功,说明证书验证有缺陷。
    • SSL Pinning检测与绕过:这是难点。工具需要静态分析APK,寻找常见的证书绑定库(如OkHttp的CertificatePinner, TrustManager的自定义实现)的使用痕迹。动态方面,可以结合Frida,Hook关键的证书验证方法(如X509TrustManager.checkServerTrusted),观察其行为,并尝试通过Frida脚本返回“信任所有证书”的结果来测试是否可绕过。
  3. 敏感信息泄露检测:在解密的流量中(或明文的HTTP流量中),使用正则表达式扫描请求参数、响应体、Cookie、Header中是否包含身份证号、银行卡号、密码、会话令牌等模式的敏感数据。

构建这个工具需要较深的网络和安全协议知识,但一旦成型,它就是自动化移动应用通信安全测试的利器。

4. 构建你的专属渗透测试工具:以“组件漏洞扫描器”为例

理论说得再多,不如动手写一行代码。让我们聚焦于“暴露的组件”这个漏洞点,来设计并实现一个简化但功能完整的漏洞扫描工具原型。我们将这个工具命名为AndroidComponentAuditor

4.1 工具架构设计

我们的工具将采用“静态分析 + 动态探测”的混合模式,工作流程如下:

  1. 输入:一个APK文件路径。
  2. 阶段一:静态提取:解压APK,解析AndroidManifest.xml,列出所有导出的Activity、Service、BroadcastReceiver。
  3. 阶段二:动态测试:通过ADB连接到设备,对每个导出的组件,构造一系列测试Intent并发送,同时监控设备日志和应用状态。
  4. 阶段三:结果分析:根据日志和反应,判断组件是否存在安全隐患(如崩溃、未授权访问、信息泄露)。
  5. 输出:一份结构化的漏洞报告(HTML或JSON格式)。

4.2 核心代码实现详解

我们将使用Python作为开发语言,因为它拥有丰富的库支持(如lxml解析XML,subprocess调用ADB)。

第一步:环境准备与APK解析

import subprocess import xml.etree.ElementTree as ET import zipfile import tempfile import os class AndroidComponentAuditor: def __init__(self, apk_path, adb_path='adb'): self.apk_path = apk_path self.adb_path = adb_path self.package_name = None self.exported_components = {'activities': [], 'services': [], 'receivers': []} self.temp_dir = tempfile.mkdtemp() def extract_manifest(self): """使用apktool解压APK,获取AndroidManifest.xml的明文内容""" # 首先尝试用aapt2或apktool,这里简化,假设已反编译 # 实际项目中,应调用 subprocess.run(['apktool', 'd', self.apk_path, '-o', self.temp_dir, '-f']) # 这里我们演示从已解压的目录读取 manifest_path = os.path.join(self.temp_dir, 'AndroidManifest.xml') if not os.path.exists(manifest_path): # 简易解压:APK本质是ZIP with zipfile.ZipFile(self.apk_path, 'r') as apk_zip: # 寻找manifest文件 for name in apk_zip.namelist(): if name == 'AndroidManifest.xml': apk_zip.extract(name, self.temp_dir) manifest_path = os.path.join(self.temp_dir, name) break return manifest_path

这部分代码负责处理APK文件。在实际成熟工具中,应集成apktoolaapt命令行工具来可靠地反编译资源并获取二进制的AndroidManifest.xml的AXML格式,然后将其转换为可读的XML。上述简化版直接从ZIP中提取,对于未压缩的Manifest有效,但很多APK会压缩它,因此这只是原理演示。

第二步:解析Manifest,识别导出组件

def parse_manifest(self, manifest_path): """解析AndroidManifest.xml,找出导出的组件""" try: # 注意:从APK直接提取的可能是二进制AXML,需要先用aapt2转换 # 这里假设已经是文本XML tree = ET.parse(manifest_path) root = tree.getroot() # 获取包名 self.package_name = root.get('package') # 定义组件类型和对应的标签 component_types = { 'activities': 'activity', 'services': 'service', 'receivers': 'receiver' # broadcast-receiver } for comp_key, comp_tag in component_types.items(): for component in root.iter(comp_tag): comp_name = component.get('{http://schemas.android.com/apk/res/android}name') if comp_name: # 处理相对类名,转换为全限定名 if comp_name.startswith('.'): full_name = self.package_name + comp_name elif '.' not in comp_name: # 可能只是类名,需要结合包名和可能的application节点下的name full_name = self.package_name + '.' + comp_name else: full_name = comp_name # 判断是否导出 exported = component.get('{http://schemas.android.com/apk/res/android}exported') # 规则:显式设置exported="true",或未设置但有intent-filter且targetSdkVersion < 17时默认导出 # 简化:这里只检查显式exported="true"或存在intent-filter且exported未显式设为false has_intent_filter = component.find('intent-filter') is not None is_exported = False if exported is not None: is_exported = exported.lower() == 'true' elif has_intent_filter: # 这里简化处理,实际需考虑targetSdkVersion。为安全起见(多报),假设导出 is_exported = True if is_exported: self.exported_components[comp_key].append({ 'name': full_name, 'has_intent_filter': has_intent_filter }) except ET.ParseError as e: print(f"解析Manifest失败,可能是二进制格式: {e}") # 应在此处调用aapt2进行转换

这段代码是静态分析的核心。它解析XML,根据Android规则判断组件是否导出。这里简化了规则,一个严谨的工具需要完整实现Android系统的导出逻辑,特别是对于<intent-filter>android:exported属性的各种组合情况。

第三步:动态探测组件

def probe_component(self, comp_type, comp_info): """通过ADB发送Intent探测组件""" comp_name = comp_info['name'] # 根据组件类型构造ADB命令 if comp_type == 'activities': # 尝试启动Activity cmd = [self.adb_path, 'shell', 'am', 'start', '-n', f'{self.package_name}/{comp_name}'] # 可以添加一些测试Extra # cmd.extend(['--es', 'test_key', 'test_value']) elif comp_type == 'services': # 尝试启动Service cmd = [self.adb_path, 'shell', 'am', 'startservice', '-n', f'{self.package_name}/{comp_name}'] elif comp_type == 'receivers': # 尝试发送广播 action_name = f"{self.package_name}.TEST_ACTION" cmd = [self.adb_path, 'shell', 'am', 'broadcast', '-a', action_name, '-n', f'{self.package_name}/{comp_name}'] else: return None try: result = subprocess.run(cmd, capture_output=True, text=True, timeout=10) return { 'command': ' '.join(cmd), 'returncode': result.returncode, 'stdout': result.stdout, 'stderr': result.stderr } except subprocess.TimeoutExpired: return {'error': 'Command timed out'} except Exception as e: return {'error': str(e)} def run_dynamic_scan(self): """对所有导出的组件进行动态探测""" scan_results = [] for comp_type, comp_list in self.exported_components.items(): for comp in comp_list: print(f"[*] 探测 {comp_type[:-1]}: {comp['name']}") result = self.probe_component(comp_type, comp) # 同时抓取logcat,寻找崩溃或异常 logcat_cmd = [self.adb_path, 'logcat', '-d', '--pid', '$(pidof com.android.insecurebankv2)', '*:E'] # 简化:这里实际需要先获取应用PID,然后过滤相关日志 # 我们可以运行探测命令后,立即抓取一段时间的logcat scan_results.append({ 'component': comp, 'type': comp_type, 'probe_result': result, # 'log_snippet': log_snippet }) return scan_results

动态探测模块通过ADB shell命令模拟其他应用或用户发送Intent。我们构造了基本的启动命令。一个完善的工具需要构造更丰富的Intent,包括添加不同的Action、Category、Data URI和Extras,以测试组件对各种输入的处理。

第四步:结果分析与报告生成

def analyze_and_report(self, scan_results): """分析探测结果,生成简易报告""" vulnerabilities = [] for res in scan_results: comp_name = res['component']['name'] probe_res = res['probe_result'] if probe_res and 'error' not in probe_res: # 分析stderr和stdout,寻找线索 # 例如:如果启动Activity成功(无权限错误),可能意味着未受保护 if 'Error' not in probe_res.get('stderr', '') and 'Permission Denial' not in probe_res.get('stderr', ''): # 这可能是一个潜在漏洞:组件可被外部调用 vuln = { 'component': comp_name, 'type': res['type'], 'risk': 'MEDIUM', # 需要进一步确认 'evidence': probe_res.get('stderr', 'No error')[:200] + probe_res.get('stdout', '')[:200], 'description': f'导出的{res["type"][:-1]}组件"{comp_name}"可被外部Intent启动,可能造成未授权访问。' } # 进一步,可以检查logcat中是否有该组件引起的崩溃(CRASH) # 如果有,风险升级为HIGH vulnerabilities.append(vuln) # 生成报告 report = { 'package': self.package_name, 'apk': self.apk_path, 'exported_count': {k: len(v) for k, v in self.exported_components.items()}, 'vulnerabilities': vulnerabilities } # 可以输出为JSON或HTML import json print(json.dumps(report, indent=2, ensure_ascii=False)) return report

分析模块根据ADB命令的返回结果和日志来判断组件的安全性。例如,如果启动一个Activity时没有收到“Permission Denial”错误,则说明该组件可能缺乏足够的权限保护。更精细的分析需要结合logcat日志,寻找由该Intent触发的应用崩溃(FATAL EXCEPTION),这直接表明存在可利用的漏洞。

4.3 工具使用与效果验证

将上述代码模块整合,并添加一些命令行参数处理,我们就可以运行这个工具来扫描InsecureBankv2了。

if __name__ == '__main__': import sys if len(sys.argv) < 2: print("用法: python AndroidComponentAuditor.py <path_to_apk>") sys.exit(1) apk_path = sys.argv[1] auditor = AndroidComponentAuditor(apk_path) manifest_path = auditor.extract_manifest() if manifest_path: auditor.parse_manifest(manifest_path) print(f"[+] 包名: {auditor.package_name}") for k, v in auditor.exported_components.items(): print(f"[+] 导出的{k}: {len(v)}个") for comp in v: print(f" - {comp['name']}") results = auditor.run_dynamic_scan() report = auditor.analyze_and_report(results)

运行后,工具会输出导出的组件列表,并对每个组件进行探测。对于InsecureBankv2,它很可能会成功启动一些本应受保护的PostLogin或ViewStatement页面,从而验证漏洞的存在。这个简单的原型已经具备了核心功能。你可以在此基础上,增加更复杂的Payload、集成Frida进行深度Hook、优化结果分析算法,并将其扩展成一个真正强大的自动化扫描器。

5. 高级技巧与实战问题排查

在真实环境中使用或开发这类工具时,你会遇到各种预料之外的问题。下面分享一些我踩过坑后总结的经验。

5.1 绕过证书绑定(SSL Pinning)的实用方法

InsecureBankv2可能没有启用SSL Pinning,但很多现代应用都会启用。当你的Burp代理无法解密HTTPS流量时,很可能就是遇到了它。

  1. 使用Objection一键绕过:这是最快的方法。在设备上运行Frida Server,然后在电脑上使用Objection:

    objection -g com.android.insecurebankv2 explore

    进入交互界面后,执行:

    android sslpinning disable

    Objection会自动尝试Hook和禁用常见的证书绑定实现(如OkHttp, Android TrustManager)。对于许多应用,这一条命令就足够了。

  2. 手动Frida脚本:如果Objection无效,可能需要编写自定义Frida脚本。关键是要找到应用验证证书的代码位置。通常需要Hookjavax.net.ssl.TrustManager的相关方法或X509TrustManager接口。一个通用的“信任所有证书”的Frida脚本如下:

    Java.perform(function() { var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager'); var SSLContext = Java.use('javax.net.ssl.SSLContext'); // 创建一个什么都不检查的TrustManager var TrustAllManager = Java.registerClass({ name: 'com.helper.TrustAllManager', implements: [X509TrustManager], methods: { checkClientTrusted: function(chain, authType) {}, checkServerTrusted: function(chain, authType) {}, getAcceptedIssuers: function() { return []; } } }); // Hook SSLContext.init方法,将我们的TrustAllManager设置进去 SSLContext.init.overload('[Ljavax.net.ssl.KeyManager;', '[Ljavax.net.ssl.TrustManager;', 'java.security.SecureRandom').implementation = function(k, t, s) { console.log("[*] Bypassing SSL Pinning..."); var allTrust = TrustAllManager.$new(); return this.init(k, [allTrust], s); }; });

    将脚本保存为bypass_ssl.js,然后运行:frida -U -f com.android.insecurebankv2 -l bypass_ssl.js --no-pause

  3. 修改APK:终极方法。使用apktool反编译APK,找到网络库的Smali代码(通常是CertificatePinner.smali或自定义TrustManager的Smali),直接修改其逻辑,使其总是返回成功。然后重打包并签名。这种方法最彻底,但操作也最复杂。

5.2 处理反调试与模拟器检测

一些安全意识较强的应用(虽然InsecureBankv2可能没有)会检测是否被调试或运行在模拟器中。这会导致应用崩溃或行为异常,干扰测试。

  • 反调试:应用可能调用android.os.Debug.isDebuggerConnected()或检查TracerPid。可以使用Frida Hook这些方法,使其返回false
    Java.perform(function() { var Debug = Java.use('android.os.Debug'); Debug.isDebuggerConnected.implementation = function() { console.log("[*] Anti-debug check bypassed."); return false; }; });
  • 模拟器检测:应用可能检查设备属性,如android.os.Build中的MODEL,MANUFACTURER,FINGERPRINT是否包含generic,sdk,emulator等关键词,或检查/dev/qemu_pipe等文件是否存在。同样,可以用Frida Hook相关的获取属性方法,返回真实手机的信息。或者,直接使用经过改装的模拟器镜像或真机进行测试。

5.3 常见问题排查速查表

问题现象可能原因排查步骤与解决方案
ADB连接不上设备/模拟器1. ADB服务未启动
2. 设备未开启USB调试
3. 驱动问题(Windows)
1. 执行adb kill-server && adb start-server
2. 检查设备“开发者选项”中的“USB调试”已开启
3. 在设备上查看USB连接模式是否为“文件传输”或“PTP”,并重新插拔。Windows可尝试重新安装驱动。
Burp Suite抓不到HTTPS包1. 代理未正确设置
2. 未安装Burp CA证书到系统证书区
3. 应用启用了SSL Pinning
1. 确认设备Wi-Fi或网络设置中代理IP和端口正确
2. 访问http://burp下载证书,安装后务必在“设置->安全->加密与凭据->用户凭据”中确认证书已存在且受信任
3. 使用Objection或Frida脚本绕过SSL Pinning
Frida注入失败,提示Unable to find process1. 应用进程名错误
2. Frida Server未在设备上运行或版本不匹配
3. 应用为64位而Server是32位(或反之)
1. 使用frida-ps -U确认准确的进程名
2. 在设备上执行ps | grep frida检查Server进程,并用frida --versionadb shell /data/local/tmp/frida-server --version对比版本
3. 下载与设备架构匹配的Frida Server
反编译后的代码逻辑混乱或缺少关键类1. 应用使用了代码混淆(如ProGuard)
2. 关键逻辑在Native库(.so文件)中
3. 使用了加固技术
1. 结合字符串搜索、方法调用关系图来推测逻辑。关注未被混淆的库(如第三方SDK)
2. 使用IDA Pro或Ghidra分析.so文件
3. 对于商业加固,可能需要先进行脱壳处理,这属于更高阶的逆向工程范畴
动态测试时应用频繁崩溃1. 测试Payload过于“暴力”,导致应用处理异常
2. 触发了应用自身的Bug或防护机制
3. 测试环境不稳定
1. 优化Payload,从简单到复杂逐步测试
2. 查看logcat崩溃日志,定位崩溃点,调整测试策略避开
3. 使用模拟器快照功能,频繁恢复到干净状态

构建属于自己的渗透测试工具,是一个持续迭代和积累的过程。从InsecureBankv2这个完美的起点开始,理解每一个漏洞的原理,思考如何用代码去自动化地发现它,然后在更复杂、更真实的应用上去实践和优化你的工具。这个过程带给你的,将远不止是几个脚本,而是一整套发现问题、分析问题、解决问题的安全工程师思维模式。