Date: Sun, 19 Oct 1997 20:38:40 -0400From: bryan berg <km@UNDERWORLD.NET>
To: BUGTRAQ@NETSPACE.ORGSubject: Vulnerability in PHP Example Logging Scripts
Whilst perusing various things included with the PHP distribution, I
noticed that there was a gaping security hole in a few of the example
scripts, specifically mlog.html and mylog.html, which allow any remote user
to read any arbitrary file on the system. (which is readable to the user
that httpd and thus PHP are running as) To top it all off, this exploit is
really easy to accomplish.
The problem lies in the line:
<?include "$screen">
in both mlog.html and mylog.html.
 The idea is to include a file for each
type of logging stats, however, there is no escaping of slashes, so one can
specify any file on the system.
The exploit for dummies:
http://some.stupid.isp.net/~dumbuser/cool-logs/mlog.html?screen=[fully
qualified path to any file on the system]
useful files to see are /etc/hosts.allow, /etc/passwd (for unshadowed
systems..) and just about anything else.

Temporary fix:insert the line
<?ereg_replace("/","",$screen);>
just before the <?include... line.
This problem exists in the most current distribution of PHP; I'm willing to
bet that it's been around for a while.  Hopefully, it will be officially
fixed soon... ;)



NCSA PHP/FI CGI *2 HOLES*
Description: First of all
this rather pathetic cgi allows anyone to trivially read any file on the system which is readabl by the owner of the httpd process (usually nobody or daemon).  It also has a buffer overflow.
Author:  Shamanski &ltjshaman@M-NET.ARBORNET.ORG&gt posted the read-any-file exploit
The SNI advisory is by David Sacerdote
Compromise: read files and execute code as the httpd process owner (remote)
Vulnerable Systems:  Those with php.cgi 2.0beta10 or earlier
distributed with NCAA httpd
possibly others.
Date:   16 April 1997
Notes:
Exploit:


From jshaman@M-NET.ARBORNET.ORG Fri Apr 18 22:29:09 1997
Date: Wed
16 Apr 1997 21:01:12 -0400
From: Shamanski
To: BUGTRAQ@NETSPACE.ORG
Subject: Update on PHP/FI hole

============================================================================
[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


--SNI advisory:

From davids@SECNET.COM Fri Apr 18 22:29:51 1997
Date: Thu
17 Apr 1997 16:02:07 -0600
From: David Sacerdote
To: BUGTRAQ@NETSPACE.ORG
Subject: PHP/FI command line buffer overflow

X-Premail-Auth: Key matching expected Key ID 9E55000D not found

-----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='\0';
!               strcpy(path
filename);
*s=o;
} else {
#ifdef PHP_ROOT_DIR
!               strcpy(path
PHP_ROOT_DIR);
#else
path[0] = '\0';
#endif
!               strcpy(fn
filename);
}
if(fn && *fn=='~') {
!               strcpy(path
fn);
fn[0]='\0';
}
if(*path) {
- --- 295
320 ----

s = strrchr(filename
'/');
if(s) {
!               strncpy(fn
s+1
sizeof (fn));
!               fn[sizeof(fn) - 1] = '\0';
o=*s;
*s='\0';
!               strncpy(path
filename
sizeof (path));
!               path[sizeof(path) - 1] = '\0';
*s=o;
} else {
#ifdef PHP_ROOT_DIR
!               strncpy(path
PHP_ROOT_DIR
sizeof(path));
!               path[sizeof(path) -1] = '\0';
#else
path[0] = '\0';
#endif
!               strncpy(fn
filename
sizeof (fn));
!               fn[sizeof(fn) - 1] = '\0';
}
if(fn && *fn=='~') {
!               strncpy(path
fn
sizeof (path));
!               path[sizeof(path) - 1] = '\0';
fn[0]='\0';
}
if(*path) {
***************
*** 319
328 ****
o=*s;
*s='\0';
}
!                       strcpy(user
path+1);
if(s) {
*s=o;
!                               strcpy(temp
s);
} else temp[0]='\0';
#ifdef HAVE_PWD_H
if(*user) {
- --- 324
335 ----
o=*s;
*s='\0';
}
!                       strncpy(user
path+1
sizeof (user));
!                       user[sizeof(user) - 1] = '\0';
if(s) {
*s=o;
!                               strncpy(temp
s
sizeof (temp));
!                               temp[sizeof(temp) - 1] = '\0';
} else temp[0]='\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='\0';
}
!                       strcpy(user
path+2);
if(s) {
*s=o;
!                               strcpy(temp
s);
} else temp[0]='\0';
#if HAVE_PWD_H
if(*user) {
- --- 355
366 ----
o=*s;
*s='\0';
}
!                       strncpy(user
path+2
sizeof (user));
!                       user[sizeof(user) - 1] = '\0';
if(s) {
*s=o;
!                               strncpy(temp
s
sizeof(temp));
!                               temp[sizeof(temp) - 1] = '\0';
} else temp[0]='\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] = '\0';
!                       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] = '\0';
!                               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] = '\0';
!                                       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] = '\0';
!                               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] = '\0';
!                               strncat (temp
/index.phtml

!                                       sizeof (temp) - strlen (temp) - 1);
st = stat(temp
&gsb);
}
!                       } else {
!                               strncpy(temp
path
sizeof (temp));
!                               temp[sizeof (temp) - 1] = '\0';
!                       }
}
} 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] = '\0';
!                       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] = '\0';
!                               strncat (temp
/index..phtml

!                                       sizeof (temp) - strlen (temp) - 1);
!
st = stat(temp
&gsb);
}
!               } else {
!                       strncpy(temp
fn
sizeof (temp));
!                       temp[sizeof(temp) - 1] = '\0';
!               }
}
*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 .  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-----







