예제 #1
0
def update_custom_database():

    test = core_http.test_http(HOST_CUSTOM, 80)

    if test[0]:

        httpClient = core_http.HTTPClient(HOST_CUSTOM, 80)

        request_tests = core_http.HTTPRequest()
        request_tests.set_method('GET')
        request_tests.set_path(PATH_CUSTOM_TESTS)
        response_tests = httpClient.perform_request(request_tests)

        request_banners = core_http.HTTPRequest()
        request_banners.set_method('GET')
        request_banners.set_path(PATH_CUSTOM_BANNERS)
        response_banners = httpClient.perform_request(request_banners)

        if response_tests != None and response_banners != None:

            if response_tests.get_code(
            ) == u'200' and response_banners.get_code() == u'200':

                db_banners = response_banners.get_data()
                db_tests = response_tests.get_data()

                try:
                    core_file.db_custom_update(db_tests, db_banners)
                    return True

                except IOError:  # typically: permission denied....
                    return False
            else:
                return False
        else:
            return False
    else:
        return False
예제 #2
0
def update_nikto_database():

    test = core_http.test_http(HOST_CIRT, 80)

    if test[0]:

        httpClient = core_http.HTTPClient(HOST_CIRT, 80)

        request_tests = core_http.HTTPRequest()
        request_tests.set_method('GET')
        request_tests.set_path(PATH_NIKTO_TESTS)
        response_tests = httpClient.perform_request(request_tests)

        request_vars = core_http.HTTPRequest()
        request_vars.set_method('GET')
        request_vars.set_path(PATH_NIKTO_VARIABLES)
        response_vars = httpClient.perform_request(request_vars)

        if response_tests != None and response_vars != None:

            if response_tests.get_code() == u'200' and response_vars.get_code(
            ) == u'200':

                db_vars = response_vars.get_data()
                db_tests = response_tests.get_data()

                try:
                    core_file.db_nikto_update(db_tests, db_vars)
                    return True

                except IOError:  # typically: permission denied....
                    return False
            else:
                return False
        else:
            return False
    else:
        return False
예제 #3
0
def perform(hosts, ports, roots, server, skip_string, cli, results, results_lock, switch, switch_lock):
    
