Exemple #1
0
def run():
    initEngine()
    # Coroutine mode
    outputscreen.success('[+] Coroutine mode')
    gevent.joinall([gevent.spawn(scan) for i in range(0, th.thread_num)])
    if 'errmsg' in th:
        outputscreen.error(th.errmsg)
Exemple #2
0
def ScriptRegister(args):

    # handle no scripts
    if not args.script_name:
        msg = '[-] Use -s to load script. Example: [-s spider] or [-s ./script/spider.py]'
        outputscreen.error(msg)
        sys.exit()

    # handle input: "-s ./script/spider.py"
    if os.path.split(args.script_name)[0]:
        if os.path.exists(args.script_name):
            if os.path.isfile(args.script_name):
                if args.script_name.endswith('.py'):
                    conf.module_name = os.path.split(args.script_name)[-1]
                    conf.module_path = os.path.abspath(args.script_name)
                else:
                    msg = '[-] [%s] not a Python file. Example: [-s spider] or [-s ./scripts/spider.py]' % args.script_name
                    outputscreen.error('[-] ' + msg)
                    sys.exit()
            else:
                msg = '[-] [%s] not a file. Example: [-s spider] or [-s ./scripts/spider.py]' % args.script_name
                outputscreen.error(msg)
                sys.exit()
        else:
            msg = '[-] [%s] not found. Example: [-s spider] or [-s ./scripts/spider.py]' % args.script_name
            outputscreen.error(msg)
            sys.exit()

    # handle input: "-s spider"  "-s spider.py"
    else:
        if not args.script_name.endswith('.py'):
            args.script_name += '.py'
        _path = os.path.abspath(
            os.path.join(paths.SCRIPT_PATH, args.script_name))
        if os.path.isfile(_path):
            conf.module_name = args.script_name
            conf.module_path = os.path.abspath(_path)
        else:
            msg = '[-] Script [%s] not exist. Use [--show] to view all available script in ./scripts/' % args.script_name
            outputscreen.error(msg)
            sys.exit()

    # loader POC module to conf.module_obj
    msg = '[+] Load custom script: %s' % conf.module_name
    outputscreen.success(msg)

    fp, pathname, description = imp.find_module(
        os.path.splitext(conf.module_name)[0], [paths.SCRIPT_PATH])
    try:
        conf.module_obj = imp.load_module("_", fp, pathname, description)
        for each in ESSENTIAL_MODULE_METHODS:
            if not hasattr(conf.module_obj, each):
                msg = "[-] Can't find essential method:'%s' in current script,Please modify your script." % each
                outputscreen.error(msg)
                sys.exit(0)
    except ImportError as e:
        msg = "[-] Your current script [%s.py] caused this exception\n%s\n%s" \
                   % (conf.module_name, '[Error Msg]: ' + str(e), 'Maybe you can download this module from pip or easy_install')
        outputscreen.error(msg)
        sys.exit(0)
Exemple #3
0
def TargetRegister(args):
    """
    加载目标模块
    """
    msg = '[*] Initialize targets...'
    outputscreen.warning(msg)

    #初始化目标队列
    conf.target = queue.Queue()

    # 用户输入入队
    if args.target_input:
        # 尝试解析目标地址
        try:
            lists = parseTarget(args.target_input)
        except:
            helpmsg = "Invalid input in [-i], Example: -i [http://]target.com or 192.168.1.1[/24] or 192.168.1.1-192.168.1.100"
            outputscreen.error(helpmsg)
            sys.exit()
        # 判断处理量
        if (len(lists)) > 100000:
            warnmsg = "[*] Loading %d targets, Maybe it's too much, continue? [y/N]" % (
                len(lists))
            outputscreen.warning(warnmsg)
            flag = input()
            if flag in ('Y', 'y', 'yes', 'YES', 'Yes'):
                pass
            else:
                msg = '[-] User quit!'
                outputscreen.warning(msg)
                sys.exit()
        msg = '[+] Load targets from: %s' % args.target_input
        outputscreen.success(msg)
        # save to conf
        for target in lists:
            conf.target.put(target)
        conf.target_nums = conf.target.qsize()

    # 文件读入入队
    elif args.target_file:
        if not os.path.isfile(args.target_file):
            msg = '[-] TargetFile not found: %s' % args.target_file
            outputscreen.error(msg)
            sys.exit()
        msg = '[+] Load targets from: %s' % args.target_file
        outputscreen.success(msg)
        with open(args.target_file, 'r', encoding='utf-8') as f:
            targets = f.readlines()
            for target in targets:
                target = target.strip('\n')
                parsed_target = parseTarget(target)
                for i in parsed_target:
                    conf.target.put(i)
        conf.target_nums = conf.target.qsize()

    #验证目标数量
    if conf.target.qsize() == 0:
        errormsg = msg = '[!] No targets found.Please load targets with [-i|-iF]'
        outputscreen.error(errormsg)
        sys.exit()
