"""
Faraday Penetration Test IDE
Copyright (C) 2013 Infobyte LLC (http://www.infobytesec.com/)
See the file 'doc/LICENSE' for the license information
"""
import re
import os
from faraday_plugins.plugins.plugin import PluginBase
__author__ = "Francisco Amato"
__copyright__ = "Copyright (c) 2013, Infobyte LLC"
__credits__ = ["Francisco Amato"]
__license__ = ""
__version__ = "1.0.0"
__maintainer__ = "Francisco Amato"
__email__ = "[email protected]"
__status__ = "Development"
class GoohostParser:
"""
The objective of this class is to parse an xml file generated by the goohost tool.
TODO: Handle errors.
TODO: Test goohost output version. Handle what happens if the parser doesn't support it.
TODO: Test cases.
@param goohost_scantype You could select scan type ip, mail or host
"""
def __init__(self, output, goohost_scantype, resolve_hostname):
self.items = []
self.resolve_hostname = resolve_hostname
lines = list(filter(None, output.split('\n')))
for line in lines:
if goohost_scantype == 'ip':
data = line.split()
item = {'host': data[0], 'ip': data[1]}
self.add_host_info_to_items(item['ip'], item['host'])
elif goohost_scantype == 'host':
data = line.strip()
item = {'host': data, 'ip': self.resolve_hostname(data)}
self.add_host_info_to_items(item['ip'], item['host'])
else:
item = {'data': line}
def add_host_info_to_items(self, ip_address, hostname):
data = {}
exists = False
for item in self.items:
if ip_address in item['ip']:
item['hosts'].append(hostname)
exists = True
if not exists:
data['ip'] = ip_address
data['hosts'] = [hostname]
self.items.append(data)
class GoohostPlugin(PluginBase):
"""
Example plugin to parse goohost output.
"""
def __init__(self, *arg, **kwargs):
super().__init__(*arg, **kwargs)
self.id = "Goohost"
self.name = "Goohost XML Output Plugin"
self.plugin_version = "0.0.1"
self.version = "v.0.0.1"
self.options = None
self._command_regex = re.compile(r'^(sudo goohost\.sh|goohost\.sh|sh goohost\.sh|\.\/goohost\.sh)\s+.*?')
self.host = None
self._command_string = None
def parseOutputString(self, output):
"""
This method will check if the import was made through the console or by importing a Goohost report.
Import from Console:The method will take the path of the report generated by Goohost from the output the shell sends and will read
the information from the txt where it expects it to be present.
Import from Report: The method receives the output of the txt report as parameter.
self.scantype defines the method used to generate the Goohost report
"""
scantype = self.define_scantype_by_output(output)
parser = GoohostParser(output, scantype, self.resolve_hostname)
if scantype == 'host' or scantype == 'ip':
for item in parser.items:
h_id = self.createAndAddHost(item['ip'], hostnames=item['hosts'])
del parser
def define_scantype_by_command(self, command):
method_regex = re.compile(r'-m (mail|host|ip)')
method = method_regex.search(command)
if method:
return method.group(1)
return 'host'
def define_scantype_by_output(self, output):
lines = output.split('\n')
line = lines[0].split(' ')
if len(line) == 1:
return 'host'
elif len(line) == 2:
return 'ip'
def get_report_path_from_output(self, command_output):
report_name = re.search(r"Results saved in file (\S+)", command_output)
if not report_name:
return False
else:
self._output_file_path = os.path.join(self._current_path, report_name.group(1))
if not os.path.exists(self._output_file_path):
return False
else:
self._delete_temp_file = True
def processOutput(self, command_output):
self.get_report_path_from_output(command_output)
if self.has_custom_output():
self._parse_filename(self.get_custom_file_path())
else:
self.parseOutputString(command_output)
def createPlugin(*args, **kwargs):
return GoohostPlugin(*args, **kwargs)