# Input:  hosts - [unicode] - list of target hosts or IP addresses
#         ports - [integer] - list of target ports
#         roots - [unicode] - list of root directories
#         server - unicode - force this as the web server
#         skip_string - unicode - user-defined false positive indicator
#         cli - boolean - set verbosity on STDOUT to ON/OFF
#         results - [dict] - (shared) output results list
#         results_lock - threading.Lock - (shared) lock on the output list
#         switch - [boolean] - (shared) switch controlling scan life-cycle (ON/OFF)
#         switch_lock - threading.Lock - (shared) lock on switch
#
# Return: (void)
#
# This function performs a URL scan of on target hosts/ports based on test files. The results
# are appended to the (shared) results list provided as parameter. The scan ends when all
# the applicable entries in the test list(s) lists have been processed or as soon as the (shared)
# switch is 'turned off' (i.e. switch = [False]) by the calling instance (e.g. GUI/CLI).
    
    try:
        
        # loading the list of known webserver banners from database file
        known_banners = core_file.db_load_known_banners()
        
        # Loading and checking the config parameters
        cfParser = core_file.cfg_start_get()
        use_db_nikto = core_file.cfg_get_use_db_nikto(cfParser)
        use_db_custom = core_file.cfg_get_use_db_custom(cfParser)
        threads = core_file.cfg_get_scan_threads(cfParser)
        scan_show_codes_str = core_file.cfg_get_scan_show_codes(core_file.cfg_start_get())
        core_file.cfg_end_get(cfParser)
        
        if not core_utilities.check_threads(threads) or not core_utilities.check_http_codes(scan_show_codes_str):
            
            issue_result(results, results_lock, cli, {u'ERROR': u'Invalid configuration settings.'})
        
        else:
            
            # Nikto tests can be loaded here as they are not dependent on the target
            # they are thus only loaded once (minimizing file access)
            if use_db_nikto:
                nikto_tests = core_file.db_load_nikto_tests()
            
            scan_show_codes = [c.strip() for c in scan_show_codes_str.split(u',')]
            
            hosts_done = []
            
            for host in hosts:
                
                with switch_lock:
                    
                    on = switch[0]
                    
                if not on:
                    break
                
                else:
                    
                    if host in hosts_done:
                        continue
                    else:
                        hosts_done.append(host)
                    
                    ports_done = []
                    ipaddress = core_utilities.get_ip_address(host)
                    
                    for port in ports:
                        
                        with switch_lock:
                            on = switch[0]
                            
                        if not on:
                            break
                        
                        else:
                            
                            if port in ports_done:
                                continue
                            else:
                                ports_done.append(port)
                            
                            issue_result(results, results_lock, cli, {u'HOST': host, u'PORT': unicode(port), u'IPADDRESS': ipaddress, u'TARGET': host + u' / ' + unicode(port)})
                            
                            # test if target is up and valid...
                            http_test = core_http.test_http(host, port)
                            
                            if not http_test[0]:
                                error_message = http_test[1]
                                
                                issue_result(results, results_lock, cli, {u'HOST': host, u'PORT': unicode(port), u'IPADDRESS': ipaddress, u'ERROR': error_message})
                                
                                continue
                                # if the host/port is not valid, skip to next port or next host
                            
                            else: # host/port respond to http
                            
                                # indentify server
                                httpClient = core_http.HTTPClient(host, port)
                                
                                request_404 = core_http.HTTPRequest()
                                request_404.set_method(u'GET')
                                request_404.set_path(u'/' + u''.join([choice(letters + digits) for i in range(8)]))
                                response_404 = httpClient.perform_request(request_404)
                                
                                if response_404 == None:
                                    issue_result(results, results_lock, cli, {u'HOST': host, u'PORT': unicode(port), u'IPADDRESS': ipaddress, u'ERROR': u'HTTP Request to server failed. Scan aborted.'})
                                    
                                    continue
                                    # if these request does not work, the following tests will cause trouble,
                                    # thus consider that host/port is not valid...
                                    
                                else:
                                    
                                    server_known, server_banner, server_id = __identify_server(response_404, known_banners)
                                    
                                    # if the user wants to force the server
                                    if server != u'' and server in known_banners.values():
                                        server_id = server
                                        issue_result(results, results_lock, cli, {u'HOST': host, u'PORT': unicode(port), u'IPADDRESS': ipaddress, u'SERVER': server_id + ' *FORCED', u'BANNER': server_banner})
                                    else:
                                        issue_result(results, results_lock, cli, {u'HOST': host, u'PORT': unicode(port), u'IPADDRESS': ipaddress, u'SERVER': server_id, u'BANNER': server_banner})
                                    
                                    # loading the tests from database
                                    tests_original = []
                                    
                                    if use_db_nikto:
                                        tests_original.extend(nikto_tests)
                                        
                                    if use_db_custom:
                                        tests_original.extend(core_file.db_load_custom_tests([], host, True))

                                    roots_done = []
                                    for root in roots:
                                        
                                        with switch_lock:
                                            on = switch[0]
                                            
                                        if not on:
                                            break
                                        
                                        else:
                                        
                                            if root in roots_done:
                                                continue
                                            else:
                                                roots_done.append(root)
                                        
                                            # fingerprint interesting messages
                                            # root
                                            request_root = core_http.HTTPRequest()
                                            request_root.set_method(u'GET')
                                            request_root.set_path(root)
                                            response_root = httpClient.perform_request(request_root)
                                            # index.php
                                            request_indexphp = core_http.HTTPRequest()
                                            request_indexphp.set_method(u'GET')
                                            request_indexphp.set_path(root + u'index.php')
                                            response_indexphp = httpClient.perform_request(request_indexphp)
                                            # 404 message - or should be
                                            request_404 = core_http.HTTPRequest()
                                            request_404.set_method(u'GET')
                                            request_404.set_path(root + u''.join([choice(letters + digits) for i in range(8)]))
                                            response_404 = httpClient.perform_request(request_404)
                                            
                                            fingerprints = {}
                                            
                                            fingerprints[u'root'] = core_http.fingerprint_response(request_root, response_root)
                                            if fingerprints[u'root'] == None:
                                                issue_result(results, results_lock, cli, {u'HOST': host, u'PORT': unicode(port), u'IPADDRESS': ipaddress, u'ERROR': u'FP(' + request_root.get_path() + ') => failure!'})
                                            else:
                                                issue_result(results, results_lock, cli, {u'HOST': host, u'PORT': unicode(port), u'IPADDRESS': ipaddress, u'INFO': u'FP(' + request_root.get_path() + ') => ' + str(fingerprints[u'root'][0]) + u'#' + str(fingerprints[u'root'][1]) + u'#' + str(fingerprints[u'root'][2]) + u'#' + str(fingerprints[u'root'][3])})
                                               
                                            fingerprints[u'error404'] = core_http.fingerprint_response(request_404, response_404)
                                            if fingerprints[u'error404'] == None:
                                                issue_result(results, results_lock, cli, {u'HOST': host, u'PORT': unicode(port), u'IPADDRESS': ipaddress, u'ERROR': u'FP(' + request_404.get_path() + ') => failure!'})
                                            else:
                                                issue_result(results, results_lock, cli, {u'HOST': host, u'PORT': unicode(port), u'IPADDRESS': ipaddress, u'INFO': u'FP(' + request_404.get_path() + ') => ' + str(fingerprints[u'error404'][0]) + u'#' + str(fingerprints[u'error404'][1]) + u'#' + str(fingerprints[u'error404'][2]) + u'#' + str(fingerprints[u'error404'][3])})
                                               
                                            fingerprints[u'index.php'] = core_http.fingerprint_response(request_indexphp, response_indexphp)
                                            if fingerprints[u'index.php'] == None:
                                                issue_result(results, results_lock, cli, {u'HOST': host, u'PORT': unicode(port), u'IPADDRESS': ipaddress, u'ERROR': u'FP(' + request_indexphp.get_path() + ') => failure!'})
                                            else:
                                                issue_result(results, results_lock, cli, {u'HOST': host, u'PORT': unicode(port), u'IPADDRESS': ipaddress, u'INFO': u'FP(' + request_indexphp.get_path() + ') => ' + str(fingerprints[u'index.php'][0]) + u'#' + str(fingerprints[u'index.php'][1]) + u'#' + str(fingerprints[u'index.php'][2]) + u'#' + str(fingerprints[u'index.php'][3])})
                                            
                                            
                                            # robots.txt
                                            request_robots = core_http.HTTPRequest()
                                            request_robots.set_method(u'GET')
                                            request_robots.set_path(root + u'robots.txt')
                                            response_robots = httpClient.perform_request(request_robots)
                                            
                                            if response_robots.get_code() == u'200':
                                                robots_fingerprint = core_http.fingerprint_response(request_robots, response_robots)
                                                if not core_http.test_response_fingerprint(robots_fingerprint, fingerprints[u'root']) and not core_http.test_response_fingerprint(robots_fingerprint, fingerprints[u'error404']) and not core_http.test_response_fingerprint(robots_fingerprint, fingerprints[u'index.php']):
                                                    issue_result(results, results_lock, cli, {u'HOST': host, u'PORT': unicode(port), u'IPADDRESS': ipaddress, u'INFO': root + u'robots.txt found. It might be interesting to have a look inside.'})
                                            
                                            tests = tests_original[:]
                                            used_triggers = []
                                            triggers = [server_id]
                                            
                                            while len(triggers) > 0:
                                                
                                                with switch_lock:
                                                    on = switch[0]
                                                    
                                                if not on:
                                                    break
                                                else:
                                                    
                                                    if use_db_custom:
                                                        tests.extend(core_file.db_load_custom_tests(triggers, host, False))
                                                    
                                                    used_triggers.extend(triggers)
                                                    triggers = []
                                                    
                                                    running = []
                                                    for i in range(0, threads):
                                                        scan_thread = ScanThread(host, port, ipaddress, root, fingerprints, tests, triggers, skip_string, scan_show_codes, cli, results, results_lock, switch, switch_lock)
                                                        scan_thread.start()
                                                        running.append(scan_thread)
                                                    for thread in running:
                                                        thread.join()
                                                        
                                                    for trigger in triggers:
                                                        if trigger in used_triggers:
                                                            triggers.remove(trigger)
    except core_error.Config_Error, e:
        issue_result(results, results_lock, cli, {u'ERROR': e.error_message})