Exemple #4
0
    def _give_it_a_try(self):
        """Every time this method is called it will request a random resource
            the target domain. Return value is a dictionary with values as
            HTTP response code, resquest size, md5 of the content and the content
            itself. If there were a redirection it will record the new url"""
        s = []
        for n in range(0, 42):
            random.seed()
            s.append(chr(random.randrange(97, 122)))
        s = "".join(s)
        target = self.target + s

        outputscreen.success("[+] Checking with %s" % target)

        page = requests.get(target, headers=user_agent, verify=False)
        content = page.content

        result = {'code': str(page.status_code),
                  'size': len(content),
                  'md5': hashlib.md5(content).hexdigest(),
                  'content': content,
                  'location': None}

        if len(page.history) >= 1:
            result['location'] = page.url

        return result
Exemple #5
0
    def login(self):
        msg = '[+] Trying to login with credentials in config file: %s.' % paths.CONFIG_PATH
        outputscreen.success(msg)
        self.api_key = ConfigFileParser().shodan_apikey()

        if not self.api_key:
            msg = '[*] Automatic authorization failed.'
            outputscreen.warning(msg)
            msg = '[*] Please input your Shodan API Key (https://account.shodan.io/).'
            outputscreen.warning(msg)
            self.api_key = input('[*] API KEY > ').strip()
Exemple #6
0
def initEngine():
    # init control parameter
    th.result = []
    th.thread_num = conf.thread_num
    th.target = conf.target
    #是否继续扫描标志位
    th.is_continue = True
    #控制台宽度
    th.console_width = getTerminalSize()[0] - 2
    #记录开始时间
    th.start_time = time.time()
    msg = '[+] Set the number of thread: %d' % th.thread_num
    outputscreen.success(msg)
Exemple #7
0
def loadSingleDict(path):
    '''
    @description: 添加单个字典文件
    @param {path:字典文件路径} 
    @return: 
    '''
    try:
        outputscreen.success('[+] Load dict:{}'.format(path))
        #加载文件时,使用utf-8编码,防止出现编码问题
        with open(path, encoding='UTF-8') as single_file:
            return single_file.read().splitlines()
    except Exception as e:
        outputscreen.error('[x] plz check file path!\n[x] error:{}'.format(e))
Exemple #8
0
 def account_info(self):
     try:
         if not self.api_key:
             outputscreen.error("[-] Shodan api cant not be Null")
             sys.exit()
         api = Shodan(self.api_key)
         account_info = api.info()
         msg = "[+] Available Shodan query credits: %d" % account_info.get(
             'query_credits')
         outputscreen.success(msg)
     except APIError as e:
         outputscreen.error(e)
         sys.exit()
     return True
Exemple #9
0
def run():
    initEngine()
    if th.thread_mode:
        # set lock for multi_threaded mode
        setThreadLock()
        outputscreen.success('[+] Set working way Multi-Threaded mode')
        outputscreen.success('[+] Set the number of thread: %d' %
                             th.concurrent_num)
        for i in range(th.concurrent_num):
            t = threading.Thread(target=scan, name=str(i))
            t.setDaemon(True)
            t.start()
        # It can quit with Ctrl-C
        while th.concurrent_count > 0 and th.is_continue:
            time.sleep(0.01)

    # Coroutine mode
    else:
        outputscreen.success('[+] Set working way Coroutine mode')
        outputscreen.success('[+] Set the number of Coroutine: %d' %
                             th.concurrent_num)
        gevent.joinall(
            [gevent.spawn(scan) for i in range(0, th.concurrent_num)])

    # save result to output file
    if not th.no_output:
        output2file(th.result)
    printProgress()
    if 'errmsg' in th:
        outputscreen.error(th.errmsg)
