Newer
Older
DirtyScripts / ReportToolz / rep2.php
#!/usr/bin/php
<?php
//error_reporting(0);

/***
 * Configuration options
 */
$sub1 = 5; // header no in doc e.g. "5 Discovered Vulnerabilities"

/***
 * Main program - Don't edit below
 */
echo "_____ _____ _____ 2\n||_// ||==  ||_// \n|| \\  ||___ ||    \n\n";

foreach (glob("classes/*.php") as $filename)
    include $filename;

$definitions = new \Clapp\CommandLineArgumentDefinition(
    array(
        "help|h"            => "Shows help message",
        "doc|d=s"           => "/path/to/doc.odt to use",
    )
);

$filter = new \Clapp\CommandArgumentFilter($definitions, $argv);

if ($filter->getParam('h') === true || $argc < 2) {
    fwrite(STDERR, $definitions->getUsage());
    exit(0);
} 

// see if doc exists 
if ($filter->getParam("doc") == false)
	die("[-] no doc set\n");

echo "[!] doc: ".$filter->getParam("doc")."\n";
if(!file_exists($filter->getParam("doc")))
	die("[-] no such file! \n");

// extract doc and get contents
$rand = uniqid();
mkdir("/tmp/$rand");
if(unzipFolder($filter->getParam("doc"), "/tmp/$rand/")) {
    $source = file_get_contents("/tmp/$rand/content.xml");
    echo "[+] doc extracted\n";
} else {
	die("[-] unable to extract doc\n");
}
	
// Parse Doc's XML
$line = array();
$reader = new XMLReader();
if (!$reader->open("/tmp/$rand/content.xml")) die("[-] Failed to open 'content.xml'\n");

// font checker
/***
 * FUTURE FEATURE PERHAPS
 */
$fonts = array();
while ($reader->read()){ 
	//print_r($reader->name);
    if ($reader->nodeType == XMLREADER::ELEMENT && ($reader->name === 'style:font-face')) {  
    	//if(!empty($reader->name)){
    		//echo "here2\n";
        	//$line[] = $reader->expand()->textContent; // Put the text into array in correct order...
    		$fonts[] = $reader->getAttribute("style:name");
        	//echo $font;echo "\n"; // DEBUG
        //}
    }
}
$reader->close();
//die();
echo "[=] fonts found: ".sizeof($fonts)."\n";

// step through text:h and text:p elements to put them into an array
$reader = new XMLReader();
if (!$reader->open("/tmp/$rand/content.xml")) die("[-] Failed to open 'content.xml'\n");
while ($reader->read()){ 
    if ($reader->nodeType == XMLREADER::ELEMENT && ($reader->name === 'text:h' || $reader->name === 'text:p' || $reader->name === 'text:bookmark')) {  
    	if(!empty($reader->expand()->textContent))
        	$line[] = $reader->expand()->textContent; // Put the text into array in correct order...
        	//echo $reader->expand()->textContent;echo "\n"; // DEBUG
    }
}
$reader->close();

// find the content we want
$start = 0; $end = 0;
foreach($line as $key => $val){
	if(strpos($val, "Discovered Vulnerabilities") === 0){ $start = $key; }
	if(strpos($val, "Observed Hosts and Services") === 0){ $end = $key-2; }
	$line[$key] = trim($val);
}

// add to sexy array's
$vuln = array();
$vulnPlace = 0;
$switch = 0;
$sub2 = 0;
$sub3 = 1;
for ($i=$start; $i <= $end ; $i++) { 
	// change state (action to take)
	/***
	 * ~states~
	 * 0 = do nothing
	 * 1 = next is title
	 * 2 = next is description
	 * 3 = next is solution
	 * 4 = next is remediation
	 * 5 = next is cvss no
	 * 6 = next is risk level
	 * 7 = next is hosts
	 * 8 = next possibly title
	 */
	switch ($line[$i]) {
		case 'Discovered Vulnerabilieies':
			$switch = 0;
			break;
		case 'Serious Risk Vulnerabilities':
			$sub2++; $sub3 = 1;
			$switch = 1;
			break;
		case 'High Risk Vulnerabilities':
			$sub2++; $sub3 = 1;
			$switch = 1;
			break;
		case 'Medium Risk Vulnerabilities':
			$sub2++; $sub3 = 1;
			$switch = 1;
			break;
		case 'Low Risk Vulnerabilities':
			$sub2++; $sub3 = 1;
			$switch = 1;
			break;
		case 'Description':
			$switch = 2;
			break;
		case 'Solution':
			$switch = 3;
			break;
		case 'Remediation':
			$switch = 4;
			break;
		case 'CVSS Base Score':
			$switch = 5;
			break;
		case 'Risk Level':
			$switch = 6;
			break;
		case 'Vulnerabilities Exist On':
			$switch = 7;
			break;
		default:
			# code...
			break;
	}

	//take action
	switch ($switch) {
		case 1:
			$i++;
			$vuln[$vulnPlace]['title'] = $line[$i];
			$vuln[$vulnPlace]['ref'] = "$sub1.$sub2.$sub3";
			$sub3++;
			$switch = 0;
			break;
		case 2:
			@$vuln[$vulnPlace]['desc'] .= $line[$i];
			break;
		case 3:
			@$vuln[$vulnPlace]['fix'] .= $line[$i];
			break;
		case 4:
			$i++;
			$vuln[$vulnPlace]['rem'] = trim(strtok($line[$i], " "));
			$switch = 0;
			break;
		case 5:
			$i++;
			$vuln[$vulnPlace]['cvss'] = $line[$i];
			$switch = 0;
			break;
		case 6:
			$i++;
			$vuln[$vulnPlace]['risk'] = trim(strtok($line[$i], " "));
			$vuln[$vulnPlace]['owasp'] = trim(substr($line[$i], strpos($line[$i], ":") + 1));    
			$switch = 0;
			break;
		case 7:
			$i++;
			$vuln[$vulnPlace]['hosts'] = $line[$i];
			$switch = 8;
			$vulnPlace++;
			break;
		case 8:
			$vuln[$vulnPlace]['title'] = trim($line[$i]);
			$vuln[$vulnPlace]['ref'] = "$sub1.$sub2.$sub3";
			$sub3++;
			$switch = 0;
			break;
		default:
			# code...
			break;
	}

	//echo $line[$i]."\n"; // DEBUG
}

