Published:
22 April 1997
Protect yourself against future threats.
-----BEGIN PGP SIGNED MESSAGE----- =========================================================================== AUSCERT External Security Bulletin Redistribution ESB-97.047 -- SNI Security Advisory and DIS Advisory 97-347.1 PHP/FI command line buffer overflow and PHP/FI cgi program files restriction 23 April 1997 =========================================================================== Secure Networks Inc and the Digital Information Society (DIS) have released the following advisories concerning two vulnerabilities in the PHP/FI cgi program. The first vulnerability, addressed in the SNI advisory, concerns a buffer overflow in the PHP cgi program. This vulnerability may allow unauthorized users to obtain shell or command line access to any vulnerable system. The second vulnerability, addressed in the DIS advisory, concerns a lack of restriction on the files that can be viewed on the system. This vulnerability may allow unauthorized users to view arbitrary file contents on the vulnerable system. AUSCERT has received information from the maintainer of PHP/FI, Rasmus Lerdorf, that PHP/FI 2.0b11 to be released in the near future, will address both vulnerabilities. In the interim, sites are advised to remove the PHP cgi program if it is not required. If it is needed, it is advised that sites apply BOTH solutions given in the bulletins bellow to remove both vulnerabilities. More information on PHP/FI can be found at: http://www.vex.net/php/ The following security bulletins are provided as a service to AUSCERT's members. As AUSCERT did not write these documents, AUSCERT has had no control over their contents. As such, the decision to use any or all of this information is the responsibility of each user or organisation, and should be done so in accordance with site policies and procedures. Contact information for Secure Networks Inc and the Digital Information Society is included in the Security Bulletins below. If you have any questions or need further information, please contact them directly. If you believe that your system has been compromised, contact AUSCERT or your representative in FIRST (Forum of Incident Response and Security Teams). Internet Email: auscert@auscert.org.au Facsimile: (07) 3365 4477 Telephone: (07) 3365 4417 (International: +61 7 3365 4417) AUSCERT personnel answer during Queensland business hours which are GMT+10:00 (AEST). On call after hours for emergencies. - --------------------------BEGIN INCLUDED TEXT-------------------- - -----BEGIN PGP SIGNED MESSAGE----- ###### ## ## ###### ## ### ## ## ###### ## # ## ## ## ## ### ## ###### . ## ## . ######. Secure Networks Inc. Security Advisory April 17, 1997 Buffer Overflow in php.cgi This advisory describes a remotely exploitable buffer overflow in the PHP cgi program. This is *NOT* the PATTERN_RESTRICT issue described in earlier bugtraq discussion. Problem Description ~~~~~~~~~~~~~~~~~~~ In the function FixFilename() function in file.c, PHP attempts to pass strings whose length may be as long as 8 kilobytes into buffers as small as 128 bytes. This overwrites the stack, making it possible for an attacker to obtain shell access to the machine running the web server. Technical Details ~~~~~~~~~~~~~~~~~ The filename argument to FixFilename is derived from the command line used to invoke to the CGI script, or from the QUERY_STRING environment variable passed to it. The total length of either can be as long as eight kilobytes, but the fn string is a mere 128 bytes long. An excerpt from the flawed code reads: char *FixFilename(char *filename, int cd, int *ret) { ... char fn[128], user[128], *s; ... s = strrchr(filename,'/'); if(s) { strcpy(fn,s+1); ... Impact ~~~~~~ Attackers can remotely obtain shell or command line access to any vulnerable system. Vulnerable Systems ~~~~~~~~~~~~~~~~~~ Any computer running a web server with php.cgi 2.0beta10 or earlier is vulnerable, irrespective of what operating system it is running, provided that PHP is run as a cgi, and not as an Apache module. When compiled as an Apache module, PHP does not appear to execute the problem code. To determine whether a system is running a web server with php.cgi installed as a cgi, use your favorite web browser to access the URL http://hostname/cgi-bin/php.cgi If you see something like: PHP/FI Version 2.0b10 ... Then the machine hostname is running PHP/FI. Fix information ~~~~~~~~~~~~~~~ Use the patch program to apply the following diffs to file.c, then recompile php.cgi. These diffs are against version 2.0b10. *** file.c Thu Apr 17 09:36:07 1997 - - --- file.c.fixed Thu Apr 17 09:36:00 1997 *************** *** 295,315 **** s = strrchr(filename,'/'); if(s) { ! strcpy(fn,s+1); o=*s; *s=''; ! strcpy(path,filename); *s=o; } else { #ifdef PHP_ROOT_DIR ! strcpy(path,PHP_ROOT_DIR); #else path[0] = ''; #endif ! strcpy(fn,filename); } if(fn && *fn=='~') { ! strcpy(path,fn); fn[0]=''; } if(*path) { - - --- 295,320 ---- s = strrchr(filename,'/'); if(s) { ! strncpy(fn,s+1, sizeof (fn)); ! fn[sizeof(fn) - 1] = ''; o=*s; *s=''; ! strncpy(path,filename, sizeof (path)); ! path[sizeof(path) - 1] = ''; *s=o; } else { #ifdef PHP_ROOT_DIR ! strncpy(path,PHP_ROOT_DIR, sizeof(path)); ! path[sizeof(path) -1] = ''; #else path[0] = ''; #endif ! strncpy(fn,filename, sizeof (fn)); ! fn[sizeof(fn) - 1] = ''; } if(fn && *fn=='~') { ! strncpy(path,fn, sizeof (path)); ! path[sizeof(path) - 1] = ''; fn[0]=''; } if(*path) { *************** *** 319,328 **** o=*s; *s=''; } ! strcpy(user,path+1); if(s) { *s=o; ! strcpy(temp,s); } else temp[0]=''; #ifdef HAVE_PWD_H if(*user) { - - --- 324,335 ---- o=*s; *s=''; } ! strncpy(user,path+1, sizeof (user)); ! user[sizeof(user) - 1] = ''; if(s) { *s=o; ! strncpy(temp,s, sizeof (temp)); ! temp[sizeof(temp) - 1] = ''; } else temp[0]=''; #ifdef HAVE_PWD_H if(*user) { *************** *** 333,339 **** pd = getenv(PHP_PUB_DIRNAME_ENV); #endif if (pd == 0) pd = PHP_PUB_DIRNAME; ! sprintf(path,"%s/%s%s",pw->pw_dir,pd,temp); } } #endif - - --- 340,351 ---- pd = getenv(PHP_PUB_DIRNAME_ENV); #endif if (pd == 0) pd = PHP_PUB_DIRNAME; ! strcpy (path,pw->pw_dir); ! strcat (path,"/"); ! strncat (path, pd, ! sizeof(path) - strlen(path) - 1); ! strncat (path, temp, ! sizeof (path) - strlen(path) - 1); } } #endif *************** *** 343,352 **** o=*s; *s=''; } ! strcpy(user,path+2); if(s) { *s=o; ! strcpy(temp,s); } else temp[0]=''; #if HAVE_PWD_H if(*user) { - - --- 355,366 ---- o=*s; *s=''; } ! strncpy(user,path+2, sizeof (user)); ! user[sizeof(user) - 1] = ''; if(s) { *s=o; ! strncpy(temp,s,sizeof(temp)); ! temp[sizeof(temp) - 1] = ''; } else temp[0]=''; #if HAVE_PWD_H if(*user) { *************** *** 357,363 **** pd = getenv(PHP_PUB_DIRNAME_ENV); #endif if (pd == 0) pd = PHP_PUB_DIRNAME; ! sprintf(path,"%s/%s%s",pw->pw_dir,pd,temp); } } #endif } - - --- 371,383 ---- pd = getenv(PHP_PUB_DIRNAME_ENV); #endif if (pd == 0) pd = PHP_PUB_DIRNAME; ! strcpy (path,pw->pw_dir); ! strcat (path,"/"); ! strncat (path, pd, ! sizeof(path) - strlen(path) - 1); ! strncat (path, temp, ! sizeof (path) - strlen(path) - 1); ! } } #endif } *************** *** 370,376 **** } } if(*fn) { ! sprintf(temp,"%s/%s",path,fn); #ifndef WINDOWS st = stat(temp,&gsb); #else - - --- 390,399 ---- } } if(*fn) { ! strncpy (temp, path, sizeof (temp)); ! temp[sizeof(temp) - 1] = ''; ! strcat (temp,"/"); ! strncat(temp,fn,sizeof(temp) - strlen(temp) - 1); #ifndef WINDOWS st = stat(temp,&gsb); #else *************** *** 382,394 **** st = -1; #endif if((st!=-1) && (gsb.st_mode&S_IFMT)==S_IFDIR) { ! sprintf(temp,"%s/%s/index.html",path,fn); st = stat(temp,&gsb); if(st==-1) { ! sprintf(temp,"%s/%s/index.phtml",path,fn); st = stat(temp,&gsb); } ! sprintf(path,"%s/%s",path,fn); } else if(st==-1) { l = strlen(temp); if(strlen(fn)>4) { - - --- 405,431 ---- st = -1; #endif if((st!=-1) && (gsb.st_mode&S_IFMT)==S_IFDIR) { ! strncpy (temp,path,sizeof(temp)); ! temp[sizeof(temp) - 1] = ''; ! strcat (temp, "/"); ! strncat (temp,fn, ! sizeof(temp) - strlen (temp) - 1); ! strncat (temp,"/index.html", ! sizeof(temp) - strlen (temp) - 1); st = stat(temp,&gsb); if(st==-1) { ! strncpy (temp,path,sizeof(temp)); ! temp[sizeof(temp) - 1] = ''; ! strcat (temp, "/"); ! strncat (temp,fn, ! sizeof(temp) - strlen (temp) - 1); ! strncat (temp,"/index.html", ! sizeof(temp) - strlen (temp) - 1); st = stat(temp,&gsb); } ! strcat (path,"/"); ! strncat (path, fn, ! sizeof(path) - strlen(path) - 1); } else if(st==-1) { l = strlen(temp); if(strlen(fn)>4) { *************** *** 410,422 **** st = -1; #endif if((st!=-1) && (gsb.st_mode&S_IFMT)==S_IFDIR) { ! sprintf(temp,"%s/index.html",path); st = stat(temp,&gsb); if(st==-1) { ! sprintf(temp,"%s/index.phtml",path); st = stat(temp,&gsb); } ! } else strcpy(temp,path); } } else { #ifndef WINDOWS - - --- 447,468 ---- st = -1; #endif if((st!=-1) && (gsb.st_mode&S_IFMT)==S_IFDIR) { ! strncpy (temp, path, sizeof (temp)); ! temp[sizeof(temp) - 1] = ''; ! strncat (temp, "/index.html", ! sizeof (temp) - strlen (temp) - 1); st = stat(temp,&gsb); if(st==-1) { ! strncpy (temp, path, sizeof (temp)); ! temp[sizeof(temp) - 1] = ''; ! strncat (temp, "/index.phtml", ! sizeof (temp) - strlen (temp) - 1); st = stat(temp,&gsb); } ! } else { ! strncpy(temp,path, sizeof (temp)); ! temp[sizeof (temp) - 1] = ''; ! } } } else { #ifndef WINDOWS *************** *** 430,442 **** st = -1; #endif if((st!=-1) && (gsb.st_mode&S_IFMT)==S_IFDIR) { ! sprintf(temp,"%s/index.html",fn); st = stat(temp,&gsb); if(st==-1) { ! sprintf(temp,"%s/index.phtml",fn); st = stat(temp,&gsb); } ! } else strcpy(temp,fn); } *ret=st; return(temp); - - --- 476,498 ---- st = -1; #endif if((st!=-1) && (gsb.st_mode&S_IFMT)==S_IFDIR) { ! strncpy (temp, fn, sizeof (temp)); ! temp[sizeof(temp) - 1] = ''; ! strncat (temp, "/index.html", ! sizeof (temp) - strlen (temp) - 1); st = stat(temp,&gsb); if(st==-1) { ! strncpy (temp, fn, sizeof (temp)); ! temp[sizeof(temp) - 1] = ''; ! strncat (temp, "/index..phtml", ! sizeof (temp) - strlen (temp) - 1); ! st = stat(temp,&gsb); } ! } else { ! strncpy(temp,fn,sizeof (temp)); ! temp[sizeof(temp) - 1] = ''; ! } } *ret=st; return(temp); Additional Information ~~~~~~~~~~~~~~~~~~~~~~ If you have any questions about this advisory, feel free to mail me at davids@secnet.com. Past Secure Networks advisories can be found at ftp://ftp.secnet.com/pub/advisories, and Secure Networks papers can be found at ftp://ftp.secnet.com/pub/papers. PHP/FI was written by Rasmus Lerdorf <rasmus@vex.net>. Additional information about PHP/FI can be found at http://www.vex.net/php This advisory does NOT address a recently published hole in the php.cgi which allows attackers to obtain copies of any file on the web server which is readable by the user the php.cgi program runs as. FIRST and vendor contacts please note that this advisory was expedited. This is becuase we felt that previous public post (by another) party would lead to the eventual discovery of this bug. As a result of this we therefore wanted a fix to be availible to the public as soon as possible. The following PGP key is for davids@secnet.com, should you wish to encrypt any message traffic to the author of this advisory: - - -----BEGIN PGP PUBLIC KEY BLOCK----- Version: 2.6.2 mQCNAzJ4qJAAAAEEAOgB7mooQ6NgzcUSIehKUufGsyojutC7phVXZ+p8FnHLLZNB BLQEtj5kmfww2A2pR29q4rgPeqEUOjWPlLNdSLby3NI8yKz1AQSQLHAwIDXt/lku 8QXClaV6pNIaQSN8cnyyvjH6TYF778yZhYz0mwLqW6dU5whHtP93ojDw1UhtAAUR tCtEYXZpZCBTYWNlcmRvdGUgPGRhdmlkc0BzaWxlbmNlLnNlY25ldC5jb20+ =LtL9 - - -----END PGP PUBLIC KEY BLOCK----- Feel free to send responses and commments to sni@secnet.com. If you should wish to encrypt such traffic, please use the Secure Networks Inc. key: - - -----BEGIN PGP PUBLIC KEY BLOCK----- Version: 2.6.2 mQCNAzLaFzIAAAEEAKsVzPR7Y6oFN5VPE/Rp6Sm82oE0y6Mkuof8QzERV6taihn5 uySb31UeNJ4l6Ud9alOPT/0YdeOO9on6eD1iU8qumFxzO3TLm8nTAdZehQSAQfoa rWmpwj7KpXN/3n+VyBWvhpBdKxe08SQN4ZjvV5HXy4YIrE5bTbgIhFKeVQANAAUR tCVTZWN1cmUgTmV0d29ya3MgSW5jLiA8c25pQHNlY25ldC5jb20+iQCVAwUQM03n 27Tl3s+VYMi5AQHdGwP+N3hhILzzhSvhx1gj6ZElgsLa7Q1P3cTlc/Xqx50/wkcX qIwiPudH+9UHvpL8fUNaHc9iZf3y8YZz0HWz56Vm5SG7uBfB/ksq4x04pQ65dQ1m v51DYCvLG9u0jL4hC3Mz9WvIMANXqOUlAhuU1iy0wM41joE8aHdh2jsLHlB5qlSJ AJUDBRAzTlbK/3eiMPDVSG0BAcTNA/9eF0X4Ei8LM4CXFW7JTB5vwXxerR6FmKI8 0JXt6KTrjGBzTfBrDGUZHNakPELjQPQI+fqg6hKJ7Ro1eSL4QbtX2BTO+wIWoLJG hQmccKleuEK5N9vFgzvPTRknfkbqL1Ta7g3Z9tE8TQhFbj0x4yNFAPB/hOhVvY3s YOkUx4T12A== =ljNl - - -----END PGP PUBLIC KEY BLOCK----- Copyright Notice ~~~~~~~~~~~~~~~~ The contents of this advisory are Copyright (C) 1997 Secure Networks Inc, and may be distributed freely provided that no fee is charged for distribution, and that proper credit is given. PHP sources distributed as part of this advisory fall under the GNU Public license, version 2. - -----BEGIN PGP SIGNATURE----- Version: 2.6.2 iQCVAwUBM1ZjwbgIhFKeVQANAQE/HQP/cuvfviM3RdAtMFw4JlafVfAZ8KNYaP61 dHcg0KmEZYeChOFgtRULHj9d2bhYniAjwVkioO4vIwvsmfNZSGnP3kMMQRv0oSkJ 9MNqeupqeF3cs3i88m8bT8TH9qNOvsbHAGix/TNHvgSK63rzUfzbfDbId8YwA2JD 2892qweY4b0= =vuDt - -----END PGP SIGNATURE----- - ----------------------------------------------------------------------------- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ============================================================================ [DiS] Advisory 97-347.1 Issue date: April 16, 1997 Topic: REMOTE Vulnerability in PHP/FI - ---------------------------------------------------------------------------- A vulnerability has been found by DiS in PHP/FI, a NCSA httpd cgi enhancment. This vulnerability allows unauthorized users to view arbitrary file contents on the machine running httpd by sending the file name wishing to be displayed as the QUERY_STRING. I. Exploit simply use any web browser to send the following URL: http://boogered.system.com/cgi-bin/php.cgi?/file/to/view Note: this exploit has not been tested on a system that has compiled PHP/FI as an apache module. This information may or may not be applicable on such a system. II. Impact Remote, unauthorized users can view arbitrary file contents on the system with the same privileges as the httpd (HTTP daemon) child process. III. Solution The author has propsed the following sollution: >> ...The workaround is to set the following in php.h >> >> #define PATTERN_RESTRICT ".*\.phtml$" >> >> This will limit the php.cgi parser to only display files ending in .phtml >> >> The exact same adviasory applies to any other parser someone might decide >> to stick in their cgi-bin directory. This is in no way specific to PHP/FI. >> >> You can also avoid the problem by using either CGI redirection or >> by using the Apache module version. >> >> -Rasmus - ---------------------------------------------------------------------------- The current PHP/FI distribution may be obtained from http://www.vex.net/php J-Man Th' Shaman [DiGiTAL iNFORMATiON SOCiETY] jshaman@m-net.arbornet.org jamin@avatar.ml.org ============================================================================ - --------------------------END INCLUDED TEXT-------------------- -----BEGIN PGP SIGNATURE----- Version: 2.6.3i Charset: noconv Comment: ftp://ftp.auscert.org.au/pub/auscert/AUSCERT_PGP.key iQCVAwUBM14wEih9+71yA2DNAQHU2QP/WDb3JsDSiTLALUsJaUD4xJmhvIvYKJzG 31yrPJGUpChITh1K9t9+KMWqL+ioMSipY4UE0CPT6A4pWIP8Dv8bCaGLqaBZfHZT 9/8l22ZDu2tEVoM/+8OIUOtNgEUJXBaciNGbzU9WVozdtYOPWjNijfuMXQb8U5Ib 0I+d88BjJdk= =W1Fi -----END PGP SIGNATURE-----