| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 4247b45 commit 8d841bc
2 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -386,6 +386,7 @@ public static String encodeForHTML(Object param) { | |||
| 386 | 386 | ||
| 387 | 387 | String value = "objectTypeUnknown"; | |
| 388 | 388 | if (param instanceof String) { | |
| 389 | + value = (String) param; | ||
| 389 | 390 | } else if (param instanceof java.io.InputStream) { | |
| 390 | 391 | byte[] buff = new byte[1000]; | |
| 391 | 392 | int length = 0; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -19,19 +19,21 @@ | |||
| 19 | 19 | ||
| 20 | 20 | import java.io.File; | |
| 21 | 21 | import java.io.FileInputStream; | |
| 22 | + import java.util.ArrayList; | ||
| 22 | 23 | import java.util.List; | |
| 23 | 24 | import javax.xml.parsers.DocumentBuilder; | |
| 24 | 25 | import javax.xml.parsers.DocumentBuilderFactory; | |
| 25 | 26 | import org.owasp.benchmark.score.BenchmarkScore; | |
| 26 | 27 | import org.owasp.benchmark.score.TestCaseResult; | |
| 27 | 28 | import org.owasp.benchmark.score.TestSuiteResults; | |
| 28 | 29 | import org.w3c.dom.Document; | |
| 30 | + import org.w3c.dom.NamedNodeMap; | ||
| 29 | 31 | import org.w3c.dom.Node; | |
| 30 | 32 | import org.xml.sax.InputSource; | |
| 31 | 33 | ||
| 32 | 34 | public class AppScanDynamicReader2 extends Reader { | |
| 33 | 35 | ||
| 34 | - // This is the new AppScan Dynamnic reader, where they generate ".xml" files. | ||
| 36 | + // This is the new AppScan Dynamic reader, where they generate ".xml" files. | ||
| 35 | 37 | ||
| 36 | 38 | public TestSuiteResults parse(File f) throws Exception { | |
| 37 | 39 | ||
@@ -44,6 +46,10 @@ public TestSuiteResults parse(File f) throws Exception { | |||
| 44 | 46 | ||
| 45 | 47 | Node root = doc.getDocumentElement(); | |
| 46 | 48 | Node scanInfo = getNamedChild("scan-information", root); | |
| 49 | + | ||
| 50 | + Node scanConfiguration = getNamedChild("scan-configuration", root); | ||
| 51 | + String startingUrl = getNamedChild("starting-url", scanConfiguration).getTextContent(); | ||
| 52 | + | ||
| 47 | 53 | TestSuiteResults tr = | |
| 48 | 54 | new TestSuiteResults("IBM AppScan Dynamic", true, TestSuiteResults.ToolType.DAST); | |
| 49 | 55 | ||
@@ -58,130 +64,201 @@ public TestSuiteResults parse(File f) throws Exception { | |||
| 58 | 64 | Node allIssues = getNamedChild("url-group", root); | |
| 59 | 65 | List<Node> vulnerabilities = getNamedChildren("item", allIssues); | |
| 60 | 66 | ||
| 67 | + Node allIssueVariants = getNamedChild("issue-group", root); | ||
| 68 | + List<Node> variants = getNamedChildren("item", allIssueVariants); | ||
| 69 | + | ||
| 61 | 70 | // Loop through all the vulnerabilities | |
| 62 | 71 | for (Node vulnerability : vulnerabilities) { | |
| 63 | - | ||
| 64 | - // First get the type of vuln, and if we don't care about that type, move on | ||
| 65 | 72 | String issueType = getNamedChild("issue-type", vulnerability).getTextContent(); | |
| 66 | 73 | ||
| 67 | 74 | String url = getNamedChild("name", vulnerability).getTextContent(); | |
| 68 | 75 | // to give DAST tools some credit, if they report a similar vuln in a different area, we | |
| 69 | 76 | // count it. | |
| 70 | 77 | // e.g., SQLi in the XPATHi tests. To do that, we have to pull out the vuln type from | |
| 71 | 78 | // the URL. | |
| 72 | - String urlElements[] = url.split("/"); | ||
| 73 | - String testArea = | ||
| 74 | - urlElements[urlElements.length - 2].split("-")[0]; // .split strips off the -## | ||
| 75 | - // System.out.println("Candidate test area is: " + testArea); | ||
| 76 | - | ||
| 77 | - int vtype = cweLookup(issueType, testArea); | ||
| 78 | - // System.out.println("Vuln type: " + issueType + " has CWE of: " + vtype); | ||
| 79 | - | ||
| 80 | - // Then get the filename containing the vuln. And if not in a test case, skip it. | ||
| 81 | - // Parse out test number from: | ||
| 82 | - // https://localhost:port/benchmark/testarea-##/BenchmarkTest02603 | ||
| 83 | - int startOfTestCase = url.lastIndexOf("/") + 1; | ||
| 84 | - String testcase = url.substring(startOfTestCase, url.length()); | ||
| 85 | - testcase = | ||
| 86 | - testcase.split("\\.")[ | ||
| 87 | - 0]; // if test case has extension (e.g., BenchmarkTestCase#####.html), | ||
| 88 | - // strip it off. | ||
| 89 | - // System.out.println("Candidate test case is: " + testcase); | ||
| 90 | - if (testcase.startsWith(BenchmarkScore.TESTCASENAME)) { | ||
| 91 | - int tn = -1; | ||
| 92 | - String testno = testcase.substring(BenchmarkScore.TESTCASENAME.length()); | ||
| 93 | - try { | ||
| 94 | - tn = Integer.parseInt(testno); | ||
| 95 | - } catch (NumberFormatException e) { | ||
| 96 | - e.printStackTrace(); | ||
| 97 | - } | ||
| 98 | - | ||
| 99 | - // if (tn == -1) System.out.println("Found vuln outside of test case of type: " + | ||
| 100 | - // issueType); | ||
| 101 | 79 | ||
| 102 | - // Add the vuln found in a test case to the results for this tool | ||
| 103 | - TestCaseResult tcr = new TestCaseResult(); | ||
| 104 | - tcr.setNumber(tn); | ||
| 105 | - tcr.setCategory(issueType); // TODO: Is this right? | ||
| 106 | - tcr.setCWE(vtype); | ||
| 107 | - tcr.setEvidence(issueType); | ||
| 80 | + NamedNodeMap itemNode = vulnerability.getAttributes(); | ||
| 81 | + String variantItemID = itemNode.getNamedItem("id").getNodeValue(); | ||
| 108 | 82 | ||
| 83 | + List<String> testCaseElementsFromVariants = | ||
| 84 | + variantLookup(issueType, variantItemID, startingUrl, variants); | ||
| 85 | + if (testCaseElementsFromVariants.isEmpty()) { | ||
| 86 | + // Handle non-variant issue types , Older xml format as in 9.x release versions and | ||
| 87 | + // before | ||
| 88 | + // First get the type of vuln, and if we don't care about that type, move on | ||
| 89 | + TestCaseResult tcr = TestCaseLookup(issueType, url); | ||
| 109 | 90 | tr.put(tcr); | |
| 91 | + } else { | ||
| 92 | + // Handle issues which are Variants, new xml format after 10.x release | ||
| 93 | + for (String testArea : testCaseElementsFromVariants) { | ||
| 94 | + TestCaseResult tcr = TestCaseLookup(issueType, testArea); | ||
| 95 | + tr.put(tcr); | ||
| 96 | + } | ||
| 110 | 97 | } | |
| 111 | 98 | } | |
| 99 | + | ||
| 112 | 100 | return tr; | |
| 113 | 101 | } | |
| 114 | 102 | ||
| 115 | - // e.g., 3 Hour(s) 7 Minute(s) 58 Second(s) | ||
| 116 | - /* private String parseTime(String message) { | ||
| 117 | - String[] parts = message.split( "\\) "); | ||
| 118 | - String hours = parts[0].substring( 0, parts[0].indexOf(' ') ).trim(); | ||
| 119 | - if ( hours.length() < 2 ) hours = "0" + hours; | ||
| 120 | - String mins = parts[1].substring( 0, parts[1].indexOf(' ') ).trim(); | ||
| 121 | - if ( mins.length() < 2 ) mins = "0" + mins; | ||
| 122 | - String secs = parts[2].substring( 0, parts[2].indexOf(' ') ).trim(); | ||
| 123 | - if ( secs.length() < 2 ) secs = "0" + secs; | ||
| 124 | - return hours + ":" + mins + ":" + secs; | ||
| 103 | + /// Issues which are not variants | ||
| 104 | + private static TestCaseResult TestCaseLookup(String issueType, String url) { | ||
| 105 | + TestCaseResult tcr = new TestCaseResult(); | ||
| 106 | + String urlElements[] = url.split("/"); | ||
| 107 | + String testArea = | ||
| 108 | + urlElements[urlElements.length - 2].split("-")[0]; // .split strips off the -## | ||
| 109 | + | ||
| 110 | + int vtype = cweLookup(issueType, testArea); | ||
| 111 | + | ||
| 112 | + // Then get the filename containing the vuln. And if not in a test case, skip it. | ||
| 113 | + // Parse out test number from: | ||
| 114 | + // https://localhost:port/benchmark/testarea-##/BenchmarkTest02603 | ||
| 115 | + int startOfTestCase = url.lastIndexOf("/") + 1; | ||
| 116 | + String testcase = url.substring(startOfTestCase, url.length()); | ||
| 117 | + // if test case has extension (e.g., BenchmarkTestCase#####.html), strip it off. | ||
| 118 | + testcase = testcase.split("\\.")[0]; | ||
| 119 | + // System.out.println("Candidate test case is: " + testcase); | ||
| 120 | + if (testcase.startsWith(BenchmarkScore.TESTCASENAME)) { | ||
| 121 | + int tn = -1; | ||
| 122 | + String testno = testcase.substring(BenchmarkScore.TESTCASENAME.length()); | ||
| 123 | + try { | ||
| 124 | + tn = Integer.parseInt(testno); | ||
| 125 | + } catch (NumberFormatException e) { | ||
| 126 | + e.printStackTrace(); | ||
| 127 | + } | ||
| 128 | + | ||
| 129 | + // if (tn == -1) System.out.println("Found vuln outside of test case of type: " + | ||
| 130 | + // issueType); | ||
| 131 | + | ||
| 132 | + // Add the vuln found in a test case to the results for this tool | ||
| 133 | + tcr.setNumber(tn); | ||
| 134 | + tcr.setCategory(issueType); // TODO: Is this right? | ||
| 135 | + tcr.setCWE(vtype); | ||
| 136 | + tcr.setEvidence(issueType); | ||
| 125 | 137 | } | |
| 126 | - */ | ||
| 138 | + return tcr; | ||
| 139 | + } | ||
| 140 | + | ||
| 141 | + // Fetch Issues listed as variants, to cater to post 10.x release xml format | ||
| 142 | + private static List<String> variantLookup( | ||
| 143 | + String issueType, String itemID, String startingUrl, List<Node> variants) { | ||
| 144 | + List<String> testCaseElementsFromVariants = new ArrayList<String>(); | ||
| 145 | + | ||
| 146 | + // System.out.println("Variant Lookup Item ID: " + itemID); | ||
| 147 | + | ||
| 148 | + for (Node variant : variants) { | ||
| 149 | + String variantUrlRefId = getNamedChild("url", variant).getTextContent().trim(); | ||
| 150 | + String variantIssueType = getNamedChild("issue-type", variant).getTextContent().trim(); | ||
| 151 | + // System.out.println("Variant Url Ref ID: " + variantUrlRefId); | ||
| 152 | + | ||
| 153 | + // Add the record only if the issue type matches for the relevant variants | ||
| 154 | + if (issueType.equals(variantIssueType) && itemID.equals(variantUrlRefId)) { | ||
| 155 | + Node variantNodes = getNamedChild("variant-group", variant); | ||
| 156 | + List<Node> variantNodeChildren = getNamedChildren("item", variantNodes); | ||
| 157 | + for (Node variantNodeChild : variantNodeChildren) { | ||
| 158 | + String httpTraffic = | ||
| 159 | + getNamedChild("test-http-traffic", variantNodeChild).getTextContent(); | ||
| 160 | + String[] variantUrl = httpTraffic.split(" "); | ||
| 161 | + | ||
| 162 | + String benchMarkTestCase = variantUrl[1].trim(); | ||
| 163 | + | ||
| 164 | + if (benchMarkTestCase.contains("BenchmarkTest")) { | ||
| 165 | + String urlElements[] = benchMarkTestCase.split("/"); | ||
| 166 | + | ||
| 167 | + String testAreaUrl = | ||
| 168 | + startingUrl | ||
| 169 | + + urlElements[urlElements.length - 2] | ||
| 170 | + + "/" | ||
| 171 | + + urlElements[urlElements.length - 1]; | ||
| 172 | + String testArea = testAreaUrl.split("\\?")[0]; // .split strips off the -## | ||
| 173 | + | ||
| 174 | + if (testArea.contains("BenchmarkTest")) | ||
| 175 | + testCaseElementsFromVariants.add(testArea); | ||
| 176 | + } | ||
| 177 | + } | ||
| 178 | + } | ||
| 179 | + } | ||
| 180 | + | ||
| 181 | + return testCaseElementsFromVariants; | ||
| 182 | + } | ||
| 183 | + | ||
| 127 | 184 | private static int cweLookup(String vtype, String testArea) { | |
| 128 | - int cwe = cweLookup(vtype); | ||
| 129 | - if ("xpathi".equals(testArea) && cwe == 89) cwe = 643; // CWE for xpath injection | ||
| 130 | - if ("ldapi".equals(testArea) && cwe == 89) cwe = 90; // CWE for xpath injection | ||
| 185 | + int cwe = cweLookup(vtype); // Do the standard CWE lookup | ||
| 186 | + | ||
| 187 | + // Then map some to other CWEs based on the test area being processed. | ||
| 188 | + if ("xpathi".equals(testArea) && cwe == 89) cwe = 643; // CWE for XPath injection | ||
| 189 | + if ("ldapi".equals(testArea) && cwe == 89) cwe = 90; // CWE for LDAP injection | ||
| 131 | 190 | ||
| 132 | 191 | return cwe; | |
| 133 | 192 | } | |
| 134 | 193 | ||
| 135 | 194 | private static int cweLookup(String vtype) { | |
| 136 | 195 | switch (vtype) { | |
| 137 | - case "attBlindSqlInjectionStrings": | ||
| 138 | - return 89; // Score worse or better? | ||
| 139 | - case "attCachedSSL": | ||
| 140 | - return 00; | ||
| 196 | + case "attDirectoryFound": | ||
| 197 | + case "attDirOptions": | ||
| 198 | + case "attFileUnix": | ||
| 199 | + return 22; | ||
| 200 | + | ||
| 201 | + case "attApplicationRemoteCodeExecutionAdns": | ||
| 141 | 202 | case "attCodeInjectionInSystemCall": | |
| 142 | - return 78; // Score worse or better? | ||
| 203 | + case "attCommandInjectionAdns": | ||
| 204 | + case "attCommandInjectionUnixTws": | ||
| 205 | + case "attFileParamPipe": | ||
| 206 | + return 78; | ||
| 207 | + | ||
| 143 | 208 | case "attCrossSiteScripting": | |
| 144 | 209 | return 79; | |
| 145 | - case "attJSCookie": | ||
| 146 | - return 00; | ||
| 147 | - // case "attLinkInjection" : return 00; | ||
| 210 | + | ||
| 211 | + case "attBlindSqlInjectionStrings": | ||
| 212 | + case "attSqlInjectionChecks": | ||
| 213 | + return 89; | ||
| 214 | + | ||
| 215 | + case "attLDAPInjection": | ||
| 216 | + case "attLDAPInjection2": | ||
| 217 | + case "attBlindLDAPInjection": | ||
| 218 | + return 90; | ||
| 219 | + | ||
| 220 | + case "SHA1CipherSuites": | ||
| 221 | + return 327; // Better if set to 327? | ||
| 222 | + | ||
| 223 | + case "passParamGET": | ||
| 224 | + return 523; | ||
| 225 | + | ||
| 148 | 226 | case "attRespCookieNotSecureSSL": | |
| 149 | 227 | return 614; | |
| 150 | - case "attSqlInjectionChecks": | ||
| 151 | - return 89; // Score worse or better? | ||
| 228 | + | ||
| 229 | + case "attXPathInjection": | ||
| 230 | + case "attBlindXpathInjectionSingleQuote": | ||
| 231 | + case "attBlindXPathInjection": | ||
| 232 | + return 643; | ||
| 233 | + | ||
| 234 | + // These don't map to anything we care about | ||
| 235 | + case "attContentSecurityPolicyObjectSrc": | ||
| 236 | + case "attContentSecurityPolicyScriptSrc": | ||
| 237 | + case "attCachedSSL": | ||
| 238 | + case "attJSCookie": | ||
| 239 | + // case "attLinkInjection" : return 00; | ||
| 152 | 240 | case "attUndefinedState": | |
| 153 | - return 00; | ||
| 154 | 241 | case "bodyParamsInQuery": | |
| 155 | - return 00; | ||
| 156 | 242 | case "ContentSecurityPolicy": | |
| 157 | - return 00; | ||
| 158 | 243 | case "ContentTypeOptions": | |
| 159 | - return 00; | ||
| 160 | - | ||
| 161 | - // case "GD_EmailAddress" : return 00; | ||
| 244 | + case "GD_EmailAddress": | ||
| 162 | 245 | case "GETParamOverSSL": | |
| 163 | - return 00; | ||
| 164 | - // case "GV_SQLErr" : return 89; // Score worse or better with this or 00? | ||
| 165 | - // case "HSTS" : return 00; | ||
| 246 | + case "GV_SQLErr": | ||
| 247 | + // case "HSTS" : return 00; | ||
| 166 | 248 | ||
| 167 | - // Microsoft MHTML XSS - Giving AppScan 'credit' for this introduces ~2.4% False | ||
| 168 | - // Positives and no real ones so I disabled it instead | ||
| 249 | + // Microsoft MHTML XSS - Giving AppScan XSS 'credit' for this introduces ~2.4% False | ||
| 250 | + // Positives and no real ones so I (shivababuh) disabled it instead | ||
| 169 | 251 | case "MHTMLXSS": | |
| 170 | - return 00; | ||
| 171 | - | ||
| 172 | - // case "OpenSource" : return 00; // Known vuln in open source lib. | ||
| 173 | - // case "phishingInFrames" : return 00; | ||
| 174 | - case "SHA1CipherSuites": | ||
| 175 | - return 327; // Better if set to 327? | ||
| 252 | + // case "OpenSource" : return 00; // Known vuln in open source lib. | ||
| 253 | + // case "phishingInFrames" : return 00; | ||
| 176 | 254 | case "ShellShockCheck": | |
| 177 | - return 00; // don't care | ||
| 178 | 255 | case "SriSupport": | |
| 179 | - return 00; // don't care | ||
| 180 | - // case "SSL_CertWithBadCN" : return 00; // don't care | ||
| 181 | - // case "XSSProtectionHeader" : return 00; | ||
| 256 | + // case "SSL_CertWithBadCN" : return 00; | ||
| 257 | + // case "XSSProtectionHeader" : return 00; | ||
| 258 | + return 00; | ||
| 182 | 259 | ||
| 183 | 260 | default: | |
| 184 | - System.out.println("Identified unknown type of: " + vtype); | ||
| 261 | + System.out.println("Identified unknown vulnerability type of: " + vtype); | ||
| 185 | 262 | } | |
| 186 | 263 | return 0; | |
| 187 | 264 | } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments