Esempio n. 1
0
    def delete(self):
        """Delete selected services"""
        results = self.get_results()
        if not results:
            logger.error('No matching service')
        else:
            for r in results:
                logger.info('Service {service} host={ip}{hostname} ' \
                    'port={port}/{proto} deleted'.format(
                    service  = r.name,
                    ip       = r.host.ip,
                    hostname = '('+r.host.hostname+')' if r.host.hostname else '',
                    port     = r.port,
                    proto    = {Protocol.TCP: 'tcp', Protocol.UDP: 'udp'}.get(
                        r.protocol)))

                self.sqlsess.delete(r)
                self.sqlsess.commit()

                # Delete host if no more service in it
                if len(r.host.services) == 0:
                    logger.info('Host {ip} {hostname} deleted because it does not ' \
                        'have service anymore'.format(
                        ip=r.host.ip,
                        hostname='('+r.host.hostname+')' if r.host.hostname else ''))

                    self.sqlsess.delete(r.host)
                    self.sqlsess.commit()
 def add_cred(self, service_id, username, password, auth_type=None):
     cred = self.sqlsess.query(Credential).join(Service)\
                        .filter(Service.id == service_id)\
                        .filter(Credential.username == username)\
                        .filter(Credential.password == password)\
                        .filter(Credential.type == auth_type).first()
     if cred:
         logger.warning('Credential already exists in database')
     else:
         service = self.sqlsess.query(Service).filter(
             Service.id == service_id).first()
         if not service:
             logger.error(
                 'Service id {id} is invalid'.format(id=service_id))
         else:
             cred = Credential(username=username,
                               password=password,
                               type=auth_type if service.name == 'http' else
                               None)  # auth type relevant only for http
             self.sqlsess.add(cred)
             service.credentials.append(cred)
             logger.success('Credential {username}/{password}{auth_type} added to service {service} '\
                     'host={ip}{hostname} port={port}/{proto}'.format(
                         username  = '******' if username == '' else username,
                         password  = {'': '<empty>', None: '<???>'}.get(password, password),
                         auth_type = '('+str(auth_type)+')' if auth_type else '',
                         service   = service.name,
                         ip        = service.host.ip,
                         hostname  = '('+service.host.hostname+')' if service.host.hostname else '',
                         port      = service.port,
                         proto     = {Protocol.TCP: 'tcp', Protocol.UDP: 'udp'}.get(service.protocol)))
             self.sqlsess.commit()
Esempio n. 3
0
    def __init__(self, ips_list, services_config):
        """
        Initialize Shodan Parser from results file.

        :param list(str) ips_list: list of ip addresses
        :param ServicesConfig services_config: Services configuration
        """

        self.services_config = services_config
        self.api = None
        self.api_key = None
        self.ips_list = ips_list

        # config = os.path.expanduser("~/.shodan_api_key")
        # if not FileUtils.can_read(config):
        #     logger.error("Shodan key file doesn't exists in {0}".format(config))
        # else:
        #     self.api_key = FileUtils.read(config).rstrip()
        #     if self.api_key is not None \
        #         or self.api_key is not '':
        #             self.api = Shodan(self.api_key)
        #     else:
        #         logger.error("Error missing shodan api key in {0}".format(config))
        #         return
        if 'shodan' in API_KEYS.keys() and API_KEYS['shodan']:
            self.api_key = API_KEYS['shodan']
            self.api = Shodan(self.api_key)
        else:
            logger.error('Shodan API key is missing in "apikeys.py"')
            return None
 def __create_subprocess(self, cmd):
     """
     Run a command. Display output (stdout+stderr) in live and also store it into
     a variable which is returned by the function.
     :param cmd: Command to execute
     :return: Command output
     """
     output = ''
     try:
         proc = subprocess.Popen(cmd,
                                 shell=True,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.STDOUT)
         #subprocess.call(cmd, shell=True, stdout=self.output_file, stderr=subprocess.STDOUT)
         #subprocess.Popen(cmd, shell=True)
         #subprocess.call(cmd, shell=True)
         for line in iter(proc.stdout.readline, b''):
             out = line.decode(sys.stdout.encoding)
             sys.stdout.write(out)
             output += out
         #output = proc.stdout.read()
         #print(output)
     except Exception as e:
         logger.error(
             'Error when trying to run command: {exception}'.format(
                 exception=e))
     return output
