diff --git a/.gitignore b/.gitignore index a67d42b..dd9deec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,3 @@ composer.phar /vendor/ - -# Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control -# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file -# composer.lock +/composer.lock diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..8ad6791 --- /dev/null +++ b/composer.json @@ -0,0 +1,24 @@ +{ + "name": "umutphp/wp-vulnerability-check", + "license": "GNU GENERAL PUBLIC LICENSE", + "description": "Check the WPScan Vulnerability Database via API to identify the security issues on plugins and WordPress installed.", + "authors": [ + { + "name": "Umut Işık", + "email": "umutphp@gmail.com" + } + ], + "autoload": { + "psr-4": {"UmutPHP\\WPVulnerabilityCheck\\": "src/"} + }, + "require": { + "php": ">=5.4.0", + "ext-curl": "*", + "ext-json": "*" + }, + "require-dev": { + "phpunit/phpunit": "~4.5", + "jakub-onderka/php-parallel-lint": "~1.0" + }, + "bin": ["wp-vulnerability-check"] +} diff --git a/src/ArrayIterator.php b/src/ArrayIterator.php new file mode 100644 index 0000000..ac17d95 --- /dev/null +++ b/src/ArrayIterator.php @@ -0,0 +1,11 @@ +next(); + return $this->current(); + } +} diff --git a/src/Manager.php b/src/Manager.php new file mode 100644 index 0000000..15b2173 --- /dev/null +++ b/src/Manager.php @@ -0,0 +1,115 @@ +getFilesFromPaths($settings->path, $settings->excluded); + + /** @var Result[] $results */ + $results = array(); + $startTime = microtime(true); + $checkedPlugins = 0; + $vulnerablePlugins = 0; + $results = array(); + + foreach ($plugins as $plugin) { + try { + $fileResult = $this->checkPlugin($plugin); + $checkedPlugins++; + + // Get Vulnerabilities and check the plugin with version + $vulnerablePlugins++; + echo "v"; // For vulnerability + echo "."; // For success + $pluginResult = array('Vulnerability Result'); + $results = array_merge($results, $pluginResult); + } catch (Exception\Exception $e) { + echo "f"; // Fail + $pluginResult = array($e->getMessage()); + $results = array_merge($results, $pluginResult); + } + } + + $runTime = round(microtime(true) - $startTime, 1); + + echo PHP_EOL . PHP_EOL; + + $message = "Checked $checkedPlugins plugins in $runTime second, "; + if ($vulnerablePlugins === 0) { + $message .= "no vulnerability found."; + } else { + $message .= "some vulnerability(s) in $vulnerablePlugins "; + $message .= ($vulnerablePlugins === 1 ? 'file' : 'files'); + } + + echo $message . PHP_EOL; + + if (!empty($results)) { + $output->writeNewLine(); + + foreach ($results as $result) { + echo str_repeat('-', 60); + echo $result[0]; + echo PHP_EOL; + } + + return false; + } + + return true; + } + + /** + * Check plugin with plugin name via API + * + * @param string $pluginName + * @param Settings $settings + * @return Result[] + * @throws Exception + */ + public function checkPlugin($pluginName, Settings $settings = null) + { + if ($settings === null) { + $settings = new Settings(); + } + + $results = array(); + + return $results; + } + + /** + * Private function to get the result from the API + * + * @param string $pluginName + * @param string $APIToken + * @return array Array decoded from JSON string + */ + private function get($pluginName, $APIToken) { + $ch = curl_init(); + $url = self::WPVULNDB_V3_URL . 'plugins/' . $pluginName; + + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + $headers = array( + 'Authorization: Token token=' . $APIToken + ); + + curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); + + $server_output = curl_exec ($ch); + + curl_close ($ch); + + return json_decode($server_output); + } +} diff --git a/src/Settings.php b/src/Settings.php new file mode 100644 index 0000000..09f03f1 --- /dev/null +++ b/src/Settings.php @@ -0,0 +1,64 @@ +paths[] = $argument; + } else { + switch ($argument) { + case '--path': + $setting->path = trim($arguments->getNext()); + break; + case '--token': + $setting->token = trim($arguments->getNext()); + break; + case '--exclude': + $setting->excluded[] = explode(',', $arguments->getNext()); + break; + case '--no-colors': + $setting->colors = false; + break; + default: + throw new \Exception("Invalid argument $argument"); + } + } + } + + return $setting; + } +} diff --git a/wp-vulnerability-check b/wp-vulnerability-check new file mode 100644 index 0000000..f498a3b --- /dev/null +++ b/wp-vulnerability-check @@ -0,0 +1,3 @@ +#!/usr/bin/env php + +Options: + --path Full path for the plugin directory of your WordPress installation. + --token Token got from wpvulndb.com + --exclude Exclude the plugins given in comma separated format. + --version Show version. + --help Print this help. + +WP Vulnerability Check version +--------------------------- +Usage: + wp-vulnerability-check [options] +getArgument()}" . PHP_EOL); + echo PHP_EOL; + showOptions(); + die(FAILED); +} + +try { + $check = new WPVulnerabilityCheck\Manager(); + $status = $check->check($settings); + die($status ? SUCCESS : WITH_ERRORS); +} catch (\Exception $e) { + fwrite(STDERR, $e->getMessage() . PHP_EOL); + die(FAILED); +}