Exemple #10
0
    def auto_login(self):
        msg = '[+] Trying to login with credentials in config file: %s.' % paths.CONFIG_PATH
        outputscreen.success(msg)
        try:
            self.username = ConfigFileParser().ZoomEyeEmail()
            self.password = ConfigFileParser().ZoomEyePassword()
        except:
            pass

        if bool(self.username and self.password):
            if self.get_token():
                return

        msg = '[*] Automatic authorization failed.'
        outputscreen.warning(msg)
        self.manual_login()
Exemple #11
0
def Output(args):
    if args.no_output and args.output_path:
        msg = '[-] Cannot use [-oF] and [-o] together, please read the usage with [-h].'
        outputscreen.error(msg)
        sys.exit()

    conf.no_output = args.no_output 
    
    if not args.no_output:
        # if not define output, named it by time
        if not args.output_path:
            filename= time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()) +'.txt'

        conf.output_path = os.path.join(paths.OUTPUT_PATH, filename)
        msg = '[+] Output: %s' % conf.output_path
        outputscreen.success(msg)
Exemple #12
0
def initEngine():
    # init control parameter
    th.result = []
    th.thread_count = th.thread_num = conf.thread_num
    th.module_name = conf.module_name
    th.module_path = conf.module_path
    th.module_obj = conf.module_obj
    th.target = conf.target
    th.no_output = conf.no_output
    th.output_path = conf.output_path
    th.scan_count = th.found_count = 0
    th.is_continue = True
    th.console_width = getTerminalSize()[0] - 2
    th.start_time = time.time()
    setThreadLock()
    msg = '[+] Set the number of thread: %d' % th.thread_num
    outputscreen.success(msg)
Exemple #13
0
    def check_this(self):
        """Get the a request and decide what to do"""
        first_result = self._give_it_a_try()

        if first_result['code'] == '404':
            outputscreen.success("Got a nice 404, problems not expected")
            # Ok, resquest gave a 404 so we should not find problems
            return '', Inspector.TEST404_OK

        elif first_result['code'] == '302' or first_result['location']:
            location = first_result['location']
            return location, Inspector.TEST404_URL

        else:
            return first_result['md5'], Inspector.TEST404_MD5

        # We give up here :(
        return '', Inspector.TEST404_NONE
Exemple #14
0
def handle_google(query, limit, offset=0):
    key = ConfigFileParser().google_developer_key()
    engine = ConfigFileParser().google_engine()
    if not key or not engine:
        msg = "[-] Please config your 'developer_key' and 'search_enging' at saucerfram.conf"
        outputscreen.error(msg)
        sys.exit()
    try:
        service = build("customsearch",
                        "v1",
                        http=_initHttpClient(),
                        developerKey=key)

        result_info = service.cse().list(q=query, cx=engine).execute()
        msg = '[+] Max query results: %s' % str(
            result_info.get('searchInformation', {}).get('totalResults'))
        outputscreen.success(msg)

        ans = set()
        limit += offset
        for i in range(int(offset / 10), int((limit + 10 - 1) / 10)):
            result = service.cse().list(q=query,
                                        cx=engine,
                                        num=10,
                                        start=i * 10 + 1).execute()
            if 'items' in result:
                for url in result.get('items'):
                    ans.add(url.get('link'))
        for t in ans:
            conf.target.put(t)

    except SocketError:
        outputscreen.error(
            '[-] Unable to connect Google, maybe agent/proxy error.')
        sys.exit()
    except ServerHttpDenied as e:
        outputscreen.warning(
            '[-] It seems like Google-Server denied this request.')
        outputscreen.error(e)
        sys.exit()