Esempio n. 5
0
    def check(self):
        """
        Check the toolbox: Run all check commands (when available) from all
        installed tools, in automatic mode (i.e. checks based on exit codes)

        In case of an error code returned by one check command (!= 0), the function
        stops and exits the program with exit code 1 (error). 
        Otherwise, if all check commands have returned a success exit code (0), 
        it exits the program with exit code 0 (success).

        Designed to be used for Continuous Integration.
        """
        Output.title1('Automatic check of installed tools')
        for service in self.services:
            for tool in self.tools[service]:
                if tool.installed:
                    # Automatic mode (no prompt), only based on exit status
                    status = tool.run_check_command(fast_mode=True)
                    if not status:
                        logger.error('An error occured with the tool "{tool}". Exit ' \
                            'check with exit code 1...'.format(tool=tool.name))
                        sys.exit(1)
                print()
                print()

        logger.success('No error has been detected with all tools check commands. ' \
            'Exit with success code 0...')
        sys.exit(0)
Esempio n. 6
0
    def __check_args_attack_context_option(self):
        """
        Check arguments for subcommand Attack > Context parameters > --option
        Syntax: --option <name=value>

        If some options submitted, self.args.options is turned into a dict
        {name: value}
        """

        if not self.args.options:
            return True

        options = dict()
        for option in self.args.options:
            if '=' in option:
                name, value = map(lambda x: x.lower(),
                                  option.split('=', maxsplit=1))

                if not self.settings.services.is_specific_option_name_supported(
                        name, service=self.args.service or None):
                    logger.error('The specific option name "{name}" is not ' \
                        'supported. Check "info --options".'.format(name=name))
                    return False

                elif not self.settings.services.is_specific_option_value_supported(
                        name, value):
                    logger.error('The value for the specific option named "{name}" is ' \
                        'not valid. Check "info --options".'.format(name=name))
                    return False

                else:
                    options[name] = value

        self.args.options = options
Esempio n. 7
0
    def __init__(self, settings):
        self.settings = settings
        self.mode = None
        self.args = None

        parser = argparse.ArgumentParser(
            usage=USAGE, formatter_class=ArgumentsParser.formatter_class)
        parser.add_argument('command', help=argparse.SUPPRESS)

        # https://chase-seibert.github.io/blog/2014/03/21/python-multilevel-argparse.html
        # parse_args defaults to [1:] for args, but need to exclude the rest of the args
        args = parser.parse_args(sys.argv[1:2])
        if not hasattr(self, args.command):
            logger.error('Unrecognized command')
            parser.print_help()
            raise ArgumentsException()

        self.subparser = None

        # Use dispatch pattern to invoke method with same name
        getattr(self, args.command)()

        # Check arguments
        if not self.check_args():
            raise ArgumentsException()
Esempio n. 8
0
    def check_args_attack(self):
        """Check arguments for subcommand Attack"""

        status = True
        if self.args.target_ip_or_url and self.args.mission:
            logger.error(
                '--target and --mission cannot be used at the same time')
            return False

        elif self.args.target_ip_or_url:
            status &= self.__check_args_attack_single_target()

        elif self.args.mission:
            status &= self.__check_args_attack_multi_targets()

        else:
            #logger.error('At least one target must be selected')
            self.subparser.print_help()
            return False

        if self.args.debug:
            logger.setLevel('DEBUG')
            logger.debug('Debug mode enabled')

        # status &= self.__check_args_attack_single_target()
        # status &= self.__check_args_attack_multi_targets()
        status &= self.__check_args_attack_bruteforce()
        status &= self.__check_args_attack_selection()
        status &= self.__check_args_attack_context()

        return status
Esempio n. 9
0
    def check_args_toolbox(self):
        """Check arguments for subcommand Toolbox"""

        service = self.args.show_toolbox_for_svc \
            or self.args.install_for_svc \
            or self.args.update_for_svc \
            or self.args.uninstall_for_svc

        tool = self.args.install_tool \
            or self.args.update_tool \
            or self.args.uninstall_tool

        if len(sys.argv) == 2:
            self.subparser.print_help()
            return False

        # Check options with service name as parameter
        if service:
            if not self.settings.services.is_service_supported(service,
                                                               multi=True):
                logger.error('Service "{service}" is not supported. ' \
                    'Check "info --services".'.format(service=service.upper()))
                return False

        # Check option with tool name as parameter
        if tool:
            if self.settings.toolbox.get_tool(tool) is None:

                logger.error('Tool "{tool}" is not referenced inside the toolbox. ' \
                    'Check "toolbox --show-all".'.format(tool=tool))
                return False

        return True
