示例#1
0
    def _analyze_ips(self, ip_address_list, fuzzable_request):
        '''
        Search all IP addresses in Bing and determine if they have more than
        one domain hosted on it. Store findings in KB.
        '''
        bing_wrapper = bing(self._uri_opener)

        # This is the best way to search, one by one!
        for ip_address in ip_address_list:
            results = bing_wrapper.get_n_results('ip:' + ip_address,
                                                 self._result_limit)

            results = [r.URL.base_url() for r in results]
            results = list(set(results))

            # not vuln by default
            is_vulnerable = False

            if len(results) > 1:
                # We may have something...
                is_vulnerable = True

                if len(results) == 2:
                    # Maybe we have this case:
                    # [Mon 09 Jun 2008 01:08:26 PM ART] - http://216.244.147.14/
                    # [Mon 09 Jun 2008 01:08:26 PM ART] - http://www.business.com/
                    # Where www.business.com resolves to 216.244.147.14; so we don't really
                    # have more than one domain in the same server.
                    try:
                        res0 = socket.gethostbyname(results[0].get_domain())
                        res1 = socket.gethostbyname(results[1].get_domain())
                    except:
                        pass
                    else:
                        if res0 == res1:
                            is_vulnerable = False

            if is_vulnerable:
                desc = 'The web application under test seems to be in a shared' \
                       ' hosting. This list of domains, and the domain of the ' \
                       ' web application under test, all point to the same IP' \
                       ' address (%s):\n' % ip_address

                domain_list = kb.kb.raw_read(self, 'domains')

                for url in results:
                    domain = url.get_domain()
                    desc += '- %s\n' % domain

                    domain_list.append(domain)

                kb.kb.raw_write(self, 'domains', domain_list)

                v = Vuln.from_fr('Shared hosting', desc, severity.MEDIUM, 1,
                                 self.get_name(), fuzzable_request)

                v['also_in_hosting'] = results

                om.out.vulnerability(desc, severity=severity.MEDIUM)
                kb.kb.append(self, 'shared_hosting', v)
示例#2
0
    def _analyze_ips(self, ip_address_list, fuzzable_request):
        '''
        Search all IP addresses in Bing and determine if they have more than
        one domain hosted on it. Store findings in KB.
        '''
        bing_wrapper = bing(self._uri_opener)
        
        # This is the best way to search, one by one!
        for ip_address in ip_address_list:
            results = bing_wrapper.get_n_results('ip:' + ip_address,
                                               self._result_limit)

            results = [r.URL.base_url() for r in results]
            results = list(set(results))

            # not vuln by default
            is_vulnerable = False

            if len(results) > 1:
                # We may have something...
                is_vulnerable = True

                if len(results) == 2:
                    # Maybe we have this case:
                    # [Mon 09 Jun 2008 01:08:26 PM ART] - http://216.244.147.14/
                    # [Mon 09 Jun 2008 01:08:26 PM ART] - http://www.business.com/
                    # Where www.business.com resolves to 216.244.147.14; so we don't really
                    # have more than one domain in the same server.
                    try:
                        res0 = socket.gethostbyname(results[0].get_domain())
                        res1 = socket.gethostbyname(results[1].get_domain())
                    except:
                        pass
                    else:
                        if res0 == res1:
                            is_vulnerable = False

            if is_vulnerable:
                desc = 'The web application under test seems to be in a shared' \
                       ' hosting. This list of domains, and the domain of the ' \
                       ' web application under test, all point to the same IP' \
                       ' address (%s):\n' % ip_address
                
                domain_list = kb.kb.raw_read(self, 'domains')
                
                for url in results:
                    domain = url.get_domain()
                    desc += '- %s\n' % domain
                    
                    domain_list.append(domain)
                    
                kb.kb.raw_write(self, 'domains', domain_list)
                    
                v = Vuln.from_fr('Shared hosting', desc, severity.MEDIUM, 1,
                                 self.get_name(), fuzzable_request)

                v['also_in_hosting'] = results
                
                om.out.vulnerability(desc, severity=severity.MEDIUM)
                kb.kb.append(self, 'shared_hosting', v)
