APPLE越狱软件测试,iOS的越狱检测和反越狱检测剖析
iOS的越狱检测和反越狱检测原理剖析
为什么要检测越狱?因为越狱后会⼤幅降低安全性。对于⼀些⾦融类的APP或者游戏类的,因为监管原因、资⾦安全问题,甚⾄防⽌使⽤越狱分析等,需要进⾏检测。不过其实越狱与反越狱就像⽭与盾⼀样,都没有完美的⽅案。⽤⼀些反越狱插件可以防99%的越狱检测⽅式,本质上因为越狱后可以hook已知的所有检测越狱的⽅法,包括我下⾯的⼏种常⽤的。对于具体的反越狱插件可以⽤⼀些特定的⽅案来辅助检测。
具体代码清参考我的github
⼀、 越狱检测⽅案
1. 检测动态库
1.1 判断动态库stat是否是系统的库,并利⽤stat 来检测⼀些特定的⽂件权限
stat 命令时OS系统中⽤来判断⽂件信息的,但是对于私有的路径调⽤命令返回的是-1,如果越狱后,因为权限变化,可以通过stat返回私有⽬录下的⽂件信息。具体命令可以参考官⽅⽂档
代码实现:
BOOL isStatNotSystemLib() {
if(TARGET_IPHONE_SIMULATOR)return NO;
int ret ;
Dl_info dylib_info;
int (*func_stat)(const char *, struct stat *) = stat;
if ((ret = dladdr(func_stat, &dylib_info))) {
NSString *fName = [NSString stringWithUTF8String: dylib_info.dli_fname];
if(![fName isEqualToString:@"/usr/lib/system/libsystem_kernel.dylib"]){
return YES;
}
}
char *JbPaths[] = {"/Applications/Cydia.app",
"/usr/sbin/sshd",
"/bin/bash",
"/etc/apt",
"/Library/MobileSubstrate",
"/User/Applications/"};
for (int i = 0;i < sizeof(JbPaths) / sizeof(char *);i++) {
struct stat stat_info;
if (0 == stat(JbPaths[i], &stat_info)) {
return YES;
}
}
return NO;
}
1.2 判断是否注⼊了动态库
利⽤_dyld_get_image_name来获取动态库的名字,并查看是否有相关的动态库,这个相对来说最为准确,因为这个系统库运⾏的更早,且很多越狱的也需要依赖这个库的正常运⾏,所以更难被绕过
BOOL isInjectedWithDynamicLibrary()
{
int i=0;
char *substrate = "/Library/MobileSubstrate/MobileSubstrate.dylib";
while(true){
// hook _dyld_get_image_name⽅法可以绕过
const char *name = _dyld_get_image_name(i++);
if(name==NULL){
break;
}
if (name != NULL) {
if (strcmp(name,substrate)==0) {
return YES;
}
}
}
return NO;
}
2. 判断是否有越狱相关⽂件或权限
2.1 判断是否能打开越狱软件
利⽤URL Scheme来查看是否能够代开⽐如cydia这些越狱软件
//Check cydia URL hook canOpenURL 来绕过
if([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"cydia://package/com.avl"]])
{
return YES;
}
if([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"cydia://ample.package"]])
{
return YES;
}
2.2 判断是否可以访问⼀些越狱的⽂件
越狱后会产⽣额外的⽂件,通过判断是否存在这些⽂件来判断是否越狱了,可以⽤fopen和FileManager两个不同的⽅法去获取BOOL fileExist(NSString* path)
{
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL isDirectory = NO;
if([fileManager fileExistsAtPath:path isDirectory:&isDirectory]){
return YES;
}
return NO;
}
BOOL directoryExist(NSString* path)
{
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL isDirectory = YES;
if([fileManager fileExistsAtPath:path isDirectory:&isDirectory]){
return YES;
}
return NO;
}
BOOL canOpen(NSString* path)
{
FILE *file = fopen([path UTF8String], "r");
if(file==nil){
return fileExist(path) || directoryExist(path);
}
fclose(file);
return YES;
}
NSArray* checks = [[NSArray alloc] initWithObjects:@"/Application/Cydia.app",
@"/Library/MobileSubstrate/MobileSubstrate.dylib",
@"/bin/bash",
@"/usr/sbin/sshd",
@"/etc/apt",
@"/usr/bin/ssh",
@"/private/var/lib/apt",
@"/private/var/lib/cydia",
@"/private/var/tmp/cydia.log",
@"/Applications/WinterBoard.app",
@"/var/lib/cydia",
@"/private/etc/dpkg/origins/debian",
@"/bin.sh",
@"/private/etc/apt",软件测试app
@"/etc/ssh/sshd_config",
@"/private/etc/ssh/sshd_config",
@"/Applications/SBSetttings.app",
@"/private/var/mobileLibrary/SBSettingsThemes/",
@"/private/var/stash",
@"/usr/libexec/sftp-server",
@"/usr/libexec/cydia/",
@"/usr/sbin/frida-server",
@"/usr/bin/cycript",
@"/usr/local/bin/cycript",
@"/usr/lib/libcycript.dylib",
@"/System/Library/LaunchDaemons/com.saurik.Cydia.Startup.plist", @"/System/Library/LaunchDaemons/com.ikey.bbot.plist",
@"/Applications/FakeCarrier.app",
@"/Library/MobileSubstrate/DynamicLibraries/Veency.plist",
@"/Library/MobileSubstrate/DynamicLibraries/LiveClock.plist", @"/usr/libexec/ssh-keysign",
@"/usr/libexec/sftp-server",
@"/Applications/blackra1n.app",
@"/Applications/IntelliScreen.app",
@"/Applications/Snoop-itConfig.app"
@"/var/lib/dpkg/info", nil];
//Check installed app
for(NSString* check in checks)
{
if(canOpen(check))
{
return YES;
}
}
2.3 查看是否有权限写⼊私有⽬录
通过检测是否可以写⼊私有⽬录来判断,是否越狱了
NSString *path = @"/";
NSFileManager *fileManager = [NSFileManager defaultManager];
@try {
NSError* error;
NSString *test = @"AVL was here";
[test writeToFile:path atomically:NO encoding:NSStringEncodingConversionAllowLossy error:&error];
[fileManager removeItemAtPath:path error:nil];
if(error==nil)
{
return YES;
}
return NO;
} @catch (NSException *exception) {
return NO;
}
3. 利⽤系统命令来判断
3.1 通过lstat命令来判断系统的⼀些⽬录是否存在还是变成了链接
因为越狱后会变动⼀些⽂件,这些⽂件⽬录会迁移到其他区域,但是原来的⽂件位置必须有效,所以会创建符号链接,链接到原来的路径,我们可以检测这些符号链接是否存在,存在说明就越狱了
//symlink verification
struct stat sym;
// hook lstat可以绕过
if(lstat("/Applications", &sym) || lstat("/var/stash/Library/Ringtones", &sym) ||
lstat("/var/stash/Library/Wallpaper", &sym) ||
lstat("/var/stash/usr/include", &sym) ||

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。