Created
February 12, 2016 18:26
-
-
Save jkrehm/7b38a20d6324779ce90b to your computer and use it in GitHub Desktop.
PHP Version Scanner
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 namespace HighPoint\VersionScan; | |
use Exception; | |
use GuzzleHttp\Client; | |
use GuzzleHttp\Query; | |
/** | |
* Version scanner | |
*/ | |
class Scanner | |
{ | |
protected $client; | |
/** | |
* Instantiate a Guzzle client | |
*/ | |
public function __construct() | |
{ | |
$this->client = new Client(); | |
} | |
/** | |
* Scan the specified version of PHP for vulnerabilities | |
* | |
* @param string $version PHP version to scan | |
* | |
* @return array Array of vulnerabilities | |
* | |
* @throws Exception If exception caught | |
*/ | |
public function scan($version = '') | |
{ | |
// Default to current PHP version | |
$version = $version ?: phpversion(); | |
// Clean up version number | |
$modifiedVersion = preg_replace('/([0-9]+\.[0-9]+\.[0-9]+).*/', '$1', $version); | |
try { | |
$html = $this->getHTML($modifiedVersion); | |
$id = $this->parseHTML($html); | |
$vulnerabilities = $this->getVulnerabilities($id); | |
} catch (Exception $e) { | |
if ($e->getCode() !== 200) { | |
throw $e; | |
} | |
$vulnerabilities = []; | |
} | |
return array( | |
'version' => $modifiedVersion, | |
'versionModified' => $version !== $modifiedVersion, | |
'vulnerabilities' => $vulnerabilities, | |
); | |
} | |
/** | |
* Get HTML with PHP version ID | |
* | |
* @param string $version PHP version to retrieve | |
* | |
* @return string HTML with PHP version ID | |
* | |
* @throws Exception If request fails | |
*/ | |
protected function getHTML($version) | |
{ | |
$request = $this->client->createRequest('GET', 'http://www.cvedetails.com/version-search.php'); | |
$query = new Query(array( | |
'vendor' => '', | |
'product' => 'PHP', | |
'version' => $version, | |
)); | |
$request->setQuery($query); | |
$response = $this->client->send($request); | |
if ($response->getStatusCode() !== 200) { | |
throw new Exception('Error getting HTML', $response->getStatusCode()); | |
} | |
return $response->getBody()->__toString(); | |
} | |
/** | |
* Parse HTML to retrieve version ID | |
* | |
* @param string $html HTML with PHP version ID | |
* | |
* @return string PHP version ID | |
* | |
* @throws Exception If ID is not found in the HTML | |
*/ | |
protected function parseHTML($html) | |
{ | |
// e.g. <link rel="canonical" href="http://www.cvedetails.com/vulnerability-list.php?vendor_id=74&product_id=128&version_id=178362"/> | |
if (preg_match('/link.*rel="canonical".*&version_id=(.*?)[&"]/', $html, $id)) { | |
$id = $id[1]; | |
} else { | |
throw new Exception('Version ID not found', 200); | |
} | |
return $id; | |
} | |
/** | |
* Get list of known vulnerabilities for the PHP version | |
* | |
* @param string $id PHP version ID | |
* | |
* @return array Known vulnerabilities for PHP version | |
* | |
* @throws Exception If request fails | |
*/ | |
protected function getVulnerabilities($id) | |
{ | |
$request = $this->client->createRequest('GET', 'http://www.cvedetails.com/json-feed.php'); | |
$query = new Query(array( | |
'vendor_id' => '74', | |
'product_id' => '128', | |
'version_id' => $id, | |
)); | |
$request->setQuery($query); | |
$response = $this->client->send($request); | |
if ($response->getStatusCode() !== 200) { | |
throw new Exception('Error getting vulnerabilities', $response->getStatusCode()); | |
} | |
return $response->json(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Usage: