iOS安全系列

作者: 圣艾修 | 来源:发表于2019-09-29 16:04 被阅读0次

一、日志输出

关闭XCODE打包时日志打印

项目Edit Scheme -所有命令的 Build Configration 设置为Release

二、后台快照

应用进入后台时仍会展示当且的页面,模糊视图即可

修改前后:

  • 2D477E38-36B5-4919-8535-2CE1C3066DB1.png
  • 23ECCA4E-6542-49AD-9175-A961E693E942.png

代码:

.h

/**
 后台模糊工具
 */
@interface SafeBackstageTool : NSObject

/**
 单例对象
 
 @return 单例
 */
+ (instancetype)shared;

/**
 模糊后台视图
 */
- (void)blurBackstageView;

/**
 移除后台模糊视图
 */
- (void)clearBackstageView;

/**
 获取当前展示视图

 @return 当前展示视图
 */
- (UIViewController *)setupCurrentViewController;

@end

.m

#import "AppDelegate.h"
#import "SafeBackstageTool.h"

//屏幕宽度
#define ScreenWidth           [UIScreen mainScreen].bounds.size.width

//屏幕高度
#define ScreenHeight          [UIScreen mainScreen].bounds.size.height

@interface SafeBackstageTool ()

/**
 当前视窗
 */
@property (nonatomic, strong) UIWindow *window;

@end

// 单例对象
static SafeBackstageTool *singletonVC;
// dispatch_once_t
static dispatch_once_t onceToken;
// 偏移量
static NSUInteger const kOffset = 0X33;
@implementation SafeBackstageTool

/**
 单例对象
 
 @return 单例
 */
+ (instancetype)shared {
    dispatch_once(&onceToken, ^{
        singletonVC = [[SafeBackstageTool alloc] init];
    });
    return singletonVC;
}

/**
 模糊后台视图
 */
- (void)blurBackstageView {
    [self setupKeyWindow];
    UIView *view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
    UIImageView *imageView = [[UIImageView alloc] initWithFrame:[UIScreen mainScreen].bounds];
    view.tag = kOffset;
    // 获取当前视图控制器
    UIViewController *controller = [self setupCurrentViewController];
    UIImage *image = [self snapshot:controller.view];
    imageView.image = [self setupCoreBlurImage:image];
    imageView.contentMode = UIViewContentModeScaleAspectFill;
    [view addSubview:imageView];
    [self.window addSubview:view];
}

- (void)setupKeyWindow {
    AppDelegate *app = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    self.window = app.window;
}


// 获取当前屏幕显示的viewcontroller
- (UIViewController *)setupCurrentViewController {
    if (!self.window) {
        [self setupKeyWindow];
    }
    UIViewController *result = nil;
    UIView *frontView = [[self.window subviews] firstObject];
    id nextResponder = [frontView nextResponder];
    if ([nextResponder isKindOfClass:[UIViewController class]]) {
        result = nextResponder;
    } else {
        result = self.window.rootViewController;
    }
    return result;
}


// 截取当前视图为图片
- (UIImage *)snapshot:(UIView *)view {
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, YES, 0);
    [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

// 对图片进行模糊处理
- (UIImage *)setupCoreBlurImage:(UIImage *)image {
    CIContext *context = [CIContext contextWithOptions:nil];
    CIImage *inputImage= [CIImage imageWithCGImage:image.CGImage];
    // 设置filter
    CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur"];
    [filter setValue:inputImage forKey:kCIInputImageKey];
    // 模糊图片
    CIImage *result = [filter valueForKey:kCIOutputImageKey];
    CGRect rect = CGRectMake(0, 0, ScreenWidth * 2, ScreenHeight * 2);
    CGImageRef outImage = [context createCGImage:result fromRect:rect];
    UIImage *blurImage = [UIImage imageWithCGImage:outImage];
    CGImageRelease(outImage);
    return blurImage;
}


/**
 移除后台模糊视图
 */
- (void)clearBackstageView {
    UIView *view = [self.window viewWithTag: kOffset];
    if (view) {
        [UIView animateWithDuration:0.5 animations:^{
            [view removeFromSuperview];
        }];
    }
}

@end

AppDelegate.m

- (void)applicationWillResignActive:(UIApplication *)application {
    // 后台模糊
    [[SafeBackstageTool shared] blurBackstageView];
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
    // 移除后台模糊
    [[SafeBackstageTool shared] clearBackstageView];
}

三、越狱检测

设备越狱提示或退出程序

.h

/**
 检查设备是否越狱
 */
@interface JailBreakCheckTool : NSObject

+ (BOOL)isJailbroken;

/**
 越狱设备提示
 */
+ (void)setupJailBreakAlertWithController:(UIViewController *)controller;

@end

.m


#import "JailBreakCheckTool.h"
#include <sys/stat.h>
#include <dlfcn.h>
#define ARRAY_SIZE(a) sizeof(a)/sizeof(a[0])

const char* jailbreak_paths[] = {
    "/Applications/Cydia.app",
    "/Library/MobileSubstrate/MobileSubstrate.dylib",
    "/var/lib/cydia/",
    "/var/cache/apt"
};

@implementation JailBreakCheckTool

+ (BOOL)isJailbroken {
    // 以下检测的过程是越往下,越狱越高级
    BOOL jailbroken = NO;
    if ([self judgeFilePath]) {
        jailbroken = YES;
    }
    if ([self judgeFilePathWithStat]) {
        jailbroken = YES;
        
    }
    // 可能存在stat也被hook了,可以看stat是不是出自系统库,有没有被攻击者换掉
    
    // 在真机的情况下,这里要判断是否是模拟器,模拟器系统库不是这个
#if !(TARGET_IPHONE_SIMULATOR)
    // 如果不是系统库,判断已越狱 0
    int ret;
    Dl_info dylib_info;
    int (*func_stat)(const char *,struct stat *) = stat;
    if ((ret = dladdr(func_stat, &dylib_info))) {
        if (strcmp(dylib_info.dli_fname, "/usr/lib/system/libsystem_kernel.dylib")) {
            jailbroken = YES;
        }
    }
    
#else
    
    NSLog(@"The device is IPHONE_SIMULATOR!");
    
#endif
    
    // 如果攻击者给MobileSubstrate改名,但是原理都是通过DYLD_INSERT_LIBRARIES注入动态库
    // 那么可以,检测当前程序运行的环境变量
    char *env = getenv("DYLD_INSERT_LIBRARIES");
    if (env != NULL) {
        jailbroken = YES;
    }
    return jailbroken;
}

// 判断是否存在文件
+ (BOOL)judgeFilePath {
    for (int index = 0; index < ARRAY_SIZE(jailbreak_paths); index++) {
        if ([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithUTF8String:jailbreak_paths[index]]]) {
            NSLog(@"The device is jail broken!");
            return YES;
        }
    }
    return NO;
}