Esempio n. 10
0
    def __create_tool_dir(self):
        """
        Create the tool directory if necessary.

        :return: Status
        :rtype: bool
        """
        if self.tool_dir:
            if FileUtils.is_dir(self.tool_dir):
                logger.info('Directory "{dir}" already exists'.format(
                    dir=self.tool_dir))
                return True

            try:
                FileUtils.create_directory(self.tool_dir)
            except Exception as e:
                logger.error(
                    'Unable to create new directory "{dir}": {exc}'.format(
                        dir=self.tool_dir, exc=e))
                return False
            logger.info(
                'New directory "{dir}" created'.format(dir=self.tool_dir))
            return True
        else:
            return False
Esempio n. 11
0
    def remove(self, settings):
        """
        Remove the tool:
            - Remove tool directory into toolbox
            - Change install status to false.

        :param Settings settings: Settings from config files
        :return: Removal status
        :rtype: bool
        """

        # Delete tool directory if tool was installed inside toolbox directory
        if self.install_command:
            if not FileUtils.is_dir(self.tool_dir):
                logger.warning('Directory "{dir}" does not exist'.format(
                    dir=self.tool_dir))
                #return False
            elif not FileUtils.remove_directory(self.tool_dir):
                logger.error('Unable to delete directory "{dir}". ' \
                    'Check permissions and/or re-run with sudo'.format(
                        dir=self.tool_dir))
                return False
            else:
                logger.success(
                    'Tool directory "{dir}" deleted'.format(dir=self.tool_dir))

        # Remove virtualenv files if necessary
        virtualenv_dir = '{}/{}'.format(VIRTUALENVS_DIR, self.name)
        if FileUtils.is_dir(virtualenv_dir):
            if FileUtils.remove_directory(virtualenv_dir):
                logger.success('Virtualenv directory deleted')
            else:
                logger.warning('Unable to delete Virtualenv directory')

        if self.virtualenv.startswith('ruby'):
            logger.info('Delete RVM environment ({ruby}@{name})...'.format(
                ruby=self.virtualenv, name=self.name))
            cmd = 'source /usr/local/rvm/scripts/rvm; rvm use {ruby} && ' \
                'rvm gemset delete {name} --force'.format(
                    ruby=self.virtualenv,
                    name=self.name)
            returncode, _ = ProcessLauncher(cmd).start()

            if returncode == 0:
                logger.success('RVM environment deleted with success')
            else:
                logger.warning('Unable to delete RVM environment')

        # Make sure "installed" option in config file is set to False
        if settings.change_installed_status(self.target_service,
                                            self.name,
                                            install_status=False):
            logger.success('Tool marked as uninstalled')
        else:
            logger.error('An unexpected error occured when trying to mark the tool ' \
                'as uninstalled !')
            return False

        self.installed = False
        return True
    def __check_args_attack_selection(self):
        """
        Check arguments for ATTACK > Check Selection options
        """
        # Selection of categories of checks to run or to exclude
        categories = self.args.cat_only or self.args.cat_exclude
        if categories is not None:
            categories = categories.split(',')
            for cat in categories:
                if cat not in self.settings.services.list_all_categories():
                    logger.error(
                        'Category {cat} does not exist. Check "info --categories".'
                        .format(cat=cat))
                    return False

            if self.args.cat_only:
                self.args.cat_only = list(set(
                    categories))  # will contain the list of categories to run
            else:
                self.args.cat_only = list(
                    set(self.settings.services.list_all_categories()).
                    difference(set(categories)))

        # Selection of checks to run
        elif self.args.checks is not None:
            self.args.checks = self.args.checks.split(
                ',')  # will contain the list of checks to run
            for check in self.args.checks:
                if not self.settings.services.is_existing_check(check):
                    logger.error(
                        'Check {check} does not exist. Check "info --checks <service>".'
                        .format(check=check))
                    return False

        return True
    def check_args_attack(self):
        """
        Check arguments for mode ATTACK
        """
        status = True
        if self.args.target_ip_or_url and self.args.mission:
            logger.error(
                '--target and --mission cannot be used at the same time')
            return False

        elif self.args.target_ip_or_url is not None:
            status &= self.__check_args_attack_single_target()

        elif self.args.mission is not None:
            status &= self.__check_args_attack_multi_targets()

        else:
            #logger.error('At least one target must be selected')
            self.subparser.print_help()
            return False

        status &= self.__check_args_attack_selection()
        status &= self.__check_args_attack_authentication()
        status &= self.__check_args_attack_specific_options()

        return status
    def check_args_toolbox(self):
        """
        Check arguments for mode TOOLBOX
        """
        service = self.args.show_toolbox_for_svc or \
                  self.args.install_for_svc      or \
                  self.args.update_for_svc       or \
                  self.args.uninstall_for_svc

        if len(sys.argv) == 2:
            self.subparser.print_help()
            return False

        if service is not None and not self.settings.services.is_service_supported(
                service):
            logger.error(
                'Service "{service}" is not supported. Check "info --services".'
                .format(service=service.lower()))
            return False

        if self.args.uninstall_tool is not None and \
           self.settings.toolbox.get_tool(self.args.uninstall_tool) is None:
            logger.error('Tool "{tool}" is not referenced inside the toolbox. ' \
                'Check "toolbox --show-all".'.format(tool=self.args.uninstall_tool))
            return False

        return True
