From 17ba8fbaa73b4de9888eeff10987eaa7090f68a4 Mon Sep 17 00:00:00 2001 From: opa334 Date: Sun, 26 Nov 2023 20:43:30 +0100 Subject: [PATCH] TrollStore 2: First working POC :D --- Exploits/fastPathSign/src/adhoc.h | 3 - Exploits/fastPathSign/src/codesign.h | 4 ++ .../fastPathSign/src/{adhoc.m => codesign.m} | 32 ++++++++- Exploits/fastPathSign/src/{main.c => main.m} | 22 +++++-- Makefile | 4 +- RootHelper/Makefile | 6 +- RootHelper/external/lib/libchoma.a | Bin 91872 -> 91944 bytes RootHelper/main.m | 61 +++++++++--------- TrollHelper/Makefile | 5 +- TrollStore/Makefile | 5 +- 10 files changed, 97 insertions(+), 45 deletions(-) delete mode 100644 Exploits/fastPathSign/src/adhoc.h create mode 100644 Exploits/fastPathSign/src/codesign.h rename Exploits/fastPathSign/src/{adhoc.m => codesign.m} (82%) rename Exploits/fastPathSign/src/{main.c => main.m} (75%) diff --git a/Exploits/fastPathSign/src/adhoc.h b/Exploits/fastPathSign/src/adhoc.h deleted file mode 100644 index 6a491c1..0000000 --- a/Exploits/fastPathSign/src/adhoc.h +++ /dev/null @@ -1,3 +0,0 @@ -#include - -int binary_sign_adhoc(const char *path, bool preserveMetadata); \ No newline at end of file diff --git a/Exploits/fastPathSign/src/codesign.h b/Exploits/fastPathSign/src/codesign.h new file mode 100644 index 0000000..1432272 --- /dev/null +++ b/Exploits/fastPathSign/src/codesign.h @@ -0,0 +1,4 @@ +#import +#import + +int codesign_sign_adhoc(const char *path, bool preserveMetadata, NSDictionary *customEntitlements); \ No newline at end of file diff --git a/Exploits/fastPathSign/src/adhoc.m b/Exploits/fastPathSign/src/codesign.m similarity index 82% rename from Exploits/fastPathSign/src/adhoc.m rename to Exploits/fastPathSign/src/codesign.m index 1b37404..5d01c04 100644 --- a/Exploits/fastPathSign/src/adhoc.m +++ b/Exploits/fastPathSign/src/codesign.m @@ -89,7 +89,7 @@ extern const CFStringRef kSecCodeInfoResourceDirectory; /* Internal */ } #endif -int binary_sign_adhoc(const char *path, bool preserveMetadata) +int codesign_sign_adhoc(const char *path, bool preserveMetadata, NSDictionary *customEntitlements) { NSString *filePath = [NSString stringWithUTF8String:path]; OSStatus status = 0; @@ -99,8 +99,31 @@ int binary_sign_adhoc(const char *path, bool preserveMetadata) SecIdentityRef identity = (SecIdentityRef)kCFNull; NSMutableDictionary* parameters = [[NSMutableDictionary alloc] init]; parameters[(__bridge NSString*)kSecCodeSignerIdentity] = (__bridge id)identity; + uint64_t preserveMetadataFlags = 0; if (preserveMetadata) { - parameters[(__bridge NSString*)kSecCodeSignerPreserveMetadata] = @(kSecCSPreserveIdentifier | kSecCSPreserveRequirements | kSecCSPreserveEntitlements | kSecCSPreserveResourceRules); + preserveMetadataFlags = (kSecCSPreserveIdentifier | kSecCSPreserveRequirements | kSecCSPreserveEntitlements | kSecCSPreserveResourceRules); + if (!customEntitlements) { + preserveMetadataFlags |= kSecCSPreserveEntitlements; + } + parameters[(__bridge NSString*)kSecCodeSignerPreserveMetadata] = @(preserveMetadataFlags); + } + + if (customEntitlements) { + NSError *error; + NSData *xmlData = [NSPropertyListSerialization dataWithPropertyList:customEntitlements format:NSPropertyListXMLFormat_v1_0 options:0 error:&error]; + if (!xmlData) { + NSLog(@"Failed to encode entitlements: %@", error); + return -1; + } + else { + // Super easy to use API, definitely not busted... + // Did I forget to mention it just segfaults if you don't add this prefix? + uint32_t entitlementsData[xmlData.length+8]; + entitlementsData[0] = OSSwapHostToBigInt32(0xFADE7171); + entitlementsData[1] = OSSwapHostToBigInt32(xmlData.length+8); + [xmlData getBytes:&entitlementsData[2] length:xmlData.length]; + parameters[(__bridge NSString*)kSecCodeSignerEntitlements] = [NSData dataWithBytes:entitlementsData length:xmlData.length+8]; + } } SecCodeSignerRef signerRef; @@ -137,4 +160,9 @@ int binary_sign_adhoc(const char *path, bool preserveMetadata) } return retval; +} + +NSDictionary *codesign_dump_entitlements(NSString *path) +{ + return nil; } \ No newline at end of file diff --git a/Exploits/fastPathSign/src/main.c b/Exploits/fastPathSign/src/main.m similarity index 75% rename from Exploits/fastPathSign/src/main.c rename to Exploits/fastPathSign/src/main.m index b9fc540..2dabe77 100644 --- a/Exploits/fastPathSign/src/main.c +++ b/Exploits/fastPathSign/src/main.m @@ -1,4 +1,4 @@ -#include "adhoc.h" +#include "codesign.h" #include "coretrust_bug.h" #include #include @@ -52,12 +52,22 @@ int apply_coretrust_bypass_wrapper(const char *inputPath, const char *outputPath int main(int argc, char *argv[]) { - if (argc != 2) return -1; + if (argc < 2) return -1; - char *machoPath = extract_preferred_slice(argv[1]); + char *input = argv[argc-1]; + + NSDictionary *customEntitlements = nil; + if (argc == 4) { + if (!strcmp(argv[1], "--entitlements")) { + NSString *entitlementsPath = [NSString stringWithUTF8String:argv[2]]; + customEntitlements = [NSDictionary dictionaryWithContentsOfFile:entitlementsPath]; + } + } + + char *machoPath = extract_preferred_slice(input); printf("Extracted best slice to %s\n", machoPath); - int r = binary_sign_adhoc(machoPath, true); + int r = codesign_sign_adhoc(machoPath, true, customEntitlements); if (r != 0) { printf("Failed adhoc signing (%d) Continuing anyways...\n", r); } @@ -72,8 +82,8 @@ int main(int argc, char *argv[]) { return -1; } - if (copyfile(machoPath, argv[1], 0, COPYFILE_ALL | COPYFILE_MOVE | COPYFILE_UNLINK) == 0) { - chmod(argv[1], 0755); + if (copyfile(machoPath, input, 0, COPYFILE_ALL | COPYFILE_MOVE | COPYFILE_UNLINK) == 0) { + chmod(input, 0755); printf("Applied CoreTrust Bypass!\n"); } else { diff --git a/Makefile b/Makefile index f283912..1b2b67c 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ TOPTARGETS := all clean -$(TOPTARGETS): pre_build make_roothelper make_trollstore make_trollhelper make_trollhelper_package assemble_trollstore make_trollhelper_embedded build_installer15 build_installer64e +$(TOPTARGETS): pre_build make_fastPathSign make_roothelper make_trollstore make_trollhelper make_trollhelper_package assemble_trollstore make_trollhelper_embedded build_installer15 build_installer64e pre_build: @rm -rf ./_build 2>/dev/null || true @@ -8,6 +8,8 @@ pre_build: make_external: +make_fastPathSign: + @$(MAKE) -C ./Exploits/fastPathSign $(MAKECMDGOALS) make_roothelper: @$(MAKE) -C ./RootHelper FINALPACKAGE=1 $(MAKECMDGOALS) diff --git a/RootHelper/Makefile b/RootHelper/Makefile index aeb708b..f53fb33 100644 --- a/RootHelper/Makefile +++ b/RootHelper/Makefile @@ -1,14 +1,16 @@ TARGET := iphone:clang:16.4:14.0 ARCHS = arm64 +TARGET_CODESIGN = ../Exploits/fastPathSign/fastPathSign + include $(THEOS)/makefiles/common.mk TOOL_NAME = trollstorehelper -trollstorehelper_FILES = $(wildcard *.m) $(wildcard ../Shared/*.m) ../Exploits/fastPathSign/src/coretrust_bug.c ../Exploits/fastPathSign/src/adhoc.m +trollstorehelper_FILES = $(wildcard *.m) $(wildcard ../Shared/*.m) ../Exploits/fastPathSign/src/coretrust_bug.c ../Exploits/fastPathSign/src/codesign.m trollstorehelper_CFLAGS = -fobjc-arc -I../Shared $(shell pkg-config --cflags libcrypto) -Iexternal/include -I../Exploits/fastPathSign/src trollstorehelper_LDFLAGS = -Lexternal/lib -lcrypto -lchoma -trollstorehelper_CODESIGN_FLAGS = -Sentitlements.plist -K../cert.p12 +trollstorehelper_CODESIGN_FLAGS = --entitlements entitlements.plist trollstorehelper_INSTALL_PATH = /usr/local/bin trollstorehelper_LIBRARIES = archive trollstorehelper_PRIVATE_FRAMEWORKS = SpringBoardServices BackBoardServices MobileContainerManager diff --git a/RootHelper/external/lib/libchoma.a b/RootHelper/external/lib/libchoma.a index fdd802d5ffcf53f999319b4bfcf68ee71754bc26..6048fae5c9c272f0e835d8cfb507cbee180b2c7c 100644 GIT binary patch delta 2324 zcma);e{54#6vxl&+tzjr*3PnSE37pGx&`V=8Qp@EJy(+P2N7f_W5`dz_$y4~A8Np~ zaZbUZvEC&R5jF%vCz#cggcf2PsfGzCj6{dgKe~WPmk^>e#x{ZA_r9K0jsJL)x6eE0 zd+xpGp3~kg{cUmdyW;of7WtZ+S`JRERjMP)7A&(orcmV!BFX2BM6o+WeauBAMAt46 zT`?17eG0ivM4fhpx)87Jhf(gdL}uBg`L}S*8U=mc?ygwlX`IyP0n@ z4>M!TSM>5L^bH^AkEM8#eR+txdl4DS?poA*sVCSjLjuwt)Z^k)>hT#xK7Z4a$b=R{2 z)>}KVha5MQJUhipM_R?&RVK6apw#3Q+hfgE8xAGMJdV398tkprEjW=JF7{f=h;SH6 zi|t37&GqF(b75u0v7@oss&VXYcg@hfJ&vJ!sgg+aDZ^N%Q9M1cLg^5n49uIqfs$Co zmf4^sqw3s*d>;&MPGEk2x`VY2ac979*yj)n2H)!}SI8Dc#E`lrTW=-I+LAR{wdAB~ z`qZR^uV>tpqu0%cqfmIAO5qP=tVj=T54H1-?J}Dh&ZaA$ zO^~%9v>>=)|}APYCaNc4%Qsdf~@thW@oKY z%T3y~r0D;+-*POdjt#0}`Jnm}p8n;c<@ln|qiC7l3>5P}4Vi_882`}_)RpPlSeYR=%Q#>^tP{x!-<#JS#Dv;0wzqe@)pwKuF}>xy)F z^>46zD+~)R897G9#9Madh8P=inq#o4T_ z3dG)?DDwdOUu5nC3jmVezD&5PrV0#tEPxo^x z>r<>h!FDNMy1i^q@Ar(fRjQ-uTX_x~xFl)%BQb>*OWR@;=T6sJZ=n8i?8hVBvH0Za zj||1~pAm2To#A+?qQzI7+iEWSs3cOq{QcXLxb$^hK{<5i-TG64<7%*+D zlaU!?^N1r%7%&VS%xqZW)?u=l{xO_L*fc?dnm6^2f^k8N+D6Fy-uKRo-0bah&iUSZ z?s@07x3MeP+E>}{Ey=2EsA}l4RttOdA$Q}Y7C|Koh$LT}N3?5(sFS%ehp1zM=(2@q zuu72IOjKYK)Q0)#ZP8;(3$;fC-Iz}#`GOw3Fi|H&hbm0|&`SeE1KC89-!ltk$|T~v zMI&#q+k_I_MD5HC9N)owo!QCkVh%9BWS-^qe^@A_*IbP1WbLb&+nH}N`&KJG~~a|iQ)Ib<{|%7K3781p-3npuD*%jPa;`kCvQdzpur-ONGe zYkKS^|KQGkpG^?C8zO7DW~%DS3{>iDtz-8pQ| zFZtTa=1*>C9h;`jzpg5iAEz3ZtJYiTa=EI!_~)whdh2QstEu;T)!gGxTJ6X!$G5_u zU48kuU-hmv=gA0KOt*50YDxWZbCvZQ6ePzop4{JcAt?N%X}qW$E)HKsPP_^oRkxj} zw`h4pOW+Nvr%ntmO6E-7*;m?k_kg4CZX_ofd(JeOa;wkxtP+jthds;gTSEzCDNd~k zBx1^vVQHTXZW_k=BU+HPpgPl2XR2_h_n&-s`J7pVr|1n!x11eQHm50@ zGE(b_jfQ4p z%?3?z8d_wdk<-mN-N+en4wvW)lPs3ASgx8*`$J{ymC31gqqOAHMj9t;PH0KilnsVv zW6cIlDdksUt%$WEXhGH@tmU)j4rFfR2NLSo=_3WxK_#lyhkYlN>kn&9VV}CacV#Gm zCQ}}o`@hEOO{H+FY^>gF5yMc@~3An zfg+p327O*|5rlp;pcFg;I>7y)OdJ5Eo(np`6mAHqcYwHNJbRce%o?VhnG2%5o~xLQ zzbelshT%C1VsFnu=2nhB%4`7jh3et+*Ftkw*j}7m9-bJM%F!u(%&g|S>>&H{l9yvG z&!0QSEv$dc`cv#ru;0%9+HuTU$^U6zXx$j3AHNw|$oq(67^yV(zbay*Vl>icmJ zava7Z{pNV(M<1B@+MgPT&lePbdt{4+BR7-(;Fm)F5X5gzTrcP7#7u96VGg}w6WvbT et{Ez<7Ax}EUcFkpx|Hpat)g47-S(`wlJzggxCdDP diff --git a/RootHelper/main.m b/RootHelper/main.m index 89de375..4337fb6 100644 --- a/RootHelper/main.m +++ b/RootHelper/main.m @@ -11,7 +11,7 @@ #import #import #ifndef EMBEDDED_ROOT_HELPER -#import "adhoc.h" +#import "codesign.h" #import "coretrust_bug.h" #import #import @@ -398,45 +398,48 @@ int signApp(NSString* appPath) while(fileURL = [enumerator nextObject]) { NSString *filePath = fileURL.path; + NSLog(@"Checking %@", filePath); FAT *fat = fat_init_from_path(filePath.fileSystemRepresentation); if (fat) { + NSLog(@"%@ is binary", filePath); // This is FAT or MachO, sign and apply CoreTrust bypass MachO *machoForExtraction = fat_find_preferred_slice(fat); if (machoForExtraction) { - NSLog(@"Starting signing of %@\n", filePath); NSString *tmpPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSUUID UUID].UUIDString]; - MemoryStream *sliceOutStream = file_stream_init_from_path(tmpPath.fileSystemRepresentation, 0, 0, FILE_STREAM_FLAG_WRITABLE | FILE_STREAM_FLAG_AUTO_EXPAND); MemoryStream *sliceStream = macho_get_stream(machoForExtraction); - memory_stream_copy_data(sliceStream, 0, sliceOutStream, 0, memory_stream_get_size(sliceStream)); - memory_stream_free(sliceOutStream); + MemoryStream *sliceOutStream = file_stream_init_from_path(tmpPath.fileSystemRepresentation, 0, 0, FILE_STREAM_FLAG_WRITABLE | FILE_STREAM_FLAG_AUTO_EXPAND); + if (sliceOutStream) { + memory_stream_copy_data(sliceStream, 0, sliceOutStream, 0, memory_stream_get_size(sliceStream)); + memory_stream_free(sliceOutStream); - // Now we have the single slice at tmpPath, which we will sign and apply the bypass, then copy over the original file + // Now we have the single slice at tmpPath, which we will sign and apply the bypass, then copy over the original file - NSLog(@"[%@] Adhoc signing...", filePath); + NSLog(@"[%@] Adhoc signing...", filePath); - // First attempt ad hoc signing - int r = binary_sign_adhoc(tmpPath.fileSystemRepresentation, true); - if (r != 0) { - NSLog(@"[%@] Adhoc signing failed with error code %d, continuing anyways...\n", filePath, r); + // First attempt ad hoc signing + int r = codesign_sign_adhoc(tmpPath.fileSystemRepresentation, true, nil); + if (r != 0) { + NSLog(@"[%@] Adhoc signing failed with error code %d, continuing anyways...\n", filePath, r); + } + else { + NSLog(@"[%@] Adhoc signing worked!\n", filePath); + } + + NSLog(@"[%@] Applying CoreTrust bypass...", filePath); + r = apply_coretrust_bypass(tmpPath.fileSystemRepresentation); + if (r == 0) { + NSLog(@"[%@] Applied CoreTrust bypass!", filePath); + } + else { + NSLog(@"[%@] CoreTrust bypass failed!!! :(", filePath); + fat_free(fat); + return 175; + } + + // tempFile is now signed, overwrite original file at filePath with it + [[NSFileManager defaultManager] removeItemAtPath:filePath error:nil]; + [[NSFileManager defaultManager] moveItemAtPath:tmpPath toPath:filePath error:nil]; } - else { - NSLog(@"[%@] Adhoc signing worked!\n", filePath); - } - - NSLog(@"[%@] Applying CoreTrust bypass...", filePath); - r = apply_coretrust_bypass(tmpPath.fileSystemRepresentation); - if (r == 0) { - NSLog(@"[%@] Applied CoreTrust bypass!", filePath); - } - else { - NSLog(@"[%@] CoreTrust bypass failed!!! :(", filePath); - fat_free(fat); - return 175; - } - - // tempFile is now signed, overwrite original file at filePath with it - [[NSFileManager defaultManager] removeItemAtPath:filePath error:nil]; - [[NSFileManager defaultManager] moveItemAtPath:tmpPath toPath:filePath error:nil]; } fat_free(fat); } diff --git a/TrollHelper/Makefile b/TrollHelper/Makefile index ba488f3..deeb2ed 100644 --- a/TrollHelper/Makefile +++ b/TrollHelper/Makefile @@ -2,6 +2,9 @@ export EMBEDDED_ROOT_HELPER ?= 0 TARGET := iphone:clang:16.4:14.0 INSTALL_TARGET_PROCESSES = TrollStorePersistenceHelper +ARCHS = arm64 + +TARGET_CODESIGN = ../Exploits/fastPathSign/fastPathSign include $(THEOS)/makefiles/common.mk @@ -11,7 +14,7 @@ TrollStorePersistenceHelper_FILES = $(wildcard *.m) $(wildcard ../Shared/*.m) TrollStorePersistenceHelper_FRAMEWORKS = UIKit CoreGraphics CoreServices TrollStorePersistenceHelper_PRIVATE_FRAMEWORKS = Preferences MobileContainerManager TrollStorePersistenceHelper_CFLAGS = -fobjc-arc -I../Shared -TrollStorePersistenceHelper_CODESIGN_FLAGS = -Sentitlements.plist -K../cert.p12 +TrollStorePersistenceHelper_CODESIGN_FLAGS = --entitlements entitlements.plist ifeq ($(EMBEDDED_ROOT_HELPER),1) TrollStorePersistenceHelper_CFLAGS += -DEMBEDDED_ROOT_HELPER=1 diff --git a/TrollStore/Makefile b/TrollStore/Makefile index ee5038f..d0c62e2 100644 --- a/TrollStore/Makefile +++ b/TrollStore/Makefile @@ -1,5 +1,8 @@ TARGET := iphone:clang:16.4:14.0 INSTALL_TARGET_PROCESSES = TrollStore +ARCHS = arm64 + +TARGET_CODESIGN = ../Exploits/fastPathSign/fastPathSign include $(THEOS)/makefiles/common.mk @@ -10,6 +13,6 @@ TrollStore_FRAMEWORKS = UIKit CoreGraphics CoreServices TrollStore_PRIVATE_FRAMEWORKS = Preferences MobileIcons MobileContainerManager TrollStore_LIBRARIES = archive TrollStore_CFLAGS = -fobjc-arc -I../Shared -TrollStore_CODESIGN_FLAGS = -Sentitlements.plist -K../cert.p12 +TrollStore_CODESIGN_FLAGS = --entitlements entitlements.plist include $(THEOS_MAKE_PATH)/application.mk