移动应用安全基础篇——绕过iOS越狱检测
字数 1346 2025-08-18 11:38:28
iOS应用越狱检测绕过技术详解
一、工具准备
核心工具
- Frida: 动态插桩工具,用于运行时hook和修改应用行为
- Needle: iOS安全测试框架,包含多种检测和绕过模块
- IDA Pro 7.0: 反汇编和逆向工程工具
- Hopper Disassembler V4: 替代IDA的反汇编工具
- Cydia: 越狱设备的包管理器,需添加Darwin CC Tools依赖
辅助工具
- frida-ios-dump: 基于Frida的砸壳工具
- xCon: 通用越狱检测绕过工具
- Liberty Lite(Beta): iOS 11+的越狱检测绕过工具
二、基本流程
-
砸壳: 使用frida-ios-dump一键dump应用
python dump.py [BundleID] -
逆向分析: 将可执行文件导入IDA或Hopper
-
检测定位: 在__cfstring段搜索越狱关键词
-
绕过实现: 使用Frida或Needle进行hook和修改
三、检测方法及绕过技术
案例1:文件系统检测
检测原理:
- 使用stat/stat64函数检查常见越狱文件路径
- 路径示例:
"/Applications/Cydia.app", "/bin/bash", "/usr/sbin/sshd", "/private/var/lib/cydia"
绕过方法:
- Hook stat/stat64函数
- 当检测到目标路径时返回-1
Frida脚本示例:
var paths = ["/Applications/Cydia.app", "/bin/bash" /*完整列表见文档*/];
var f = Module.findExportByName("libSystem.B.dylib","stat64");
Interceptor.attach(f, {
onEnter: function(args) {
this.is_common_path = false;
var arg = Memory.readUtf8String(args[0]);
for (var path in paths) {
if (arg.indexOf(paths[path]) > -1) {
console.log("Hooking stat64: " + arg);
this.is_common_path = true;
break;
}
}
},
onLeave: function(retval) {
if (this.is_common_path){
console.log("stat64 Bypass!!!");
retval.replace(-1);
}
}
});
案例2:方法返回值检测
检测原理:
- 通过-[UIDevice isJailbroken]等方法直接返回越狱状态
绕过方法:
- 直接修改方法返回值
Frida脚本示例:
var className = "UIDevice";
var funcName = "- isJailbroken";
var hook = ObjC.classes[className][funcName];
Interceptor.attach(hook.implementation, {
onLeave: function(retval) {
console.log("Bypassing isJailbroken");
retval.replace(0); // 返回0表示未越狱
}
});
案例3:多方法综合检测
检测原理:
- 应用可能使用5种以上不同方法检测越狱
- 检测逻辑可能隐藏在framework中
应对策略:
- 全面分析__cfstring段
- 查找所有可疑方法如jailBreak, isJailbroken等
- 逐个hook关键方法
四、自动化工具
1. xCon
- 安装源: http://xcon.crazy.net
- 特点:
- Patch已知所有越狱检测方法
- 闭源项目
- 检测范围:
- 文件存在性检测
- 沙箱完整性检测
- 文件系统分区检测
- SSH安装检测
2. Liberty Lite(Beta)
- 安装源: https://ryleyangus.com/repo/
- 特点:
- 支持iOS 11+
- 选择性绕过特定应用
- 使用方法:
- 设置 → Liberty Lite
- 启用Block Jailbreak Detection
- 选择目标应用
五、高级技巧
Needle框架定制
- 修改默认设置:
grep -rn "HIDE_SYSTEM_APPS" needle grep -rn "spawn" needle - 重新编译源码以修改:
- 进程选择时隐藏系统APP
- 默认使用spawn启动方式
反逆向技巧
- 使用Hopper辅助IDA分析
- 针对framework中的检测逻辑
- 处理崩溃问题(如IDA崩溃时的应对)
六、完整Frida脚本模板
// 通用越狱检测绕过脚本
function bypassJailbreakDetection() {
// 1. 文件系统检测绕过
var filePaths = [
"/Applications/Cydia.app",
"/bin/bash",
// 完整列表参考文档
];
// Hook stat系列函数
var statFunctions = ["stat", "stat64", "lstat", "lstat64", "fstat", "fstat64"];
statFunctions.forEach(function(funcName) {
var func = Module.findExportByName("libSystem.B.dylib", funcName);
if (func) {
Interceptor.attach(func, {
onEnter: function(args) {
this.isJailPath = false;
try {
var path = Memory.readUtf8String(args[0]);
filePaths.forEach(function(jailPath) {
if (path.indexOf(jailPath) !== -1) {
this.isJailPath = true;
console.log("Bypassing " + funcName + " for: " + path);
}
}.bind(this));
} catch (e) {}
},
onLeave: function(retval) {
if (this.isJailPath) {
retval.replace(-1);
}
}
});
}
});
// 2. 常见检测方法绕过
var checkMethods = [
"-[UIDevice isJailbroken]",
"-[BMKSecurityManager jailBreak]",
"isJailbroken",
"jailbreakCheck"
];
checkMethods.forEach(function(method) {
try {
var tokens = method.split(/[
$$
$$
]/).filter(Boolean);
if (tokens.length >= 2) {
var className = tokens[0];
var methodName = tokens[1];
if (ObjC.classes[className] && ObjC.classes[className][methodName]) {
Interceptor.attach(ObjC.classes[className][methodName].implementation, {
onLeave: function(retval) {
console.log("Bypassing " + method);
retval.replace(0);
}
});
}
}
} catch (e) {}
});
}
// 执行绕过
bypassJailbreakDetection();
七、注意事项
- 不同iOS版本可能需要调整hook点
- 某些应用可能有独特的检测方法,需要具体分析
- 企业级应用可能使用服务器端验证配合客户端检测
- 持续更新检测路径和方法列表以应对新检测技术
八、参考资料
- Tide安全团队官网: http://www.TideSec.net
- Frida官方文档: https://frida.re/docs/ios/
- Needle GitHub仓库: https://github.com/mwrlabs/needle