"""
Faraday Penetration Test IDE
Copyright (C) 2013 Infobyte LLC (http://www.infobytesec.com/)
See the file 'doc/LICENSE' for the license information
"""
import re
from faraday_plugins.plugins.plugin import PluginBase
__author__ = "Francisco Amato"
__copyright__ = "Copyright 2013, Faraday Project"
__credits__ = ["Francisco Amato"]
__license__ = ""
__version__ = "1.0.0"
__maintainer__ = "Francisco Amato"
__email__ = "[email protected]"
__status__ = "Development"
class MedusaParser:
"""
The objective of this class is to parse an xml file generated by the medusa tool.
@param medusa_filepath A proper simple report generated by medusa
"""
def __init__(self, xml_output, resolve_hostname):
self.resolve_hostname = resolve_hostname
self.srv = {
'ftp': '21', 'http': '80', 'imap': '143', 'mssql': '1433', 'mysql': '3306',
'ncp': '524', 'nntp': '119', 'pcanywhere': '5631', 'pop3': '110', 'postgres': '5432',
'rexec': '512', 'rlogin': '513', 'rsh': '514', 'smbnt': 'smbnt', 'smtp': '25',
'smtp-vrfy': 'smtp-vrfy', 'snmp': '161', 'ssh': '22', 'svn': '3690',
'telnet': '23', 'vmauthd': 'vmauthd', 'vnc': '5900', 'web-form': 'web-form',
'wrapper': 'wrapper'
}
lines = xml_output.splitlines()
self.items = []
for line in lines:
reg = re.search(r"ACCOUNT FOUND: \[([^$]+)\] Host: ([^$]+) User: ([^$]+) Password: ([^$]+) \[SUCCESS\]", line)
if reg:
item = {
'service': reg.group(1),
'host': reg.group(2),
'user': reg.group(3),
'pass': reg.group(4)
}
item['ip'] = resolve_hostname(item['host'])
item['port'] = self.srv[item['service']]
self.items.append(item)
class MedusaPlugin(PluginBase):
"""
Example plugin to parse medusa output.
"""
def __init__(self, *arg, **kwargs):
super().__init__(*arg, **kwargs)
self.id = "Medusa"
self.name = "Medusa Output Plugin"
self.plugin_version = "0.0.1"
self.version = "2.1.1"
self.options = None
self._command_regex = re.compile(r'^(sudo medusa|sudo \.\/medusa|medusa|\.\/medusa)\s+.*?')
self.host = None
self.port = ""
self._use_temp_file = True
self._temp_file_extension = "txt"
self.xml_arg_re = re.compile(r"^.*(-O\s*[^\s]+).*$")
def parseOutputString(self, output):
"""
This method will discard the output the shell sends, it will read it from
the xml where it expects it to be present.
NOTE: if 'debug' is true then it is being run from a test case and the
output being sent is valid.
"""
parser = MedusaParser(output, resolve_hostname=self.resolve_hostname)
for item in parser.items:
h_id = self.createAndAddHost(item['ip'], hostnames=[item['host']])
port = self.port if self.port else item['port']
s_id = self.createAndAddServiceToHost(
h_id,
item['service'],
ports=[port],
protocol="tcp",
status="open")
self.createAndAddCredToService(
h_id,
s_id,
item['user'],
item['pass'])
self.createAndAddVulnToService(h_id,
s_id,
"Weak Credentials",
f"[medusa found the following credentials]\nuser:{item['user']}\npass:{item['pass']}",
severity="high")
del parser
def processCommandString(self, username, current_path, command_string):
super().processCommandString(username, current_path, command_string)
self.port = ""
arg_match = self.xml_arg_re.match(command_string)
mreg = re.search(r"\-n( |)([\d]+)", command_string)
if mreg:
self.port = mreg.group(2)
if arg_match is None:
return re.sub(r"(^.*?medusa?)", r"\1 -O %s" % self._output_file_path, command_string)
else:
return re.sub(arg_match.group(1), r"-O %s" % self._output_file_path, command_string)
def _isIPV4(self, ip):
if len(ip.split(".")) == 4:
return True
else:
return False
def createPlugin(*args, **kwargs):
return MedusaPlugin(*args, **kwargs)