not all php implementations are equally useful

Post on 23-Jun-2015

1.582 Views

Category:

Technology

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

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?

top related