mirror of
				https://github.com/opa334/TrollStore.git
				synced 2025-11-04 07:32:36 +08:00 
			
		
		
		
	Merge pull request #604 from luken11/signing-fast-path-v2
Add support for multi-exploit Info.plist fast path
This commit is contained in:
		
						commit
						9daa349a68
					
				@ -532,35 +532,37 @@ int signApp(NSString* appPath)
 | 
			
		||||
 | 
			
		||||
	if(![[NSFileManager defaultManager] fileExistsAtPath:mainExecutablePath]) return 174;
 | 
			
		||||
 | 
			
		||||
	NSObject *tsBundleIsPreSigned = appInfoDict[@"TSBundlePreSigned"];
 | 
			
		||||
	if([tsBundleIsPreSigned isKindOfClass:[NSNumber class]])
 | 
			
		||||
	// Check if the bundle has had a supported exploit pre-applied
 | 
			
		||||
	EXPLOIT_TYPE declaredPreAppliedExploitType = getDeclaredExploitTypeFromInfoDictionary(appInfoDict);
 | 
			
		||||
	if(isPlatformVulnerableToExploitType(declaredPreAppliedExploitType))
 | 
			
		||||
	{
 | 
			
		||||
		// if TSBundlePreSigned = YES, this bundle has been externally signed so we can skip over signing it now
 | 
			
		||||
		NSNumber *tsBundleIsPreSignedNum = (NSNumber *)tsBundleIsPreSigned;
 | 
			
		||||
		if([tsBundleIsPreSignedNum boolValue] == YES)
 | 
			
		||||
		{
 | 
			
		||||
			NSLog(@"[signApp] taking fast path for app which declares it has already been signed (%@)", mainExecutablePath);
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// XXX: There used to be a check here whether the main binary was already signed with bypass
 | 
			
		||||
	// In that case it would skip signing aswell, no clue if that's still needed
 | 
			
		||||
	// With the new bypass adhoc signing should fail and reapplying the bypass should produce an identical binary
 | 
			
		||||
	/*SecStaticCodeRef codeRef = getStaticCodeRef(mainExecutablePath);
 | 
			
		||||
	if(codeRef != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		if(codeCertChainContainsFakeAppStoreExtensions(codeRef))
 | 
			
		||||
		{
 | 
			
		||||
			NSLog(@"[signApp] taking fast path for app signed using a custom root certificate (%@)", mainExecutablePath);
 | 
			
		||||
			CFRelease(codeRef);
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
		NSLog(@"[signApp] taking fast path for app which declares use of a supported pre-applied exploit (%@)", mainExecutablePath);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		NSLog(@"[signApp] failed to get static code, can't derive entitlements from %@, continuing anways...", mainExecutablePath);
 | 
			
		||||
	}*/
 | 
			
		||||
		NSLog(@"[signApp] app (%@) declares use of a pre-applied exploit that is not supported on this device. Proceeding to re-sign...", mainExecutablePath);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// If the app doesn't declare a pre-applied exploit, and the host supports fake custom root certs,
 | 
			
		||||
	// we can also skip doing any work here when that app is signed with fake roots
 | 
			
		||||
	// If not, with the new bypass, a previously modified binary should failed to be adhoc signed, and
 | 
			
		||||
	// reapplying the bypass should produce an identical binary
 | 
			
		||||
	if(isPlatformVulnerableToExploitType(EXPLOIT_TYPE_CUSTOM_ROOT_CERTIFICATE_V1))
 | 
			
		||||
	{
 | 
			
		||||
		SecStaticCodeRef codeRef = getStaticCodeRef(mainExecutablePath);
 | 
			
		||||
		if(codeRef != NULL)
 | 
			
		||||
		{
 | 
			
		||||
			if(codeCertChainContainsFakeAppStoreExtensions(codeRef))
 | 
			
		||||
			{
 | 
			
		||||
				NSLog(@"[signApp] taking fast path for app signed using a custom root certificate (%@)", mainExecutablePath);
 | 
			
		||||
				CFRelease(codeRef);
 | 
			
		||||
				return 0;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			CFRelease(codeRef);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	NSURL* fileURL;
 | 
			
		||||
	NSDirectoryEnumerator *enumerator;
 | 
			
		||||
 | 
			
		||||
@ -36,6 +36,22 @@ typedef enum
 | 
			
		||||
	PERSISTENCE_HELPER_TYPE_ALL = PERSISTENCE_HELPER_TYPE_USER | PERSISTENCE_HELPER_TYPE_SYSTEM
 | 
			
		||||
} PERSISTENCE_HELPER_TYPE;
 | 
			
		||||
 | 
			
		||||
// EXPLOIT_TYPE is defined as a bitmask as some devices are vulnerable to multiple exploits
 | 
			
		||||
//
 | 
			
		||||
// An app that has had one of these exploits applied ahead of time can declare which exploit
 | 
			
		||||
// was used via the TSPreAppliedExploitType Info.plist key. The corresponding value should be
 | 
			
		||||
// (number of bits to left-shift + 1).
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
	// CVE-2022-26766
 | 
			
		||||
    // TSPreAppliedExploitType = 1
 | 
			
		||||
	EXPLOIT_TYPE_CUSTOM_ROOT_CERTIFICATE_V1 = 1 << 0,
 | 
			
		||||
 | 
			
		||||
	// CVE-2023-41991
 | 
			
		||||
    // TSPreAppliedExploitType = 2
 | 
			
		||||
	EXPLOIT_TYPE_CMS_SIGNERINFO_V1 = 1 << 1
 | 
			
		||||
} EXPLOIT_TYPE;
 | 
			
		||||
 | 
			
		||||
extern LSApplicationProxy* findPersistenceHelperApp(PERSISTENCE_HELPER_TYPE allowedTypes);
 | 
			
		||||
 | 
			
		||||
typedef struct __SecCode const *SecStaticCodeRef;
 | 
			
		||||
@ -61,3 +77,6 @@ extern SecStaticCodeRef getStaticCodeRef(NSString *binaryPath);
 | 
			
		||||
extern NSDictionary* dumpEntitlements(SecStaticCodeRef codeRef);
 | 
			
		||||
extern NSDictionary* dumpEntitlementsFromBinaryAtPath(NSString *binaryPath);
 | 
			
		||||
extern NSDictionary* dumpEntitlementsFromBinaryData(NSData* binaryData);
 | 
			
		||||
 | 
			
		||||
extern EXPLOIT_TYPE getDeclaredExploitTypeFromInfoDictionary(NSDictionary *infoDict);
 | 
			
		||||
extern bool isPlatformVulnerableToExploitType(EXPLOIT_TYPE exploitType);
 | 
			
		||||
 | 
			
		||||
@ -5,6 +5,8 @@
 | 
			
		||||
#import <sys/sysctl.h>
 | 
			
		||||
#import <mach-o/dyld.h>
 | 
			
		||||
 | 
			
		||||
static EXPLOIT_TYPE gPlatformVulnerabilities;
 | 
			
		||||
 | 
			
		||||
@interface PSAppDataUsagePolicyCache : NSObject
 | 
			
		||||
+ (instancetype)sharedInstance;
 | 
			
		||||
- (void)setUsagePoliciesForBundle:(NSString*)bundleId cellular:(BOOL)cellular wifi:(BOOL)wifi;
 | 
			
		||||
@ -522,3 +524,96 @@ NSDictionary* dumpEntitlementsFromBinaryData(NSData* binaryData)
 | 
			
		||||
	}
 | 
			
		||||
	return entitlements;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EXPLOIT_TYPE getDeclaredExploitTypeFromInfoDictionary(NSDictionary *infoDict)
 | 
			
		||||
{
 | 
			
		||||
    NSObject *tsPreAppliedExploitType = infoDict[@"TSPreAppliedExploitType"];
 | 
			
		||||
    if([tsPreAppliedExploitType isKindOfClass:[NSNumber class]])
 | 
			
		||||
    {
 | 
			
		||||
        NSNumber *tsPreAppliedExploitTypeNum = (NSNumber *)tsPreAppliedExploitType;
 | 
			
		||||
        int exploitTypeInt = [tsPreAppliedExploitTypeNum intValue];
 | 
			
		||||
 | 
			
		||||
        if(exploitTypeInt > 0)
 | 
			
		||||
        {
 | 
			
		||||
            // Convert versions 1, 2, etc... for use with bitmasking
 | 
			
		||||
            return (1 << (exploitTypeInt - 1));
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            NSLog(@"[getDeclaredExploitTypeFromInfoDictionary] rejecting TSPreAppliedExploitType Info.plist value (%i) which is out of range", exploitTypeInt);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Legacy Info.plist flag - now deprecated, but we treat it as a custom root cert if present
 | 
			
		||||
    NSObject *tsBundleIsPreSigned = infoDict[@"TSBundlePreSigned"];
 | 
			
		||||
    if([tsBundleIsPreSigned isKindOfClass:[NSNumber class]])
 | 
			
		||||
    {
 | 
			
		||||
        NSNumber *tsBundleIsPreSignedNum = (NSNumber *)tsBundleIsPreSigned;
 | 
			
		||||
        if([tsBundleIsPreSignedNum boolValue] == YES)
 | 
			
		||||
        {
 | 
			
		||||
            return EXPLOIT_TYPE_CUSTOM_ROOT_CERTIFICATE_V1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // No declarations
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void determinePlatformVulnerableExploitTypes(void *context) {
 | 
			
		||||
	size_t size = 0;
 | 
			
		||||
 | 
			
		||||
	// Get the current build number
 | 
			
		||||
	int mib[2] = {CTL_KERN, KERN_OSVERSION};
 | 
			
		||||
 | 
			
		||||
	// Get size of buffer
 | 
			
		||||
	sysctl(mib, 2, NULL, &size, NULL, 0);
 | 
			
		||||
 | 
			
		||||
	// Get the actual value
 | 
			
		||||
	char *os_build = malloc(size);
 | 
			
		||||
	if(!os_build)
 | 
			
		||||
	{
 | 
			
		||||
		// malloc failed
 | 
			
		||||
		perror("malloc buffer for KERN_OSVERSION");
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (sysctl(mib, 2, os_build, &size, NULL, 0) != 0)
 | 
			
		||||
	{
 | 
			
		||||
		// sysctl failed
 | 
			
		||||
		perror("sysctl KERN_OSVERSION");
 | 
			
		||||
		free(os_build);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	if(strncmp(os_build, "19F5070b", 8) <= 0)
 | 
			
		||||
	{
 | 
			
		||||
		// iOS 14.0 - 15.5 beta 4
 | 
			
		||||
		gPlatformVulnerabilities = (EXPLOIT_TYPE_CUSTOM_ROOT_CERTIFICATE_V1 | EXPLOIT_TYPE_CMS_SIGNERINFO_V1);
 | 
			
		||||
	}
 | 
			
		||||
	else if(strncmp(os_build, "19G5027e", 8) >= 0 && strncmp(os_build, "19G5063a", 8) <= 0)
 | 
			
		||||
	{
 | 
			
		||||
		// iOS 15.6 beta 1 - 5
 | 
			
		||||
		gPlatformVulnerabilities = (EXPLOIT_TYPE_CUSTOM_ROOT_CERTIFICATE_V1 | EXPLOIT_TYPE_CMS_SIGNERINFO_V1);
 | 
			
		||||
	}
 | 
			
		||||
	else if(strncmp(os_build, "20G81", 5) <= 0)
 | 
			
		||||
	{
 | 
			
		||||
		// iOS 14.0 - 16.6.1
 | 
			
		||||
		gPlatformVulnerabilities = EXPLOIT_TYPE_CMS_SIGNERINFO_V1;
 | 
			
		||||
	}
 | 
			
		||||
	else if(strncmp(os_build, "21A5248v", 8) >= 0 && strncmp(os_build, "21A331", 6) <= 0)
 | 
			
		||||
	{
 | 
			
		||||
		// iOS 17.0
 | 
			
		||||
		gPlatformVulnerabilities = EXPLOIT_TYPE_CMS_SIGNERINFO_V1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	free(os_build);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool isPlatformVulnerableToExploitType(EXPLOIT_TYPE exploitType) {
 | 
			
		||||
	// Find out what we are vulnerable to
 | 
			
		||||
	static dispatch_once_t once;
 | 
			
		||||
	dispatch_once_f(&once, NULL, determinePlatformVulnerableExploitTypes);
 | 
			
		||||
 | 
			
		||||
	return (exploitType & gPlatformVulnerabilities) != 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user