예제 #4
0
def perform(hosts, ports, roots, mode, modecpl, cli, results, results_lock,
            switch, switch_lock):

    # Input:  hosts - [unicode] - list of target hosts or IP addresses
    #         ports - [integer] - list of target ports
    #         roots - [unicode] - list of root directories
    #         mode - integer - 0 = listmode, 1 = filemode
    #         modecpl - unicode - recursive (list mode) or filename generator (gen mode)
    #         cli - boolean - set verbosity on STDOUT to ON/OFF
    #
    #         results - [dict] - (shared) output results list
    #         results_lock - threading.Lock - (shared) lock on the output list
    #         switch - [boolean] - (shared) switch controlling scan life-cycle (ON/OFF)
    #         switch_lock - threading.Lock - (shared) lock on switch
    #
    # Return: (void)
    #
    # This function performs a fuzzing scan on target hosts/ports. The encountered results
    # are appended to the (shared) results list provided as parameter. The scan ends when all
    # the entries in the fuzzing list(s) have been processed or as soon as the (shared)
    # switch is 'turned off' (i.e. switch = [False]) by the calling instance (e.g. GUI/CLI).
    # Note that fuzzing lists can be read from file (list mode) or generated on the fly
    # (generator mode) using a user defined expression.

    try:
        # load parameters from config file and test them
        # if some parameter is not valid, issue an 'error' result
        threads = core_file.cfg_get_fuzz_threads(core_file.cfg_start_get())
        fuzz_show_codes_str = core_file.cfg_get_fuzz_show_codes(
            core_file.cfg_start_get())
        fuzz_method = core_file.cfg_get_fuzz_method(core_file.cfg_start_get())

        if not core_utilities.check_threads(
                threads) or not core_utilities.check_http_codes(
                    fuzz_show_codes_str
                ) or not core_utilities.check_http_method(fuzz_method, True):

            result = {u'ERROR': u'Invalid configuration settings.'}
            issue_result(results, results_lock, cli, result)

        else:

            fuzz_show_codes = [
                c.strip() for c in fuzz_show_codes_str.split(u',')
            ]

            hosts_done = []

            for host in hosts:

                # check if switch is still 'ON'
                with switch_lock:
                    on = switch[0]
                if not on:
                    break
                else:

                    if host in hosts_done:
                        continue
                    else:
                        hosts_done.append(host)

                    ports_done = []

                    ipaddress = core_utilities.get_ip_address(host)

                    for port in ports:

                        # check if switch is still 'ON'
                        with switch_lock:
                            on = switch[0]
                        if not on:
                            break
                        else:

                            if port in ports_done:
                                continue
                            else:
                                ports_done.append(port)

                            # this 'informative' result is only for display of the new target on GUI/CLI
                            result = {
                                u'HOST': host,
                                u'PORT': unicode(port),
                                u'IPADDRESS': ipaddress,
                                u'TARGET': host + ' / ' + unicode(port)
                            }
                            issue_result(results, results_lock, cli, result)

                            # test if target is up and valid...
                            http_test = core_http.test_http(
                                host, port, fuzz_method)
                            if not http_test[0]:
                                error_message = http_test[1]

                                # if target is down output an 'error' result
                                result = {
                                    u'HOST': host,
                                    u'PORT': unicode(port),
                                    u'IPADDRESS': ipaddress,
                                    u'ERROR': error_message
                                }
                                issue_result(results, results_lock, cli,
                                             result)

                                # if the host/port is not valid, go to next port or next host
                                continue

                            else:  # if the target responds to HTTP, go on...

                                httpClient = core_http.HTTPClient(host, port)

                                roots_done = []
                                for root in roots:

                                    # check if switch is still 'ON'
                                    with switch_lock:
                                        on = switch[0]
                                    if not on:
                                        break
                                    else:

                                        if root in roots_done:
                                            continue
                                        else:
                                            roots_done.append(root)

                                        # fingerprint interesting messages

                                        # root
                                        request_root = core_http.HTTPRequest()
                                        request_root.set_method(u'GET')
                                        request_root.set_path(root)
                                        response_root = httpClient.perform_request(
                                            request_root)
                                        # 404 message - or should be
                                        request_404 = core_http.HTTPRequest()
                                        request_404.set_method(u'GET')
                                        request_404.set_path(root + u''.join([
                                            choice(letters + digits)
                                            for i in range(8)
                                        ]))
                                        response_404 = httpClient.perform_request(
                                            request_404)

                                        fingerprints = {}

                                        fingerprints[
                                            u'root'] = core_http.fingerprint_response(
                                                request_root, response_root)
                                        if fingerprints[u'root'] == None:
                                            issue_result(
                                                results, results_lock, cli, {
                                                    u'HOST':
                                                    host,
                                                    u'PORT':
                                                    unicode(port),
                                                    u'IPADDRESS':
                                                    ipaddress,
                                                    u'ERROR':
                                                    u'FP(' +
                                                    request_root.get_path() +
                                                    ') => failure!'
                                                })
                                        else:
                                            issue_result(
                                                results, results_lock, cli, {
                                                    u'HOST':
                                                    host,
                                                    u'PORT':
                                                    unicode(port),
                                                    u'IPADDRESS':
                                                    ipaddress,
                                                    u'INFO':
                                                    u'FP(' +
                                                    request_root.get_path() +
                                                    ') => ' +
                                                    str(fingerprints[u'root']
                                                        [0]) + u'#' +
                                                    str(fingerprints[u'root']
                                                        [1]) + u'#' +
                                                    str(fingerprints[u'root']
                                                        [2]) + u'#' +
                                                    str(fingerprints[u'root']
                                                        [3])
                                                })

                                        fingerprints[
                                            u'error404'] = core_http.fingerprint_response(
                                                request_404, response_404)
                                        if fingerprints[u'error404'] == None:
                                            issue_result(
                                                results, results_lock, cli, {
                                                    u'HOST':
                                                    host,
                                                    u'PORT':
                                                    unicode(port),
                                                    u'IPADDRESS':
                                                    ipaddress,
                                                    u'ERROR':
                                                    u'FP(' +
                                                    request_404.get_path() +
                                                    ') => failure!'
                                                })
                                        else:
                                            issue_result(
                                                results, results_lock, cli, {
                                                    u'HOST':
                                                    host,
                                                    u'PORT':
                                                    unicode(port),
                                                    u'IPADDRESS':
                                                    ipaddress,
                                                    u'INFO':
                                                    u'FP(' +
                                                    request_404.get_path() +
                                                    ') => ' + str(fingerprints[
                                                        u'error404'][0]) +
                                                    u'#' + str(fingerprints[
                                                        u'error404'][1]) +
                                                    u'#' + str(fingerprints[
                                                        u'error404'][2]) +
                                                    u'#' + str(fingerprints[
                                                        u'error404'][3])
                                                })

                                        if mode == 0:

                                            with switch_lock:
                                                on = switch[0]
                                            if not on:
                                                break
                                            else:

                                                if modecpl[0] == u'1':

                                                    directories = __find_directories(
                                                        host, port, ipaddress,
                                                        root, fingerprints,
                                                        fuzz_method, threads,
                                                        fuzz_show_codes, cli,
                                                        results, results_lock,
                                                        switch, switch_lock)
                                                else:
                                                    directories = []

                                            with switch_lock:
                                                on = switch[0]
                                            if not on:
                                                break
                                            else:

                                                if modecpl[1] == u'1':
                                                    __find_files(
                                                        host, port, ipaddress,
                                                        root, fingerprints,
                                                        fuzz_method, threads,
                                                        fuzz_show_codes, cli,
                                                        results, results_lock,
                                                        switch, switch_lock,
                                                        directories)

                                        else:

                                            with switch_lock:
                                                on = switch[0]
                                            if not on:
                                                break
                                            else:
                                                __find_generator(
                                                    host, port, ipaddress,
                                                    root,
                                                    fingerprints, fuzz_method,
                                                    modecpl.strip(), threads,
                                                    fuzz_show_codes, cli,
                                                    results, results_lock,
                                                    switch, switch_lock)

    except core_error.Config_Error, e:
        issue_result(results, results_lock, cli, {u'ERROR': e.error_message})
