iOS 越狱(iOS Jailbreaking),是用于获取苹果公司便携装置操作系统iOS最高权限的一种技术手段,用户使用这种技术及软件可以获取到 iOS 的最高权限,甚至可能可以进一步解开运营商对手机网络的限制。手机越狱后会面临更多的安全风险,不建议对iOS设备进行越狱。在开发中可以针对越狱设备进行安全防范。
可以尝试用 NSFileManager 判断设备是否安装了越狱插件。
#define ARRAY_SIZE(a) sizeof(a)/sizeof(a[0]) const char* jailbreak_tool_pathes[] = {
"/Applications/Cydia.app",
"/Library/MobileSubstrate/MobileSubstrate.dylib",
"/bin/bash",
"/usr/sbin/sshd",
"/etc/apt"
};
#pragma mark - 判断设备是否被越狱
+ (BOOL)isJailBreak
{
for (int i=; i<ARRAY_SIZE(jailbreak_tool_pathes); i++) {
if ([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithUTF8String:jailbreak_tool_pathes[i]]]) {
XSDLog(@"The device is jail broken!");
return YES;
}
}
XSDLog(@"The device is NOT jail broken!");
return NO;
}
可以通过尝试读取应用列表,看有无权限:
if ([[NSFileManager defaultManager] fileExistsAtPath:@"/User/Applications/"]){
NSLog(@"Device is jailbroken");
NSArray *applist = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:@"/User/Applications/"
error:nil];
NSLog(@"applist = %@",applist);
}
未越狱设备是无法读取数据的,越狱设备是可以获得一个列表。
使用stat系列函数检测Cydia等工具:
#import <sys/stat.h> void checkCydia(void)
{
struct stat stat_info;
if ( == stat("/Applications/Cydia.app", &stat_info)) {
NSLog(@"Device is jailbroken");
}
}
可以看看stat是不是出自系统库,有没有被攻击者换掉:
#import <dlfcn.h> void checkInject(void)
{
int ret ;
Dl_info dylib_info;
int (*func_stat)(const char *, struct stat *) = stat;
if ((ret = dladdr(func_stat, &dylib_info))) {
NSLog(@"lib :%s", dylib_info.dli_fname);
}
}
输出结果为:
如果结果不是 /usr/lib/system/libsystem_kernel.dylib 的话,那就100%被攻击了。
如果 libsystem_kernel.dylib 都是被攻击者替换掉的……
动态库检测:
#import <mach-o/dyld.h> void checkDylibs(void)
{
uint32_t count = _dyld_image_count();
for (uint32_t i = ; i < count; ++i) {
NSString *name = [[NSString alloc]initWithUTF8String:_dyld_get_image_name(i)];
NSLog(@"动态库检测结果--%@", name);
}
}
通常情况下,会包含越狱机的输出结果会包含字符串: Library/MobileSubstrate/MobileSubstrate.dylib 。
结果:
通过检测程序当前运行的环境:
#include <stdlib.h> void printEnv(void)
{
char *env = getenv("DYLD_INSERT_LIBRARIES");
NSLog(@"===%s", env);
}
结果:
-- ::30.232140+ TestSecurityAdvance[:] ===(null)
未越狱设备返回的是 null。
参见:念茜的博客。