Why apply integrity check

You may have heard similar concepts of vests. If a malicious attacker makes use of your App, it will be embarrassing to directly change the App Icon, App name and skin.

How to do

From a security point of view, it’s easier to know how to defend yourself if you know how to attack, but it’s also relatively easy to just wear down the attacker and hope they give up.

Method 1: Jailbreak detection

This method is the simplest and most violent. We can detect whether the current device is jailbroken or not, and give hints to the key business judgment to force the exit to avoid security problems. The key business may need to be defined by ourselves, such as the business involving user sensitive information. The key code is posted below:

const char* jailbreak_tool_pathes[] = {
       "/Applications/Cydia.app"."/Library/MobileSubstrate/MobileSubstrate.dylib"."/bin/bash"."/usr/sbin/sshd"."/etc/apt"
       };
       #define ARRAY_SIZE(a) sizeof(a)/sizeof(a[0])
+ (BOOL)isJailBroken
{
    if ([self isSimulator] == YES)
    {
        return NO;
    }
    
    for (int i=0; i<ARRAY_SIZE(jailbreak_tool_pathes); i++) {
           if ([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithUTF8String:jailbreak_tool_pathes[i]]]) {
               NSLog(@"The device is jail broken!");
               return YES;
            }
       }
      NSLog(@"The device is NOT jail broken!");
      return NO;
}


+ (BOOL)isSimulator {
#if TARGET_OS_SIMULATOR
    return YES;
#else
    return NO;
#endif
}
Copy the code

This is actually a very indirect way of avoiding the topic

Method 2: Check whether the Mach-O file is tampered with

Check whether the Mach-O file has been tampered with by checking SignerIdentity. The principle is: SignerIdentity value does not exist in info.plist, developers will not add it, apple will not, but when ipA package is decompiled tamper file again packaging, need to forge SignerIdentity. So any time you get hacked and tampered with something it’s gonna show up on your phone if you run it again.


+ (BOOL)checkMach_O
{
    
    NSBundle *bundle = [NSBundle mainBundle];
    NSDictionary *info = [bundle infoDictionary];
    if ([info objectForKey: @"SignerIdentity"]! = nil){// If this key exists, it is packaged twicereturn YES;
    }
    
    return NO;
}


Copy the code

Method 3: Re-signature check

If you tamper with the App, you have to re-sign it. As for why you re-sign it, it is because Apple has made a verification change. If anything fails to be verified, it will flash back directly. The signature packaging process will bring up the Embedded. Mobileprovision file, which has a piece of teamID that we can verify to see if it’s our own team’s teamID. Or determine whether the BundleID has been changed.

+ (BOOL) checkCodeSignWithProvisionID: (provisionID nsstrings *) {/ / description file path nsstrings * embeddedPath = [[NSBundle mainBundle]  pathForResource:@"embedded" ofType:@"mobileprovision"];
        if([[NSFileManager defaultManager] fileExistsAtPath: embeddedPath]) {/ / read the application - identifier nsstrings *embeddedProvisioning = [NSString stringWithContentsOfFile:embeddedPath encoding:NSASCIIStringEncoding error:nil]; NSArray *embeddedProvisioningLines = [embeddedProvisioning componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];for (int i = 0; i < [embeddedProvisioningLines count]; i++) {
                if ([[embeddedProvisioningLines objectAtIndex:i] rangeOfString:@"application-identifier"].location ! = NSNotFound) { NSInteger fromPosition = [[embeddedProvisioningLines objectAtIndex:i+1] rangeOfString:@"<string>"].location+8;
                    
                    NSInteger toPosition = [[embeddedProvisioningLines objectAtIndex:i+1] rangeOfString:@"</string>"].location;
                    
                    NSRange range;
                    range.location = fromPosition;
                    range.length = toPosition - fromPosition;
                    
                    NSString *fullIdentifier = [[embeddedProvisioningLines objectAtIndex:i+1] substringWithRange:range];
                    
    //                NSLog(@"% @", fullIdentifier);
                    
                    NSArray *identifierComponents = [fullIdentifier componentsSeparatedByString:@"."]; NSString *appIdentifier = [identifierComponents firstObject]; // Compare signature idsif(! [appIdentifier isEqual:provisionID]) {return NO;
                    }
                    else
                    {
                        returnYES; }}}}return YES;

}
Copy the code

Understanding the principle of signing can help prevent the App from being re-signed.

Method 4: Check the hash value of key resources

We did hash check on Plist files and ICON resource files of App. Some online verification of CodeResources and App binaries of _CodeSignature is problematic. Because the Hash values generated by Xcode packaging process vary in different environments, the following figure shows the hash values generated by Xcode packaging process in different environments. So we have to filter out the changing files. Check things like Plist files and App Icon resource files.

Key code:

// Generate the resource file name and correspondinghashDict +(NSDictionary *)getBundleFileHash{NSMutableDictionary * dicHash = [NSMutableDictionary dictionary]; NSArray * fileArr = [self allFilesAtPath:[[NSBundle mainBundle]resourcePath]];for (NSString * fileName inFileArr) {// The corresponding file is generatedhash
        NSString * HashString = [FileHash md5HashOfFileAtPath:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:fileName]];
        if(HashString ! = nil) { [dicHashsetObject:HashString forKey:fileName]; }} // All resource fileshashIt's stored in this arrayreturn dicHash;
}
Copy the code

Some encryption tools are checked locally for inclusion in the hardened SDK, but it is safer to check through the server.

Conclusion:

Check out the following links:

  • How Xcode builds make changes to binary files and CodeResources of _CodeSignature.

LLVM: Deterministic Build

  • Principle of Signature

IOS Reverse (5) – IPA packet re-signature