def run(self):
        args = self.arguments.args
        self.creds = defaultdict(list)
        self.users = defaultdict(list)
        self.options = defaultdict(list)

        # Load smart modules
        self.smartmodules_loader = SmartModulesLoader(self.sqlsess,
                                                      self.settings.services)

        # Initialize provided credentials
        if args.creds:
            for c in args.creds:
                self.creds[c['service']].append(
                    Credential(type=c['auth_type'],
                               username=c['username'],
                               password=c['password']))

        # Initialize provided single usernames
        if args.users:
            for u in args.users:
                self.users[c['service']].append(
                    Credential(type=u['auth_type'],
                               username=u['username'],
                               password=None))

        # Initialize provided context-specific options
        if args.specific:
            for option_name in args.specific:
                service = self.settings.services.get_service_for_specific_option(
                    option_name)
                if service:
                    self.options[service].append(
                        Option(name=option_name,
                               value=args.specific[option_name]))

        # Run the attack
        self.attack_scope = AttackScope(self.settings,
                                        ResultsRequester(self.sqlsess),
                                        self.smartmodules_loader,
                                        args.cat_only,
                                        args.checks,
                                        fast_mode=args.fast_mode)

        begin = time.time()
        if args.target_ip_or_url:
            self.__run_for_single_target(args)
        else:
            self.__run_for_multi_targets(args)

        print()
        logger.info('Done. Time spent: {0} seconds'.format(time.time() -
                                                           begin))
 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()
 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()
예제 #4
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()
예제 #5
0
    def add_credentials(self, username, password, auth_type=None):
        # Do not add too times the same credentials
        for c in self.credentials:
            if c.type == auth_type and c.username == username and c.password == password:
                return

        if auth_type:
            auth_type = auth_type.lower()
            
        self.credentials.append(
            Credential(type=auth_type, username=username, password=password))
예제 #6
0
    def add_username(self, username, auth_type=None):
        # Do not add too times the same username
        for u in self.usernames:
            if u.type == auth_type and u.username == username and u.password == None:
                return
                
        if auth_type:
            auth_type = auth_type.lower()

        self.usernames.append(
            Credential(type=auth_type, username=username, password=None))
예제 #7
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()
예제 #8
0
    def __check_args_attack_context_user(self):
        """
        Check arguments for subcommand Attack > Context parameters > --user
        Syntax: --user [<svc>[.<type>]] <user>

        If some usernames submitted, self.args.users is turned into a dict
        { service name: list(Credential) }
        """

        if not self.args.users:
            return True

        users = defaultdict(list)
        for user in self.args.users:
            current_user = Credential(
                type='',  # relevant for HTTP
                username='',
                password=None)

            # When format is: <svc>[.<type>] <user>
            if len(user) == 2:
                if '.' in user[0]:
                    svc, auth_type = user[0].split('.', maxsplit=1)
                    svc = svc.lower()
                    if svc != 'http':
                        logger.error('Auth-type in --user is only supported with ' \
                            'HTTP. Syntax: --user http.<auth-type> <username>')
                        return False

                    elif not self.settings.services.is_valid_auth_type(
                            auth_type):
                        logger.error('Invalid authentication type provided in --user. ' \
                            'Check "info --list-http-auth".')
                        return False

                    current_user.type = auth_type

                else:
                    svc = user[0].lower()
                    if not self.settings.services.is_service_supported(svc):
                        logger.error('Service "{svc}" in --user is not ' \
                            'supported'.format(svc=svc))
                        return False

                if self.args.service and self.args.service != svc:
                    logger.error('Single target mode selected but targeted service ' \
                        '({tgt_svc}) is different from service specified in --user ' \
                        '({user_svc})'.format(tgt_svc=self.args.service, user_svc=svc))
                    return False

                current_user.username = user[1]
                users[svc].append(current_user)

            # When format is simply: <user>
            # Accepted only in single target mode
            else:
                if self.args.service:
                    current_user.username = user[0]
                    users[self.args.service].append(current_user)
                else:
                    logger.error('Service must be specified in --user in multi targets' \
                        ' mode. Syntax: --user <service> <user>')
                    return False

        # Turn self.args.users into a dict { service name: list(Credential)}
        self.args.users = users
        return True
예제 #9
0
 def add_credentials(self, username, password, auth_type=None):
     self.credentials.append(
         Credential(type=auth_type, username=username, password=password))
예제 #10
0
 def add_username(self, username, auth_type=None):
     self.usernames.append(
         Credential(type=auth_type, username=username, password=None))
예제 #11
0
    def run(self):
        """Run the Attack Controller"""

        args = self.arguments.args

        # Context parameters are organized in dict 
        # { service : list of db objects }
        self.creds    = defaultdict(list)
        self.users    = defaultdict(list)
        self.products = defaultdict(list)
        self.options  = defaultdict(list)

        if args.creds:
            for c in args.creds:
                self.creds[c['service']].append(
                    Credential(type=c['auth_type'], 
                               username=c['username'], 
                               password=c['password']))
        if args.users:
            for u in args.users:
                self.users[c['service']].append(
                    Credential(type=u['auth_type'], 
                               username=u['username'], 
                               password=None))

        if args.products:
            for type_,name in args.products.items():
                service = self.settings.services.get_service_for_product_type(type_)
                if service:
                    self.products[service].append(
                        Product(type=type_,
                                name=name))

        if args.options:
            for name, value in args.options.items():
                service = self.settings.services.get_service_for_specific_option(name)
                if service:
                    self.options[service].append(
                        Option(name=name, 
                               value=value))

        # Attack configuration
        categories = self.settings.services.list_all_categories() # default: all

        if args.cat_only:
            categories = [ cat for cat in categories if cat in args.cat_only ]
        elif args.cat_exclude:
            categories = [ cat for cat in categories if cat not in args.cat_exclude ]

        # Run the attack
        self.attack_scope = AttackScope(self.settings, 
                                        self.arguments,
                                        self.sqlsess,
                                        args.mission or args.add,
                                        filter_categories=categories, 
                                        filter_checks=args.checks, 
                                        attack_profile=args.profile,
                                        fast_mode=args.fast_mode)

        begin = datetime.datetime.now()
        if args.target_ip_or_url:
            self.__run_for_single_target(args)
        else:
            self.__run_for_multi_targets(args)
            
        print()
        duration = datetime.datetime.now() - begin
        logger.info('Done. Time spent: {} seconds'.format(duration.seconds))