- #!/usr/bin/php
- <?php
- //error_reporting(0);
- include('config.php');
-
- /***
- * 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"));
- $riskRatings = array("Serious","High","Medium","Low","Info");
-
- //create owasp top 10 placeholders
- for ($i=1; $i <= 10 ; $i++) { $padNo = sprintf("%02d", $i); ${"A".$padNo} = 0; }
- for ($i=1; $i <= 10 ; $i++) { $padNo = sprintf("%02d", $i); ${"M".$padNo} = 0; }
- for ($i=1; $i <= 10 ; $i++) { $padNo = sprintf("%02d", $i); ${"API".$padNo} = 0; }
-
- //create owasp top 10 table placeholders
- for ($i=1; $i <= 10 ; $i++) { $padNo = sprintf("%02d", $i); ${"A".$padNo."_table"} = ""; }
- for ($i=1; $i <= 10 ; $i++) { $padNo = sprintf("%02d", $i); ${"M".$padNo."_table"} = ""; }
- for ($i=1; $i <= 10 ; $i++) { $padNo = sprintf("%02d", $i); ${"API".$padNo."_table"} = ""; }
-
- // 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 = $Info = "";
- $Count_Serious = $Count_High = $Count_Medium = $Count_Low = $Count_Info = 0;
- $Summary_Serious = $Summary_High = $Summary_Medium = $Summary_Low = $Summary_Info = array();
- 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 'Info':
- $templateSource = str_replace('{risk_img}', '100000000000001C0000001C7365C375D1750C0F.gif', $templateSource);
- break;
- }
- }
- }
-
- if(isset($singlevuln['hosts']) && $singlevuln['hosts'] <> ""){
- $templateSource = str_replace('{hosts}', $singlevuln['hosts'], $templateSource);
- }else{
- $templateSource = str_replace('{hosts}', "N/A", $templateSource);
- }
- $$togo .= $templateSource;
- ${"Count_$togo"} += 1;
- echo "[+] added $togo: ".$singlevuln['title']."\n";
-
- // fixing summary tables
- $descExpl = explode(".", $singlevuln['description']);
- $fixExpl = explode(".", $singlevuln['solution']);
- $descFinal = $descExpl[0].".";
- $fixFinal = $fixExpl[0].".";
- // if small summaries exist use them!
- if(isset($singlevuln['summary_issue']) && $singlevuln['summary_issue'] <> ""){
- // DEBUG: echo "[+] summary description found for: ".$singlevuln['title']."\n";
- $descFinal = $singlevuln['summary_issue'];
- }
- if(isset($singlevuln['summary_solution']) && $singlevuln['summary_solution'] <> ""){
- // DEBUG: echo "[+] summary solution found for: ".$singlevuln['title']."\n";
- $fixFinal = $singlevuln['summary_solution'];
- }
-
- // set OWASP counts
- $issueOwasp = explode(":", $singlevuln['owasp']);
- if($issueOwasp[0] !== "N/A")
- ${$issueOwasp[0]}++;
-
- $hostSummary = (isset($singlevuln['hosts']) && $singlevuln['hosts'] <> "") ? $singlevuln['hosts'] : "N/A";
- // populate arrays for small vuln tables
- // key = title, 0 = desc, 1 = fix, 2 = hosts, 3 = owasp, 4, page ref
- ${"Summary_$togo"}[$singlevuln['title']] = array($descFinal, $fixFinal, $hostSummary, $issueOwasp[0]);
-
- }
-
- // add page ref to each issue
- $placeA = 1;
- foreach ($riskRatings as $riskKey => $riskVal) {
- $placeB = 1;
- if(!empty( ${"Summary_$riskVal"} )){
- foreach (${"Summary_$riskVal"} as $sumKey => $sumVal) {
- array_push(${"Summary_$riskVal"}[$sumKey], "5.".$placeA.".".$placeB);
- $placeB++;
- }
- $placeA++;
- }
- }
-
- // create sumaries tables
- $Summary_Serious_Final = $Summary_High_Final = $Summary_Medium_Final = $Summary_Low_Final = $Summary_Info_Final = "";
- $placeA = 1;
- foreach ($riskRatings as $riskKey => $riskVal) {
- $placeB = 1;
- if(empty( ${"Summary_$riskVal"} )){
- ${"Summary_".$riskVal."_Final"} = '
- <table:table-row table:style-name="Table11.1">
- <table:table-cell table:style-name="Table11.A2" office:value-type="string">
- <text:p text:style-name="P189">None Identified</text:p>
- </table:table-cell>
- <table:table-cell table:style-name="Table11.A2" office:value-type="string">
- <text:p text:style-name="P170"/>
- </table:table-cell>
- <table:table-cell table:style-name="Table11.C2" office:value-type="string">
- <text:p text:style-name="P171"/>
- </table:table-cell>
- <table:table-cell table:style-name="Table11.C2" office:value-type="string">
- <text:p text:style-name="P172"/>
- </table:table-cell>
- </table:table-row>
- ';
- }else{
- foreach (${"Summary_$riskVal"} as $sumKey => $sumVal) {
- // DEBUG: echo "[i] $sumKey:\n".$sumVal[0]."\n".$sumVal[1]."\n\n";
- ${"Summary_".$riskVal."_Final"} .= '
- <table:table-row table:style-name="Table11.1">
- <table:table-cell table:style-name="Table11.A2" office:value-type="string">
- <text:p text:style-name="P189">'.$sumKey.'</text:p>
- <text:p text:style-name="P170">'.$sumVal[0].'</text:p>
- </table:table-cell>
- <table:table-cell table:style-name="Table11.A2" office:value-type="string">
- <text:p text:style-name="P170">'.$sumVal[1].'</text:p>
- </table:table-cell>
- <table:table-cell table:style-name="Table11.C2" office:value-type="string">
- <text:p text:style-name="P171">'.$sumVal[4].'</text:p>
- </table:table-cell>
- <table:table-cell table:style-name="Table11.C2" office:value-type="string">
- <text:p text:style-name="P172">'.$sumVal[2].'</text:p>
- </table:table-cell>
- </table:table-row>
- ';
- }
- }
-
- }
-
- //populate owasp findings tables
- foreach ($riskRatings as $riskKey => $riskVal) {
- if(!empty( ${"Summary_$riskVal"} )){
- foreach (${"Summary_$riskVal"} as $sumKey => $sumVal) {
- if($sumVal[3] == "N/A")
- break; // no N/A owasp table!
- if( ${$sumVal[3]."_table"} == ""){ // if is first entry
- ${$sumVal[3]."_table"} = '
- <table:table table:name="Table8" table:style-name="Table8">
- <table:table-column table:style-name="Table8.C"/>
- <table:table-column table:style-name="Table8.D"/>
- <table:table-header-rows>
- <table:table-row table:style-name="Table8.1">
- <table:table-cell table:style-name="Table8.A1" office:value-type="string">
- <text:p text:style-name="P71">Vulnerabilities in This Category</text:p>
- </table:table-cell>
- <table:table-cell table:style-name="Table8.B1" office:value-type="string">
- <text:p text:style-name="P72">Document Reference</text:p>
- </table:table-cell>
- </table:table-row>
- </table:table-header-rows>
- <table:table-row>
- <table:table-cell table:style-name="Table8.A10" office:value-type="string">
- <text:p text:style-name="P40">'.$sumKey.'</text:p>
- </table:table-cell>
- <table:table-cell table:style-name="Table8.B2" office:value-type="string">
- <text:p text:style-name="P44">'.$sumVal[4].'</text:p>
- </table:table-cell>
- </table:table-row>
- ';
- }else{ // not first entry, append new line
- ${$sumVal[3]."_table"} = str_replace("</table:table>", "", ${$sumVal[3]."_table"});
- ${$sumVal[3]."_table"} .= '
- <table:table-row>
- <table:table-cell table:style-name="Table8.A10" office:value-type="string">
- <text:p text:style-name="P40">'.$sumKey.'</text:p>
- </table:table-cell>
- <table:table-cell table:style-name="Table8.B2" office:value-type="string">
- <text:p text:style-name="P44">'.$sumVal[4].'</text:p>
- </table:table-cell>
- </table:table-row>
- ';
- }
- // close the table
- ${$sumVal[3]."_table"} .= '</table:table>';
- }
- }
- }
-
- // squash vulns into one big 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($Info)){
- $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 .= $Info;
- }
- // add to template
- $source = file_get_contents("/tmp/$rand/content.xml");
- $source = str_replace('{vuln}', $value, $source);
-
- //update total counts in exec summary table
- $source = str_replace('{count_serious}', $Count_Serious, $source);
- $source = str_replace('{count_high}', $Count_High, $source);
- $source = str_replace('{count_medium}', $Count_Medium, $source);
- $source = str_replace('{count_low}', $Count_Low, $source);
- echo "[+] added exec summary counts: $Count_Serious, $Count_High, $Count_Medium, $Count_Low\n";
-
- //update issues summary tables
- $source = str_replace('{summary_table_serious}', $Summary_Serious_Final, $source);
- $source = str_replace('{summary_table_high}', $Summary_High_Final, $source);
- $source = str_replace('{summary_table_medium}', $Summary_Medium_Final, $source);
- $source = str_replace('{summary_table_low}', $Summary_Low_Final, $source);
- $source = str_replace('{summary_table_info}', $Summary_Info_Final, $source);
- echo "[+] added findings summary tables\n";
-
- //update owasp count tables
- for ($i=1; $i <= 10 ; $i++) {
- $padNo = sprintf("%02d", $i);
- $source = str_replace('{A'.$padNo.'}', ${"A".$padNo}, $source);
- }
- for ($i=1; $i <= 10 ; $i++) {
- $padNo = sprintf("%02d", $i);
- $source = str_replace('{M'.$padNo.'}', ${"M".$padNo}, $source);
- }
- for ($i=1; $i <= 10 ; $i++) {
- $padNo = sprintf("%02d", $i);
- $source = str_replace('{API'.$padNo.'}', ${"API".$padNo}, $source);
- }
- echo "[+] updated OWASP count tables\n";
-
- //update owasp findings tables
- for ($i=1; $i <= 10 ; $i++) {
- $padNo = sprintf("%02d", $i);
- $source = str_replace('{A'.$padNo.'_table}', ${"A".$padNo."_table"}, $source);
- }
- for ($i=1; $i <= 10 ; $i++) {
- $padNo = sprintf("%02d", $i);
- $source = str_replace('{M'.$padNo.'_table}', ${"M".$padNo."_table"}, $source);
- }
- for ($i=1; $i <= 10 ; $i++) {
- $padNo = sprintf("%02d", $i);
- $source = str_replace('{API'.$padNo.'_table}', ${"API".$padNo."_table"}, $source);
- }
- echo "[+] updated OWASP findings tables\n";
-
- // save to file
- echo "[!] writing to /tmp content.xml\n";
- 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();
- }
-
- ?>