// minor tidying of arrays
for ($i=0; $i < sizeof($vuln) ; $i++) { 
	if (strpos($vuln[$i]['desc'], "Description") === 0) $vuln[$i]['desc'] = substr($vuln[$i]['desc'], strlen("Description"));
	if (strpos($vuln[$i]['fix'], "Solution") === 0) $vuln[$i]['fix'] = substr($vuln[$i]['fix'], strlen("Solution"));
	$vuln[$i]['risk'] = rtrim($vuln[$i]['risk'], ":");
	// remove html encoding
	foreach($vuln[$i] as $key => $val){
		$vuln[$i][$key] = mb_convert_encoding($val, "UTF-8", 'UTF-8');
	}
}

//print_r($vuln); // DEBUG
echo "[+] vulnerabilities identified\n";

delTree("/tmp/$rand");
echo "[+] temp files removed\n";

$resultsFolder = substr($filter->getParam("doc"), 0, strrpos( $filter->getParam("doc"), '/') )."/rep2";
if(!file_exists($resultsFolder."/")){
	mkdir($resultsFolder."/");
	echo "[+] created directory $resultsFolder/\n";
}else{
	$i = 1;
	while (file_exists($resultsFolder."_$i/"))
		$i++;
	mkdir($resultsFolder."_$i/");
	$resultsFolder .= "_$i";
	echo "[+] created directory $resultsFolder/\n";
}

if(writeIssueTable($vuln, "Serious", $resultsFolder."/findings_serious.csv"))
	echo "[+] serious issues: $resultsFolder/findings_serious.csv\n";
if(writeIssueTable($vuln, "High", $resultsFolder."/findings_high.csv"))
	echo "[+] high issues: $resultsFolder/findings_serious.csv\n";
if(writeIssueTable($vuln, "Medium", $resultsFolder."/findings_medium.csv"))
	echo "[+] medium issues: $resultsFolder/findings_serious.csv\n";
if(writeIssueTable($vuln, "Low", $resultsFolder."/findings_low.csv"))
	echo "[+] low issues: $resultsFolder/findings_serious.csv\n";

if(writeAllTable($vuln, $resultsFolder."/findings_all.csv"))
	echo "[+] all issues: $resultsFolder/findings_all.csv\n";

if(writeRemediationTable($vuln, $resultsFolder."/remediation.csv"))
	echo "[+] remediation table: $resultsFolder/remediation.csv\n";

if(writeOWASPTable($vuln, $resultsFolder."/owasp.csv"))
	echo "[+] OWASP table: $resultsFolder/owasp.csv\n";

viewVulns($vuln);

function unzipFolder($zipInputFile, $outputFolder) {
    $zip = new ZipArchive;
    $res = $zip->open($zipInputFile);
    if ($res === true) {
        $zip->extractTo($outputFolder);
        $zip->close();
        return true;
    }
    else {
        return false;
    }
}

function XML2Array(SimpleXMLElement $parent){
    $array = array();

    foreach ($parent as $name => $element) {
        ($node = & $array[$name])
            && (1 === count($node) ? $node = array($node) : 1)
            && $node = & $node[];

        $node = $element->count() ? XML2Array($element) : trim($element);
    }

    return $array;
}

function delTree($dir){ 
    $files = array_diff(scandir($dir), array('.', '..')); 

    foreach ($files as $file) { 
        (is_dir("$dir/$file")) ? delTree("$dir/$file") : unlink("$dir/$file"); 
    }

    return rmdir($dir); 
} 