Esempio n. 15
0
    def show_command_outputs_for_check(self):
        """
        Display command outputs text for selected result/check
        This method must call only when filtering on one Result.id, i.e. 
        Condition(xxx, FilterData.CHECK_ID)
        """
        result = self.get_first_result()

        if not result:
            logger.error('Invalid check id (not existing)')
        else:
            Output.title2('Results for check {category} > {check}:'.format(
                category=result.category, check=result.check))

            if result.service.host.hostname:
                hostname = ' (' + result.service.host.hostname + ')'
            else:
                hostname = ''

            Output.title2('Target: host={ip}{hostname} | port={port}/{proto} | ' \
                'service {service}'.format(
                ip       = result.service.host.ip,
                hostname = hostname,
                port     = result.service.port,
                proto    = {Protocol.TCP: 'tcp', Protocol.UDP: 'udp'}.get(
                    result.service.protocol),
                service  = result.service.name))

            print()
            for o in result.command_outputs:
                Output.title3(o.cmdline)
                print()
                print(o.output)
                print()
    def do_nmap(self, args):
        """Import Nmap results"""
        print()

        file = os.path.expanduser(args.file[0])
        if not FileUtils.can_read(file):
            logger.error('Cannot read specified file')
            return
        logger.info('Importing Nmap results from {file}'.format(file=file))
        if not args.no_http_recheck:
            logger.info('Each service will be re-checked to detect HTTP services. Use --no-http-recheck if you want to disable it (faster import)')

        parser = NmapResultsParser(file, self.settings.services)
        results = parser.parse(not args.no_http_recheck)
        if results is not None:
            if len(results) == 0:
                logger.warning('No new service has been added into current mission')
            else:
                req = HostsRequester(self.sqlsess)
                req.select_mission(self.current_mission)
                for host in results:
                    req.add_or_merge_host(host)
                logger.success('Nmap results imported with success into current mission')

        print()
