自动化渗透脚本:Python编写批量扫描、Frida脚本自动化
说实话,做移动安全测试这几年,我最大的体会就是——手动重复劳动是最大的敌人。你想想看,一个App几十个Activity,每个都要手工测一遍注入、调试、Hook,那得测到猴年马月去?
所以这一章,我们来聊聊怎么让机器替我们干活。我会把我在实际项目中沉淀下来的两套自动化方案分享给你:Python批量扫描框架和Frida脚本自动化。这两套东西配合起来,基本能覆盖90%的日常渗透场景。
核心思路:用Python做"广度"覆盖(批量发现漏洞入口),用Frida做"深度"突破(动态Hook关键逻辑)。两者结合,效率翻倍。
一、Python批量扫描框架设计
先说说Python这块。我个人习惯把扫描框架拆成三个模块:信息收集层、漏洞检测层、报告输出层。这样后期维护起来特别方便,哪个模块出了问题,直接替换就行。
二、核心代码实现
下面这段代码是我从实际项目中抽出来的核心骨架。你直接拿去改改就能用。
import subprocess
import os
import json
from concurrent.futures import ThreadPoolExecutor
class AndroidScanner:
def __init__(self, apk_path, threads=8):
self.apk_path = apk_path
self.threads = threads
self.results = []
self.decompile_dir = "decompiled_" + os.path.basename(apk_path)
def decompile_apk(self):
"""第一步:反编译APK"""
cmd = f"apktool d {self.apk_path} -o {self.decompile_dir} -f"
subprocess.run(cmd, shell=True, capture_output=True)
print(f"[+] 反编译完成: {self.decompile_dir}")
def extract_activities(self):
"""提取所有导出的Activity"""
manifest_path = os.path.join(self.decompile_dir, "AndroidManifest.xml")
# 实际项目中用xml解析库处理
activities = []
# ... 解析逻辑省略
return activities
def check_intent_hijack(self, activity):
"""检测Intent劫持风险"""
# 检查exported="true"且没有自定义权限的Activity
# 我在项目中遇到过,某社交App的分享Activity没加权限
# 结果被恶意App直接调起,弹出了钓鱼登录页
pass
def scan_all(self):
"""多线程批量扫描"""
self.decompile_apk()
activities = self.extract_activities()
with ThreadPoolExecutor(max_workers=self.threads) as executor:
futures = []
for act in activities:
futures.append(executor.submit(self.check_intent_hijack, act))
for future in futures:
result = future.result()
if result:
self.results.append(result)
self.generate_report()
def generate_report(self):
"""生成JSON报告"""
report = {
"apk": self.apk_path,
"vulnerabilities": self.results,
"total": len(self.results)
}
with open("scan_report.json", "w") as f:
json.dump(report, f, indent=2)
print(f"[+] 报告已生成: scan_report.json")
if __name__ == "__main__":
scanner = AndroidScanner("target.apk")
scanner.scan_all()
我的经验:多线程数别开太大,8-12个线程就够了。开太多反而会因为I/O瓶颈导致速度下降。另外,记得加个超时机制,有些Activity解析起来特别慢。
三、Frida脚本自动化
Python搞定了"广度",接下来用Frida搞"深度"。说白了,Frida就是让我们能在App运行时动态地注入JavaScript代码,去Hook关键函数、修改返回值、甚至绕过SSL Pinning。
我常用的Frida自动化脚本分三类:
- 信息采集类:Hook加密函数,抓取密钥和算法
- 绕过检测类:绕过Root检测、模拟器检测、调试检测
- 逻辑篡改类:修改支付金额、跳过验证码、伪造签名
四、Frida批量Hook脚本示例
下面这个脚本,是我在一次金融App测试中写的。当时需要批量Hook所有加密相关的方法,手动一个个写太慢了,于是写了这个自动化生成脚本。
// frida_bulk_hook.js
// 批量Hook所有包含"encrypt"、"decrypt"、"sign"的方法
Java.perform(function() {
var targetClasses = [];
// 先枚举所有已加载的类
Java.enumerateLoadedClasses({
onMatch: function(className) {
if (className.indexOf("crypto") !== -1 ||
className.indexOf("security") !== -1 ||
className.indexOf("encrypt") !== -1) {
targetClasses.push(className);
}
},
onComplete: function() {
console.log("[+] 找到 " + targetClasses.length + " 个目标类");
targetClasses.forEach(function(clsName) {
hookClassMethods(clsName);
});
}
});
function hookClassMethods(className) {
try {
var targetClass = Java.use(className);
var methods = targetClass.class.getDeclaredMethods();
methods.forEach(function(method) {
var methodName = method.getName();
// 只Hook关键方法
if (methodName.indexOf("encrypt") !== -1 ||
methodName.indexOf("decrypt") !== -1 ||
methodName.indexOf("sign") !== -1 ||
methodName.indexOf("verify") !== -1) {
var overloads = targetClass[methodName].overloads;
overloads.forEach(function(overload) {
overload.implementation = function() {
console.log("[Hook] " + className + "." + methodName);
console.log("[Args] " + JSON.stringify(arguments));
var result = this[methodName].apply(this, arguments);
console.log("[Result] " + result);
return result;
};
});
console.log(" [OK] Hooked: " + methodName);
}
});
} catch(e) {
console.log(" [ERR] " + className + ": " + e);
}
}
});
注意:批量Hook虽然方便,但也会产生大量日志。我建议你加个过滤条件,只Hook你真正关心的类和方法。否则日志刷屏,反而找不到关键信息。
五、Python + Frida 联动自动化
这才是真正的杀手锏。用Python启动Frida,自动注入脚本,然后收集结果。整个过程不需要人工干预。
import frida
import time
import json
class FridaAutomation:
def __init__(self, package_name, script_path):
self.package_name = package_name
self.script_path = script_path
self.session = None
self.script = None
self.hook_results = []
def connect_to_device(self):
"""连接到设备或模拟器"""
try:
device = frida.get_usb_device()
print("[+] 已连接到USB设备")
return device
except:
print("[!] 未找到USB设备,尝试连接模拟器")
device = frida.get_remote_device()
return device
def spawn_and_hook(self):
"""启动App并注入脚本"""
device = self.connect_to_device()
# 启动App(spawn方式)
pid = device.spawn([self.package_name])
self.session = device.attach(pid)
# 加载脚本
with open(self.script_path, 'r') as f:
script_code = f.read()
self.script = self.session.create_script(script_code)
# 注册消息回调
self.script.on('message', self.on_message)
self.script.load()
device.resume(pid)
print(f"[+] App已启动,PID: {pid}")
# 等待一段时间收集数据
time.sleep(10)
self.cleanup()
def on_message(self, message, data):
"""处理Frida返回的消息"""
if message['type'] == 'send':
self.hook_results.append(message['payload'])
print(f"[数据] {message['payload']}")
elif message['type'] == 'error':
print(f"[错误] {message['description']}")
def cleanup(self):
"""清理资源"""
if self.script:
self.script.unload()
if self.session:
self.session.detach()
# 保存结果
with open("frida_results.json", "w") as f:
json.dump(self.hook_results, f, indent=2)
print(f"[+] 共收集 {len(self.hook_results)} 条Hook数据")
if __name__ == "__main__":
automation = FridaAutomation(
package_name="com.example.target",
script_path="frida_bulk_hook.js"
)
automation.spawn_and_hook()
实战效果:这套联动方案在我之前的项目中,把单个App的渗透测试时间从2天压缩到了4小时。Python负责批量扫描暴露面,Frida负责深度Hook关键逻辑。两者配合,基本没有漏网之鱼。
六、避坑指南
做自动化渗透,有几个坑我踩过,你一定要注意:
- App加固问题:很多App用了360加固、腾讯加固。反编译后代码全是壳,根本看不到真实逻辑。我的做法是先脱壳,或者直接用Frida在运行时Hook。
- 多线程死锁:Python多线程扫描时,如果目标App有反调试机制,可能会触发死锁。我建议每个线程加个超时,超过30秒直接跳过。
- Frida版本兼容:不同Android版本对Frida的支持不一样。Android 10以上有些Hook方式会失效。我一般准备两套脚本,一套针对低版本,一套针对高版本。
我曾经踩过的坑:有一次在测试某银行App时,Frida脚本一直注入失败。折腾了半天才发现,是App里集成了Frida检测库,检测到Frida进程就直接退出。后来我用Frida的"spawn"模式,在App启动前就注入,才绕过了检测。
七、总结
自动化渗透脚本的核心就两句话:Python做广度覆盖,Frida做深度突破。你不需要一开始就写一个完美的框架,先从一个简单的扫描脚本开始,慢慢积累自己的Hook库。用不了半年,你就能攒出一套属于自己的自动化渗透工具箱。
记住,自动化不是目的,效率才是。别为了自动化而自动化,有些场景手工测反而更快。灵活切换,才是老手该有的样子。
公众号:蓝海资料掘金营,微信deep3321