function viewVulns($vuln){
	$s = $h = $m = $l = 0;
	for ($i=0; $i < sizeof($vuln) ; $i++) { 
		switch ($vuln[$i]['risk']) {
			case 'Serious':
				$s++;
				break;
			case 'High':
				$h++;
				break;
			case 'Medium':
				$m++;
				break;
			case 'Low':
				$l++;
				break;
		}
	}
	echo "[=] Serious = $s, High = $h, Medium = $m, Low = $l\n";

echo"
Ref    | Title                             |  Risk  |  CVSS  |  Remediation  |  OWASP
-------|-----------------------------------|--------|--------|---------------|------------------------------\n";
for ($i=0; $i < sizeof($vuln) ; $i++) { 
	$ref = str_pad($vuln[$i]['ref'], 7);
	$title = str_pad($vuln[$i]['title'], 35);
	$risk = str_pad($vuln[$i]['risk'], 8);
	$cvss = str_pad($vuln[$i]['cvss'], 8);
	$rem = str_pad($vuln[$i]['rem'], 15);
	$owasp = str_pad($vuln[$i]['owasp'], 30);

	echo substr($ref, 0, 7); echo "|";
	echo substr($title, 0, 35); echo "|";
	echo substr($risk, 0, 8); echo "|";
	echo substr($cvss, 0, 8); echo "|";
	echo substr($rem, 0, 15); echo "|";
	echo substr($owasp, 0, 30); echo "\n";
}
}

function writeIssueTable($vuln, $issue, $path){
	$towrite = array();
	for ($i=0; $i < sizeof($vuln) ; $i++) { 
		if($vuln[$i]['risk'] == $issue){
			$towrite[$i]['desc'] = $vuln[$i]['title']." - ".$vuln[$i]['desc'];
			$towrite[$i]['fix'] = $vuln[$i]['fix'];
			$towrite[$i]['ref'] = $vuln[$i]['ref'];
			$towrite[$i]['hosts'] = $vuln[$i]['hosts'];
		}
	}
	if(sizeof($towrite) > 0){
		$fp = fopen($path, 'w');
		fprintf($fp, chr(0xEF).chr(0xBB).chr(0xBF));
		foreach ($towrite as $fields) {
	    	fputcsv($fp, $fields);
		}
		fclose($fp);
		return true;
	}else{
		return false;
	} 
}

function writeAllTable($vuln, $path){
	if(sizeof($vuln) > 0){
		$fp = fopen($path, 'w');
		fprintf($fp, chr(0xEF).chr(0xBB).chr(0xBF));
		fputcsv($fp, array("Title", "Ref", "Description", "Solution", "Remediation", "CVSS", "Risk", "OWASP", "Affected"));
		foreach ($vuln as $fields) {
	    	fputcsv($fp, $fields);
		}
		fclose($fp);
		return true;
	}else{
		return false;
	} 
}

function writeRemediationTable($vuln, $path){
	$towrite = array();
	for ($i=0; $i < sizeof($vuln) ; $i++) { 
		$towrite[$i]['hosts'] = $vuln[$i]['hosts'];
		$towrite[$i]['ref'] = $vuln[$i]['ref'];
		$towrite[$i]['p'] = " ";	
		$towrite[$i]['c'] = " ";	
		$towrite[$i]['d'] = " ";	
		$towrite[$i]['u'] = " ";	
		switch ($vuln[$i]['rem']) {
			case 'Patch':
				$towrite[$i]['p'] = $vuln[$i]['risk'][0];
				break;
			case 'Configuration':
				$towrite[$i]['c'] = $vuln[$i]['risk'][0];
				break;
			case 'Development':
				$towrite[$i]['d'] = $vuln[$i]['risk'][0];
				break;
			case 'Upgrade':
				$towrite[$i]['u'] = $vuln[$i]['risk'][0];
				break;
		}	
	}
	if(sizeof($towrite) > 0){
		$fp = fopen($path, 'w');
		fprintf($fp, chr(0xEF).chr(0xBB).chr(0xBF));
		fputcsv($fp, array("Host", "Ref", "P", "C", "D", "U"));
		foreach ($towrite as $fields) {
	    	fputcsv($fp, $fields);
		}
		fclose($fp);
		return true;
	}else{
		return false;
	} 
}

function writeOWASPTable($vuln, $path){
	$towrite = array();
	for ($i=0; $i < sizeof($vuln) ; $i++) { 
		if(in_array($vuln[$i]['owasp'], array_column($towrite, 'owaspId'))){
			$towrite[$vuln[$i]['owasp']]['no']++;
		}else{
			$towrite[$vuln[$i]['owasp']]['owaspId'] = $vuln[$i]['owasp'];
			$towrite[$vuln[$i]['owasp']]['no'] = 1;
		}
	}
	if(sizeof($towrite) > 0){
		$fp = fopen($path, 'w');
		fprintf($fp, chr(0xEF).chr(0xBB).chr(0xBF));
		foreach ($towrite as $fields) {
	    	fputcsv($fp, $fields);
		}
		fclose($fp);
		return true;
	}else{
		return false;
	} 
}

?>