Esempio n. 17
0
    def show_command_outputs(self, result_id):
        result_check = self.sqlsess.query(Result).join(Service).join(
            Host).filter(Result.id == result_id).first()
        if not result_check:
            logger.error('Invalid check id')
            return

        command_outputs = self.sqlsess.query(CommandOutput).filter(
            CommandOutput.result_id == result_id).all()

        Output.title2('Results for check {category} > {check}:'.format(
            category=result_check.category, check=result_check.check))
        Output.title2(
            'Target: host={ip}{hostname} | port={port}/{proto} | service {service}'
            .format(ip=result_check.service.host.ip,
                    hostname=' (' + result_check.service.host.hostname +
                    ')' if result_check.service.host.hostname else '',
                    port=result_check.service.port,
                    proto={
                        Protocol.TCP: 'tcp',
                        Protocol.UDP: 'udp'
                    }.get(result_check.service.protocol),
                    service=result_check.service.name))

        print()
        for o in command_outputs:
            Output.title3(o.cmdline)
            print()
            print(o.output)
            print()
 def add_cred(self, username, password, auth_type=None):
     results = self.get_results()
     if not results:
         logger.error('No matching service')
     else:
         for r in results:
             cred = self.sqlsess.query(Credential).join(Service)\
                                .filter(Service.id == r.id)\
                                .filter(Credential.username == username)\
                                .filter(Credential.password == password)\
                                .filter(Credential.type == auth_type).first()
             if not cred:
                 cred = Credential(username=username,
                                   password=password,
                                   type=auth_type if r.name == 'http' else
                                   None)  # auth type relevant only for http
                 self.sqlsess.add(cred)
                 r.credentials.append(cred)
                 logger.success('Credential {username}/{password}{auth_type} added to service {service} '\
                     'host={ip}{hostname} port={port}/{proto}'.format(
                         username  = '******' if cred.username == '' else cred.username,
                         password  = {'': '<empty>', None: '<???>'}.get(cred.password, cred.password),
                         auth_type = '('+str(auth_type)+')' if (auth_type and r.name == 'http') else '',
                         service   = r.name,
                         ip        = r.host.ip,
                         hostname  = '('+r.host.hostname+')' if r.host.hostname else '',
                         port      = r.port,
                         proto     = {Protocol.TCP: 'tcp', Protocol.UDP: 'udp'}.get(r.protocol)))
         self.sqlsess.commit()
Esempio n. 19
0
    def __run_for_multi_targets(self, args):
        """Run attack against multiple targets from the database"""

        # Get Mission from which targets must be extracted
        mission = self.sqlsess.query(Mission)\
                    .filter(Mission.name == args.mission).first()
        if mission:
            logger.info('Extracting targets from mission "{mission}" ...'.format(
                mission=mission.name))
        else:
            raise AttackException('Mission {mission} does not exist into the ' \
                'database'.format(mission=args.mission))

        # Initialize Services requester and add filter if provided
        req = ServicesRequester(self.sqlsess)
        req.select_mission(args.mission)

        if args.filters_combined:
            for filt in args.filter:
                logger.info('Applying filters on mission scope: {filter}'.format(
                    filter=filt))
            if len(args.filter) > 1:
                logger.info('Note: Logical OR is applied between each filter')
            req.add_filter(args.filters_combined)

        # Retrieve targeted services from database
        services = req.get_results()
        if not services:
            raise AttackException('There is no matching service to target into the ' \
                'database')

        # Add each targeted service into Attack scope 
        for service in services:

            # Update credentials, options, products if specified in command-line
            if args.creds:
                for c in args.creds[service.name]: 
                    service.add_credential(c.clone())
            if args.users:
                for u in args.users[service.name]: 
                    service.add_credential(u.clone())
            if args.products:
                for p in args.products[service.name]: 
                    service.add_product(p.clone())
            if args.options:
                for o in args.options[service.name]: 
                    service.add_option(o.clone())

            # Initialize Target 
            try:
                target = Target(service, self.settings.services)
            except TargetException as e:
                logger.error(e)
                continue

            self.attack_scope.add_target(target)

        # Run the attack
        self.attack_scope.attack()
 def delete(self):
     results = self.get_results()
     if not results:
         logger.error('No mission with this name')
     else:
         for r in results:
             self.sqlsess.delete(r)
         self.sqlsess.commit()
         logger.success('Mission deleted')
 def edit_comment(self, comment):
     results = self.get_results()
     if not results:
         logger.error('No matching credential')
     else:
         for r in results:
             r.comment = comment
         self.sqlsess.commit()
         logger.success('Comment edited')
 def edit_comment(self, comment):
     results = self.get_results()
     if not results:
         logger.error('No mission with this name')
     else:
         for r in results:
             r.comment = comment
         self.sqlsess.commit()
         logger.success('Comment edited')
 def change_current_mission(self, name, verbose=False):
     mission = self.sqlsess.query(Mission).filter(Mission.name == name).first()
     if not mission:
         logger.error('No mission with this name')
     else:
         self.current_mission = name
         self.prompt = Output.colored('jok3rdb', color='light_green', attrs='bold') + \
                       Output.colored('[{mission}]'.format(mission=name), color='light_blue', attrs='bold') + \
                       Output.colored('> ', color='light_green', attrs='bold')
         if verbose: logger.info('Selected mission is now {name}'.format(name=name))
 def switch_https(self):
     results = self.get_results()
     if not results:
         logger.error('No matching service')
     else:
         for r in results:
             if r.url:
                 r.url = WebUtils.switch_http_https(r.url)
         self.sqlsess.commit()
         logger.success('Switch done')
