Newer
Older
DirtyScripts / ReportToolz / repgen.php
root on 10 Nov 2022 17 KB the big return update
  1. #!/usr/bin/php
  2. <?php
  3. //error_reporting(0);
  4. include('config.php');
  5.  
  6. /***
  7. * Main program - Don't edit below
  8. */
  9. echo "_____ _____ _____ Gen\n||_// ||== ||_// \n|| \\ ||___ || \n\n";
  10.  
  11. foreach (glob("classes/*.php") as $filename)
  12. include $filename;
  13.  
  14. $definitions = new \Clapp\CommandLineArgumentDefinition(
  15. array(
  16. "help|h" => "Shows help message",
  17. "path|p=s" => "/path/to/configs/", // should contain config.json and all vuln.json files
  18. )
  19. );
  20.  
  21. $filter = new \Clapp\CommandArgumentFilter($definitions, $argv);
  22.  
  23. if ($filter->getParam('h') === true || $argc < 2) {
  24. fwrite(STDERR, $definitions->getUsage());
  25. exit(0);
  26. }
  27.  
  28. // see if doc exists
  29. if ($filter->getParam("path") == false)
  30. die("[-] no path set\n");
  31.  
  32. echo "[!] path: ".$filter->getParam("path")."\n";
  33. if(!is_dir($filter->getParam("path")))
  34. die("[-] no such folder! \n");
  35.  
  36. //get config file
  37. $config = json_decode(file_get_contents($filter->getParam("path")."config.conf"));
  38. $riskRatings = array("Serious","High","Medium","Low");
  39.  
  40. //create owasp top 10 placeholders
  41. for ($i=1; $i <= 10 ; $i++) { $padNo = sprintf("%02d", $i); ${"A".$padNo} = 0; }
  42. for ($i=1; $i <= 10 ; $i++) { $padNo = sprintf("%02d", $i); ${"M".$padNo} = 0; }
  43. for ($i=1; $i <= 10 ; $i++) { $padNo = sprintf("%02d", $i); ${"API".$padNo} = 0; }
  44.  
  45. //create owasp top 10 table placeholders
  46. for ($i=1; $i <= 10 ; $i++) { $padNo = sprintf("%02d", $i); ${"A".$padNo."_table"} = ""; }
  47. for ($i=1; $i <= 10 ; $i++) { $padNo = sprintf("%02d", $i); ${"M".$padNo."_table"} = ""; }
  48. for ($i=1; $i <= 10 ; $i++) { $padNo = sprintf("%02d", $i); ${"API".$padNo."_table"} = ""; }
  49.  
  50. // extract doc and get contents
  51. $rand = uniqid();
  52. mkdir("/tmp/$rand");
  53. if(unzipFolder($template, "/tmp/$rand/")) {
  54. $source = file_get_contents("/tmp/$rand/content.xml");
  55. echo "[+] doc extracted\n";
  56. } else {
  57. die("[-] unable to extract doc\n");
  58. }
  59. $source = file_get_contents("/tmp/$rand/content.xml");
  60. // add CHECK section into report if needed
  61. if(isset($config->checkRef) && trim($config->checkRef) <> ""){
  62. $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">
  63. <draw:image xlink:href="Pictures/10000000000004A3000001C98E2CC6AE1D6F811E.jpg" xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad" loext:mime-type="image/jpeg"/>
  64. </draw:frame>';
  65. $check_section = '<text:p text:style-name="P26"/>
  66. <text:p text:style-name="P26"/>
  67. <text:p text:style-name="P26"/>
  68. <text:p text:style-name="P26"/>
  69. <text:p text:style-name="P26">
  70. CHECK Ref: {checkRef}
  71. </text:p>';
  72. $source = str_replace('{check_img}', $check_img, $source);
  73. $source = str_replace('{check_section}', $check_section, $source);
  74. echo "[+] Added CHECK section\n";
  75. }else{
  76. $check_section = '<text:p text:style-name="P26">
  77. <text:bookmark-start text:name="__RefHeading___Toc72207_536000782"/>
  78. <text:bookmark-end text:name="__RefHeading___Toc72207_536000782"/>
  79. </text:p>';
  80. $source = str_replace('{check_img}', "", $source);
  81. $source = str_replace('{check_section}', $check_section, $source);
  82. }
  83.  
  84. // add config into template
  85. foreach ($config as $key => $value) {
  86. $source = str_replace('{'.$key.'}', $value, $source);
  87. }
  88. file_put_contents("/tmp/$rand/content.xml", $source);
  89. echo "[+] added config values\n";
  90.  
  91. // get all vulns
  92. $vuln = array();
  93. $files = glob($filter->getParam("path")."*.json");
  94. foreach($files as $finding){
  95. $vuln[] = $found = json_decode(file_get_contents($finding), true);
  96. }
  97.  
  98. echo "[+] sorting vulns by CVSS\n";
  99. usort($vuln, 'order_by_cvss');
  100. function order_by_cvss($a, $b) {
  101. return $b['cvss_score'] > $a['cvss_score'] ? 1 : -1;
  102. }
  103.  
  104. if(empty($vuln))
  105. echo "[-] no vulns found!\n";
  106.  
  107. // create vulns for odf
  108. $templateOrig = file_get_contents($vulnTemplate);
  109. $Serious = $High = $Medium = $Low = $Info = "";
  110. $Count_Serious = $Count_High = $Count_Medium = $Count_Low = $Count_Info = 0;
  111. $Summary_Serious = $Summary_High = $Summary_Medium = $Summary_Low = $Summary_Info = array();
  112. foreach ($vuln as $singlevuln) {
  113. $templateSource = $templateOrig;
  114. $togo = $singlevuln['risk'];
  115. foreach ($singlevuln as $key => $value){
  116. $value = str_replace("<", "&lt;", $value);
  117. $value = str_replace(">", "&gt;", $value);
  118. $value = str_replace("\n", "</text:p><text:p text:style-name=\"Text_20_body\">", $value);
  119. $templateSource = str_replace('{'.$key.'}', $value, $templateSource);
  120. if($key == "risk"){
  121. switch ($togo) {
  122. case 'Serious':
  123. $templateSource = str_replace('{risk_img}', '100000000000001C0000001C2B2344F988E3C014.png', $templateSource);
  124. break;
  125. case 'High':
  126. $templateSource = str_replace('{risk_img}', '100000000000001C0000001C478E326DAB1B0673.gif', $templateSource);
  127. break;
  128. case 'Medium':
  129. $templateSource = str_replace('{risk_img}', '100000000000001C0000001C08AD11DB0A5D02CD.png', $templateSource);
  130. break;
  131. case 'Low':
  132. $templateSource = str_replace('{risk_img}', '100000000000001C0000001C6CC3BB57AA64608B.gif', $templateSource);
  133. break;
  134. case 'Info':
  135. $templateSource = str_replace('{risk_img}', '100000000000001C0000001C7365C375D1750C0F.gif', $templateSource);
  136. break;
  137. }
  138. }
  139. }
  140. if(isset($singlevuln['hosts']) && $singlevuln['hosts'] <> ""){
  141. $templateSource = str_replace('{hosts}', $singlevuln['hosts'], $templateSource);
  142. }else{
  143. $templateSource = str_replace('{hosts}', "N/A", $templateSource);
  144. }
  145. $$togo .= $templateSource;
  146. ${"Count_$togo"} += 1;
  147. echo "[+] added $togo: ".$singlevuln['title']."\n";
  148.  
  149. // fixing summary tables
  150. $descExpl = explode(".", $singlevuln['description']);
  151. $fixExpl = explode(".", $singlevuln['solution']);
  152. $descFinal = $descExpl[0].".";
  153. $fixFinal = $fixExpl[0].".";
  154. // if small summaries exist use them!
  155. if(isset($singlevuln['summary_issue']) && $singlevuln['summary_issue'] <> ""){
  156. // DEBUG: echo "[+] summary description found for: ".$singlevuln['title']."\n";
  157. $descFinal = $singlevuln['summary_issue'];
  158. }
  159. if(isset($singlevuln['summary_solution']) && $singlevuln['summary_solution'] <> ""){
  160. // DEBUG: echo "[+] summary solution found for: ".$singlevuln['title']."\n";
  161. $fixFinal = $singlevuln['summary_solution'];
  162. }
  163.  
  164. // set OWASP counts
  165. $issueOwasp = explode(":", $singlevuln['owasp']);
  166. ${$issueOwasp[0]}++;
  167.  
  168. $hostSummary = (isset($singlevuln['hosts']) && $singlevuln['hosts'] <> "") ? $singlevuln['hosts'] : "N/A";
  169. // populate arrays for small vuln tables
  170. // key = title, 0 = desc, 1 = fix, 2 = hosts, 3 = owasp, 4, page ref
  171. ${"Summary_$togo"}[$singlevuln['title']] = array($descFinal, $fixFinal, $hostSummary, $issueOwasp[0]);
  172. }
  173.  
  174. // add page ref to each issue
  175. $placeA = 1;
  176. foreach ($riskRatings as $riskKey => $riskVal) {
  177. $placeB = 1;
  178. if(!empty( ${"Summary_$riskVal"} )){
  179. foreach (${"Summary_$riskVal"} as $sumKey => $sumVal) {
  180. array_push(${"Summary_$riskVal"}[$sumKey], "5.".$placeA.".".$placeB);
  181. $placeB++;
  182. }
  183. $placeA++;
  184. }
  185. }
  186.  
  187. // create sumaries tables
  188. $Summary_Serious_Final = $Summary_High_Final = $Summary_Medium_Final = $Summary_Low_Final = "";
  189. $placeA = 1;
  190. foreach ($riskRatings as $riskKey => $riskVal) {
  191. $placeB = 1;
  192. if(empty( ${"Summary_$riskVal"} )){
  193. ${"Summary_".$riskVal."_Final"} = '
  194. <table:table-row table:style-name="Table11.1">
  195. <table:table-cell table:style-name="Table11.A2" office:value-type="string">
  196. <text:p text:style-name="P189">None Identified</text:p>
  197. </table:table-cell>
  198. <table:table-cell table:style-name="Table11.A2" office:value-type="string">
  199. <text:p text:style-name="P170"/>
  200. </table:table-cell>
  201. <table:table-cell table:style-name="Table11.C2" office:value-type="string">
  202. <text:p text:style-name="P171"/>
  203. </table:table-cell>
  204. <table:table-cell table:style-name="Table11.C2" office:value-type="string">
  205. <text:p text:style-name="P172"/>
  206. </table:table-cell>
  207. </table:table-row>
  208. ';
  209. }else{
  210. foreach (${"Summary_$riskVal"} as $sumKey => $sumVal) {
  211. // DEBUG: echo "[i] $sumKey:\n".$sumVal[0]."\n".$sumVal[1]."\n\n";
  212. ${"Summary_".$riskVal."_Final"} .= '
  213. <table:table-row table:style-name="Table11.1">
  214. <table:table-cell table:style-name="Table11.A2" office:value-type="string">
  215. <text:p text:style-name="P189">'.$sumKey.'</text:p>
  216. <text:p text:style-name="P170">'.$sumVal[0].'</text:p>
  217. </table:table-cell>
  218. <table:table-cell table:style-name="Table11.A2" office:value-type="string">
  219. <text:p text:style-name="P170">'.$sumVal[1].'</text:p>
  220. </table:table-cell>
  221. <table:table-cell table:style-name="Table11.C2" office:value-type="string">
  222. <text:p text:style-name="P171">'.$sumVal[4].'</text:p>
  223. </table:table-cell>
  224. <table:table-cell table:style-name="Table11.C2" office:value-type="string">
  225. <text:p text:style-name="P172">'.$sumVal[2].'</text:p>
  226. </table:table-cell>
  227. </table:table-row>
  228. ';
  229. }
  230. }
  231.  
  232. }
  233.  
  234. //populate owasp findings tables
  235. foreach ($riskRatings as $riskKey => $riskVal) {
  236. if(!empty( ${"Summary_$riskVal"} )){
  237. foreach (${"Summary_$riskVal"} as $sumKey => $sumVal) {
  238. if( ${$sumVal[3]."_table"} == ""){ // if is first entry
  239. ${$sumVal[3]."_table"} = '
  240. <table:table table:name="Table8" table:style-name="Table8">
  241. <table:table-column table:style-name="Table8.C"/>
  242. <table:table-column table:style-name="Table8.D"/>
  243. <table:table-header-rows>
  244. <table:table-row table:style-name="Table8.1">
  245. <table:table-cell table:style-name="Table8.A1" office:value-type="string">
  246. <text:p text:style-name="P71">Vulnerabilities in This Category</text:p>
  247. </table:table-cell>
  248. <table:table-cell table:style-name="Table8.B1" office:value-type="string">
  249. <text:p text:style-name="P72">Document Reference</text:p>
  250. </table:table-cell>
  251. </table:table-row>
  252. </table:table-header-rows>
  253. <table:table-row>
  254. <table:table-cell table:style-name="Table8.A10" office:value-type="string">
  255. <text:p text:style-name="P40">'.$sumKey.'</text:p>
  256. </table:table-cell>
  257. <table:table-cell table:style-name="Table8.B2" office:value-type="string">
  258. <text:p text:style-name="P44">'.$sumVal[4].'</text:p>
  259. </table:table-cell>
  260. </table:table-row>
  261. ';
  262. }else{ // not first entry, append new line
  263. ${$sumVal[3]."_table"} = str_replace("</table:table>", "", ${$sumVal[3]."_table"});
  264. ${$sumVal[3]."_table"} .= '
  265. <table:table-row>
  266. <table:table-cell table:style-name="Table8.A10" office:value-type="string">
  267. <text:p text:style-name="P40">'.$sumKey.'</text:p>
  268. </table:table-cell>
  269. <table:table-cell table:style-name="Table8.B2" office:value-type="string">
  270. <text:p text:style-name="P44">'.$sumVal[4].'</text:p>
  271. </table:table-cell>
  272. </table:table-row>
  273. ';
  274. }
  275. // close the table
  276. ${$sumVal[3]."_table"} .= '</table:table>';
  277. }
  278. }
  279. }
  280.  
  281. // squash vulns into one big xml
  282. $value = "";
  283. if(!empty($Serious)){
  284. $value .= '<text:list text:continue-numbering="true" text:style-name="Outline">
  285. <text:list-item>
  286. <text:list>
  287. <text:list-item>
  288. <text:h text:outline-level="2">Serious Risk Vulnerabilities</text:h>
  289. </text:list-item>
  290. </text:list>
  291. </text:list-item>
  292. </text:list>';
  293. $value .= $Serious;
  294. }
  295.  
  296. if(!empty($High)){
  297. $value .= '<text:list text:continue-numbering="true" text:style-name="Outline">
  298. <text:list-item>
  299. <text:list>
  300. <text:list-item>
  301. <text:h text:outline-level="2">High Risk Vulnerabilities</text:h>
  302. </text:list-item>
  303. </text:list>
  304. </text:list-item>
  305. </text:list>';
  306. $value .= $High;
  307. }
  308. if(!empty($Medium)){
  309. $value .= '<text:list text:continue-numbering="true" text:style-name="Outline">
  310. <text:list-item>
  311. <text:list>
  312. <text:list-item>
  313. <text:h text:outline-level="2">Medium Risk Vulnerabilities</text:h>
  314. </text:list-item>
  315. </text:list>
  316. </text:list-item>
  317. </text:list>';
  318. $value .= $Medium;
  319. }
  320. if(!empty($Low)){
  321. $value .= '<text:list text:continue-numbering="true" text:style-name="Outline">
  322. <text:list-item>
  323. <text:list>
  324. <text:list-item>
  325. <text:h text:outline-level="2">Low Risk Vulnerabilities</text:h>
  326. </text:list-item>
  327. </text:list>
  328. </text:list-item>
  329. </text:list>';
  330. $value .= $Low;
  331. }
  332. if(!empty($Info)){
  333. $value .= '<text:list text:continue-numbering="true" text:style-name="Outline">
  334. <text:list-item>
  335. <text:list>
  336. <text:list-item>
  337. <text:h text:outline-level="2">Informational Risk Vulnerabilities</text:h>
  338. </text:list-item>
  339. </text:list>
  340. </text:list-item>
  341. </text:list>';
  342. $value .= $Info;
  343. }
  344. // add to template
  345. $source = file_get_contents("/tmp/$rand/content.xml");
  346. $source = str_replace('{vuln}', $value, $source);
  347.  
  348. //update total counts in exec summary table
  349. $source = str_replace('{count_serious}', $Count_Serious, $source);
  350. $source = str_replace('{count_high}', $Count_High, $source);
  351. $source = str_replace('{count_medium}', $Count_Medium, $source);
  352. $source = str_replace('{count_low}', $Count_Low, $source);
  353. echo "[+] added exec summary counts: $Count_Serious, $Count_High, $Count_Medium, $Count_Low\n";
  354.  
  355. //update issues summary tables
  356. $source = str_replace('{summary_table_serious}', $Summary_Serious_Final, $source);
  357. $source = str_replace('{summary_table_high}', $Summary_High_Final, $source);
  358. $source = str_replace('{summary_table_medium}', $Summary_Medium_Final, $source);
  359. $source = str_replace('{summary_table_low}', $Summary_Low_Final, $source);
  360. echo "[+] added findings summary tables\n";
  361.  
  362. //update owasp count tables
  363. for ($i=1; $i <= 10 ; $i++) {
  364. $padNo = sprintf("%02d", $i);
  365. $source = str_replace('{A'.$padNo.'}', ${"A".$padNo}, $source);
  366. }
  367. for ($i=1; $i <= 10 ; $i++) {
  368. $padNo = sprintf("%02d", $i);
  369. $source = str_replace('{M'.$padNo.'}', ${"M".$padNo}, $source);
  370. }
  371. for ($i=1; $i <= 10 ; $i++) {
  372. $padNo = sprintf("%02d", $i);
  373. $source = str_replace('{API'.$padNo.'}', ${"API".$padNo}, $source);
  374. }
  375. echo "[+] updated OWASP count tables\n";
  376.  
  377. //update owasp findings tables
  378. for ($i=1; $i <= 10 ; $i++) {
  379. $padNo = sprintf("%02d", $i);
  380. $source = str_replace('{A'.$padNo.'_table}', ${"A".$padNo."_table"}, $source);
  381. }
  382. for ($i=1; $i <= 10 ; $i++) {
  383. $padNo = sprintf("%02d", $i);
  384. $source = str_replace('{M'.$padNo.'_table}', ${"M".$padNo."_table"}, $source);
  385. }
  386. for ($i=1; $i <= 10 ; $i++) {
  387. $padNo = sprintf("%02d", $i);
  388. $source = str_replace('{API'.$padNo.'_table}', ${"API".$padNo."_table"}, $source);
  389. }
  390. echo "[+] updated OWASP findings tables\n";
  391.  
  392. // save to file
  393. echo "[!] writing to /tmp content.xml\n";
  394. file_put_contents("/tmp/$rand/content.xml", $source);
  395.  
  396. // create report and tidying
  397. $repOutName = $config->ref.".3 ".$config->client ." ". $config->title1;
  398. zipFolder("/tmp/$rand", $filter->getParam("path").$repOutName.".odt");
  399. echo "[=] generated report: ".$filter->getParam("path").$repOutName.".odt\n";
  400. delTree("/tmp/$rand");
  401. echo "[+] temp files removed\n";
  402.  
  403. function unzipFolder($zipInputFile, $outputFolder) {
  404. $zip = new ZipArchive;
  405. $res = $zip->open($zipInputFile);
  406. if ($res === true) {
  407. $zip->extractTo($outputFolder);
  408. $zip->close();
  409. return true;
  410. }
  411. else {
  412. return false;
  413. }
  414. }
  415.  
  416. function XML2Array(SimpleXMLElement $parent){
  417. $array = array();
  418.  
  419. foreach ($parent as $name => $element) {
  420. ($node = & $array[$name])
  421. && (1 === count($node) ? $node = array($node) : 1)
  422. && $node = & $node[];
  423.  
  424. $node = $element->count() ? XML2Array($element) : trim($element);
  425. }
  426.  
  427. return $array;
  428. }
  429.  
  430. function delTree($dir){
  431. $files = array_diff(scandir($dir), array('.', '..'));
  432.  
  433. foreach ($files as $file) {
  434. (is_dir("$dir/$file")) ? delTree("$dir/$file") : unlink("$dir/$file");
  435. }
  436.  
  437. return rmdir($dir);
  438. }
  439.  
  440. function zipFolder($inputFolder, $zipOutputFile) {
  441. if (!extension_loaded('zip') || !file_exists($inputFolder)) {
  442. return false;
  443. }
  444.  
  445. $zip = new ZipArchive();
  446. if (!$zip->open($zipOutputFile, ZIPARCHIVE::CREATE)) {
  447. return false;
  448. }
  449.  
  450. $inputFolder = str_replace('\\', "/", realpath($inputFolder));
  451.  
  452. if (is_dir($inputFolder) === true) {
  453. $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($inputFolder), RecursiveIteratorIterator::SELF_FIRST);
  454.  
  455. foreach ($files as $file) {
  456. $file = str_replace('\\', "/", $file);
  457.  
  458. if (in_array(substr($file, strrpos($file, '/')+1), array('.', '..'))) {
  459. continue;
  460. }
  461.  
  462. $file = realpath($file);
  463.  
  464. if (is_dir($file) === true) {
  465. $dirName = str_replace($inputFolder."/", '', $file."/");
  466. $zip->addEmptyDir($dirName);
  467. }
  468. else if (is_file($file) === true) {
  469. $fileName = str_replace($inputFolder."/", '', $file);
  470. $zip->addFromString($fileName, file_get_contents($file));
  471. }
  472. }
  473. }
  474. else if (is_file($inputFolder) === true) {
  475. $zip->addFromString(basename($inputFolder), file_get_contents($inputFolder));
  476. }
  477.  
  478. return $zip->close();
  479. }
  480.  
  481. ?>
Buy Me A Coffee