예제 #5
0
def perform(target, cli, results, results_lock, switch, switch_lock):

    # Input:  target - unicode - target machine (IPv4 or hostname)
    #         cli - boolean - set verbosity on STDOUT to ON/OFF
    #         results - [dict] - (shared) output results list
    #         results_lock - threading.Lock - (shared) lock on the output list
    #         switch - [boolean] - (shared) switch controlling scan life-cycle (ON/OFF)
    #         switch_lock - threading.Lock - (shared) lock on switch
    #
    # Return: (void)
    #
    # This function is in charge of retrieving all the referenced domains
    # that are hosted at given IP address (or at the IP address corresponding
    # to the given hostname). For this, the LIVE search webservice is used,
    # a valid Live AppID is needed (stored in the configuration file).

    try:
        # load the Live ID from the configuration file
        live_id = core_file.cfg_get_live_id(core_file.cfg_start_get())
        if not core_utilities.check_live_id(live_id):

            __issue_result(results, results_lock, cli, {
                u'ERROR':
                u'Invalid LIVE ID. Please verify configuration file.'
            })

        else:

            domains = []
            limit_iteration = 10
            offset = 0
            count = 50
            iteration = 1
            found = 0

            path = urlparse(WS_ENDPOINT).path
            port = urlparse(WS_ENDPOINT).port
            host = urlparse(WS_ENDPOINT).netloc.replace(
                u':' + unicode(port), u'')

            ip_address = gethostbyname(target)
            httpClient = core_http.HTTPClient(host, port, True)

            # test if web service is up and valid...
            http_test = core_http.test_http(host,
                                            port,
                                            override_disable_ssl=True)
            if not http_test[0]:
                error_message = http_test[1]

                __issue_result(
                    results, results_lock, cli,
                    {u'ERROR': u'Web service end-point: ' + error_message})

            else:

                __issue_result(results, results_lock, cli, {
                    u'IPADDRESS': ip_address,
                    u'TARGET': ip_address
                })

                while iteration < limit_iteration:

                    # crafting the HTTP request #
                    httpRequest = core_http.HTTPRequest()
                    httpRequest.set_method(u'POST')
                    httpRequest.set_path(path)
                    httpRequest.set_data(
                        __soap_live_request(live_id, ip_address, offset,
                                            count))

                    # sending the HTTP request #
                    httpResponse = httpClient.perform_request(httpRequest)

                    if httpResponse != None:

                        if httpResponse.get_code() == u'200':

                            parsedData = parseString(
                                httpResponse.get_data().encode(WS_ENCODING))

                            # checking if the request produced a SOAP error #
                            faults = parsedData.getElementsByTagName(
                                u'soapenv:Fault')
                            if len(faults) > 0:

                                errorMessage = faults[0].getElementsByTagName(
                                    u'detail')[0].firstChild.data.strip()

                                __issue_result(
                                    results, results_lock, cli,
                                    {u'ERROR': u'SOAP error: ' + errorMessage})

                                break

                            # processing the results #
                            res = parsedData.getElementsByTagName(u'Result')
                            if len(res) > 0:
                                for item in res:
                                    for url_item in item.getElementsByTagName(
                                            u'Url'):
                                        url = url_item.firstChild.data.strip()
                                        domain = urlparse(url).netloc
                                        if domain not in domains:
                                            domains.append(domain)

                                            __issue_result(
                                                results, results_lock, cli, {
                                                    u'IPADDRESS': ip_address,
                                                    u'VHOST': domain
                                                })

                                            found += 1
                                    offset += 1
                                iteration += 1
                                parsedData.unlink()
                            else:
                                # If there are no more results left, exit the loop,
                                # even if limit_iteration is not reached.
                                break
                        else:
                            break
                    else:
                        break

    except core_error.Config_Error, e:
        __issue_result(results, results_lock, cli, {u'ERROR': e.error_message})