Esempio n. 25
0
    def run(self):

        # Extract HTTP services from the mission in database
        req = ServicesRequester(self.sqlsession)
        req.select_mission(self.mission_name)
        filter_ = Filter(FilterOperator.AND)
        filter_.add_condition(Condition('http', FilterData.SERVICE_EXACT))
        req.add_filter(filter_)
        services = req.get_results()

        if len(services) == 0:
            return

        logger.info('Taking web page screenshots for HTTP services (total: ' \
            '{nb})...'.format(nb=len(services)))

        screenshoter = WebScreenshoter()
        if not screenshoter.create_driver():
            logger.error('No screenshot will be added to the report')
            return

        i = 1
        for s in services:
            if s.screenshot is not None \
                    and s.screenshot.status == ScreenStatus.OK \
                    and s.screenshot.image is not None \
                    and s.screenshot.thumbnail is not None:
                logger.info('[{i}/{nb}] Screenshot already in database for {url}'.format(
                    i=i, nb=len(services), url=s.url))

            else:
                logger.info('[{i}/{nb}] Taking screenshot for {url}...'.format(
                    i=i, nb=len(services), url=s.url))
                status, screen = screenshoter.take_screenshot(s.url)

                # Create Screenshot entry in database if necessary
                if s.screenshot is None:
                    screenshot = Screenshot(status=status)
                    self.sqlsession.add(screenshot)
                    s.screenshot = screenshot
                    self.sqlsession.commit()

                # Create thumbnail if status is OK
                if status == ScreenStatus.OK:
                    thumb = ImageUtils.create_thumbnail(screen, 300, 300)
                    if not thumb:
                        status = ScreenStatus.ERROR
                    s.screenshot.status = status
                    s.screenshot.image = screen
                    s.screenshot.thumbnail = thumb
                else:
                    s.screenshot.status = status
            self.sqlsession.commit()

            i += 1
Esempio n. 26
0
    def add_cred(self, service_id, username, password, auth_type=None):
        """
        Add new credential for a given service.
        :param int service_id: Id of service
        :param str username: Username
        :param str password: Password (None if unknown)
        :param str auth_type: Authentication type for HTTP service
        """
        cred = self.sqlsess.query(Credential).join(Service)\
                           .filter(Service.id == service_id)\
                           .filter(Credential.username == username)\
                           .filter(Credential.password == password)\
                           .filter(Credential.type == auth_type).first()
        if cred:
            logger.warning('Credential already exists in database')
        else:
            service = self.sqlsess.query(Service).filter(Service.id == service_id)\
                                  .first()
            if not service:
                logger.error(
                    'Service id {id} is invalid'.format(id=service_id))
            else:
                cred = Credential(
                    username=username,
                    password=password,
                    type=auth_type if service.name == 'http' else None)

                self.sqlsess.add(cred)
                service.credentials.append(cred)

                username = '******' if username == '' else username
                password = {
                    '': '<empty>',
                    None: '<???>'
                }.get(password, password)
                auth_typ = '(' + str(auth_type) + ')' if auth_type else ''
                hostname = '(' + service.host.hostname + ')' if service.host.hostname else ''
                protocol = {
                    Protocol.TCP: 'tcp',
                    Protocol.UDP: 'udp'
                }.get(service.protocol)

                logger.success('Credential {username}/{password}{auth_type} added ' \
                    'to service {service} host={ip}{hostname} ' \
                    'port={port}/{proto}'.format(
                    username  = username,
                    password  = password,
                    auth_type = auth_typ,
                    service   = service.name,
                    ip        = service.host.ip,
                    hostname  = hostname,
                    port      = service.port,
                    proto     = protocol))

                self.sqlsess.commit()