Exemple #15
0
def handle_fofa(query, limit, offset=0):
    try:
        msg = '[+] Trying to login with credentials in config file: %s.' % paths.CONFIG_PATH
        outputscreen.success(msg)
        email = ConfigFileParser().fofa_email()
        key = ConfigFileParser().fofa_key()
        if check(email, key):
            pass
        else:
            raise  # will go to except block
    except:
        msg = '[*] Automatic authorization failed.'
        outputscreen.warning(msg)
        msg = '[*] Please input your FoFa Email and API Key below.'
        outputscreen.warning(msg)
        email = input("[*] Fofa Email: ").strip()
        key = input('[*] Fofa API Key: ').strip()
        if not check(email, key):
            msg = '[-] Fofa API authorization failed, Please re-run it and enter a valid key.'
            outputscreen.error(msg)
            sys.exit()

    query = base64.b64encode(query)

    request = "https://fofa.so/api/v1/search/all?email={0}&key={1}&qbase64={2}".format(
        email, key, query)
    try:
        response = requests.get(request)
        resp = response.readlines()[0]
        resp = json.loads(resp)
        if resp["error"] is None:
            for item in resp.get('results'):
                cong.target.append(item[0])
            if resp.get('size') >= 100:
                outputscreen.warning(
                    "{0} items found! just 100 returned....".format(
                        resp.get('size')))
    except Exception as e:
        outputscreen.error(e)
        sys.exit()
Exemple #16
0
def handle_zoomeye(query, limit=50, type='host', offset=0):
    z = ZoomEye()
    z.auto_login()
    info = z.resources_info().get('resources')
    if info:
        msg = '[+] Available ZoomEye search: (search:%s)' % (info.get(
            'search', 'NO FOUND'))
        outputscreen.success(msg)
    else:
        msg = '[-] ZoomEye API authorization failed, Please re-run it and enter a new token.'
        outputscreen.error(msg)
        sys.exit()
    # 开始爬取
    limit += offset
    for page_n in range(int(offset / 10), int((limit + 9) / 10)):
        data = z.dork_search(query, page=page_n, resource=type)
        if data:
            for i in data:
                ip_str = i.get('ip')
                if 'portinfo' in i:
                    ip_str = ip_str + ':' + str(i.get('portinfo').get('port'))
                conf.target.put(ip_str)
        else:
            break
Exemple #17
0
def checkShow(args):
    # if show scripts 
    if args.show_scripts:
        module_name_list = os.listdir(paths.SCRIPT_PATH)
        outputscreen.success('[+] Script Name ')
        order = 1
        for module in module_name_list:
            if module != '__init__.py' and os.path.splitext(module)[1] == '.py':
                outputscreen.success(str(order)+ '. ' +module)
                order += 1
        msg = '\n' + ' ' * 20 + 'Total: %d' % (order-1)
        outputscreen.success(msg)
        sys.exit()
