Codebase list faraday-plugins / 007869eb-f18c-4730-b9e2-83a9758038bb/main
New upstream release. Kali Janitor 2 years ago
10 changed file(s) with 211 addition(s) and 23 deletion(s). Raw diff Collapse all Expand all
0 Nov 19th, 2021
0 FIX extrainfo of netsparker plugin
0 Add nuclei_legacy plugin
0 1.5.7 [Nov 19th, 2021]:
1 ---
2 * FIX extrainfo of netsparker plugin
3 * Add nuclei_legacy plugin
4
05 1.5.6 [Nov 10th, 2021]:
16 ---
27 * FIX issue with acunetix plugin
8
39 * FIX typo in nikto plugin
410
511 1.5.5 [Oct 21st, 2021]:
0 faraday-plugins (1.5.7-0kali1) UNRELEASED; urgency=low
1
2 * New upstream release.
3
4 -- Kali Janitor <[email protected]> Mon, 22 Nov 2021 05:53:27 -0000
5
06 faraday-plugins (1.5.6-0kali1) kali-dev; urgency=medium
17
28 * New upstream version 1.5.6
0 __version__ = '1.5.6'
0 __version__ = '1.5.7'
33 See the file 'doc/LICENSE' for the license information
44
55 """
6 import sys
67 import re
78 import xml.etree.ElementTree as ET
89
3233 @param netsparker_xml_filepath A proper xml generated by netsparker
3334 """
3435
35 def __init__(self, xml_output):
36 def __init__(self, xml_output, plugin):
3637 self.filepath = xml_output
38 self.plugin = plugin
3739
3840 tree = self.parse_xml(xml_output)
3941 if tree:
5355 try:
5456 tree = ET.fromstring(xml_output)
5557 except SyntaxError as err:
56 self.logger.error("SyntaxError: %s. %s" % (err, xml_output))
58 self.plugin.logger.error("SyntaxError: %s. %s" % (err, xml_output))
5759 return None
5860
5961 return tree
116118
117119 self.extra = []
118120 for v in item_node.findall("extrainformation/info"):
119 name = v.get('name')
120 if name:
121 self.extra.append("{name}:{v.text}")
121 name_tag = v.find('name')
122 value_tag = v.find('value')
123 if name_tag is not None:
124 self.extra.append(f"{name_tag.text}:{value_tag.text}")
122125
123126 self.node = item_node
124127 self.node = item_node.find("classification")
189192 self.options = None
190193
191194 def parseOutputString(self, output):
192 parser = NetsparkerXmlParser(output)
195 parser = NetsparkerXmlParser(output, self)
193196 host_names_resolve = {}
194197 for i in parser.items:
195198
33 See the file 'doc/LICENSE' for the license information
44
55 """
6 import socket
6 import subprocess
77 import re
8 import sys
89 import json
910 import dateutil
10 from collections import defaultdict
1111 from urllib.parse import urlparse
12 from packaging import version
1213 from faraday_plugins.plugins.plugin import PluginMultiLineJsonFormat
1314 from faraday_plugins.plugins.plugins_utils import resolve_hostname
1415
3132 super().__init__(*arg, **kwargs)
3233 self.id = "nuclei"
3334 self.name = "Nuclei"
34 self.plugin_version = "1.0.1"
35 self.version = "2.3.8"
36 self.json_keys = {"matched", "templateID", "host"}
35 self.plugin_version = "1.0.2"
36 self.version = "2.5.3"
37 self.json_keys = {"matched-at", "template-id", "host"}
3738 self._command_regex = re.compile(r'^(sudo nuclei|nuclei|\.\/nuclei|^.*?nuclei)\s+.*?')
3839 self.xml_arg_re = re.compile(r"^.*(-o\s*[^\s]+).*$")
3940 self._use_temp_file = True
6263 status='open',
6364 version='',
6465 description='web server')
65 matched = vuln_dict.get('matched')
66 matched_data = urlparse(matched)
66 matched = vuln_dict.get('matched-at', '')
67 if matched:
68 matched_data = urlparse(matched)
69 else:
70 print('Version not supported, use nuclei 2.5.3 or higher')
71 sys.exit(1)
6772 reference = vuln_dict["info"].get('reference', [])
6873 if not reference:
6974 reference = []
96101 method = request.split(" ")[0]
97102 else:
98103 method = ""
99 data = [f"Matched: {vuln_dict.get('matched')}",
104
105 data = [f"Matched: {vuln_dict.get('matched-at')}",
100106 f"Tags: {vuln_dict['info'].get('tags', '')}",
101 f"Template ID: {vuln_dict['templateID']}"]
107 f"Template ID: {vuln_dict.get('template-id', '')}"]
102108
103109 name = vuln_dict["info"].get("name")
104110 run_date = vuln_dict.get('timestamp')
123129 params=matched_data.params,
124130 path=matched_data.path,
125131 data="\n".join(data),
126 external_id=f"NUCLEI-{vuln_dict.get('templateID', '')}",
132 external_id=f"NUCLEI-{vuln_dict.get('template-id', '')}",
127133 run_date=run_date
128134 )
129
135
130136 def processCommandString(self, username, current_path, command_string):
131 """
132 Adds the -oX parameter to get xml output to the command string that the
133 user has set.
134 """
135137 super().processCommandString(username, current_path, command_string)
136138 arg_match = self.xml_arg_re.match(command_string)
137139 if arg_match is None:
141143 else:
142144 return re.sub(arg_match.group(1),
143145 r"--json -irr -o %s" % self._output_file_path,
144 command_string)
146 command_string)
147
148 def canParseCommandString(self, current_input):
149 can_parse = super().canParseCommandString(current_input)
150 if can_parse:
151 try:
152 proc = subprocess.Popen([self.command, '-version'], stderr=subprocess.PIPE)
153 output = proc.stderr.read()
154 match = re.search(r"Current Version: ([0-9.]+)", output.decode('UTF-8'))
155 if match:
156 nuclei_version = match.groups()[0]
157 return version.parse(nuclei_version) >= version.parse("2.5.3")
158 else:
159 return False
160 except Exception as e:
161 return False
145162
146163
147164 def createPlugin(ignore_info=False):
0 import subprocess
1 import re
2 import json
3 import dateutil
4 from packaging import version
5 from urllib.parse import urlparse
6 from faraday_plugins.plugins.plugin import PluginMultiLineJsonFormat
7 from faraday_plugins.plugins.plugins_utils import resolve_hostname
8
9 __author__ = "Emilio Couto"
10 __copyright__ = "Copyright (c) 2021, Faraday Security"
11 __credits__ = ["Emilio Couto"]
12 __license__ = ""
13 __version__ = "1.0.0"
14 __maintainer__ = "Emilio Couto"
15 __email__ = "[email protected]"
16 __status__ = "Development"
17
18
19 class NucleiLegacyPlugin(PluginMultiLineJsonFormat):
20 """ Handle the Nuclei tool. Detects the output of the tool
21 and adds the information to Faraday.
22 """
23
24 def __init__(self, *arg, **kwargs):
25 super().__init__(*arg, **kwargs)
26 self.id = "nuclei_legacy"
27 self.name = "Nuclei"
28 self.plugin_version = "1.0.0"
29 self.version = "2.5.2"
30 self._command_regex = re.compile(r'^(sudo nuclei|nuclei|\.\/nuclei|^.*?nuclei)\s+.*?')
31 self.xml_arg_re = re.compile(r"^.*(-o\s*[^\s]+).*$")
32 self._use_temp_file = True
33 self._temp_file_extension = "json"
34 self.json_keys = {"matched", "templateID", "host"}
35
36 def parseOutputString(self, output, debug=False):
37 for vuln_json in filter(lambda x: x != '', output.split("\n")):
38 vuln_dict = json.loads(vuln_json)
39 host = vuln_dict.get('host')
40 url_data = urlparse(host)
41 ip = vuln_dict.get("ip", resolve_hostname(url_data.hostname))
42 host_id = self.createAndAddHost(
43 name=ip,
44 hostnames=[url_data.hostname])
45 port = url_data.port
46 if not port:
47 if url_data.scheme == 'https':
48 port = 443
49 else:
50 port = 80
51 service_id = self.createAndAddServiceToHost(
52 host_id,
53 name=url_data.scheme,
54 ports=port,
55 protocol="tcp",
56 status='open',
57 version='',
58 description='web server')
59 matched = vuln_dict.get('matched')
60 matched_data = urlparse(matched)
61 reference = vuln_dict["info"].get('reference', [])
62 if not reference:
63 reference = []
64 else:
65 if isinstance(reference, str):
66 if re.match('^- ', reference):
67 reference = list(filter(None, [re.sub('^- ', '', elem) for elem in reference.split('\n')]))
68 else:
69 reference = [reference]
70 references = vuln_dict["info"].get('references', [])
71 if references:
72 if isinstance(references, str):
73 if re.match('^- ', references):
74 references = list(filter(None, [re.sub('^- ', '', elem) for elem in references.split('\n')]))
75 else:
76 references = [references]
77 else:
78 references = []
79 cwe = vuln_dict['info'].get('cwe', [])
80 capec = vuln_dict['info'].get('capec', [])
81 refs = sorted(list(set(reference + references + cwe + capec)))
82 tags = vuln_dict['info'].get('tags', [])
83 if isinstance(tags, str):
84 tags = tags.split(',')
85 impact = vuln_dict['info'].get('impact')
86 resolution = vuln_dict['info'].get('resolution', '')
87 easeofresolution = vuln_dict['info'].get('easeofresolution')
88 request = vuln_dict.get('request', '')
89 if request:
90 method = request.split(" ")[0]
91 else:
92 method = ""
93 data = [f"Matched: {vuln_dict.get('matched', '')}",
94 f"Tags: {vuln_dict['info'].get('tags', '')}",
95 f"Template ID: {vuln_dict.get('templateID', '')}"]
96
97 name = vuln_dict["info"].get("name")
98 run_date = vuln_dict.get('timestamp')
99 if run_date:
100 run_date = dateutil.parser.parse(run_date)
101 self.createAndAddVulnWebToService(
102 host_id,
103 service_id,
104 name=name,
105 desc=vuln_dict["info"].get("description", name),
106 ref=refs,
107 severity=vuln_dict["info"].get('severity'),
108 tags=tags,
109 impact=impact,
110 resolution=resolution,
111 easeofresolution=easeofresolution,
112 website=host,
113 request=request,
114 response=vuln_dict.get('response', ''),
115 method=method,
116 query=matched_data.query,
117 params=matched_data.params,
118 path=matched_data.path,
119 data="\n".join(data),
120 external_id=f"NUCLEI-{vuln_dict.get('templateID', '')}",
121 run_date=run_date
122 )
123
124 def processCommandString(self, username, current_path, command_string):
125 super().processCommandString(username, current_path, command_string)
126 arg_match = self.xml_arg_re.match(command_string)
127 if arg_match is None:
128 return re.sub(r"(^.*?nuclei)",
129 r"\1 --json -irr -o %s" % self._output_file_path,
130 command_string)
131 else:
132 return re.sub(arg_match.group(1),
133 r"--json -irr -o %s" % self._output_file_path,
134 command_string)
135
136 def canParseCommandString(self, current_input):
137 can_parse = super().canParseCommandString(current_input)
138 if can_parse:
139 try:
140 proc = subprocess.Popen([self.command, '-version'], stderr=subprocess.PIPE)
141 output = proc.stderr.read()
142 match = re.search(r"Current Version: ([0-9.]+)", output.decode('UTF-8'))
143 if match:
144 nuclei_version = match.groups()[0]
145 return version.parse(nuclei_version) <= version.parse("2.5.2")
146 else:
147 return False
148 except Exception as e:
149 return False
150
151 def createPlugin(ignore_info=False):
152 return NucleiLegacyPlugin(ignore_info=ignore_info)