Esempio n. 27
0
    def create_driver(self):
        """
        Creates a selenium FirefoxDriver.

        :return: Creation status
        :rtype: bool
        """
        profile = webdriver.FirefoxProfile()

        # Load custom firefox addon to handle basic auth.
        extension_path = os.path.join(
            os.path.dirname(os.path.realpath(__file__)),'dismissauth.xpi')
        profile.add_extension(extension_path)

        # Set user agent if necessary
        if self.user_agent is not None:
            profile.set_preference('general.useragent.override', self.user_agent)

        # Set up our proxy information directly in the firefox profile
        # if cli_parsed.proxy_ip is not None and cli_parsed.proxy_port is not None:
        # profile.set_preference('network.proxy.type', 1)
        #     if "socks" in cli_parsed.proxy_type:
        #     profile.set_preference('network.proxy.socks', cli_parsed.proxy_ip)
        #     profile.set_preference('network.proxy.socks_port', cli_parsed.proxy_port)
        #     profile.set_preference('network.proxy.socks_remote_dns', True)
        # else:
        #     profile.set_preference('network.proxy.http', cli_parsed.proxy_ip)
        #     profile.set_preference(
        #     'network.proxy.http_port', cli_parsed.proxy_port)
        #     profile.set_preference('network.proxy.ssl', cli_parsed.proxy_ip)
        #     profile.set_preference('network.proxy.ssl_port', cli_parsed.proxy_port)

        profile.set_preference('app.update.enabled', False)
        profile.set_preference('browser.search.update', False)
        profile.set_preference('extensions.update.enabled', False)
        profile.set_preference('capability.policy.default.Window.alert', 'noAccess')
        profile.set_preference('capability.policy.default.Window.confirm', 'noAccess')
        profile.set_preference('capability.policy.default.Window.prompt', 'noAccess')

        try:
            capabilities = DesiredCapabilities.FIREFOX.copy()
            capabilities.update({'acceptInsecureCerts': True})
            options = Options()
            options.add_argument("--headless")
            driver = webdriver.Firefox(
                profile, capabilities=capabilities, options=options)
            driver.set_page_load_timeout(self.timeout)
            self.driver = driver
            return True
        except Exception as e:
            if 'Failed to find firefox binary' in str(e):
                logger.error('Firefox not found! You can fix this by installing Firefox')
            else:
                logger.error(e)
            return False
Esempio n. 28
0
 def switch_https(self):
     """Switch between HTTP and HTTPS on selected services"""
     results = self.get_results()
     if not results:
         logger.error('No matching service')
     else:
         for r in results:
             if r.url:
                 r.url = WebUtils.switch_http_https(r.url)
         self.sqlsess.commit()
         logger.success('Switch done')
Esempio n. 29
0
    def add_cred(self, username, password, auth_type=None):
        """
        Add new credential for selected service(s).

        :param str username: Username
        :param str password: Password (None if unknown)
        :param str auth_type: Authentication type for HTTP service
        """
        results = self.get_results()
        if not results:
            logger.error('No matching service')
        else:
            for r in results:
                cred = self.sqlsess.query(Credential).join(Service)\
                                   .filter(Service.id == r.id)\
                                   .filter(Credential.username == username)\
                                   .filter(Credential.password == password)\
                                   .filter(Credential.type == auth_type).first()
                if not cred:
                    cred = Credential(
                        username=username,
                        password=password,
                        type=auth_type if r.name == 'http' else None)

                    self.sqlsess.add(cred)
                    r.credentials.append(cred)

                    username = '******' if cred.username == '' else cred.username
                    password = {
                        '': '<empty>',
                        None: '<???>'
                    }.get(cred.password, cred.password)
                    auth_type = '('+str(auth_type)+')' if \
                        (auth_type and r.name == 'http') else ''
                    hostname = '(' + r.host.hostname + ')' if r.host.hostname else ''
                    protocol = {
                        Protocol.TCP: 'tcp',
                        Protocol.UDP: 'udp'
                    }.get(r.protocol)

                    logger.success('Credential {username}/{password}{auth_type} ' \
                        'added to service {service} host={ip}{hostname} ' \
                        'port={port}/{proto}'.format(
                            username  = username,
                            password  = password,
                            auth_type = auth_type,
                            service   = r.name,
                            ip        = r.host.ip,
                            hostname  = hostname,
                            port      = r.port,
                            proto     = protocol))

            self.sqlsess.commit()
Esempio n. 30
0
    def __check_args_attack_bruteforce(self):
        """Check arguments for subcommand Attack > Bruteforce options"""

        #for f in self.args.userlist, self.args.passlist, self.args.weblist:
        for f in self.args.userlist, self.args.passlist:
            if f:
                if not FileUtils.can_read(f):
                    logger.error('File {file} does not exist or cannot be read'.format(
                        file=f))
                    return False

        return True