1+ /**
2+ * OWASP Benchmark Project
3+ *
4+ * This file is part of the Open Web Application Security Project (OWASP)
5+ * Benchmark Project For details, please see
6+ * <a href="https://www.owasp.org/index.php/Benchmark">https://www.owasp.org/index.php/Benchmark</a>.
7+ *
8+ * The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms
9+ * of the GNU General Public License as published by the Free Software Foundation, version 2.
10+ *
11+ * The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
12+ * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+ * GNU General Public License for more details
14+ *
15+ * @author Dave Wichers <a href="https://www.aspectsecurity.com">Aspect Security</a>
16+ * @created 2015
17+ */
18+
19+ package org .owasp .benchmark .score .parsers ;
20+
21+ import java .io .File ;
22+ import java .io .FileInputStream ;
23+ import java .net .URI ;
24+ import java .net .URISyntaxException ;
25+ import java .text .SimpleDateFormat ;
26+ import java .util .List ;
27+
28+ import javax .xml .parsers .DocumentBuilder ;
29+ import javax .xml .parsers .DocumentBuilderFactory ;
30+
31+ import org .w3c .dom .Document ;
32+ import org .w3c .dom .Node ;
33+ import org .xml .sax .InputSource ;
34+
35+ public class ArachniReader extends Reader {
36+
37+ // <report xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/Arachni/arachni/v2.0dev/components/reporters/xml/schema.xsd">
38+ // <version>2.0dev</version>
39+ // <start_datetime>2015-08-17T14:21:14+03:00</start_datetime>
40+ // <finish_datetime>2015-08-17T14:44:14+03:00</finish_datetime>
41+ // <sitemap>
42+
43+
44+ public TestResults parse (File f ) throws Exception {
45+ DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory .newInstance ();
46+ DocumentBuilder docBuilder = docBuilderFactory .newDocumentBuilder ();
47+ InputSource is = new InputSource ( new FileInputStream (f ) );
48+ Document doc = docBuilder .parse (is );
49+
50+ TestResults tr = new TestResults ( "Arachni" , false , TestResults .ToolType .DAST );
51+
52+ Node arachni = doc .getDocumentElement ();
53+ String version = getNamedChild ( "version" , arachni ).getTextContent ();
54+ tr .setToolVersion ( version );
55+
56+ String start = getNamedChild ( "start_datetime" , arachni ).getTextContent ();
57+ String stop = getNamedChild ( "finish_datetime" , arachni ).getTextContent ();
58+ tr .setTime ( calculateTime ( start , stop ));
59+
60+ Node issues = getNamedChild ( "issues" , arachni );
61+ List <Node > issueList = getNamedChildren ( "issue" , issues );
62+
63+ for ( Node issue : issueList ) {
64+ try {
65+ TestCaseResult tcr = parseArachniIssue (issue );
66+ if (tcr != null ) {
67+ // System.out.println( tcr.getNumber() + " " + tcr.getName() + " -> " + tcr.getCWE() + "\t" + tcr.getEvidence() );
68+ tr .put (tcr );
69+ }
70+ } catch ( Exception e ) {
71+ // print and continue
72+ e .printStackTrace ();
73+ }
74+ }
75+ return tr ;
76+ }
77+
78+ // <issue>
79+ // <name>Cross-Site Scripting (XSS)</name>
80+ // <description>
81+ //Client-side scripts are used extensively by modern web applications.
82+ //</description>
83+ // <remedy_guidance>
84+ //</remedy_guidance>
85+ // <remedy_code/>
86+ // <severity>high</severity>
87+ // <check>
88+ // <name>XSS</name>
89+ // <description>
90+ //Injects an HTML element into page inputs and then parses the HTML markup of
91+ //</description>
92+ // <author>Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com> </author>
93+ // <version>0.4.4</version>
94+ // <shortname>xss</shortname>
95+ // </check>
96+ // <cwe>79</cwe>
97+ // <digest>3396861445</digest>
98+ // <references>
99+ // </references>
100+ // <vector>
101+ // <class>Arachni::Element::Form</class>
102+ // <type>form</type>
103+ // <url>https://127.0.0.2:8443/benchmark/BenchmarkTest00397.html</url>
104+ // <action>https://127.0.0.2:8443/benchmark/BenchmarkTest00397</action>
105+ // <source>/form></source>
106+ // <method>post</method>
107+ // <affected_input_name>vector</affected_input_name>
108+ // <inputs>
109+ // <input name="vector" value="Singing"/>
110+ // <input name="foo" value="bar"/>
111+ // </inputs>
112+ // </vector>
113+ // </issue>
114+
115+ // 2015-08-17T14:21:14+03:00
116+ private SimpleDateFormat sdf = new SimpleDateFormat ("yyyy-MM-dd'T'HH:mm:ssXXX" );
117+ private String calculateTime (String submitted , String published ) {
118+ try {
119+ long start = sdf .parse ( submitted ).getTime ();
120+ long finish = sdf .parse ( published ).getTime ();
121+ return TestResults .formatTime ( finish - start );
122+ } catch ( Exception e ) {
123+ e .printStackTrace ();
124+ return "Unknown" ;
125+ }
126+ }
127+
128+
129+
130+ private TestCaseResult parseArachniIssue (Node flaw ) throws URISyntaxException {
131+ TestCaseResult tcr = new TestCaseResult ();
132+ Node rule = getNamedChild ("cwe" , flaw );
133+ if ( rule != null ) {
134+ tcr .setCWE ( cweLookup ( rule .getTextContent () ) );
135+ }
136+
137+ String cat = getNamedChild ("name" , flaw ).getTextContent ();
138+ tcr .setCategory ( cat );
139+
140+ // not used
141+ String conf = getNamedChild ( "severity" , flaw ).getTextContent ();
142+
143+ // confidence not available
144+ // tcr.setConfidence( Integer.parseInt( conf ) );
145+
146+ tcr .setEvidence ( cat );
147+
148+ Node vector = getNamedChild ( "vector" , flaw );
149+ String uri = getNamedChild ( "url" , vector ).getTextContent ();
150+ URI url = new URI ( uri );
151+ String testfile = url .getPath ();
152+ testfile = testfile .substring ( testfile .lastIndexOf ('/' ) +1 );
153+
154+ if ( testfile .startsWith ( "BenchmarkTest" ) ) {
155+ String testno = testfile .substring ("BenchmarkTest" .length ());
156+ if ( testno .endsWith ( ".html" ) ) {
157+ testno = testno .substring (0 , testno .length () -5 );
158+ }
159+ try {
160+ tcr .setNumber ( Integer .parseInt ( testno ) );
161+ return tcr ;
162+ } catch ( NumberFormatException e ) {
163+ System .out .println ( "> Parse error " + testfile + ":: " + testno );
164+ }
165+ }
166+ return null ;
167+ }
168+
169+
170+ private int cweLookup (String orig ) {
171+
172+ switch ( orig ) {
173+ }
174+
175+ return Integer .parseInt ( orig );
176+ }
177+
178+ }
179+
180+
0 commit comments