Skip to content

Commit

Permalink
Found the right fd
Browse files Browse the repository at this point in the history
  • Loading branch information
UInt2048 committed May 12, 2024
1 parent 4bc7c8a commit 0a6d7ae
Show file tree
Hide file tree
Showing 16 changed files with 118 additions and 483 deletions.
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[submodule "submodules/libjake"]
path = submodules/libjake
url = https://github.com/JakeBlair420/libjake.git
url = https://github.com/UInt2048/libjake.git
35 changes: 25 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ RES = res
APP = $(BIN)/Payload/$(TARGET_GUI).app
SRC_GUI = src/app
SRC_CLI = src/untether
PAYLOAD = $(SRC_CLI)/generated/lol.spyware.spiceuntether_1.0.160_iphoneos-arm.deb
NO_UNTETHER := $(SRC_CLI)/stage3.m $(SRC_CLI)/stage4.m $(SRC_CLI)/generator.m # These are only pre-dependencies
UNTETHER_SRC := $(filter-out $(NO_UNTETHER),$(wildcard $(SRC_CLI)/*.m))
SRC_ALL = src/shared
Expand Down Expand Up @@ -42,14 +43,16 @@ IBTOOL_FLAGS ?= --output-format human-readable-text --errors --warnings --not
SIGN ?= codesign
SIGN_FLAGS ?= -s -

.PHONY: all ipa untether clean install
.PHONY: all ipa untether clean install payload

all: $(IPA) $(UNTETHER) $(TRAMP)

ipa: $(IPA)

untether: $(UNTETHER) $(TRAMP)

payload: $(PAYLOAD)

$(IPA): $(addprefix $(APP)/, $(FILES))
cd $(BIN) && zip -x .DS_Store -qr9 ../$@ Payload

Expand All @@ -67,17 +70,29 @@ $(APP)/jailbreak-resources.deb:
cp $(RES)/jailbreak-resources.deb $@

# TODO: Make more accurate prerequisites

$(SRC_CLI)/generated/stage2_hash3.h: $(SRC_CLI)/stage3.m

$(SRC_CLI)/compile_stage2.sh:
$(SRC_CLI)/compile_stage3.sh:
$(SRC_CLI)/compile_stage4.sh:

$(SRC_CLI)/generated/stage2_hash3.h: $(SRC_CLI)/stage3.m $(SRC_CLI)/compile_stage3.sh
bash $(SRC_CLI)/compile_stage3.sh
$(SRC_CLI)/generated/stage2_hash4.h: $(SRC_CLI)/stage4.m $(SRC_ALL)/*.m $(SRC_ALL)/*.c $(SRC_CLI)/generated/stage2_hash3.h

$(SRC_CLI)/generated/stage2_hash4.h: $(SRC_CLI)/stage4.m $(SRC_ALL)/*.m $(SRC_ALL)/*.c $(SRC_CLI)/generated/stage2_hash3.h $(SRC_CLI)/compile_stage4.sh
bash $(SRC_CLI)/compile_stage4.sh

$(SRC_CLI)/stage2.m: $(SRC_ALL)/*.c $(SRC_CLI)/generated/stage2_hash3.h $(SRC_CLI)/generated/stage2_hash4.h

$(SRC_CLI)/install.m: $(SRC_CLI)/jboffsets.h $(SRC_CLI)/generated/stage2_hash3.h $(SRC_CLI)/generated/install_stage3_offsets.h

$(SRC_CLI)/stage2.m: $(SRC_ALL)/*.c $(SRC_CLI)/install.m $(SRC_CLI)/stage1.m $(SRC_CLI)/generated/stage2_hash3.h $(SRC_CLI)/generated/stage2_hash4.h $(SRC_CLI)/stage2.entitlements $(SRC_CLI)/compile_stage2.sh
bash $(SRC_CLI)/compile_stage2.sh

$(SRC_CLI)/install.m: $(SRC_CLI)/generated/stage2_hash3.h $(SRC_CLI)/generated/install_stage3_offsets.h

$(PAYLOAD): $(UNTETHER_SRC) $(SRC_ALL)/*.m $(SRC_ALL)/*.c $(SRC_CLI)/*.sh $(SRC_CLI)/generated/stage2_hash3.h $(SRC_CLI)/generated/stage2_hash4.h $(SRC_CLI)/stage2.m
rm -rf -- $(SRC_CLI)/generated/package && rm -f $(SRC_CLI)/generated/*.deb
mkdir -p $(SRC_CLI)/generated/package/DEBIAN && cp $(SRC_CLI)/control $(SRC_CLI)/generated/package/DEBIAN/control
mkdir -p $(SRC_CLI)/generated/package/private/etc/racoon && cp $(SRC_CLI)/generated/install_stage1_2 $(SRC_CLI)/generated/package/private/etc/racoon/install_stage1_2
mkdir -p $(SRC_CLI)/generated/package/usr/sbin && cp $(SRC_CLI)/generated/racoon.dylib $(SRC_CLI)/generated/package/usr/sbin/racoon.dylib
mkdir -p $(SRC_CLI)/generated/package/mystuff && cp $(SRC_CLI)/generated/stage4 $(SRC_CLI)/generated/package/mystuff/stage4
find . -name ".DS_Store" -delete && dpkg-deb -b $(SRC_CLI)/generated/package && dpkg-name $(SRC_CLI)/generated/package.deb

$(APP)/$(TARGET_GUI): $(SRC_GUI)/*.m $(SRC_ALL)/*.m $(SRC_ALL)/*.c $(JAKE)/libjake.a $(SRC_CLI)/uland_offsetfinder.m | $(APP)
$(IGCC) $(ARCH_GUI) $(UNTETHER_FLAGS) -o $@ -Wl,-exported_symbols_list,res/app.txt $(IGCC_FLAGS) $^
Expand All @@ -97,7 +112,7 @@ $(APP):
$(APP)/Base.lproj:
mkdir -p $@

$(UNTETHER): $(UNTETHER_SRC) $(SRC_ALL)/*.m $(SRC_ALL)/*.c $(JAKE)/libjake.a
$(UNTETHER): $(UNTETHER_SRC) $(SRC_ALL)/*.m $(SRC_ALL)/*.c $(JAKE)/libjake.a | $(PAYLOAD)
$(IGCC) $(ARCH_CLI) $(UNTETHER_FLAGS) -shared -o $@ -Wl,-exported_symbols_list,res/untether.txt $(IGCC_FLAGS) $^
$(SIGN) $(SIGN_FLAGS) $@

Expand Down
39 changes: 29 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,21 +130,40 @@ So we just use swapprefix sysctl and the cool thing about this is that it's a st
We can use this to put our fake port at a known address and both new trustcache entries.

## Installation
For compilation of stage 2-4, use the shell scripts in the untether folder, the makefile only works for the app.
For the installation, copy stage 2 onto the device into some random folder and stage 3 (/usr/sbin/racoon.dylib) and 4 (/mystuff/stage4) at their right paths.
Create the folder /var/run/racoon and run stage 2 (note: stage 1 expects stage 2 at /private/etc/racoon/stg2).
Then execute racoon till it doesn't kernel panic anymore to make sure you got the right offsets.
Then also set the nvram variable boot-args to "`__developer_mode_enabled`" and check if the system keeps running stable even with racoon (this is the killswitch).
If you did you can then go for the real untether by replacing one of the launch daemons and unsetting the variable to run the untether on the next boot.
There you need to watch out for three things:
Obviously, just run `make` to create all generated files (the makefile requires macOS, use a VM or something if you need it).

The app is a *semi-untethered jailbreak*. The app will not install the untether payload.

If you have an issue upgrading essential packages, run `apt --fix-broken install file libplist3 libssl1.1.1` then `apt install -f dpkg ldid -o APT::Immediate-Configure=0` over an SSH connection.

To install the untether payload (these files are located in ./src/untether/generated):
1. Install the DEB file (use `make payload` if you can't find it) or manually copy the stage 1-2 install script to `/private/etc/racoon/install_stage1_2`, stage 3 to `/usr/sbin/racoon.dylib`, and stage 4 to `/mystuff/stage4`.
2. Type `/private/etc/racoon/install_stage1_2` in a terminal or SSH connection. This will create the folder `/var/run/racoon` if it does not yet exist.
There will be a lot of output. If successful, the end looks something like:
```
0x1f0214e60: 0x00000000 (NOP)
0x1f0214e68: 0x1e1639494 (code address org:1a1639494) Beast gadget (x30)
=
===
2024-05-11 05:47:33.135 install_stage1_2[4321:134320] Chain will be at: 1afe90d30
2024-05-11 05:47:33.141 install_stage1_2[4321:134320] 4610 iterations
```
3. Then execute racoon (the real one in PATH, should be `/usr/sbin/racoon`) till it doesn't kernel panic anymore to make sure you got the right offsets.
If you get a segfault, and the crash report shows the beast gadget offset listed in your output, you likely need to set `STAGE1FD_SCREAM_TEST` to find the right stage 1 fd in the crash log.
4. Then also set the nvram variable boot-args to "`__developer_mode_enabled`" and check if the system keeps running stable even with racoon (this is the killswitch).
5. If you did you can then go for the real untether by replacing one of the launch daemons and unsetting the killswitch to run the untether on the next boot.

There, you need to watch out for three things:
- the launch daemon isn't used by anything important (namely springboard) (otherwise you will softbrick when it fails to run)
- the launch daemon doesn't have keepalive set (if it does launchd will try to always restart it if you crash it and that will also softbrick)
- the launch daemon starts up early

We found out that you can safely replace prdaily but this one will start really late during boot so you get the same behaviour we also showed in febuary in the demo.
You can also replace wifiFirmwareLoaderLegacy, but this one has keepalive set so you might softbrick. The big advantage you get tho is speed because it starts really early.
After you chose your daemon you need to update jailbreak.m to unload the right one (currently unloads prdaily) and recompile stage 4/replace it on disk again.
As a last step please run sync a few times to make sure that everything got written to disk and then fingers crossed it works and you don't softbrick.
If you restart and it keeps kernel panicing boot into recovery and set the boot-args to "`__developer_mode_enabled`" using irecovery and then reboot this will disable stage 2/the kernel exploit.

If you choose something other than prdaily, you need to update jailbreak.m to unload the right one (currently unloads prdaily) and recompile stage 4/replace it on disk again.
As a last step, please run sync a few times to make sure that everything got written to disk and then fingers crossed it works and you don't softbrick.
If you restart and it keeps kernel panicing, boot into recovery and set the boot-args to "`__developer_mode_enabled`" using irecovery and then reboot this will disable stage 2/the kernel exploit.
If you still can't boot after that you basically softbricked sry.

## References
Expand Down
186 changes: 9 additions & 177 deletions src/app/CreditsVC.m
Original file line number Diff line number Diff line change
@@ -1,82 +1,5 @@
#import "CreditsVC.h"

// Copied from <shared/jailbreak.m>, don't actually do this
#import <shared/common.h>
#include <untether/uland_offsetfinder.h>
#include "patchfinder.h"
static offsets_t dynamicOffsets(const char *config_path, const char *racoon_path, const char *dyld_cache_path) {
init_uland_offsetfinder(racoon_path,dyld_cache_path);

// init the kernel offset finder (libjake)
jake_img_t kernel_symbols = malloc(sizeof(jake_img));

#define KERNEL_CACHE_PATH "/System/Library/Caches/com.apple.kernelcaches/kernelcache"
if (jake_init_image(kernel_symbols, KERNEL_CACHE_PATH)) {
LOG("Patchfinder init failed\n");
return (offsets_t){};
}

// Duplicate code from stage2.m
#define sym(name) jake_find_symbol(kernel_symbols,name)
return (offsets_t){
.constant = {
.kernel_image_base = 0xfffffff007004000, // static
},
.funcs = {
.copyin = sym("_copyin"), // symbol, duplicate
.copyout = sym("_copyout"), // symbol
.current_task = sym("_current_task"), // symbol
.get_bsdtask_info = sym("_get_bsdtask_info"), // symbol
.vm_map_wire_external = sym("vm_map_wire_external"), // symbol
.vfs_context_current = sym("vfs_context_current"), // symbol
.vnode_lookup = sym("_vnode_lookup"), // symbol
.osunserializexml = sym("__Z16OSUnserializeXMLPKcPP8OSString"), // symbol
.proc_find = sym("_proc_find"), // symbol
.proc_rele = sym("_proc_rele"), // symbol

.smalloc = 0xfffffff006b1acb0,
.ipc_port_alloc_special = 0xfffffff0070b9328,
.ipc_kobject_set = 0xfffffff0070cf2c8,
.ipc_port_make_send = 0xfffffff0070b8aa4,
},
.gadgets = {
.add_x0_x0_ret = sym("_csblob_get_cdhash"), // gadget
},
.data = {
.kernel_task = sym("_kernel_task"), // symbol
.kern_proc = sym("_kernproc"), // symbol
.rootvnode = sym("_rootvnode"), // symbol

.realhost = find_realhost(kernel_symbols), // _host_priv_self -> adrp addr
.zone_map = find_zonemap(kernel_symbols), // str 'zone_init: kmem_suballoc failed', first qword above
.osboolean_true = 0, // OSBoolean::withBoolean -> first adrp addr
.trust_cache = find_trustcache(kernel_symbols), // duplicate of trust_chain_head_ptr?
},
.vtabs = {
.iosurface_root_userclient = 0, // 'iometa -Csov IOSurfaceRootUserClient kernel', vtab=...
},
.struct_offsets = {
.is_task_offset = 0x28, // duplicate
.task_itk_self = 0xd8,
.itk_registered = 0x2f0, // duplicate
.ipr_size = 8, // duplicate, ipc_port_request->name->size
.sizeof_task = 0x5c8, // size of entire task struct
.proc_task = 0, // proc->task
.proc_p_csflags = 0, // proc->p_csflags (_cs_restricted, first ldr offset)
.task_t_flags = 0x3a0, // task->t_flags, not set in untether version
.task_all_image_info_addr = 0x3a8, // task->all_image_info_addr (theoretically just +0x8 from t_flags)
.task_all_image_info_size = 0x3b0, // task->all_image_info_size
},
.iosurface = {
.create_outsize = 0,
.create_surface = 0,
.set_value = 0,
},
};
}

// End copied code

UILabel *creditLabel;
UILabel *offsetLabel;

Expand Down Expand Up @@ -111,112 +34,21 @@ - (void)loadView

creditLabel = [UILabel new];
creditLabel.translatesAutoresizingMaskIntoConstraints = NO;
creditLabel.numberOfLines = 0;
creditLabel.text = @"Credit to @s1guza, @stek29, @sparkey, @littlelailo\nfor creating the untether\nCredit to @UInt2048 for fixing the UI and offsets";
creditLabel.numberOfLines = 7;
creditLabel.text = @"\
- JakeBlair420 team for the actual jailbreak\n\
- Apple for XNU source and leaving CVE-2020-3840 in iOS for years (since iPhoneOS 1.0 if you believe the NVD entry for CVE-2012-3727)\n\
- National Security Agency for Ghidra\n\
- planetbeing et al. for xpwntool to decompress the iOS 10 kernel cache\n\
- PrimePlatypus, LukeZGD, cxdxn1 for explaining that xpwntool exists and how to use it\n\
- blacktop for the ipsw tool to decompress the iOS 11 kernel cache\n\
- Jonathan Levin for jtool";
[creditLabel setBackgroundColor:[UIColor colorWithRed:1.00 green:0.00 blue:0.00 alpha:0.0]];
creditLabel.font = [UIFont systemFontOfSize:14];

[self.view addSubview:creditLabel];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:creditLabel attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:creditLabel attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1.7 constant:0.0]];


#define CONFIG_PATH "etc/racoon/racoon.conf"
#define RACOON_PATH "/usr/sbin/racoon"
#ifdef __LP64__
#define DYLD_CACHE_PATH "/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64"
#else
#define DYLD_CACHE_PATH "/System/Library/Caches/com.apple.dyld/dyld_shared_cache_armv7s"
#endif

offsets_t offs = dynamicOffsets(CONFIG_PATH, RACOON_PATH, DYLD_CACHE_PATH);

offsetLabel = [UILabel new];
offsetLabel.translatesAutoresizingMaskIntoConstraints = NO;
offsetLabel.numberOfLines = 0;
offsetLabel.text = [NSString stringWithFormat:@"\
kernel_image_base: %x\n\
copyin: %x\n\
copyout: %x\n\
current_task: %x\n\
get_bsdtask_info: %x\n\
vm_map_wire_external: %x\n\
vfs_context_current: %x\n\
vnode_lookup: %x\n\
osunserializexml: %x\n\
proc_find: %x\n\
proc_rele: %x\n\
smalloc: %x\n\
ipc_port_alloc_special: %x\n\
ipc_kobject_set: %x\n\
ipc_port_make_send: %x\n\
add_x0_x0_ret: %x\n\
kernel_task: %x\n\
kern_proc: %x\n\
rootvnode: %x\n\
realhost: %x\n\
zone_map: %x\n\
osboolean_true: %x\n\
trust_cache: %x\n\
iosurface_root_userclient: %x\n\
is_taskoffset: %x\n\
task_itk_self: %x\n\
itk_registered: %x\n\
ipr_size: %x\n\
sizeof_task: %x\n\
proc_task: %x\n\
proc_p_csflags: %x\n\
task_t_flags: %x\n\
task_all_image_info_addr: %x\n\
task_all_image_info_size: %x\n\
create_outsize: %x\n\
create_surface: %x\n\
set_value: %x\n\
",
offs.constant.kernel_image_base,
offs.funcs.copyin,
offs.funcs.copyout,
offs.funcs.current_task,
offs.funcs.get_bsdtask_info,
offs.funcs.vm_map_wire_external,
offs.funcs.vfs_context_current,
offs.funcs.vnode_lookup,
offs.funcs.osunserializexml,
offs.funcs.proc_find,
offs.funcs.proc_rele,
offs.funcs.smalloc,
offs.funcs.ipc_port_alloc_special,
offs.funcs.ipc_kobject_set,
offs.funcs.ipc_port_make_send,
offs.gadgets.add_x0_x0_ret,
offs.data.kernel_task,
offs.data.kern_proc,
offs.data.rootvnode,
offs.data.realhost,
offs.data.zone_map,
offs.data.osboolean_true,
offs.data.trust_cache,
offs.vtabs.iosurface_root_userclient,
offs.struct_offsets.is_task_offset,
offs.struct_offsets.task_itk_self,
offs.struct_offsets.itk_registered,
offs.struct_offsets.ipr_size,
offs.struct_offsets.sizeof_task,
offs.struct_offsets.proc_task,
offs.struct_offsets.proc_p_csflags,
offs.struct_offsets.task_t_flags,
offs.struct_offsets.task_all_image_info_addr,
offs.struct_offsets.task_all_image_info_size,
offs.iosurface.create_outsize,
offs.iosurface.create_surface,
offs.iosurface.set_value
];
[offsetLabel setBackgroundColor:[UIColor colorWithRed:1.00 green:0.00 blue:0.00 alpha:0.0]];
offsetLabel.font = [UIFont systemFontOfSize:14];
[self.view addSubview:offsetLabel];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:offsetLabel attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:offsetLabel attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1.7 constant:0.0]];

}

@end
2 changes: 1 addition & 1 deletion src/app/MainVC.m
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ - (void)loadView

titleLabel = [UILabel new];
titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
titleLabel.text = @"An iOS 10.3.4 untether";
titleLabel.text = @"First untether-upgradable iOS 11 jailbreak";
[titleLabel setBackgroundColor:[UIColor colorWithRed:1.00 green:0.00 blue:0.00 alpha:0.0]];
titleLabel.font = [UIFont systemFontOfSize:14];

Expand Down
Loading

0 comments on commit 0a6d7ae

Please sign in to comment.