Exemple #18
0
def bruter(url):
    '''
    @description: 扫描插件入口函数
    @param {url:目标} 
    @return: 
    '''
    #全局target的url,给crawl、fuzz模块使用。FIXME
    conf.url = url
    #url初始化
    conf.parsed_url = urllib.parse.urlparse(url)
    #填补协议
    if conf.parsed_url.scheme != 'http' and conf.parsed_url.scheme != 'https':
        url = 'http://' + url
        conf.parsed_url = urllib.parse.urlparse(url)
    #填补url后的/
    if not url.endswith('/'):
        url = url + '/'

    #自动识别404-预先获取404页面特征
    if conf.auto_check_404_page:
        outputscreen.warning("[*] Launching auto check 404")
        # Autodiscriminator (probably deprecated by future diagnostic subsystem)
        i = Inspector(url)
        (result, notfound_type) = i.check_this()
        if notfound_type == Inspector.TEST404_URL:
            conf.autodiscriminator_location = result
            outputscreen.success("[+] 404 ---> 302 ----> {}".format(
                conf.autodiscriminator_location))
        elif notfound_type == Inspector.TEST404_MD5:
            conf.autodiscriminator_md5 = result
            outputscreen.success("[+] 404 ---> PAGE_MD5 ----> {}".format(
                conf.autodiscriminator_md5))

    #加载payloads
    #添加payloads是否加载成功判断
    payloads.all_payloads = scanModeHandler()
    if payloads.all_payloads == None:
        outputscreen.error('[x] load payloads error!')
        if conf.dict_mode:
            outputscreen.error('[x] plz check dict mode config!')
        if conf.blast_mode:
            outputscreen.error('[x] plz check blast mode config!')
        if conf.crawl_mode:
            outputscreen.error('[x] plz check crawl mode config!')
        if conf.fuzz_mode:
            outputscreen.error('[x] plz check fuzz mode config!')
        sys.exit()
    #FIXME:设置后缀名。当前以拼接方式实现,遍历一遍payload。
    try:
        if conf.file_extension:
            outputscreen.warning('[+] Use file extentsion: {}'.format(
                conf.file_extension))
            for i in range(len(payloads.all_payloads)):
                payloads.all_payloads[i] += conf.file_extension
    except:
        outputscreen.error('[+] plz check extension!')
    #debug模式,打印所有payload,并退出
    if conf.debug:
        outputscreen.blue('[+] all payloads:{}'.format(payloads.all_payloads))
        sys.exit()
    #payload入队task队列
    for payload in payloads.all_payloads:
        #FIXME:添加fuzz模式时,引入的url_payload构造判断
        if conf.fuzz_mode:
            url_payload = conf.parsed_url.scheme + '://' + conf.parsed_url.netloc + payload
        else:
            url_payload = url + payload
        #payload入队,等待处理
        tasks.all_task.put(url_payload)
    #设置进度条长度,若是递归模式,则不设置任务队列长度,即无法显示进度,仅显示耗时
    if not conf.recursive_scan:
        tasks.task_length = tasks.all_task.qsize()
        bar.log.start(tasks.task_length)
    #FIXME:循环任务数不能一次性取完所有的task,暂时采用每次执行30个任务。这样写还能解决hub.LoopExit的bug
    while not tasks.all_task.empty():
        all_task = [gevent.spawn(boss) for i in range(conf.request_limit)]
        gevent.joinall(all_task)
Exemple #19
0
def bruter(url):
    '''
    @description: 扫描插件入口函数
    @param {url:目标}
    @return:
    '''

    #url初始化
    conf.parsed_url = urllib.parse.urlparse(url)
    #填补协议
    if conf.parsed_url.scheme != 'http' and conf.parsed_url.scheme != 'https':
        url = 'http://' + url
        conf.parsed_url = urllib.parse.urlparse(url)
    #全局target的url,给crawl、fuzz模块使用。XXX:要放在填补url之前,否则fuzz模式会出现这样的问题:https://target.com/phpinfo.{dir}/
    conf.url = url
    #填补url后的/
    if not url.endswith('/'):
        url = url + '/'

    #打印当前target
    msg = '[+] Current target: {}'.format(url)
    outputscreen.success('\r' + msg + ' ' * (th.console_width - len(msg) + 1))
    #自动识别404-预先获取404页面特征
    if conf.auto_check_404_page:
        outputscreen.warning("[*] Launching auto check 404")
        # Autodiscriminator (probably deprecated by future diagnostic subsystem)
        i = Inspector(url)
        (result, notfound_type) = i.check_this()
        if notfound_type == Inspector.TEST404_MD5 or notfound_type == Inspector.TEST404_OK:
            conf.autodiscriminator_md5.add(result)

    #加载payloads
    payloads.all_payloads = scanModeHandler()
    #FIXME:设置后缀名。当前以拼接方式实现,遍历一遍payload。
    try:
        if conf.file_extension:
            outputscreen.warning('[+] Use file extentsion: {}'.format(
                conf.file_extension))
            for i in range(len(payloads.all_payloads)):
                payloads.all_payloads[i] += conf.file_extension
    except:
        outputscreen.error('[+] plz check extension!')
        sys.exit()
    #debug模式,打印所有payload,并退出
    if conf.debug:
        outputscreen.blue('[+] all payloads:{}'.format(payloads.all_payloads))
        sys.exit()
    #payload入队task队列
    for payload in payloads.all_payloads:
        #FIXME:添加fuzz模式时,引入的url_payload构造判断
        if conf.fuzz_mode:
            url_payload = conf.parsed_url.scheme + '://' + conf.parsed_url.netloc + payload
        else:
            url_payload = url + payload
        #print(url_payload)
        #payload入队,等待处理
        tasks.all_task.put(url_payload)
    #设置进度条长度,若是递归模式或爬虫模式,则不设置任务队列长度,即无法显示进度,仅显示耗时
    if not conf.recursive_scan:
        #NOTE:这里取所有payloads的长度*target数量计算任务总数,修复issue#2
        tasks.task_length = len(payloads.all_payloads) * conf.target_nums
        bar.log.start(tasks.task_length)
    #FIXME:循环任务数不能一次性取完所有的task,暂时采用每次执行30个任务。这样写还能解决hub.LoopExit的bug
    while not tasks.all_task.empty():
        all_task = [gevent.spawn(boss) for i in range(conf.request_limit)]
        gevent.joinall(all_task)
