예제 #1
0
 def modifyRequest(self, request ):
     '''
     Mangles the request
     
     @parameter request: urllib2.Request instance that is going to be modified by the evasion plugin
     '''
     # First we mangle the URL        
     path = urlParser.getPathQs( request.get_full_url() )
     path = self._mutate( path )
     
     # Now we mangle the postdata
     data = request.get_data()
     if data:
         # Only mangle the postdata if it is a url encoded string
         try:
             urlParser.getQueryString('http://w3af/?' + data )
         except:
             pass
         else:
             data = self._mutate( data )            
     
     # Finally, we set all the mutants to the request in order to return it
     url = urlParser.getProtocol( request.get_full_url() )
     url += '://' + urlParser.getNetLocation( request.get_full_url() ) + path
     
     new_req = urllib2.Request( url , data, request.headers, request.get_origin_req_host() )
     
     return new_req
예제 #2
0
 def modifyRequest(self, request ):
     '''
     Mangles the request
     
     @parameter request: urllib2.Request instance that is going to be modified by the evasion plugin
     '''
     # This is a test URL
     # http://172.16.1.132/index.asp?q=%uFF1Cscript%3Ealert(%22Hello%22)%3C/script%3E
     # This is the content of index.asp :
     # <%=Request.QueryString("q")%>
     
     # First we mangle the URL        
     path = urlParser.getPathQs( request.get_full_url() )
     path = self._mutate( path )
     
     # Now we mangle the postdata
     data = request.get_data()
     if data:
         # Only mangle the postdata if it is a url encoded string
         try:
             urlParser.getQueryString('http://w3af/?' + data )
         except:
             pass
         else:
             data = self._mutate( data )            
     
     # Finally, we set all the mutants to the request in order to return it
     url = urlParser.getProtocol( request.get_full_url() )
     url += '://' + urlParser.getNetLocation( request.get_full_url() ) + path
     
     new_req = urllib2.Request( url , data, request.headers, request.get_origin_req_host() )
     
     return new_req
예제 #3
0
    def discover(self, fuzzableRequest ):
        '''
        It calls the "main" from hmap and writes the results to the kb.
        
        @parameter fuzzableRequest: A fuzzableRequest instance that contains (among other things) the URL to test.
        '''
        if not self._exec:
            # This will remove the plugin from the discovery plugins to be runned.
            raise w3afRunOnce()
        else:
            
            if self._runned_hmap:
                # Nothing else to do here.
                self._exec = False
                            
            if not self._runned_hmap:
                self._runned_hmap = True
                
                msg = 'Hmap web server fingerprint is starting, this may take a while.'
                om.out.information( msg )
                
                url = fuzzableRequest.getURL()
                protocol = urlParser.getProtocol( url )
                server = urlParser.getNetLocation( url )
                
                # Set some defaults that can be overriden later
                if protocol == 'https':
                    port = 443
                    ssl = True
                else:
                    port = 80
                    ssl = False
                
                # Override the defaults
                if server.count(':'):
                    port = int( server.split(':')[1] )
                    server = server.split(':')[0]

                
                try:
                    results = originalHmap.testServer( ssl, server, port, 1, self._genFpF )
                except w3afException, w3:
                    msg = 'A w3afException ocurred while running hmap: "' + str(w3) + '"'
                    om.out.error( msg )
                except Exception,  e:
                    msg = 'An unhandled exception ocurred while running hmap: "' + str(e) + '"'
                    om.out.error( msg )
                else:
예제 #4
0
 def modifyRequest(self, request ):
     '''
     Mangles the request
     
     @parameter request: urllib2.Request instance that is going to be modified by the evasion plugin
     '''
     # We mangle the URL
     path = urlParser.getPathQs( request.get_full_url() )
     path = path.replace('/','/./' )
     
     # Finally, we set all the mutants to the request in order to return it
     url = urlParser.getProtocol( request.get_full_url() )
     url += '://' + urlParser.getNetLocation( request.get_full_url() ) + path        
     new_req = urllib2.Request( url , request.get_data(), request.headers, 
                                             request.get_origin_req_host() )
     
     return new_req
예제 #5
0
 def modifyRequest(self, request ):
     '''
     Mangles the request
     
     @parameter request: urllib2.Request instance that is going to be modified by the evasion plugin
     '''
     # We mangle the URL
     path = urlParser.getPathQs( request.get_full_url() )
     if re.match('^/', path):
         random_alnum = createRandAlNum()
         path = '/' + random_alnum + '/..' + path
     
     # Finally, we set all the mutants to the request in order to return it
     url = urlParser.getProtocol( request.get_full_url() )
     url += '://' + urlParser.getNetLocation( request.get_full_url() ) + path        
     new_req = urllib2.Request( url , request.get_data(), request.headers,
                                             request.get_origin_req_host() )
     
     return new_req
예제 #6
0
    def audit(self, freq ):
        '''
        Get the cert and do some checks against it.

        @param freq: A fuzzableRequest
        '''
        url = freq.getURL()
        
        if 'HTTPS' != getProtocol( url ).upper():
            return

        domain = getDomain(url)
        # We need to check certificate only once per host
        if domain in self._already_tested_domains:
            return

        # Parse the domain:port
        splited = getNetLocation(url).split(':')
        port = 443
        host = splited[0]

        if len( splited ) > 1:
            port = int(splited[1])

        # Create the connection
        socket_obj = socket.socket()
        try:
            socket_obj.connect( ( host , port ) )
            ctx = SSL.Context(SSL.SSLv23_METHOD)
            ssl_conn = SSL.Connection(ctx, socket_obj)

            # Go to client mode
            ssl_conn.set_connect_state()

            # If I don't send something here, the "get_peer_certificate"
            # method returns None. Don't ask me why!
            #ssl_conn.send('GET / HTTP/1.1\r\n\r\n')
            self.ssl_wrapper( ssl_conn, ssl_conn.send, ('GET / HTTP/1.1\r\n\r\n', ), {})
        except Exception, e:
            om.out.error('Error in audit.sslCertificate: "' + repr(e)  +'".')
