-
-
Save mttjohnson/3ed0ec32e4b45e4c154686ec3276474a to your computer and use it in GitHub Desktop.
Test File or Folder for Dangerous PHP Functions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* dangerous_functions.php | |
* Perry Holden <perry.holden@gmail.com> | |
* | |
* Usage: php dangerous_functions.php [type: folder|file] [folder_or_filename] | |
* Example: php dangerous_functions.php folder vendor/businessname/module-name | |
*/ | |
if (!isset($argv[1])) { | |
echo "Missing action ('folder' or 'file')\n"; | |
die(); | |
} | |
if (!isset($argv[2])) { | |
echo "Missing folder name or file name\n"; | |
die(); | |
} | |
$dangerousFunctions = new DangerousFunctions($argv[1], $argv[2]); | |
$dangerousFunctions->execute(); | |
class DangerousFunctions | |
{ | |
/** | |
* Complete list of dangerous functions for which we will scan | |
* | |
* @var array | |
*/ | |
protected $functions = [ | |
'apache_child_terminate', | |
'apache_get_modules', | |
'apache_note', | |
'apache_setenv', | |
'define_syslog_variables', | |
'disk_free_space', | |
'disk_total_space', | |
'diskfreespace', | |
'dl', | |
'escapeshellarg', | |
'escapeshellcmd', | |
'exec', | |
'extract', | |
'get_cfg_var', | |
'get_current_user', | |
'getcwd', | |
'getenv', | |
'getlastmo', | |
'getmygid', | |
'getmyinode', | |
'getmypid', | |
'getmyuid', | |
'ini_restore', | |
'ini_set', | |
'passthru', | |
'pcntl_alarm', | |
'pcntl_exec', | |
'pcntl_fork', | |
'pcntl_get_last_error', | |
'pcntl_getpriority', | |
'pcntl_setpriority', | |
'pcntl_signal', | |
'pcntl_signal_dispatch', | |
'pcntl_sigprocmask', | |
'pcntl_sigtimedwait', | |
'pcntl_sigwaitinfo', | |
'pcntl_strerrorp', | |
'pcntl_wait', | |
'pcntl_waitpid', | |
'pcntl_wexitstatus', | |
'pcntl_wifexited', | |
'pcntl_wifsignaled', | |
'pcntl_wifstopped', | |
'pcntl_wstopsig', | |
'pcntl_wtermsig', | |
'php_uname', | |
'phpinfo', | |
'popen', | |
'posix_getlogin', | |
'posix_getpwuid', | |
'posix_kill', | |
'posix_mkfifo', | |
'posix_setpgid', | |
'posix_setsid', | |
'posix_setuid', | |
'posix_ttyname', | |
'posix_uname', | |
'posixc', | |
'proc_close', | |
'proc_get_status', | |
'proc_nice', | |
'proc_open', | |
'proc_terminate', | |
'ps_aux', | |
'putenv', | |
'readlink', | |
'runkit_function_rename', | |
'shell_exec', | |
'show_source', | |
'symlink', | |
'syslog', | |
'system', | |
]; | |
/** | |
* Folders that this script will ignore and not process | |
* | |
* @var array | |
*/ | |
protected $foldersToIgnore = [ | |
'.', | |
'..', | |
'.git', | |
'.idea' | |
]; | |
/** | |
* Action: either 'folder' or 'file' | |
* | |
* @var string | |
*/ | |
protected $action; | |
/** | |
* Name of the folder or file | |
* | |
* @var string | |
*/ | |
protected $name; | |
/** | |
* @param string $action | |
* @param string $name | |
*/ | |
public function __construct($action, $name) | |
{ | |
$this->action = $action; | |
$this->name = $name; | |
} | |
/** | |
* Main action of script | |
*/ | |
public function execute() | |
{ | |
if ($this->action == 'folder') { | |
// If folder, loop through files in folder and test individually | |
if ($allFiles = $this->getAllFiles($this->name)) { | |
foreach ($allFiles as $fileToCheck) { | |
if (substr($fileToCheck, -3) === 'php') { | |
$this->outputFileInfo($fileToCheck); | |
} | |
} | |
} else { | |
echo "Folder is empty\n"; | |
} | |
// If file, test directly | |
} else if ($this->action == 'file') { | |
$this->outputFileInfo($this->name); | |
} else { | |
echo "Invalid action: $this->action\n"; | |
} | |
} | |
/** | |
* Outputs all dangerous methods in the specified file | |
* | |
* @param string $filename | |
*/ | |
protected function outputFileInfo($filename) | |
{ | |
if ($file = fopen($filename, 'r')) { | |
$count = 1; | |
while (($line = fgets($file)) !== false) { | |
foreach ($this->functions as $function) { | |
if (preg_match("/$function\(/", $line)) { | |
echo "$filename($count): $function\n"; | |
} | |
} | |
$count++; | |
} | |
fclose($file); | |
} else { | |
echo "Invalid filename: $file\n"; | |
} | |
} | |
/** | |
* Gets all the files in the folder and returns them as an array (this is a recursive method) | |
* | |
* @param string $folder | |
* @param array $results | |
* @return array | |
*/ | |
protected function getAllFiles($folder, &$results = []) { | |
$files = scandir($folder); | |
// Ignore directories that are not needed | |
foreach ($this->foldersToIgnore as $folderToIgnore) { | |
unset($files[array_search($folderToIgnore, $files, true)]); | |
} | |
// Loop through files and add to array. If directory, recursively call again. | |
foreach($files as $key => $value){ | |
$path = $folder . DIRECTORY_SEPARATOR . $value; | |
if (!is_dir($path)) { | |
$results[] = $path; | |
} else { | |
$this->getAllFiles($path, $results); | |
} | |
} | |
return $results; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment