#!/usr/bin/php <?php //error_reporting(0); /*** * Configuration options */ $template = "templates/odt/blank_template_v1.0.odt"; //$CHECKtemplate = "templates/odt/blank_template_check_v0.4.odt"; $vulnTemplate = "templates/odt/vuln_template_v0.2.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"); //get config file $config = json_decode(file_get_contents($filter->getParam("path")."config.conf")); // 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"); } $source = file_get_contents("/tmp/$rand/content.xml"); // add CHECK section into report if needed if(isset($config->checkRef) && trim($config->checkRef) <> ""){ $check_img = '<draw:frame draw:style-name="fr9" draw:name="FPCheckLogo" text:anchor-type="frame" svg:x="0cm" svg:y="5.879cm" svg:width="6.83cm" svg:height="2.628cm" draw:z-index="40"> <draw:image xlink:href="Pictures/10000000000004A3000001C98E2CC6AE1D6F811E.jpg" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad" loext:mime-type="image/jpeg"/> </draw:frame>'; $check_section = '<text:p text:style-name="P26"/> <text:p text:style-name="P26"/> <text:p text:style-name="P26"/> <text:p text:style-name="P26"/> <text:p text:style-name="P26"> CHECK Ref: {checkRef} </text:p>'; $source = str_replace('{check_img}', $check_img, $source); $source = str_replace('{check_section}', $check_section, $source); echo "[+] Added CHECK section\n"; }else{ $check_section = '<text:p text:style-name="P26"> <text:bookmark-start text:name="__RefHeading___Toc72207_536000782"/> <text:bookmark-end text:name="__RefHeading___Toc72207_536000782"/> </text:p>'; $source = str_replace('{check_img}', "", $source); $source = str_replace('{check_section}', $check_section, $source); } // add config into template 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 = $Informational = ""; foreach ($vuln as $singlevuln) { $templateSource = $templateOrig; $togo = $singlevuln['risk']; foreach ($singlevuln as $key => $value){ $value = str_replace("<", "<", $value); $value = str_replace(">", ">", $value); $value = str_replace("\n", "</text:p><text:p text:style-name=\"Text_20_body\">", $value); $templateSource = str_replace('{'.$key.'}', $value, $templateSource); if($key == "risk"){ switch ($togo) { case 'Serious': $templateSource = str_replace('{risk_img}', '100000000000001C0000001C2B2344F988E3C014.png', $templateSource); break; case 'High': $templateSource = str_replace('{risk_img}', '100000000000001C0000001C478E326DAB1B0673.gif', $templateSource); break; case 'Medium': $templateSource = str_replace('{risk_img}', '100000000000001C0000001C08AD11DB0A5D02CD.png', $templateSource); break; case 'Low': $templateSource = str_replace('{risk_img}', '100000000000001C0000001C6CC3BB57AA64608B.gif', $templateSource); break; case 'Informational': $templateSource = str_replace('{risk_img}', '100000000000001C0000001C7365C375D1750C0F.gif', $templateSource); break; } } } $$togo .= $templateSource; echo "[+] added $togo: ".$singlevuln['title']."\n"; } // squash vulns into one bbig xml $value = ""; if(!empty($Serious)){ $value .= '<text:list text:continue-numbering="true" text:style-name="Outline"> <text:list-item> <text:list> <text:list-item> <text:h 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 text:continue-numbering="true" text:style-name="Outline"> <text:list-item> <text:list> <text:list-item> <text:h 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 text:continue-numbering="true" text:style-name="Outline"> <text:list-item> <text:list> <text:list-item> <text:h 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 text:continue-numbering="true" text:style-name="Outline"> <text:list-item> <text:list> <text:list-item> <text:h text:outline-level="2">Low Risk Vulnerabilities</text:h> </text:list-item> </text:list> </text:list-item> </text:list>'; $value .= $Low; } if(!empty($Informational)){ $value .= '<text:list text:continue-numbering="true" text:style-name="Outline"> <text:list-item> <text:list> <text:list-item> <text:h text:outline-level="2">Informational Risk Vulnerabilities</text:h> </text:list-item> </text:list> </text:list-item> </text:list>'; $value .= $Informational; } // 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 $repOutName = $config->ref.".3 ".$config->client ." ". $config->title1; zipFolder("/tmp/$rand", $filter->getParam("path").$repOutName.".odt"); echo "[=] generated report: ".$filter->getParam("path").$repOutName.".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(); } ?>