예제 #6
0
def perform(host, port, root, cli, results, results_lock, switch, switch_lock):

    # Input:  host - unicode - target host
    #         port - unicode - target port
    #         root - unicode - target root
    #         cli - boolean - set verbosity on STDOUT to ON/OFF
    #         results - [dict] - (shared) output results list
    #         results_lock - threading.Lock - (shared) lock on the output list
    #         switch - [boolean] - (shared) switch controlling scan life-cycle (ON/OFF)
    #         switch_lock - threading.Lock - (shared) lock on switch
    #
    # Return: (void)
    #
    # This function crawls a given website extracting all the encountered e-mail addresses
    # external links and internal directories. The spider follows all the internal links and
    # redirections and parses all the pages having a 'text/html' content-type. External links
    # are extracted and returned as result but not followed.

    try:
        # Loading and testing config parameters
        threads = core_file.cfg_get_spider_threads(core_file.cfg_start_get())
        use_robots = core_file.cfg_get_use_robots(core_file.cfg_start_get())

        if not core_utilities.check_threads(threads):

            issue_result(
                results, results_lock, cli, {
                    u'ERROR':
                    u'Invalid configuration parameters. Please verify configuration file.'
                })

        else:

            ipaddress = core_utilities.get_ip_address(host)
            issue_result(
                results, results_lock, cli, {
                    u'HOST': host,
                    u'PORT': unicode(port),
                    u'IPADDRESS': ipaddress,
                    u'TARGET': host + ' / ' + unicode(port)
                })

            # test if target is up and valid...
            http_test = core_http.test_http(host, port)
            if not http_test[0]:

                error_message = http_test[1]
                issue_result(
                    results, results_lock, cli, {
                        u'HOST': host,
                        u'PORT': unicode(port),
                        u'IPADDRESS': ipaddress,
                        u'ERROR': error_message
                    })

            else:

                running = []
                known = {}
                known[
                    root] = False  # put the root in the spider links to initiate
                known_lock = threading.Lock()

                # cheat.... #
                issue_result(
                    results, results_lock, False, {
                        u'HOST': host,
                        u'PORT': unicode(port),
                        u'IPADDRESS': ipaddress,
                        u'INTERNAL':
                        (dirname(root) + u'/').replace(u'//', u'/')
                    })

                # grabbing robots.txt
                if use_robots:

                    httpClient = core_http.HTTPClient(host, port)
                    request = core_http.HTTPRequest()
                    request.set_method(u'GET')
                    request.set_path(root + u'robots.txt')
                    response = httpClient.perform_request(request)

                    if response != None:

                        if response.get_code() == u'200':
                            robots_text = response.get_data()
                            robots_directories = ROBOTS_DIRS_REGEXP.findall(
                                robots_text)

                            for rdir in robots_directories:
                                # note that the last '/' is removed before putting it as a key
                                # in 'known' to comply with os.path.dirname used below that returns
                                # dirnames without last slash
                                if not known.has_key(rdir[:-1]):
                                    known[rdir[:-1]] = False
                                else:
                                    continue

                                issue_result(
                                    results, results_lock, cli, {
                                        u'HOST': host,
                                        u'PORT': unicode(port),
                                        u'IPADDRESS': ipaddress,
                                        u'INTERNAL': rdir
                                    })
                        else:
                            pass
                    else:
                        pass
                else:  # ignore robots.txt
                    pass

                # start the first thread to grab the first page
                # and populate the 'known' dictionary with a few
                # results
                running.append(
                    SpiderThread(host, port, ipaddress, known, known_lock, cli,
                                 results, results_lock, switch, switch_lock))
                running[0].start()
                sleep(THREAD_DELAY)

                # after a delay, spawn the other threads
                for i in range(1, threads):
                    spiderThread = SpiderThread(host, port, ipaddress, known,
                                                known_lock, cli, results,
                                                results_lock, switch,
                                                switch_lock)
                    spiderThread.start()
                    running.append(spiderThread)

                for thread in running:
                    thread.join()

    except core_error.Config_Error, e:
        issue_result(results, results_lock, cli, {u'ERROR': e.error_message})