Exemple #20
0
def TargetRegister(args):
    """
    加载目标模块
    """
    msg = '[*] Initialize targets...'
    outputscreen.warning(msg)

    #初始化目标队列
    conf.target = queue.Queue()

    #单目标入队
    if args.target_single:
        msg = '[+] Load target: %s' % args.target_single
        outputscreen.success(msg)
        conf.target.put(args.target_single)

    #多目标入队
    elif args.target_file:
        if not os.path.isfile(args.target_file):
            msg = '[-] TargetFile not found: %s' % args.target_file
            outputscreen.error(msg)
            sys.exit()
        msg = '[+] Load targets from: %s' % args.target_file
        outputscreen.success(msg)
        with open(args.target_file, 'r', encoding='utf8') as f:
            targets = f.readlines()
            for target in targets:
                conf.target.put(target.strip('\n'))

    #ip范围目标入队.e.g. 192.168.1.1-192.168.1.100
    elif args.target_range:
        try:
            lists = genIP(args.target_range)
            if (len(lists)) > 100000:
                warnmsg = "[*] Loading %d targets, Maybe it's too much, continue? [y/N]" % (
                    len(lists))
                outputscreen.warning(warnmsg)
                flag = input()
                if flag in ('Y', 'y', 'yes', 'YES', 'Yes'):
                    pass
                else:
                    msg = '[-] User quit!'
                    outputscreen.warning(msg)
                    sys.exit()

            msg = '[+] Load targets from: %s' % args.target_range
            outputscreen.success(msg)

            # save to conf
            for target in lists:
                conf.target.put(target)
        except:
            helpmsg = "Invalid input in [-iR], Example: -iR 192.168.1.1-192.168.1.100"
            outputscreen.error(helpmsg)
            sys.exit()

    # ip/mask e.g. 192.168.1.2/24
    elif args.target_network:
        try:
            # get 192.168.1.2 -->192.168.1.0
            ip_format = args.target_network.split('/')
            ip_str = IP(ip_format[0]).strBin()
            ip_str = ip_str[0:int(ip_format[1])] + '0' * (32 -
                                                          int(ip_format[1]))
            ip = "%s.%s.%s.%s" % (
                str(int(ip_str[0:8], 2)), str(int(ip_str[8:16], 2)),
                str(int(ip_str[16:24], 2)), str(int(ip_str[24:32], 2)))

            ip_range = IP('%s/%s' % (ip, ip_format[1]))

            msg = '[+] Load targets from: %s' % args.target_network
            outputscreen.success(msg)

            for i in ip_range:
                conf.target.put(i)
        except:
            msg = "[-] Invalid input in [-iN], Example: -iN 192.168.1.0/24"
            outputscreen.error(msg)
            sys.exit()

    #验证目标数量
    if conf.target.qsize() == 0:
        errormsg = msg = 'No targets found\nPlease load targets with [-iU|-iF|-iR|-iN] or use API with [-aZ|-aS|-aG|-aF]'
        outputscreen.error(errormsg)
        sys.exit()