예제 #7
0
    def setOptions(self, optionsMap):
        """
        This method sets all the options that are configured using the user interface 
        generated by the framework using the result of getOptions().
        
        @parameter optionsMap: A dictionary with the options for the plugin.
        @return: No value is returned.
        """
        targetUrls = optionsMap["target"].getValue()

        for targetUrl in targetUrls:
            self._verifyURL(targetUrl)

        for targetUrl in targetUrls:
            if targetUrl.count("file://"):
                try:
                    f = urllib2.urlopen(targetUrl)
                except:
                    raise w3afException("Cannot open target file: " + targetUrl)
                else:
                    for line in f:
                        target_in_file = line.strip()
                        self._verifyURL(target_in_file, fileTarget=False)
                        targetUrls.append(target_in_file)
                    f.close()
                targetUrls.remove(targetUrl)

        # Now we perform a check to see if the user has specified more than one target
        # domain, for example: "http://google.com, http://yahoo.com".
        domainList = [urlParser.getNetLocation(targetURL) for targetURL in targetUrls]
        domainList = list(set(domainList))
        if len(domainList) > 1:
            msg = "You specified more than one target domain: " + ",".join(domainList)
            msg += " . And w3af only supports one target domain at the time."
            raise w3afException(msg)

        # Save in the config, the target URLs, this may be usefull for some plugins.
        cf.cf.save("targets", targetUrls)
        cf.cf.save("targetDomains", [urlParser.getNetLocation(i) for i in targetUrls])
        cf.cf.save("baseURLs", [urlParser.baseUrl(i) for i in targetUrls])

        if targetUrls:
            sessName = [urlParser.getNetLocation(x) for x in targetUrls]
            sessName = "-".join(sessName)
        else:
            sessName = "noTarget"

        cf.cf.save("sessionName", sessName + "-" + time.strftime("%Y-%b-%d_%H-%M-%S"))

        # Advanced target selection
        os = optionsMap["targetOS"].getValueStr()
        if os.lower() in self._operatingSystems:
            cf.cf.save("targetOS", os.lower())
        else:
            raise w3afException("Unknown target operating system: " + os)

        pf = optionsMap["targetFramework"].getValueStr()
        if pf.lower() in self._programmingFrameworks:
            cf.cf.save("targetFramework", pf.lower())
        else:
            raise w3afException("Unknown target programming framework: " + pf)
    def discover(self, fuzzableRequest):
        '''
        Discovery task. Uses scapy.traceroute function in order to determine
        the distance between http and https ports for the target.
        Intended to be executed once during the discovery process.
        '''
        if not self._has_permission():
            raise w3afException(PERM_ERROR_MSG) 
        
        def set_info(name, desc):
            inf = info.info()
            inf.setPluginName(self.getName())
            inf.setName(name)
            inf.setDesc(desc)
            kb.kb.append(self, 'http_vs_https_dist', inf)

        target_url = fuzzableRequest.getURL()
        domain = uparser.getDomain(target_url)
        http_port = self._http_port
        https_port = self._https_port

        # Use target port if specified
        netloc = uparser.getNetLocation(target_url)
        try:
            port = int(netloc.split(':')[-1])
        except ValueError:
            pass # Nothing to do.
        else:
            protocol = uparser.getProtocol(target_url)
            if protocol == 'https':
                https_port = port
            else: # it has to be 'http'
                http_port = port

        # First try with httpS
        https_troute = traceroute(domain, dport=https_port)[0].get_trace()
        
        # This destination was probably 'localhost' or a host reached through
        # a vpn?
        if not https_troute:
            return []
        
        https_troute = https_troute.values()[0]
        https_ip_tuples = https_troute.values()
        last_https_ip = https_ip_tuples[-1]
        
        # Then with http
        http_troute = traceroute(domain, dport=http_port)
        http_troute = http_troute[0].get_trace().values()[0]
        http_ip_tuples = http_troute.values()
        last_http_ip = http_ip_tuples[-1]
        
        # Last IP should be True; otherwise the dest wasn't reached
        # Tuples have the next form: ('192.168.1.1', False)
        if not (last_https_ip[1] and last_http_ip[1]):
            desc = _('The port \'%s\' is not open on target %s')
            if not last_https_ip[1]:
                om.out.error(desc % (https_port, domain))
            if not last_http_ip[1]:
                om.out.error(desc % (http_port, domain))
        else:
            # Are routes different
            if http_ip_tuples != https_ip_tuples:
                header = '  TCP trace to %s:%s\n%s'
                trace_str = lambda iptuples: '\n'.join('    %s %s' % \
                                (t[0], t[1][0]) for t in enumerate(iptuples))

                trc1 = header % (domain, http_port, trace_str(http_ip_tuples))
                trc2 = header % (domain, https_port, trace_str(https_ip_tuples))

                desc = _('Routes to target \'%s\' using ports \'%s\' and ' \
                '\'%s\' are different:\n%s\n%s') % (domain, http_port, 
                                                    https_port, trc1, trc2)
                set_info('HTTP vs. HTTPS Distance', desc)
                om.out.information(desc)
        return []