示例#3
0
文件: csrf.py 项目: weisst/w3af
    def audit(self, freq, orig_response):
        '''
        Tests a URL for CSRF vulnerabilities.

        :param freq: A FuzzableRequest
        '''
        if not self._is_suitable(freq):
            return

        # Referer/Origin check
        #
        # IMPORTANT NOTE: I'm aware that checking for the referer header does
        # NOT protect the application against all cases of CSRF, but it's a
        # very good first step. In order to exploit a CSRF in an application
        # that protects using this method an intruder would have to identify
        # other vulnerabilities such as XSS or open redirects.
        #
        # TODO: This algorithm has lots of room for improvement
        if self._is_origin_checked(freq, orig_response):
            om.out.debug('Origin for %s is checked' % freq.get_url())
            return

        # Does the request have CSRF token in query string or POST payload?
        if self._find_csrf_token(freq):
            om.out.debug('Token for %s exists and was checked' %
                         freq.get_url())
            return

        # Ok, we have found vulnerable to CSRF attack request
        msg = 'Cross Site Request Forgery has been found at: ' + freq.get_url()

        v = Vuln.from_fr('CSRF vulnerability', msg, severity.HIGH,
                         orig_response.id, self.get_name(), freq)

        self.kb_append_uniq(self, 'csrf', v)
示例#4
0
文件: csrf.py 项目: Adastra-thw/w3af
    def audit(self, freq, orig_response):
        '''
        Tests a URL for CSRF vulnerabilities.

        :param freq: A FuzzableRequest
        '''
        if not self._is_suitable(freq):
            return

        # Referer/Origin check
        #
        # IMPORTANT NOTE: I'm aware that checking for the referer header does
        # NOT protect the application against all cases of CSRF, but it's a
        # very good first step. In order to exploit a CSRF in an application
        # that protects using this method an intruder would have to identify
        # other vulnerabilities such as XSS or open redirects.
        #
        # TODO: This algorithm has lots of room for improvement
        if self._is_origin_checked(freq, orig_response):
            om.out.debug('Origin for %s is checked' % freq.get_url())
            return

        # Does the request have CSRF token in query string or POST payload?
        if self._find_csrf_token(freq):
            om.out.debug('Token for %s exists and was checked' % freq.get_url())
            return

        # Ok, we have found vulnerable to CSRF attack request
        msg = 'Cross Site Request Forgery has been found at: ' + freq.get_url()
        
        v = Vuln.from_fr('CSRF vulnerability', msg, severity.HIGH,
                         orig_response.id, self.get_name(), freq)
        
        self.kb_append_uniq(self, 'csrf', v)
示例#5
0
    def _extract_urls(self, fuzzable_request, response):
        '''
        Extract information from the server-status page and return fuzzable
        requests to the caller.
        '''
        res = self._create_fuzzable_requests(response)

        # Now really parse the file and create custom made fuzzable requests
        regex = '<td>.*?<td nowrap>(.*?)</td><td nowrap>.*? (.*?) HTTP/1'
        for domain, path in re.findall(regex, response.get_body()):

            if 'unavailable' in domain:
                domain = response.get_url().get_domain()

            # Check if the requested domain and the found one are equal.
            if domain == response.get_url().get_domain():
                found_url = response.get_url(
                ).get_protocol() + '://' + domain + path
                found_url = URL(found_url)

                # They are equal, request the URL and create the fuzzable
                # requests
                tmp_res = self._uri_opener.GET(found_url, cache=True)
                if not is_404(tmp_res):
                    res.extend(self._create_fuzzable_requests(tmp_res))
            else:
                # This is a shared hosting server
                self._shared_hosting_hosts.append(domain)

        # Now that we are outsite the for loop, we can report the possible vulns
        if len(self._shared_hosting_hosts):
            desc = 'The web application under test seems to be in a shared'\
                   ' hosting.'
            v = Vuln.from_fr('Shared hosting', desc, severity.MEDIUM,
                             response.id, self.get_name(), fuzzable_request)

            self._shared_hosting_hosts = list(
                set(self._shared_hosting_hosts))
            v['also_in_hosting'] = self._shared_hosting_hosts

            kb.kb.append(self, 'shared_hosting', v)
            om.out.vulnerability(v.get_desc(), severity=v.get_severity())

            msg = 'This list of domains, and the domain of the web application'\
                  ' under test, all point to the same server:'
            om.out.vulnerability(msg, severity=severity.MEDIUM)
            for url in self._shared_hosting_hosts:
                om.out.vulnerability('- ' + url, severity=severity.MEDIUM)

        return res