// 可能存在hook了NSFileManager方法,此处用底层C stat去检测 越狱文件
+ (BOOL)judgeFilePathWithStat {
    struct stat stat_info;
    for (int index = 0; index < ARRAY_SIZE(jailbreak_paths); index++) {
        if (0 == stat(jailbreak_paths[index], &stat_info)) {
            NSLog(@"The device is jail broken!");
            return YES;
        }
    }
    return NO;
}


/**
 越狱设备提示
 */
+ (void)setupJailBreakAlertWithController:(UIViewController *)controller {
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:L(@"tip")
                                                                             message:@"当前设备已越狱,是否继续?"
                                                                      preferredStyle:UIAlertControllerStyleAlert];
    WS(weakSelf);
    UIAlertAction *action = [UIAlertAction actionWithTitle:@"继续" style:UIAlertActionStyleDefault handler:nil];
    UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        [weakSelf exitApplication];
    }];
    [alertController addAction:cancel];
    [alertController addAction:action];
    UIViewController *controller = [[SafeBackstageTool shared] setupCurrentViewController];
    [controller presentViewController:alertController animated:YES completion:nil];
}

/**
 退出程序
 */
+ (void)exitApplication {
    AppDelegate *app = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    UIWindow *window = app.window;
    [UIView animateWithDuration:1.0f animations:^{
        window.alpha = 0;
        window.frame = CGRectMake(0, window.bounds.size.width, 0, 0);
    } completion:^(BOOL finished) {
        exit(0);
    }];
}

@end

使用

    // 越狱检测
    if ([JailBreakCheckTool isJailbroken]) {
        [JailBreakCheckTool setupJailBreakAlertWithController:self];
    }

四、输入类组件禁止复制粘贴

复制粘贴可能导致信息泄露

写个类继承 UITextField 、UITextView,实现以下方法即可

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
    UIMenuController *menuController = [UIMenuController sharedMenuController];
    if(menuController) {
        [UIMenuController sharedMenuController].menuVisible=NO;
    }
    return NO;
}

相关文章

  • 【加密解密】HTTPS

    学习文章 iOS9AdaptationTips 打造安全的App!iOS安全系列之 HTTPS 概念释疑 为了强制...

  • iOS网络安全

    HTTPS Server Trust Evaluation iOS安全系列之一:HTTPS

  • SSL/TLS 分析优秀文章

    SSL/TLS协议运行机制的概述 图解SSL/TLS协议 打造安全的App!iOS安全系列之 HTTPS iOS安...

  • iOS安全系列之二:HTTPS进阶

    上一篇《iOS安全系列之一:HTTPS》被CocoaChina转载,还顺便上了下头条: 打造安全的App!iOS安...

  • iOS安全系列

    一、日志输出 关闭XCODE打包时日志打印 项目Edit Scheme -所有命令的 Build Configra...

  • iOS安全攻防

    iOS安全攻防 iOS安全攻防

  • Charles工具ios手机配置

    配置 Charles 并使用仅限 ios 手机,安卓手机由于 Android N 系列安全限制问题并不适用。 配置...

  • iOS动画系列一

    iOS动画系列一 iOS动画系列一

  • iOS安全系列工具

    1,RevealReveal网页中密码有个错误,alpine 2,Cycript,class-dump等工具此链接...

  • iOS锁系列-目录

    1、 iOS锁系列-NSLock对象锁2、iOS锁系列-NSConditionLock条件锁3、iOS锁系列-NS...

网友评论

    本文标题:iOS安全系列

    本文链接:https://www.haomeiwen.com/subject/ppwfpctx.html