Exemple #21
0
def TargetRegister(args):
    msg = '[*] Initialize targets...'
    outputscreen.warning(msg)

    # init target queue
    conf.target = queue.Queue()

    # single target to queue
    if args.target_single:
        msg = '[+] Load target : %s' % args.target_single
        outputscreen.success(msg)
        conf.target.put(args.target_single)

    # file target to queue
    elif args.target_file:
        if not os.path.isfile(args.target_file):
            msg = '[-] TargetFile not found: %s' % args.target_file
            outputscreen.error(msg)
            sys.exit()
        msg = '[+] Load targets from : %s' % args.target_file
        outputscreen.success(msg)
        with open(args.target_file, 'r', encoding='utf8') as f:
            targets = f.readlines()
            for target in targets:
                conf.target.put(target.strip('\n'))

    # range of ip target to queue .e.g. 192.168.1.1-192.168.1.100
    elif args.target_range:
        try:
            lists = gen_ip(args.target_range)
            if (len(lists)) > 100000:
                warnmsg = "[*] Loading %d targets, Maybe it's too much, continue? [y/N]" % (
                    len(lists))
                outputscreen.warning(warnmsg)
                flag = input()
                if flag in ('Y', 'y', 'yes', 'YES', 'Yes'):
                    pass
                else:
                    msg = '[-] User quit!'
                    outputscreen.warning(msg)
                    sys.exit()

            msg = '[+] Load targets from : %s' % args.target_range
            outputscreen.success(msg)

            # save to conf
            for target in lists:
                conf.target.put(target)
        except:
            helpmsg = "Invalid input in [-iR], Example: -iR 192.168.1.1-192.168.1.100"
            outputscreen.error(helpmsg)
            sys.exit()

    # ip/mask e.g. 192.168.1.2/24
    elif args.target_network:
        try:
            # get 192.168.1.2 -->192.168.1.0
            ip_format = args.target_network.split('/')
            ip_str = IP(ip_format[0]).strBin()
            ip_str = ip_str[0:int(ip_format[1])] + '0' * (32 -
                                                          int(ip_format[1]))
            ip = "%s.%s.%s.%s" % (
                str(int(ip_str[0:8], 2)), str(int(ip_str[8:16], 2)),
                str(int(ip_str[16:24], 2)), str(int(ip_str[24:32], 2)))

            ip_range = IP('%s/%s' % (ip, ip_format[1]))

            msg = '[+] Load targets from : %s' % args.target_network
            outputscreen.success(msg)

            for i in ip_range:
                conf.target.put(i)
        except:
            msg = "[-] Invalid input in [-iN], Example: -iN 192.168.1.0/24"
            outputscreen.error(msg)
            sys.exit()

    else:
        # set search limit of api
        if args.api_limit <= 0:
            errormsg = 'Invalid input in [-limit] (can not be negative number)'
            outputscreen.error(errormsg)
            sys.exit()
        elif args.api_limit > 100000:
            warnmsg = "Loading %d targets, Maybe it's too much, continue? [y/N]" % (
                len(lists))
            outputscreen.warning(warnmsg)
            flag = input()
            if flag in ('Y', 'y', 'yes', 'YES', 'Yes'):
                pass
            else:
                msg = 'User quit!'
                outputscreen.warning(msg)
                sys.exit()
        conf.limit = args.api_limit

        # set search offset of api
        conf.offset = args.api_offset

        if args.zoomeye_dork:
            # verify search_type for zoomeye
            if args.search_type not in ['web', 'host']:
                msg = '[-] Invalid value in [--search-type], show usage with [-h]'
                outputscreen.error(msg)
                sys.exit()
            conf.search_type = args.search_type
            handle_zoomeye(query=args.zoomeye_dork,
                           limit=conf.limit,
                           type=conf.search_type,
                           offset=conf.offset)

        elif args.fofa_dork:
            handle_fofa(query=args.fofa_dork,
                        limit=conf.limit,
                        offset=conf.offset)

        elif args.shodan_dork:
            handle_shodan(query=args.shodan_dork,
                          limit=conf.limit,
                          offset=conf.offset)

        elif args.google_dork:
            conf.google_proxy = args.google_proxy
            handle_google(query=args.google_dork,
                          limit=conf.limit,
                          offset=conf.offset)

    # verify targets number
    if conf.target.qsize() == 0:
        errormsg = msg = 'No targets found\nPlease load targets with [-iU|-iF|-iR|-iN] or use API with [-aZ|-aS|-aG|-aF]'
        outputscreen.error(errormsg)
        sys.exit()