示例#6
0
    def _extract_urls(self, fuzzable_request, response):
        '''
        Extract information from the server-status page and return fuzzable
        requests to the caller.
        '''
        res = self._create_fuzzable_requests(response)

        # Now really parse the file and create custom made fuzzable requests
        regex = '<td>.*?<td nowrap>(.*?)</td><td nowrap>.*? (.*?) HTTP/1'
        for domain, path in re.findall(regex, response.get_body()):

            if 'unavailable' in domain:
                domain = response.get_url().get_domain()

            # Check if the requested domain and the found one are equal.
            if domain == response.get_url().get_domain():
                found_url = response.get_url().get_protocol(
                ) + '://' + domain + path
                found_url = URL(found_url)

                # They are equal, request the URL and create the fuzzable
                # requests
                tmp_res = self._uri_opener.GET(found_url, cache=True)
                if not is_404(tmp_res):
                    res.extend(self._create_fuzzable_requests(tmp_res))
            else:
                # This is a shared hosting server
                self._shared_hosting_hosts.append(domain)

        # Now that we are outsite the for loop, we can report the possible vulns
        if len(self._shared_hosting_hosts):
            desc = 'The web application under test seems to be in a shared'\
                   ' hosting.'
            v = Vuln.from_fr('Shared hosting', desc, severity.MEDIUM,
                             response.id, self.get_name(), fuzzable_request)

            self._shared_hosting_hosts = list(set(self._shared_hosting_hosts))
            v['also_in_hosting'] = self._shared_hosting_hosts

            kb.kb.append(self, 'shared_hosting', v)
            om.out.vulnerability(v.get_desc(), severity=v.get_severity())

            msg = 'This list of domains, and the domain of the web application'\
                  ' under test, all point to the same server:'
            om.out.vulnerability(msg, severity=severity.MEDIUM)
            for url in self._shared_hosting_hosts:
                om.out.vulnerability('- ' + url, severity=severity.MEDIUM)

        return res
示例#7
0
    def _report_results(self, fuzzable_request, analysis_result):
        '''
        Report our findings
        '''
        reported = set()
        for vhost, request_id in analysis_result:
            if vhost not in reported:
                reported.add(vhost)

                domain = fuzzable_request.get_url().get_domain()
                desc = 'Found a new virtual host at the target web server, the ' \
                       'virtual host name is: "%s". To access this site' \
                       ' you might need to change your DNS resolution settings in' \
                       ' order to point "%s" to the IP address of "%s".'
                desc = desc % (vhost, vhost, domain)

                v = Vuln.from_fr('Virtual host identified', desc, severity.LOW,
                                 request_id, self.get_name(), fuzzable_request)

                kb.kb.append(self, 'find_vhosts', v)
                om.out.information(v.get_desc())
示例#8
0
    def _report_results(self, fuzzable_request, analysis_result):
        '''
        Report our findings
        '''
        reported = set()
        for vhost, request_id in analysis_result:
            if vhost not in reported:
                reported.add(vhost)

                domain = fuzzable_request.get_url().get_domain()
                desc = 'Found a new virtual host at the target web server, the ' \
                       'virtual host name is: "%s". To access this site' \
                       ' you might need to change your DNS resolution settings in' \
                       ' order to point "%s" to the IP address of "%s".'
                desc = desc % (vhost, vhost, domain)
                
                v = Vuln.from_fr('Virtual host identified', desc, severity.LOW,
                                 request_id, self.get_name(), fuzzable_request)
                
                kb.kb.append(self, 'find_vhosts', v)
                om.out.information(v.get_desc())
