def __run_for_single_target(self, args):
        """
        Run attack against a single target specified into argss
        """
        req = ServicesRequester(self.sqlsess)
        mission = None

        # Get Mission if target must be added into a mission scope
        if args.add:
            mission = self.sqlsess.query(Mission).filter(
                Mission.name == args.add).first()
            if not mission:
                raise AttackException(
                    'The specified mission does not exist in the database. You should create it if needed'
                )

        # Create new Service/Host objects (if service already exist, will be merged by ServicesRequester.add_target)
        service = Service(
            name=args.service,
            port=int(args.target_port),
            protocol={
                'tcp': Protocol.TCP,
                'udp': Protocol.UDP
            }.get(self.settings.services.get_protocol(args.service)),
            url=args.target_ip_or_url
            if args.target_mode == TargetMode.URL else '')
        host = Host(
            ip=args.target_ip_or_url if args.target_mode == TargetMode.IP else
            '')  # Will be updated when initializing Target()
        host.services.append(service)

        # Update credentials and options if needed
        for c in self.creds[args.service]:
            service.credentials.append(c)
        for u in self.users[args.service]:
            service.credentials.append(u)
        for o in self.options[args.service]:
            service.options.append(o)

        # Initialize Target and check if reachable
        target = Target(service, self.settings.services)
        if args.disable_banner_grab:
            logger.info('Check if target is reachable...')
        else:
            logger.info(
                'Check if target is reachable and grab banner using Nmap...')
        reachable = target.smart_check(
            grab_banner_nmap=not args.disable_banner_grab)

        if args.target_mode == TargetMode.IP:
            msg = 'Target {neg}reachable: host {ip} | port {port}/{proto} | service {service}'.format(
                neg='not ' if not reachable else '',
                ip=target.get_ip(),
                port=target.get_port(),
                proto=target.get_protocol(),
                service=target.get_service_name())
        else:
            msg = 'Target URL {url} is {neg}reachable'.format(
                url=target.get_url(), neg='not ' if not reachable else '')

        if reachable:
            service.up = True
            logger.success(msg)
        else:
            raise AttackException(msg)

        # Commit new data into database if target must be added to a mission
        if mission:
            logger.info(
                'Results from this attack will be saved under mission "{mission}" in database'
                .format(mission=mission.name))
            req.select_mission(mission.name)
            req.add_target(target)

        # Run the attack
        self.attack_scope.add_target(target)
        self.attack_scope.attack()
    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
        requester = ServicesRequester(self.sqlsess)
        requester.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('Logical or is applied between each filter')
            requester.add_filter(args.filters_combined)

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

        # Add each targeted service into Attack scope
        logger.info('Checking if targets are reachable...')
        for service in services:
            # Update credentials and options if needed
            for c in self.creds[service.name]:
                service.credentials.append(c)
            for u in self.users[service.name]:
                service.credentials.append(u)
            for o in self.options[service.name]:
                service.options.append(o)

            # Initialize Target and check if reachable
            target = Target(service, self.settings.services)
            service.up = target.smart_check(grab_banner_nmap=False)
            self.sqlsess.commit()

            msg = 'host {ip} | port {port}/{proto} | service {service}'.format(
                ip=target.get_ip(),
                port=target.get_port(),
                proto=target.get_protocol(),
                service=target.get_service_name())
            if service.up:
                logger.success('Target reachable: ' + msg)
            else:
                logger.warning('Target not reachable (skipped): ' + msg)
                continue

            # Update info into database if needed
            #requester.add_target(target)

            self.attack_scope.add_target(target)

        self.attack_scope.attack()