| | #!/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, "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; |
---|
| | } |
---|
| | } |
---|
| | |
---|
| | ?> |
---|
| | |