示例#9
0
文件: xst.py 项目: HamzaKo/w3af
    def audit(self, freq, orig_response):
        '''
        Verify xst vulns by sending a TRACE request and analyzing the response.
        '''

        if not self._exec:
            # Do nothing
            return
        else:
            # Only run once
            self._exec = False

            uri = freq.get_url().get_domain_path()
            method = 'TRACE'
            headers = Headers()
            headers['FakeHeader'] = 'XST'
            fr = FuzzableRequest(uri,
                                 method=method,
                                 headers=headers
                                 )

            # send the request to the server and receive the response
            response = self._uri_opener.send_mutant(fr)

            # create a regex to test the response.
            regex = re.compile("FakeHeader: *?XST", re.IGNORECASE)
            if re.search(regex, response.get_body()):
                # If vulnerable record it. This will now become visible on
                # the KB Browser
                desc = 'The web server at "%s" is vulnerable to Cross Site'\
                      ' Tracing.'
                desc = desc % response.get_url()
                
                v = Vuln.from_fr('Cross site tracing vulnerability', desc,
                                 severity.LOW, response.id, self.get_name(),
                                 freq)

                om.out.vulnerability(v.get_desc(), severity=v.get_severity())
                self.kb_append(self, 'xst', v)
示例#10
0
    def audit(self, freq, orig_response):
        '''
        Verify xst vulns by sending a TRACE request and analyzing the response.
        '''

        if not self._exec:
            # Do nothing
            return
        else:
            # Only run once
            self._exec = False

            uri = freq.get_url().get_domain_path()
            method = 'TRACE'
            headers = Headers()
            headers['FakeHeader'] = 'XST'
            fr = FuzzableRequest(uri,
                                 method=method,
                                 headers=headers
                                 )

            # send the request to the server and receive the response
            response = self._uri_opener.send_mutant(fr)

            # create a regex to test the response.
            regex = re.compile("FakeHeader: *?XST", re.IGNORECASE)
            if regex.search(response.get_body()):
                # If vulnerable record it. This will now become visible on
                # the KB Browser
                desc = 'The web server at "%s" is vulnerable to Cross Site'\
                      ' Tracing.'
                desc = desc % response.get_url()
                
                v = Vuln.from_fr('Cross site tracing vulnerability', desc,
                                 severity.LOW, response.id, self.get_name(),
                                 freq)

                om.out.vulnerability(v.get_desc(), severity=v.get_severity())
                self.kb_append(self, 'xst', v)
示例#11
0
    def _brute_worker(self, freq, user_field, passwd_field,
                      login_failed_result_list, combination):
        '''
        :param freq: A FuzzableRequest
        :param combination: A tuple with (user, pass) or a pass if this is a
                                password only form.
        '''
        if freq.get_url() not in self._found or not self._stop_on_first:
            freq = freq.copy()
            data_container = freq.get_dc()
            data_container = self._true_extra_fields(data_container,
                                                     user_field, passwd_field)

            # Handle password-only forms!
            if user_field is not None:
                user, pwd = combination
                data_container[user_field][0] = user
                data_container[passwd_field][0] = pwd
            else:
                user = '******'
                pwd = combination
                data_container[passwd_field][0] = pwd

            freq.set_dc(data_container)

            try:
                resp = self._uri_opener.send_mutant(freq,
                                                    cookies=False,
                                                    grep=False)
            except w3afMustStopOnUrlError:
                return
            else:
                body = resp.get_body()
                body = body.replace(user, '').replace(pwd, '')

                if not self._matches_failed_login(body,
                                                  login_failed_result_list):
                    # Ok, this might be a valid combination.
                    # Now test with a new invalid password to ensure our
                    # previous possible found credentials are valid
                    data_container[passwd_field][0] = rand_alnum(8)
                    freq.set_dc(data_container)
                    verif_resp = self._uri_opener.send_mutant(freq,
                                                              cookies=False,
                                                              grep=False)
                    body = verif_resp.get_body()
                    body = body.replace(user, '').replace(pwd, '')

                    if self._matches_failed_login(body,
                                                  login_failed_result_list):
                        freq_url = freq.get_url()
                        self._found.add(freq_url)

                        if user_field is not None:
                            desc = (
                                'Found authentication credentials to: '
                                '"%s". A correct user and password combination'
                                ' is: %s/%s' % (freq_url, user, pwd))
                        else:
                            # There is no user field!
                            desc = ('Found authentication credentials to: '
                                    '"%s". The correct password is: "%s".' %
                                    (freq_url, pwd))

                        v = Vuln.from_fr('Guessable credentials',
                                         desc, severity.HIGH, resp.id,
                                         self.get_name(), freq)
                        v['user'] = user
                        v['pass'] = pwd
                        v['response'] = resp

                        kb.kb.append(self, 'auth', v)

                        om.out.vulnerability(desc, severity=severity.HIGH)
                        return
