Newer
Older
DirtyScripts / ReportToolz / rep2.php
root on 23 Feb 2021 16 KB minor fix
  1. #!/usr/bin/php
  2. <?php
  3. //error_reporting(0);
  4.  
  5. /***
  6. * Configuration options
  7. */
  8. $sub1 = 5; // header no in doc e.g. "5 Discovered Vulnerabilities"
  9.  
  10. /***
  11. * Main program - Don't edit below
  12. */
  13. echo "_____ _____ _____ 2\n||_// ||== ||_// \n|| \\ ||___ || \n\n";
  14.  
  15. foreach (glob("classes/*.php") as $filename)
  16. include $filename;
  17.  
  18. $definitions = new \Clapp\CommandLineArgumentDefinition(
  19. array(
  20. "help|h" => "Shows help message",
  21. "doc|d=s" => "/path/to/doc.odt to use",
  22. )
  23. );
  24.  
  25. $filter = new \Clapp\CommandArgumentFilter($definitions, $argv);
  26.  
  27. if ($filter->getParam('h') === true || $argc < 2) {
  28. fwrite(STDERR, $definitions->getUsage());
  29. exit(0);
  30. }
  31.  
  32. // see if doc exists
  33. if ($filter->getParam("doc") == false)
  34. die("[-] no doc set\n");
  35.  
  36. echo "[!] doc: ".$filter->getParam("doc")."\n";
  37. if(!file_exists($filter->getParam("doc")))
  38. die("[-] no such file! \n");
  39.  
  40. // extract doc and get contents
  41. $rand = uniqid();
  42. mkdir("/tmp/$rand");
  43. if(unzipFolder($filter->getParam("doc"), "/tmp/$rand/")) {
  44. $source = file_get_contents("/tmp/$rand/content.xml");
  45. echo "[+] doc extracted\n";
  46. } else {
  47. die("[-] unable to extract doc\n");
  48. }
  49. // Parse Doc's XML
  50. $line = array();
  51. $reader = new XMLReader();
  52. if (!$reader->open("/tmp/$rand/content.xml")) die("[-] Failed to open 'content.xml'\n");
  53.  
  54. // font checker
  55. /***
  56. * FUTURE FEATURE PERHAPS
  57. */
  58. $fonts = array();
  59. while ($reader->read()){
  60. //print_r($reader->name);
  61. if ($reader->nodeType == XMLREADER::ELEMENT && ($reader->name === 'style:font-face')) {
  62. //if(!empty($reader->name)){
  63. //echo "here2\n";
  64. //$line[] = $reader->expand()->textContent; // Put the text into array in correct order...
  65. $fonts[] = $reader->getAttribute("style:name");
  66. //echo $font;echo "\n"; // DEBUG
  67. //}
  68. }
  69. }
  70. $reader->close();
  71. //die();
  72. echo "[=] fonts found: ".sizeof($fonts)."\n";
  73.  
  74. // get template version used
  75. $reader = new XMLReader();
  76. if (!$reader->open("/tmp/$rand/meta.xml")) die("[-] Failed to open 'meta.xml'\n");
  77. $templateVer = 0.0;
  78. while ($reader->read()) {
  79. if($reader->name == "dc:version"){
  80. $reader->read();
  81. $templateVer = number_format(floatval($reader->value), 2);
  82. break;
  83. }
  84. }
  85.  
  86. // step through text:h and text:p elements to put them into an array
  87. $reader = new XMLReader();
  88. if (!$reader->open("/tmp/$rand/content.xml")) die("[-] Failed to open 'content.xml'\n");
  89. while ($reader->read()){
  90. if ($reader->nodeType == XMLREADER::ELEMENT && ($reader->name === 'text:h' || $reader->name === 'text:p' || $reader->name === 'text:bookmark')) {
  91. if(!empty($reader->expand()->textContent))
  92. $line[] = $reader->expand()->textContent; // Put the text into array in correct order...
  93. //echo $reader->expand()->textContent;echo "\n"; // DEBUG
  94. }
  95. }
  96. $reader->close();
  97.  
  98. // find the content we want
  99. $start = 0; $end = 0;
  100. foreach($line as $key => $val){
  101. //if(strpos($val, "Discovered Vulnerabilities") === 0){ $start = $key; }
  102. if(preg_match('/Discovered *\w* Vulnerabilities/', $val, $matches) === true){ $start = $key; }
  103. //if(strpos($val, "This section provides a quick guide to plan your remediation for the vulnerabilities discovered during the test.") === 0){ $end = $key-2; }
  104. if(strpos($val, "Observed Hosts and Services") === 0){ $end = $key-2; }
  105. $line[$key] = trim($val);
  106. }
  107.  
  108. // add to sexy array's
  109. $vuln = array();
  110. $vulnPlace = 0;
  111. $switch = 0;
  112. $sub2 = 0;
  113. $sub3 = 1;
  114. if(number_format($templateVer, 2) >= number_format(1.0, 2)){
  115. echo "[=] Template $templateVer used\n";
  116. for ($i=$start; $i <= $end ; $i++) {
  117. // change state (action to take)
  118. /***
  119. * ~states~
  120. * 0 = do nothing
  121. * 1 = next is title
  122. * 2 = next is description
  123. * 3 = next is solution
  124. * 4 = next is remediation
  125. * 5 = next is cvss no
  126. * 6 = next is risk level
  127. * 7 = next is hosts
  128. * 8 = next possibly title
  129. */
  130. switch ($line[$i]) {
  131. case (preg_match('/Discovered *\w* Vulnerabilities/', $val, $matches) === true):
  132. $switch = 0;
  133. break;
  134. case 'Serious Risk Vulnerabilities':
  135. $sub2++; $sub3 = 1;
  136. $switch = 1;
  137. break;
  138. case 'High Risk Vulnerabilities':
  139. $sub2++; $sub3 = 1;
  140. $switch = 1;
  141. break;
  142. case 'Medium Risk Vulnerabilities':
  143. $sub2++; $sub3 = 1;
  144. $switch = 1;
  145. break;
  146. case 'Low Risk Vulnerabilities':
  147. $sub2++; $sub3 = 1;
  148. $switch = 1;
  149. break;
  150. case 'Informational Risk Vulnerabilities':
  151. $sub2++; $sub3 = 1;
  152. $switch = 1;
  153. break;
  154. case 'Description':
  155. $switch = 2;
  156. break;
  157. case 'Solution':
  158. $switch = 3;
  159. break;
  160. case 'Remediation':
  161. $switch = 4;
  162. break;
  163. case 'CVSS Base Score':
  164. $switch = 5;
  165. break;
  166. case 'Risk Analysis':
  167. $switch = 6;
  168. break;
  169. case 'Vulnerabilities Exist On':
  170. $switch = 7;
  171. break;
  172. case 'Potential Impact':
  173. $switch = 9;
  174. break;
  175. default:
  176. # code...
  177. break;
  178. }
  179.  
  180. //take action
  181. switch ($switch) {
  182. case 1:
  183. $i++;
  184. $vuln[$vulnPlace]['title'] = $line[$i];
  185. $vuln[$vulnPlace]['ref'] = "$sub1.$sub2.$sub3";
  186. $sub3++;
  187. $switch = 0;
  188. break;
  189. case 2:
  190. @$vuln[$vulnPlace]['desc'] .= $line[$i];
  191. break;
  192. case 3:
  193. @$vuln[$vulnPlace]['fix'] .= $line[$i];
  194. break;
  195. case 4:
  196. $i++;
  197. //$vuln[$vulnPlace]['rem'] = trim(strtok($line[$i], " "));
  198. $switch = 0;
  199. break;
  200. case 5:
  201. $i++;
  202. $vuln[$vulnPlace]['cvss'] = $line[$i];
  203. $switch = 0;
  204. break;
  205. case 6:
  206. $i++;
  207. $line[$i+3] = str_replace("Vulnerability Img", "", $line[$i+3]);
  208. $vuln[$vulnPlace]['risk'] = strstr(trim($line[$i+3]), ":", true);
  209. $vuln[$vulnPlace]['owasp'] = trim(substr($line[$i+3], strpos($line[$i+3], ":") + 1));
  210. $vuln[$vulnPlace]['impact'] = trim(strtok($line[$i+4], " "));
  211. $vuln[$vulnPlace]['rem'] = trim(strtok($line[$i+5], " "));
  212. $switch = 0;
  213. break;
  214. case 7:
  215. $i++;
  216. $vuln[$vulnPlace]['hosts'] = $line[$i];
  217. $switch = 8;
  218. $vulnPlace++;
  219. break;
  220. case 8:
  221. $vuln[$vulnPlace]['title'] = trim($line[$i]);
  222. $vuln[$vulnPlace]['ref'] = "$sub1.$sub2.$sub3";
  223. $sub3++;
  224. $switch = 0;
  225. break;
  226. case 9:
  227. @$vuln[$vulnPlace]['impact'] .= $line[$i];
  228. break;
  229. default:
  230. # code...
  231. break;
  232. }
  233.  
  234. //echo $line[$i]."\n"; // DEBUG
  235. }
  236. $first_desc = explode("Description", $vuln[0]['desc']);
  237.  
  238. $vuln[0]['desc'] = $first_desc[sizeof($first_desc)-1];
  239. }else{ // old template or Dave's format
  240. for ($i=$start; $i <= $end ; $i++) {
  241. // change state (action to take)
  242. /***
  243. * ~states~
  244. * 0 = do nothing
  245. * 1 = next is title
  246. * 2 = next is description
  247. * 3 = next is solution
  248. * 4 = next is remediation
  249. * 5 = next is cvss no
  250. * 6 = next is risk level
  251. * 7 = next is hosts
  252. * 8 = next possibly title
  253. */
  254. echo $line[$i]."\n";
  255. switch ($line[$i]) {
  256. case 'Discovered Vulnerabilities':
  257. $switch = 0;
  258. break;
  259. case 'Serious Risk Vulnerabilities':
  260. $sub2++; $sub3 = 1;
  261. $switch = 1;
  262. break;
  263. case 'High Risk Vulnerabilities':
  264. $sub2++; $sub3 = 1;
  265. $switch = 1;
  266. break;
  267. case 'Medium Risk Vulnerabilities':
  268. $sub2++; $sub3 = 1;
  269. $switch = 1;
  270. break;
  271. case 'Low Risk Vulnerabilities':
  272. $sub2++; $sub3 = 1;
  273. $switch = 1;
  274. break;
  275. case 'Informational Risk Vulnerabilities':
  276. $sub2++; $sub3 = 1;
  277. $switch = 1;
  278. break;
  279. case 'Description':
  280. $switch = 2;
  281. break;
  282. case 'Solution':
  283. $switch = 3;
  284. break;
  285. case 'Remediation':
  286. $switch = 4;
  287. break;
  288. case 'CVSS Base Score':
  289. $switch = 5;
  290. break;
  291. case 'Risk Level':
  292. $switch = 6;
  293. break;
  294. case 'Vulnerabilities Exist On':
  295. $switch = 7;
  296. break;
  297. case 'Potential Impact':
  298. $switch = 9;
  299. break;
  300. default:
  301. # code...
  302. break;
  303. }
  304.  
  305. //take action
  306. switch ($switch) {
  307. case 1:
  308. $i++;
  309. $vuln[$vulnPlace]['title'] = $line[$i];
  310. $vuln[$vulnPlace]['ref'] = "$sub1.$sub2.$sub3";
  311. $sub3++;
  312. $switch = 0;
  313. break;
  314. case 2:
  315. @$vuln[$vulnPlace]['desc'] .= $line[$i];
  316. break;
  317. case 3:
  318. @$vuln[$vulnPlace]['fix'] .= $line[$i];
  319. break;
  320. case 4:
  321. $i++;
  322. $vuln[$vulnPlace]['rem'] = trim(strtok($line[$i], " "));
  323. $switch = 0;
  324. break;
  325. case 5:
  326. $i++;
  327. $vuln[$vulnPlace]['cvss'] = $line[$i];
  328. $switch = 0;
  329. break;
  330. case 6:
  331. $i++;
  332. $vuln[$vulnPlace]['risk'] = trim(strtok($line[$i], " "));
  333. $vuln[$vulnPlace]['owasp'] = trim(substr($line[$i], strpos($line[$i], ":") + 1));
  334. $switch = 0;
  335. break;
  336. case 7:
  337. $i++;
  338. $vuln[$vulnPlace]['hosts'] = $line[$i];
  339. $switch = 8;
  340. $vulnPlace++;
  341. break;
  342. case 8:
  343. $vuln[$vulnPlace]['title'] = trim($line[$i]);
  344. $vuln[$vulnPlace]['ref'] = "$sub1.$sub2.$sub3";
  345. $sub3++;
  346. $switch = 0;
  347. break;
  348. case 9:
  349. @$vuln[$vulnPlace]['impact'] .= $line[$i];
  350. break;
  351. default:
  352. # code...
  353. break;
  354. }
  355.  
  356. //echo $line[$i]."\n"; // DEBUG
  357. }
  358. }
  359.  
  360. // get all vulns.json if there are any
  361. $currentPath = dirname($filter->getParam("doc"));
  362. $jsonVuln = array();
  363. $jsonFiles = glob($currentPath."/*.json");
  364. foreach($jsonFiles as $finding){
  365. $placeholder = json_decode(file_get_contents($finding), true);
  366. if(isset($placeholder['title'])) // is a vuln and not config file
  367. $jsonVuln[] = $placeholder;
  368. }
  369.  
  370. // minor tidying of arrays
  371. for ($i=0; $i < sizeof($vuln) ; $i++) {
  372. if (strpos($vuln[$i]['desc'], "Description") === 0) $vuln[$i]['desc'] = substr($vuln[$i]['desc'], strlen("Description"));
  373. if (strpos($vuln[$i]['fix'], "Solution") === 0) $vuln[$i]['fix'] = substr($vuln[$i]['fix'], strlen("Solution"));
  374. $vuln[$i]['risk'] = rtrim($vuln[$i]['risk'], ":");
  375. // remove html encoding
  376. foreach($vuln[$i] as $key => $val){
  377. $vuln[$i][$key] = mb_convert_encoding($val, "UTF-8", 'UTF-8');
  378. }
  379.  
  380. // fixing summary tables
  381. $descExpl = explode(".", $vuln[$i]['desc']);
  382. $fixExpl = explode(".", $vuln[$i]['fix']);
  383. $vuln[$i]['desc'] = $descExpl[0].".";
  384. $vuln[$i]['fix'] = $fixExpl[0].".";
  385. foreach($jsonVuln as $id => $jsonIssue){
  386. if($jsonIssue['title'] == $vuln[$i]['title']){
  387.  
  388. if((isset($jsonIssue['summary_issue']) && $jsonIssue['summary_issue'] <> "") || (isset($jsonIssue['summary_solution']) && $jsonIssue['summary_solution'] <> "")){
  389. echo "[+] summary found for: ".$vuln[$i]['title']."\n";
  390. $vuln[$i]['desc'] = $jsonIssue['summary_issue'];
  391. $vuln[$i]['fix'] = $jsonIssue['summary_solution'];
  392. }
  393. }
  394. }
  395.  
  396. }
  397.  
  398. //print_r($vuln); // DEBUG
  399. echo "[+] vulnerabilities identified\n";
  400.  
  401. delTree("/tmp/$rand");
  402. echo "[+] temp files removed\n";
  403.  
  404. $resultsFolder = substr($filter->getParam("doc"), 0, strrpos( $filter->getParam("doc"), '/') )."/rep2";
  405. if(!file_exists($resultsFolder."/")){
  406. mkdir($resultsFolder."/");
  407. echo "[+] created directory $resultsFolder/\n";
  408. }else{
  409. $i = 1;
  410. while (file_exists($resultsFolder."_$i/"))
  411. $i++;
  412. mkdir($resultsFolder."_$i/");
  413. $resultsFolder .= "_$i";
  414. echo "[+] created directory $resultsFolder/\n";
  415. }
  416.  
  417. if(writeIssueTable($vuln, "Serious", $resultsFolder."/findings_serious.csv"))
  418. echo "[+] serious issues: $resultsFolder/findings_serious.csv\n";
  419. if(writeIssueTable($vuln, "High", $resultsFolder."/findings_high.csv"))
  420. echo "[+] high issues: $resultsFolder/findings_high.csv\n";
  421. if(writeIssueTable($vuln, "Medium", $resultsFolder."/findings_medium.csv"))
  422. echo "[+] medium issues: $resultsFolder/findings_medium.csv\n";
  423. if(writeIssueTable($vuln, "Low", $resultsFolder."/findings_low.csv"))
  424. echo "[+] low issues: $resultsFolder/findings_low.csv\n";
  425. if(writeIssueTable($vuln, "Info", $resultsFolder."/findings_info.csv"))
  426. echo "[+] info issues: $resultsFolder/findings_info.csv\n";
  427.  
  428. $order = array('title', 'ref', 'desc', 'fix','rem','cvss','risk','impact','owasp','hosts');
  429. $orderedArray = array();
  430. foreach($vuln as $vn_no =>$vn){
  431. foreach ($order as $key) {
  432. //echo $key."\n";
  433. $orderedArray[$vn_no][$key] = $vuln[$vn_no][$key];
  434. }
  435. }
  436. if(writeAllTable($orderedArray, $resultsFolder."/findings_all.csv"))
  437. echo "[+] all issues: $resultsFolder/findings_all.csv\n";
  438.  
  439. if(writeRemediationTable($vuln, $resultsFolder."/remediation.csv"))
  440. echo "[+] remediation table: $resultsFolder/remediation.csv\n";
  441.  
  442. if(writeOWASPTable($vuln, $resultsFolder."/owasp.csv"))
  443. echo "[+] OWASP table: $resultsFolder/owasp.csv\n";
  444.  
  445. viewVulns($vuln);
  446.  
  447. function unzipFolder($zipInputFile, $outputFolder) {
  448. $zip = new ZipArchive;
  449. $res = $zip->open($zipInputFile);
  450. if ($res === true) {
  451. $zip->extractTo($outputFolder);
  452. $zip->close();
  453. return true;
  454. }
  455. else {
  456. return false;
  457. }
  458. }
  459.  
  460. function XML2Array(SimpleXMLElement $parent){
  461. $array = array();
  462.  
  463. foreach ($parent as $name => $element) {
  464. ($node = & $array[$name])
  465. && (1 === count($node) ? $node = array($node) : 1)
  466. && $node = & $node[];
  467.  
  468. $node = $element->count() ? XML2Array($element) : trim($element);
  469. }
  470.  
  471. return $array;
  472. }
  473.  
  474. function delTree($dir){
  475. $files = array_diff(scandir($dir), array('.', '..'));
  476.  
  477. foreach ($files as $file) {
  478. (is_dir("$dir/$file")) ? delTree("$dir/$file") : unlink("$dir/$file");
  479. }
  480.  
  481. return rmdir($dir);
  482. }
  483.  
  484. function viewVulns($vuln){
  485. $s = $h = $m = $l = $i = 0 ;
  486. for ($j=0; $j < sizeof($vuln) ; $j++) {
  487. switch ($vuln[$j]['risk']) {
  488. case 'Serious':
  489. $s++;
  490. break;
  491. case 'High':
  492. $h++;
  493. break;
  494. case 'Medium':
  495. $m++;
  496. break;
  497. case 'Low':
  498. $l++;
  499. break;
  500. case 'Info':
  501. $i++;
  502. break;
  503. }
  504. }
  505. echo "[=] Serious = $s, High = $h, Medium = $m, Low = $l, Info = $i\n";
  506.  
  507. echo"
  508. Ref | Title | Risk | CVSS | Remediation | OWASP
  509. -------|-----------------------------------|--------|--------|---------------|------------------------------\n";
  510. for ($i=0; $i < sizeof($vuln) ; $i++) {
  511. $ref = str_pad($vuln[$i]['ref'], 7);
  512. $title = str_pad($vuln[$i]['title'], 35);
  513. $risk = str_pad($vuln[$i]['risk'], 8);
  514. $cvs1 = explode("-", $vuln[$i]['cvss']);
  515. $cvss = str_pad($cvs1[0], 8);
  516. $rem = str_pad($vuln[$i]['rem'], 15);
  517. $owasp = str_pad($vuln[$i]['owasp'], 30);
  518.  
  519. echo substr($ref, 0, 7); echo "|";
  520. echo substr($title, 0, 35); echo "|";
  521. echo substr($risk, 0, 8); echo "|";
  522. echo substr($cvss, 0, 8); echo "|";
  523. echo substr($rem, 0, 15); echo "|";
  524. echo substr($owasp, 0, 30); echo "\n";
  525. }
  526. }
  527.  
  528. function writeIssueTable($vuln, $issue, $path){
  529. $towrite = array();
  530. for ($i=0; $i < sizeof($vuln) ; $i++) {
  531. if($vuln[$i]['risk'] == $issue){
  532. $towrite[$i]['desc'] = $vuln[$i]['title']." - ".$vuln[$i]['desc'];
  533. $towrite[$i]['fix'] = $vuln[$i]['fix'];
  534. $towrite[$i]['ref'] = $vuln[$i]['ref'];
  535. $towrite[$i]['hosts'] = $vuln[$i]['hosts'];
  536. }
  537. }
  538. if(sizeof($towrite) > 0){
  539. $fp = fopen($path, 'w');
  540. fprintf($fp, chr(0xEF).chr(0xBB).chr(0xBF));
  541. foreach ($towrite as $fields) {
  542. fputcsv($fp, $fields);
  543. }
  544. fclose($fp);
  545. return true;
  546. }else{
  547. return false;
  548. }
  549. }
  550.  
  551. function writeAllTable($vuln, $path){
  552. if(sizeof($vuln) > 0){
  553. $fp = fopen($path, 'w');
  554. fprintf($fp, chr(0xEF).chr(0xBB).chr(0xBF));
  555. fputcsv($fp, array("Title", "Ref", "Description", "Solution", "Remediation", "CVSS", "Risk","Impact", "OWASP", "Affected"));
  556.  
  557. //print_r($orderedArray);
  558. foreach ($vuln as $fields) {
  559. fputcsv($fp, $fields);
  560. }
  561. fclose($fp);
  562. return true;
  563. }else{
  564. return false;
  565. }
  566. }
  567.  
  568. function writeRemediationTable($vuln, $path){
  569. $towrite = array();
  570. for ($i=0; $i < sizeof($vuln) ; $i++) {
  571. $towrite[$i]['hosts'] = $vuln[$i]['hosts'];
  572. $towrite[$i]['ref'] = $vuln[$i]['ref'];
  573. $towrite[$i]['p'] = " ";
  574. $towrite[$i]['c'] = " ";
  575. $towrite[$i]['d'] = " ";
  576. $towrite[$i]['u'] = " ";
  577. switch ($vuln[$i]['rem']) {
  578. case 'Patch':
  579. $towrite[$i]['p'] = $vuln[$i]['risk'][0];
  580. break;
  581. case 'Configuration':
  582. $towrite[$i]['c'] = $vuln[$i]['risk'][0];
  583. break;
  584. case 'Development':
  585. $towrite[$i]['d'] = $vuln[$i]['risk'][0];
  586. break;
  587. case 'Upgrade':
  588. $towrite[$i]['u'] = $vuln[$i]['risk'][0];
  589. break;
  590. }
  591. }
  592. if(sizeof($towrite) > 0){
  593. $fp = fopen($path, 'w');
  594. fprintf($fp, chr(0xEF).chr(0xBB).chr(0xBF));
  595. fputcsv($fp, array("Host", "Ref", "P", "C", "D", "U"));
  596. foreach ($towrite as $fields) {
  597. fputcsv($fp, $fields);
  598. }
  599. fclose($fp);
  600. return true;
  601. }else{
  602. return false;
  603. }
  604. }
  605.  
  606. function writeOWASPTable($vuln, $path){
  607. $towrite = array();
  608. for ($i=0; $i < sizeof($vuln) ; $i++) {
  609. if(in_array($vuln[$i]['owasp'], array_column($towrite, 'owaspId'))){
  610. $towrite[$vuln[$i]['owasp']]['no']++;
  611. }else{
  612. $towrite[$vuln[$i]['owasp']]['owaspId'] = $vuln[$i]['owasp'];
  613. $towrite[$vuln[$i]['owasp']]['no'] = 1;
  614. }
  615. }
  616. if(sizeof($towrite) > 0){
  617. $fp = fopen($path, 'w');
  618. fprintf($fp, chr(0xEF).chr(0xBB).chr(0xBF));
  619. foreach ($towrite as $fields) {
  620. fputcsv($fp, $fields);
  621. }
  622. fclose($fp);
  623. return true;
  624. }else{
  625. return false;
  626. }
  627. }
  628.  
  629. ?>
Buy Me A Coffee