diff --git a/ReportToolz/test.php b/ReportToolz/test.php new file mode 100644 index 0000000..5db739c --- /dev/null +++ b/ReportToolz/test.php @@ -0,0 +1,435 @@ +#!/usr/bin/php + "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, "This section provides a quick guide to plan your remediation for the vulnerabilities discovered during the test.") === 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_high.csv\n"; +if(writeIssueTable($vuln, "Medium", $resultsFolder."/findings_medium.csv")) + echo "[+] medium issues: $resultsFolder/findings_medium.csv\n"; +if(writeIssueTable($vuln, "Low", $resultsFolder."/findings_low.csv")) + echo "[+] low issues: $resultsFolder/findings_low.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; + } +} + +?> \ No newline at end of file