示例#12
0
    def audit(self, freq, orig_response):
        '''
        Check if the protocol specified in freq is https and fetch the same URL
        using http. ie:
            - input: https://w3af.org/
            - check: http://w3af.org/

        :param freq: A FuzzableRequest
        '''
        if not self._run:
            return
        else:
            # Define some variables
            initial_uri = freq.get_uri()
            insecure_uri = initial_uri.copy()
            secure_uri = initial_uri.copy()

            insecure_uri.set_protocol('http')
            insecure_fr = freq.copy()
            insecure_fr.set_url(insecure_uri)

            secure_uri.set_protocol('https')
            secure_fr = freq.copy()
            secure_fr.set_url(secure_uri)

            send_mutant = self._uri_opener.send_mutant

            try:
                insecure_response = send_mutant(insecure_fr, grep=False)
                secure_response = send_mutant(secure_fr, grep=False)
            except w3afException:
                # No vulnerability to report since one of these threw an error
                # (because there is nothing listening on that port). It makes
                # no sense to keep running since we already got an error
                self._run = False
                
            else:
                if self._redirects_to_secure(insecure_response, secure_response):
                    return
                
                if insecure_response.get_code() == secure_response.get_code()\
                and relative_distance_boolean(insecure_response.get_body(),
                                              secure_response.get_body(),
                                              0.95):
                    desc = 'Secure content can be accessed using the insecure'\
                           ' protocol HTTP. The vulnerable URLs are:'\
                           ' "%s" - "%s" .'
                    desc = desc % (secure_uri, insecure_uri)
                    
                    response_ids = [insecure_response.id, secure_response.id]
                    
                    v = Vuln.from_fr('Secure content over insecure channel',
                                     desc, severity.MEDIUM, response_ids,
                                     self.get_name(), freq)

                    self.kb_append(self, 'un_ssl', v)
                    
                    om.out.vulnerability(v.get_desc(),
                                         severity=v.get_severity())
                    
                    # In most cases, when one resource is available, all are
                    # so we just stop searching for this vulnerability
                    self._run = False
示例#13
0
文件: un_ssl.py 项目: weisst/w3af
    def audit(self, freq, orig_response):
        '''
        Check if the protocol specified in freq is https and fetch the same URL
        using http. ie:
            - input: https://w3af.org/
            - check: http://w3af.org/

        :param freq: A FuzzableRequest
        '''
        if not self._run:
            return
        else:
            # Define some variables
            initial_uri = freq.get_uri()
            insecure_uri = initial_uri.copy()
            secure_uri = initial_uri.copy()

            insecure_uri.set_protocol('http')
            insecure_fr = freq.copy()
            insecure_fr.set_url(insecure_uri)

            secure_uri.set_protocol('https')
            secure_fr = freq.copy()
            secure_fr.set_url(secure_uri)

            send_mutant = self._uri_opener.send_mutant

            try:
                insecure_response = send_mutant(insecure_fr, grep=False)
                secure_response = send_mutant(secure_fr, grep=False)
            except w3afException:
                # No vulnerability to report since one of these threw an error
                # (because there is nothing listening on that port). It makes
                # no sense to keep running since we already got an error
                self._run = False

            else:
                if self._redirects_to_secure(insecure_response,
                                             secure_response):
                    return

                if insecure_response.get_code() == secure_response.get_code()\
                and relative_distance_boolean(insecure_response.get_body(),
                                              secure_response.get_body(),
                                              0.95):
                    desc = 'Secure content can be accessed using the insecure'\
                           ' protocol HTTP. The vulnerable URLs are:'\
                           ' "%s" - "%s" .'
                    desc = desc % (secure_uri, insecure_uri)

                    response_ids = [insecure_response.id, secure_response.id]

                    v = Vuln.from_fr('Secure content over insecure channel',
                                     desc, severity.MEDIUM, response_ids,
                                     self.get_name(), freq)

                    self.kb_append(self, 'un_ssl', v)

                    om.out.vulnerability(v.get_desc(),
                                         severity=v.get_severity())

                    # In most cases, when one resource is available, all are
                    # so we just stop searching for this vulnerability
                    self._run = False