#!/usr/bin/php <?php //error_reporting(0); /*** * Configuration options */ $template = "templates/odt/blank_template_v0.2.odt"; $vulnTemplate = "templates/odt/vuln_template.xml"; /*** * Main program - Don't edit below */ echo "_____ _____ _____ Gen\n||_// ||== ||_// \n|| \\ ||___ || \n\n"; foreach (glob("classes/*.php") as $filename) include $filename; $definitions = new \Clapp\CommandLineArgumentDefinition( array( "help|h" => "Shows help message", "path|p=s" => "/path/to/configs/", // should contain config.json and all vuln.json files ) ); $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("path") == false) die("[-] no path set\n"); echo "[!] path: ".$filter->getParam("path")."\n"; if(!is_dir($filter->getParam("path"))) die("[-] no such folder! \n"); // extract doc and get contents $rand = uniqid(); mkdir("/tmp/$rand"); if(unzipFolder($template, "/tmp/$rand/")) { $source = file_get_contents("/tmp/$rand/content.xml"); echo "[+] doc extracted\n"; } else { die("[-] unable to extract doc\n"); } $config = json_decode(file_get_contents($filter->getParam("path")."config.conf")); // add config into template $source = file_get_contents("/tmp/$rand/content.xml"); foreach ($config as $key => $value) { $source = str_replace('{'.$key.'}', $value, $source); } file_put_contents("/tmp/$rand/content.xml", $source); echo "[+] added config values\n"; // get all vulns $vuln = array(); $files = glob($filter->getParam("path")."*.json"); foreach($files as $finding){ $vuln[] = $found = json_decode(file_get_contents($finding), true); } echo "[+] sorting vulns by CVSS\n"; usort($vuln, 'order_by_cvss'); function order_by_cvss($a, $b) { return $b['cvss_score'] > $a['cvss_score'] ? 1 : -1; } if(empty($vuln)) echo "[-] no vulns found!\n"; // create vulns for odf $templateOrig = file_get_contents($vulnTemplate); $Serious = $High = $Medium = $Low = ""; foreach ($vuln as $singlevuln) { $templateSource = $templateOrig; $togo = $singlevuln['risk']; foreach ($singlevuln as $key => $value){ $value = str_replace("\n", "</text:p><text:p text:style-name=\"P173\">", $value); $templateSource = str_replace('{'.$key.'}', $value, $templateSource); } $$togo .= $templateSource; echo "[+] added $togo: ".$singlevuln['title']."\n"; } // squash vulns into one bbig xml $value = ""; if(!empty($Serious)){ $value .= '<text:list xml:id="list215514604433265" text:continue-numbering="true" text:style-name="Outline"> <text:list-item> <text:list> <text:list-item> <text:h text:style-name="P156" text:outline-level="2">Serious Risk Vulnerabilities</text:h> </text:list-item> </text:list> </text:list-item> </text:list>'; $value .= $Serious; } if(!empty($High)){ $value .= '<text:list xml:id="list215514604433265" text:continue-numbering="true" text:style-name="Outline"> <text:list-item> <text:list> <text:list-item> <text:h text:style-name="P156" text:outline-level="2">High Risk Vulnerabilities</text:h> </text:list-item> </text:list> </text:list-item> </text:list>'; $value .= $High; } if(!empty($Medium)){ $value .= '<text:list xml:id="list215514604433265" text:continue-numbering="true" text:style-name="Outline"> <text:list-item> <text:list> <text:list-item> <text:h text:style-name="P156" text:outline-level="2">Medium Risk Vulnerabilities</text:h> </text:list-item> </text:list> </text:list-item> </text:list>'; $value .= $Medium; } if(!empty($Low)){ $value .= '<text:list xml:id="list215514604433265" text:continue-numbering="true" text:style-name="Outline"> <text:list-item> <text:list> <text:list-item> <text:h text:style-name="P156" text:outline-level="2">Low Risk Vulnerabilities</text:h> </text:list-item> </text:list> </text:list-item> </text:list>'; $value .= $Low; } // add to template $source = file_get_contents("/tmp/$rand/content.xml"); $source = str_replace('{vuln}', $value, $source); file_put_contents("/tmp/$rand/content.xml", $source); // create report and tidying zipFolder("/tmp/$rand", $filter->getParam("path")."repgen.odt"); echo "[=] generated report: ".$filter->getParam("path")."repgen.odt\n"; delTree("/tmp/$rand"); echo "[+] temp files removed\n"; 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 zipFolder($inputFolder, $zipOutputFile) { if (!extension_loaded('zip') || !file_exists($inputFolder)) { return false; } $zip = new ZipArchive(); if (!$zip->open($zipOutputFile, ZIPARCHIVE::CREATE)) { return false; } $inputFolder = str_replace('\\', "/", realpath($inputFolder)); if (is_dir($inputFolder) === true) { $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($inputFolder), RecursiveIteratorIterator::SELF_FIRST); foreach ($files as $file) { $file = str_replace('\\', "/", $file); if (in_array(substr($file, strrpos($file, '/')+1), array('.', '..'))) { continue; } $file = realpath($file); if (is_dir($file) === true) { $dirName = str_replace($inputFolder."/", '', $file."/"); $zip->addEmptyDir($dirName); } else if (is_file($file) === true) { $fileName = str_replace($inputFolder."/", '', $file); $zip->addFromString($fileName, file_get_contents($file)); } } } else if (is_file($inputFolder) === true) { $zip->addFromString(basename($inputFolder), file_get_contents($inputFolder)); } return $zip->close(); } ?>