def load_config_from_file(self, config_path): """Load the configuration into a global dictionary. :param config_path: The configuration file path :type config_path: `str` :return: None :rtype: None """ cprint("Loading config from: %s.." % config_path) config_file = FileOperations.open(config_path, 'r') self.set_val('FRAMEWORK_DIR', self.root_dir) # Needed Later. for line in config_file: try: key = line.split(':')[0] if key[0] == '#': # Ignore comment lines. continue value = line.replace("%s: " % key, "").strip() self.set_val( key, self.multi_replace( value, { 'FRAMEWORK_DIR': self.root_dir, 'OWTF_PID': str(self.owtf_pid) })) except ValueError: self.error_handler.abort_framework( "Problem in config file: %s -> Cannot parse line: %s" % (config_path, line))
def run(PluginInfo): Content = [] plugin_params = ServiceLocator.get_component("plugin_params") config = ServiceLocator.get_component("config") args = { 'Description': DESCRIPTION, 'Mandatory': { 'EMAIL_TARGET': config.get_val('EMAIL_TARGET_DESCRIP'), 'EMAIL_FROM': config.get_val('EMAIL_FROM_DESCRIP'), 'SMTP_LOGIN': config.get_val('SMTP_LOGIN_DESCRIP'), 'SMTP_PASS': config.get_val('SMTP_PASS_DESCRIP'), 'SMTP_HOST': config.get_val('SMTP_HOST_DESCRIP'), 'SMTP_PORT': config.get_val('SMTP_PORT_DESCRIP'), 'EMAIL_PRIORITY': config.get_val('EMAIL_PRIORITY_DESCRIP'), 'EMAIL_SUBJECT': config.get_val('EMAIL_SUBJECT_DESCRIP'), 'EMAIL_BODY': config.get_val('EMAIL_BODY_DESCRIP'), }, 'Optional': { 'EMAIL_ATTACHMENT': config.get_val('EMAIL_ATTACHMENT_DESCRIP'), 'REPEAT_DELIM': config.get_val('REPEAT_DELIM_DESCRIP') } } for Args in plugin_params.GetArgs(args, PluginInfo): plugin_params.set_config(Args) # Update config if ServiceLocator.get_component("smtp").Send(Args): cprint("Email delivered succcessfully") else: cprint("Email delivery failed") resource = ServiceLocator.get_component("config").get_resources('SendPhishingAttackviaSET') Content += ServiceLocator.get_component("plugin_helper").CommandDump('Test Command', 'Output', resource, PluginInfo, Content) return Content
def run(PluginInfo): Content = [] plugin_params = ServiceLocator.get_component("plugin_params") config = ServiceLocator.get_component("config") args = { 'Description': DESCRIPTION, 'Mandatory': { 'EMAIL_TARGET': config.get_val('EMAIL_TARGET_DESCRIP'), 'EMAIL_FROM': config.get_val('EMAIL_FROM_DESCRIP'), 'SMTP_LOGIN': config.get_val('SMTP_LOGIN_DESCRIP'), 'SMTP_PASS': config.get_val('SMTP_PASS_DESCRIP'), 'SMTP_HOST': config.get_val('SMTP_HOST_DESCRIP'), 'SMTP_PORT': config.get_val('SMTP_PORT_DESCRIP'), 'EMAIL_PRIORITY': config.get_val('EMAIL_PRIORITY_DESCRIP'), 'EMAIL_SUBJECT': config.get_val('EMAIL_SUBJECT_DESCRIP'), 'EMAIL_BODY': config.get_val('EMAIL_BODY_DESCRIP'), }, 'Optional': { 'EMAIL_ATTACHMENT': config.get_val('EMAIL_ATTACHMENT_DESCRIP'), 'REPEAT_DELIM': config.get_val('REPEAT_DELIM_DESCRIP') } } for Args in plugin_params.get_args(args, PluginInfo): plugin_params.set_config(Args) # Update config if ServiceLocator.get_component("smtp").Send(Args): cprint("Email delivered succcessfully") else: cprint("Email delivery failed") resource = ServiceLocator.get_component("config").get_resources('SendPhishingAttackviaSET') Content += ServiceLocator.get_component("plugin_helper").CommandDump('Test Command', 'Output', resource, PluginInfo, Content) return Content
def delete(self, worker_id=None, action=None): if (not worker_id) or action: raise tornado.web.HTTPError(400) try: self.get_component("worker_manager").delete_worker(int(worker_id)) except exceptions.InvalidWorkerReference as e: cprint(e.parameter) raise tornado.web.HTTPError(400)
def delete(self, target_id=None): if not target_id: raise tornado.web.HTTPError(400) try: self.get_component("target").delete_target(id=target_id) except InvalidTargetReference as e: cprint(e.parameter) raise tornado.web.HTTPError(400)
def get(self, target_id=None): try: # Empty criteria ensure all transactions filter_data = dict(self.request.arguments) self.write(self.get_component("url_manager").get_all(filter_data, target_id=int(target_id))) except exceptions.InvalidTargetReference as e: cprint(e.parameter) raise tornado.web.HTTPError(400)
def patch(self, target_id=None): if not target_id or not self.request.arguments: raise tornado.web.HTTPError(400) try: patch_data = dict(self.request.arguments) self.get_component("target").update_target(patch_data, ID=target_id) except InvalidTargetReference as e: cprint(e.parameter) raise tornado.web.HTTPError(400)
def delete(self, target_id=None, transaction_id=None): try: if transaction_id: self.get_component("transaction").delete_transaction(int(transaction_id), int(target_id)) else: raise tornado.web.HTTPError(400) except exceptions.InvalidTargetReference as e: cprint(e.parameter) raise tornado.web.HTTPError(400)
def patch(self, target_id=None): if not target_id or not self.request.arguments: raise tornado.web.HTTPError(400) try: patch_data = dict(self.request.arguments) self.get_component("target").update_target(patch_data, id=target_id) except InvalidTargetReference as e: cprint(e.parameter) raise tornado.web.HTTPError(400)
def get(self, target_id=None): try: # Empty criteria ensure all transactions filter_data = dict(self.request.arguments) self.write( self.get_component("url_manager").get_all( filter_data, target_id=int(target_id))) except exceptions.InvalidTargetReference as e: cprint(e.parameter) raise tornado.web.HTTPError(400)
def delete(self, target_id=None, transaction_id=None): try: if transaction_id: self.get_component("transaction").delete_transaction( int(transaction_id), int(target_id)) else: raise tornado.web.HTTPError(400) except exceptions.InvalidTargetReference as e: cprint(e.parameter) raise tornado.web.HTTPError(400)
def post(self, target_id=None, transaction_id=None): try: if transaction_id: filter_data = dict(self.request.arguments) self.write(self.get_component("transaction").get_hrt_response(filter_data, int(transaction_id), target_id=int(target_id))) else: raise tornado.web.HTTPError(400) except (InvalidTargetReference, InvalidTransactionReference, InvalidParameterType) as e: cprint(e.parameter) raise tornado.web.HTTPError(400)
def get(self, target_id=None): try: # If no target_id, means /target is accessed with or without filters if not target_id: # Get all filter data here, so that it can be passed filter_data = dict(self.request.arguments) self.write(self.get_component("target").get_target_config_dicts(filter_data)) else: self.write(self.get_component("target").get_target_config_by_id(target_id)) except InvalidTargetReference as e: cprint(e.parameter) raise tornado.web.HTTPError(400)
def authenticate(self): """This function is handling the authentication process to TOR control connection. :return: :rtype: """ self.tor_conn.send('AUTHENTICATE "%s"\r\n' % self.password) response = self.tor_conn.recv(1024) if response.startswith('250'): # 250 is the success response cprint("Successfully Authenticated to TOR control") else: self.error_handler.abort_framework("Authentication Error : %s" % response)
def post(self, target_id=None): if (target_id) or (not self.get_argument("target_url", default=None)): # How can one post using an id xD raise tornado.web.HTTPError(400) try: self.get_component("target").add_targets(dict(self.request.arguments)["target_url"]) self.set_status(201) # Stands for "201 Created" except exceptions.DBIntegrityException as e: cprint(e.parameter) raise tornado.web.HTTPError(409) except exceptions.UnresolvableTargetException as e: cprint(e.parameter) raise tornado.web.HTTPError(409)
def get(self, target_id=None): """ REST API - /api/targets/<target_id>/export/ returns JSON(data) for template. """ if not target_id: raise tornado.web.HTTPError(400) try: filter_data = dict(self.request.arguments) plugin_outputs = self.get_component("plugin_output").get_all(filter_data, target_id=target_id, inc_output=True) except exceptions.InvalidTargetReference as e: cprint(e.parameter) raise tornado.web.HTTPError(400) except exceptions.InvalidParameterType as e: cprint(e.parameter) raise tornado.web.HTTPError(400) # Group the plugin outputs to make it easier in template grouped_plugin_outputs = defaultdict(list) for output in plugin_outputs: output['rank'] = RANKS.get(max(output['user_rank'], output['owtf_rank'])) grouped_plugin_outputs[output['plugin_code']].append(output) # Needed ordered list for ease in templates grouped_plugin_outputs = collections.OrderedDict(sorted(grouped_plugin_outputs.items())) # Get mappings mappings = self.get_argument("mapping", None) if mappings: mappings = self.get_component("mapping_db").get_mappings(mappings) # Get test groups as well, for names and info links test_groups = {} for test_group in self.get_component("db_plugin").get_all_test_groups(): test_group["mapped_code"] = test_group["code"] test_group["mapped_descrip"] = test_group["descrip"] if mappings and test_group['code'] in mappings: code, description = mappings[test_group['code']] test_group["mapped_code"] = code test_group["mapped_descrip"] = description test_groups[test_group['code']] = test_group vulnerabilities = [] for key, value in list(grouped_plugin_outputs.items()): test_groups[key]["data"] = value vulnerabilities.append(test_groups[key]) result = self.get_component("target").get_target_config_by_id(target_id) result["vulnerabilities"] = vulnerabilities result["time"] = strftime("%Y-%m-%d %H:%M:%S", gmtime()) if result: self.write(result) else: raise tornado.web.HTTPError(400)
def open_connection(self): """Opens a new connection to TOR control :return: :rtype: """ try: s = socket.socket() s.connect((self.ip, self.tor_control_port)) cprint("Connected to TOR control") return s except Exception as error: self.error_handler.abort_framework("Can't connect to the TOR daemon : %s" % error.strerror)
def get_target_url_for_id(self, id): """Get target URL by target ID :param id: target ID :type id: `int` :return: Target url :rtype: `str` """ target_obj = self.db.session.query(models.Target).get(id) if not target_obj: cprint("Failing with ID: %s" % str(id)) raise InvalidTargetReference("Target doesn't exist with ID: %s" % str(id)) return target_obj.target_url
def log_error(self, message, trace=None): """Logs the error to the error DB and prints it to stdout :param message: Error message :type message: `str` :param trace: Traceback :type trace: `str` :return: :rtype: None """ try: self.db_error.add(message, trace) # Log error in the DB. except AttributeError: cprint("ERROR: DB is not setup yet: cannot log errors to file!")
def get(self, target_id=None): if not target_id: # Must be a integer target id raise tornado.web.HTTPError(400) try: # Empty criteria ensure all transactions filter_data = dict(self.request.arguments) filter_data["search"] = True self.write(self.get_component("url_manager").search_all(filter_data, target_id=int(target_id))) except exceptions.InvalidTargetReference as e: cprint(e.parameter) raise tornado.web.HTTPError(400) except exceptions.InvalidParameterType as e: cprint(e.parameter) raise tornado.web.HTTPError(400)
def renew_ip(self): """Sends an NEWNYM message to TOR control in order to renew the IP address :return: True if IP is renewed, else False :rtype: `bool` """ self.tor_conn.send("signal NEWNYM\r\n") response = self.tor_conn.recv(1024) if response.startswith('250'): cprint("TOR : IP renewed") return True else: cprint("[TOR]Warning: IP can't renewed") return False
def post(self, target_id=None, transaction_id=None): try: if transaction_id: filter_data = dict(self.request.arguments) self.write( self.get_component("transaction").get_hrt_response( filter_data, int(transaction_id), target_id=int(target_id))) else: raise tornado.web.HTTPError(400) except (InvalidTargetReference, InvalidTransactionReference, InvalidParameterType) as e: cprint(e.parameter) raise tornado.web.HTTPError(400)
def add(self, message, type='owtf'): """Prints error to stdout or error db based on type :param message: Error message :type message: `str` :param type: Bug type :type type: `str` :return: :rtype: None """ if type == 'owtf': return self.add_new_bug(message) else: output = self.padding + message + self.sub_padding cprint(output) self.log_error(message)
def get(self, target_id=None): if not target_id: # Must be a integer target id raise tornado.web.HTTPError(400) try: # Empty criteria ensure all transactions filter_data = dict(self.request.arguments) filter_data["search"] = True self.write( self.get_component("url_manager").search_all( filter_data, target_id=int(target_id))) except exceptions.InvalidTargetReference as e: cprint(e.parameter) raise tornado.web.HTTPError(400) except exceptions.InvalidParameterType as e: cprint(e.parameter) raise tornado.web.HTTPError(400)
def get(self, target_id=None): """Retrieve scan results for a target. :return: {code: {data: [], details: {}}, code2: {data: [], details: {}} } This API doesn't return `output` section as part of optimization. `data` is array of scan results according to `plugin_types`. `details` contains info about `code`. """ try: filter_data = dict(self.request.arguments) results = self.get_component("plugin_output").get_all( filter_data, target_id=int(target_id), inc_output=False) # Get mappings mappings = self.get_component("mapping_db").get_all_mappings() # Get test groups as well, for names and info links groups = {} for group in self.get_component("db_plugin").get_all_test_groups(): group['mappings'] = mappings.get(group['code'], {}) groups[group['code']] = group dict_to_return = {} for item in results: if (dict_to_return.has_key(item['plugin_code'])): dict_to_return[item['plugin_code']]['data'].append(item) else: ini_list = [] ini_list.append(item) dict_to_return[item["plugin_code"]] = {} dict_to_return[item["plugin_code"]]["data"] = ini_list dict_to_return[item["plugin_code"]]["details"] = groups[ item["plugin_code"]] dict_to_return = collections.OrderedDict( sorted(dict_to_return.items())) if results: self.write(dict_to_return) else: raise tornado.web.HTTPError(400) except exceptions.InvalidTargetReference as e: cprint(e.parameter) raise tornado.web.HTTPError(400) except exceptions.InvalidParameterType as e: cprint(e.parameter) raise tornado.web.HTTPError(400)
def get(self, worker_id=None, action=None): if not worker_id: self.write( self.get_component("worker_manager").get_worker_details()) try: if worker_id and (not action): self.write( self.get_component("worker_manager").get_worker_details( int(worker_id))) if worker_id and action: if int(worker_id) == 0: getattr(self.get_component("worker_manager"), '%s_all_workers' % action)() getattr(self.get_component("worker_manager"), '%s_worker' % action)(int(worker_id)) except exceptions.InvalidWorkerReference as e: cprint(e.parameter) raise tornado.web.HTTPError(400)
def get_resources_from_file(self, resource_file): """Fetch resources for a file :param resource_file: Path to the resource file :type resource_file: `str` :return: Resources as a set :rtype: `set` """ resources = set() config_file = FileOperations.open(resource_file, 'r').read().splitlines() # To remove stupid '\n' at the end for line in config_file: if '#' == line[0]: continue # Skip comment lines try: type, name, resource = line.split('_____') resources.add((type, name, resource)) except ValueError: cprint("ERROR: The delimiter is incorrect in this line at Resource File: %s" % str(line.split('_____'))) return resources
def add_new_bug(self, message): """Formats the bug to be reported by the auto-reporter :param message: Error message :type message: `str` :return: :rtype: None """ exc_type, exc_value, exc_traceback = sys.exc_info() err_trace_list = traceback.format_exception(exc_type, exc_value, exc_traceback) err_trace = OutputCleaner.anonymise_command("\n".join(err_trace_list)) message = OutputCleaner.anonymise_command(message) output = "OWTF BUG: Please report the sanitised information below to help make this better.Thank you" output += "\nMessage: %s\n" % message output += "\nError Trace:" output += "\n%s" % err_trace output += "\n%s" % self.padding cprint(output) self.log_error(message, err_trace)
def delete(self, target_id=None, plugin_group=None, plugin_type=None, plugin_code=None): try: filter_data = dict(self.request.arguments) if not plugin_group: # First check if plugin_group is present in url self.get_component("plugin_output").delete_all( filter_data, target_id=int(target_id)) if plugin_group and (not plugin_type): filter_data.update({"plugin_group": plugin_group}) self.get_component("plugin_output").delete_all( filter_data, target_id=int(target_id)) if plugin_type and plugin_group and (not plugin_code): if plugin_type not in self.get_component( "db_plugin").get_types_for_plugin_group(plugin_group): raise tornado.web.HTTPError(400) filter_data.update({ "plugin_type": plugin_type, "plugin_group": plugin_group }) self.get_component("plugin_output").delete_all( filter_data, target_id=int(target_id)) if plugin_type and plugin_group and plugin_code: if plugin_type not in self.get_component( "db_plugin").get_types_for_plugin_group(plugin_group): raise tornado.web.HTTPError(400) filter_data.update({ "plugin_type": plugin_type, "plugin_group": plugin_group, "plugin_code": plugin_code }) self.get_component("plugin_output").delete_all( filter_data, target_id=int(target_id)) except exceptions.InvalidTargetReference as e: cprint(e.parameter) raise tornado.web.HTTPError(400) except exceptions.InvalidParameterType as e: cprint(e.parameter) raise tornado.web.HTTPError(400)
def get(self, target_id=None, plugin_group=None, plugin_type=None, plugin_code=None): try: filter_data = dict(self.request.arguments) if plugin_group and (not plugin_type): filter_data.update({"plugin_group": plugin_group}) if plugin_type and plugin_group and (not plugin_code): if plugin_type not in self.get_component( "db_plugin").get_types_for_plugin_group(plugin_group): raise tornado.web.HTTPError(400) filter_data.update({ "plugin_type": plugin_type, "plugin_group": plugin_group }) if plugin_type and plugin_group and plugin_code: if plugin_type not in self.get_component( "db_plugin").get_types_for_plugin_group(plugin_group): raise tornado.web.HTTPError(400) filter_data.update({ "plugin_type": plugin_type, "plugin_group": plugin_group, "plugin_code": plugin_code }) results = self.get_component("plugin_output").get_all( filter_data, target_id=int(target_id), inc_output=True) if results: self.write(results) else: raise tornado.web.HTTPError(400) except exceptions.InvalidTargetReference as e: cprint(e.parameter) raise tornado.web.HTTPError(400) except exceptions.InvalidParameterType as e: cprint(e.parameter) raise tornado.web.HTTPError(400)
def patch(self, target_id=None, plugin_group=None, plugin_type=None, plugin_code=None): try: if (not target_id) or (not plugin_group) or (not plugin_type) or ( not plugin_code): raise tornado.web.HTTPError(400) else: patch_data = dict(self.request.arguments) self.get_component("plugin_output").update(plugin_group, plugin_type, plugin_code, patch_data, target_id=target_id) except exceptions.InvalidTargetReference as e: cprint(e.parameter) raise tornado.web.HTTPError(400) except exceptions.InvalidParameterType as e: cprint(e.parameter) raise tornado.web.HTTPError(400)
def msg_configure_tor(): cprint(""" 1)Open torrc file usually located at '/etc/tor/torrc' if you can't find torrc file visit https://www.torproject.org/docs/faq.html.en#torrc 2)Enable the TOR control port by uncommenting(removing the hash(#) symbol) or adding the following line should look like this "ControlPort 9051". 3)Generate a new hashed password by running the following command "tor --hash-password 'your_password' 4)Uncomment "HashedControlPassword" and add the previously generated hash should look like the following but with you hash HashedControlPassword 16:52B319480CED2E0860BAEA7565ECCF628A59FEE59B6E0592CD3F01C710 Recommended Setting: ControlPort 9051 HashedControlPassword 16:52B319480CED2E0860BAEA7565ECCF628A59FEE59B6E0592CD3F01C710 The above hashed password is 'owtf' Advantages of recommended settings You can run owtf TOR mode without specifying the options ex. ./owtf.py -o OWTF-WVS-001 http:my.website.com --tor :::: which is the same with 127.0.0.1:9050:9051:owtf:5 """)
def get(self, plugin_group=None, plugin_type=None, plugin_code=None): try: filter_data = dict(self.request.arguments) if not plugin_group: # Check if plugin_group is present in url self.write( self.get_component("db_plugin").get_all(filter_data)) if plugin_group and (not plugin_type) and (not plugin_code): filter_data.update({"group": plugin_group}) self.write( self.get_component("db_plugin").get_all(filter_data)) if plugin_group and plugin_type and (not plugin_code): if plugin_type not in self.get_component( "db_plugin").get_types_for_plugin_group(plugin_group): raise tornado.web.HTTPError(400) filter_data.update({ "type": plugin_type, "group": plugin_group }) self.write( self.get_component("db_plugin").get_all(filter_data)) if plugin_group and plugin_type and plugin_code: if plugin_type not in self.get_component( "db_plugin").get_types_for_plugin_group(plugin_group): raise tornado.web.HTTPError(400) filter_data.update({ "type": plugin_type, "group": plugin_group, "code": plugin_code }) # This combination will be unique, so have to return a dict results = self.get_component("db_plugin").get_all(filter_data) if results: self.write(results[0]) else: raise tornado.web.HTTPError(400) except exceptions.InvalidTargetReference as e: cprint(e.parameter) raise tornado.web.HTTPError(400)
def get_resources_from_file(self, resource_file): """Fetch resources for a file :param resource_file: Path to the resource file :type resource_file: `str` :return: Resources as a set :rtype: `set` """ resources = set() config_file = FileOperations.open( resource_file, 'r').read().splitlines() # To remove stupid '\n' at the end for line in config_file: if '#' == line[0]: continue # Skip comment lines try: type, name, resource = line.split('_____') resources.add((type, name, resource)) except ValueError: cprint( "ERROR: The delimiter is incorrect in this line at Resource File: %s" % str(line.split('_____'))) return resources
def get_ip_from_hostname(self, hostname): """Get IP from the hostname :param hostname: Target hostname :type hostname: `str` :return: IP address of the target hostname :rtype: `str` """ ip = '' # IP validation based on @marcwickenden's pull request, thanks! for sck in [socket.AF_INET, socket.AF_INET6]: try: socket.inet_pton(sck, hostname) ip = hostname break except socket.error: continue if not ip: try: ip = socket.gethostbyname(hostname) except socket.gaierror: raise UnresolvableTargetException("Unable to resolve: '%s'" % hostname) ipchunks = ip.strip().split("\n") alternative_ips = [] if len(ipchunks) > 1: ip = ipchunks[0] cprint("%s has several IP addresses: (%s).Choosing first: %s" % (hostname, "".join(ipchunks)[0:-3], ip)) alternative_ips = ipchunks[1:] self.set_val('alternative_ips', alternative_ips) ip = ip.strip() self.set_val('INTERNAL_IP', is_internal_ip(ip)) logging.info("The IP address for %s is: '%s'" % (hostname, ip)) return ip
def get(self, target_id=None, transaction_id=None): try: if transaction_id: self.write(self.get_component("transaction").get_by_id_as_dict(int(transaction_id), target_id=int(target_id))) else: # Empty criteria ensure all transactions filter_data = dict(self.request.arguments) self.write(self.get_component("transaction").get_all_as_dicts(filter_data, target_id=int(target_id))) except exceptions.InvalidTargetReference as e: cprint(e.parameter) raise tornado.web.HTTPError(400) except exceptions.InvalidTransactionReference as e: cprint(e.parameter) raise tornado.web.HTTPError(400) except exceptions.InvalidParameterType as e: cprint(e.parameter) raise tornado.web.HTTPError(400)
def get(self, target_id=None, transaction_id=None): try: if transaction_id: self.write( self.get_component("transaction").get_by_id_as_dict( int(transaction_id), target_id=int(target_id))) else: # Empty criteria ensure all transactions filter_data = dict(self.request.arguments) self.write( self.get_component("transaction").get_all_as_dicts( filter_data, target_id=int(target_id))) except exceptions.InvalidTargetReference as e: cprint(e.parameter) raise tornado.web.HTTPError(400) except exceptions.InvalidTransactionReference as e: cprint(e.parameter) raise tornado.web.HTTPError(400) except exceptions.InvalidParameterType as e: cprint(e.parameter) raise tornado.web.HTTPError(400)
def get(self): try: self.write(self.get_component("plugin_output").plugin_count_output()) except exceptions.InvalidParameterType as e: cprint(e.parameter) raise tornado.web.HTTPError(400)
def msg_start_tor(self): cprint("Error : TOR daemon is not running (Tips: service tor start)")