Ejemplo n.º 1
0
 def _fill_form(self, fuzzable_req):
     '''
     Fill the HTTP request form that is passed as fuzzable_req.
     @return: A filled form
     '''
     self._already_filled_form.add(fuzzable_req.getURL())
     
     to_send = fuzzable_req.getDc().copy()
     
     for param_name in to_send:
         
         # I do not want to mess with the "static" fields
         if isinstance(to_send, form.Form):
             if to_send.getType(param_name) in ('checkbox', 'file',
                                                'radio', 'select'):
                 continue
         
         # Set all the other fields, except from the ones that have a
         # value set (example: hidden fields like __VIEWSTATE).
         for elem_index in xrange(len(to_send[param_name])):
             
             # TODO: Should I ignore it because it already has a value?
             if to_send[param_name][elem_index] != '':
                 continue
             
             # SmartFill it!
             to_send[param_name][elem_index] = smartFill(param_name)
             
     fuzzable_req.setDc(to_send)
     return fuzzable_req 
Ejemplo n.º 2
0
    def discover(self, fuzzableRequest):
        """
        Searches for links on the html.

        @parameter fuzzableRequest: A fuzzableRequest instance that contains (among other things) the URL to test.
        """
        om.out.debug("webSpider plugin is testing: " + fuzzableRequest.getURL())

        if self._first_run:
            # I have to set some variables, in order to be able to code the "onlyForward" feature
            self._first_run = False
            self._target_urls = [urlParser.getDomainPath(i) for i in cf.cf.getData("targets")]
            self._target_domain = urlParser.getDomain(cf.cf.getData("targets")[0])

        # If its a form, then smartFill the Dc.
        original_dc = fuzzableRequest.getDc()
        if isinstance(fuzzableRequest, httpPostDataRequest.httpPostDataRequest):

            # TODO!!!!!!
            if fuzzableRequest.getURL() in self._already_filled_form:
                return []
            else:
                self._already_filled_form.add(fuzzableRequest.getURL())

            to_send = original_dc.copy()
            for parameter_name in to_send:

                # I do not want to mess with the "static" fields
                if isinstance(to_send, form.form):
                    if to_send.getType(parameter_name) in ["checkbox", "file", "radio", "select"]:
                        continue

                #
                #   Set all the other fields, except from the ones that have a value set (example:
                #   hidden fields like __VIEWSTATE).
                #
                for element_index in xrange(len(to_send[parameter_name])):

                    #   should I ignore it because it already has a value?
                    if to_send[parameter_name][element_index] != "":
                        continue

                    #   smartFill it!
                    to_send[parameter_name][element_index] = smartFill(parameter_name)

            fuzzableRequest.setDc(to_send)

        self._fuzzableRequests = []
        response = None

        try:
            response = self._sendMutant(fuzzableRequest, analyze=False)
        except KeyboardInterrupt, e:
            raise e
Ejemplo n.º 3
0
def _createMutantsWorker(freq, mutantClass, mutant_str_list, fuzzableParamList, append, dataContainer=None):
    """
    An auxiliary function to createMutants.
    
    @return: A list of mutants.

    >>> from core.data.request.fuzzableRequest import fuzzableRequest
    >>> from core.data.parsers.urlParser import url_object
    >>> from core.data.dc.dataContainer import dataContainer as dc

    Mutant creation
    >>> freq = fuzzableRequest()
    >>> u = url_object('http://www.w3af.com/')
    >>> d = dc()
    >>> d['a'] = ['1',]
    >>> d['b'] = ['2',]
    >>> freq.setURL( u )
    >>> freq.setDc( d )
    >>> f = _createMutantsWorker( freq, mutantQs, ['abc', 'def'], [], True)
    >>> [ i.getDc() for i in f ]
    [{'a': ['abc'], 'b': ['2']}, {'a': ['def'], 'b': ['2']}, {'a': ['1'], 'b': ['abc']}, {'a': ['1'], 'b': ['def']}]

    Repeated parameters
    >>> freq = fuzzableRequest()
    >>> u = url_object('http://www.w3af.com/')
    >>> d = dc()
    >>> d['a'] = ['1','2','3']
    >>> freq.setURL( u )
    >>> freq.setDc( d )
    >>> f = _createMutantsWorker( freq, mutantQs, ['abc', 'def'], [], True)
    >>> [ i.getDc() for i in f ]
    [{'a': ['abc', '2', '3']}, {'a': ['def', '2', '3']}, {'a': ['1', 'abc', '3']}, {'a': ['1', 'def', '3']}, {'a': ['1', '2', 'abc']}, {'a': ['1', '2', 'def']}]

    SmartFill of parameters
    >>> from core.data.dc.form import form
    >>> from core.data.request.httpPostDataRequest import httpPostDataRequest
    >>> pdr = httpPostDataRequest()
    >>> u = url_object('http://www.w3af.com/')
    >>> f = form()
    >>> _ = f.addInput( [("name", "address") , ("type", "text")] )
    >>> _ = f.addInput( [("name", "foo") , ("type", "text")] )
    >>> pdr.setURL( u )
    >>> pdr.setDc( f )
    >>> f = _createMutantsWorker( pdr, mutantPostData, ['abc', 'def'], [], True)
    >>> [ i.getDc() for i in f ]
    [{'foo': ['abc'], 'address': ['Bonsai Street 123']}, {'foo': ['def'], 'address': ['Bonsai Street 123']}, {'foo': ['56'], 'address': ['abc']}, {'foo': ['56'], 'address': ['def']}]

    """
    result = []
    if not dataContainer:
        dataContainer = freq.getDc()

    for parameter_name in dataContainer:

        #
        #   Ignore the banned parameter names
        #
        if parameter_name in IGNORED_PARAMETERS:
            continue

        # This for is to support repeated parameter names
        for element_index, element_value in enumerate(dataContainer[parameter_name]):

            for mutant_str in mutant_str_list:

                # Exclude the file parameters, those are fuzzed in _createFileContentMutants()
                # (if the framework if configured to do so)
                #
                # But if we have a form with files, then we have a multipart form, and we have to keep it
                # that way. If we don't send the multipart form as multipart, the remote programming
                # language may ignore all the request, and the parameter that we are
                # fuzzing (that's not the file content one) will be ignored too
                #
                # The "keeping the multipart form alive" thing is done some lines below, search for
                # the "__HERE__" string!
                #
                # The exclusion is done here:
                if parameter_name in freq.getFileVariables() and not hasattr(mutant_str, "name"):
                    continue

                # Only fuzz the specified parameters (if any)
                # or fuzz all of them (the fuzzableParamList == [] case)
                if parameter_name in fuzzableParamList or fuzzableParamList == []:

                    dataContainerCopy = dataContainer.copy()
                    original_value = element_value

                    if append:
                        dataContainerCopy[parameter_name][element_index] += mutant_str
                    else:
                        dataContainerCopy[parameter_name][element_index] = mutant_str

                    # Ok, now we have a data container with the mutant string, but it's possible that
                    # all the other fields of the data container are empty (think about a form)
                    # We need to fill those in, with something *useful* to get around the easiest
                    # developer checks like: "parameter A was filled".

                    # But I only perform this task in HTML forms, everything else is left as it is:
                    if isinstance(dataContainerCopy, form):
                        for var_name_dc in dataContainerCopy:
                            for element_index_dc, element_value_dc in enumerate(dataContainerCopy[var_name_dc]):
                                if (var_name_dc, element_index_dc) != (
                                    parameter_name,
                                    element_index,
                                ) and dataContainerCopy.getType(var_name_dc) not in [
                                    "checkbox",
                                    "radio",
                                    "select",
                                    "file",
                                ]:

                                    #   Fill only if the parameter does NOT have a value set.
                                    #
                                    #   The reason of having this already set would be that the form
                                    #   has something like this:
                                    #
                                    #   <input type="text" name="p" value="foobar">
                                    #
                                    if dataContainerCopy[var_name_dc][element_index_dc] == "":
                                        #
                                        #   Fill it smartly
                                        #
                                        dataContainerCopy[var_name_dc][element_index_dc] = smartFill(var_name_dc)

                    # __HERE__
                    # Please see the comment above for an explanation of what we are doing here:
                    for var_name in freq.getFileVariables():
                        # I have to create the string_file with a "name" attr.
                        # This is needed for MultipartPostHandler
                        str_file_instance = string_file("")
                        extension = cf.cf.getData("fuzzFCExt") or "txt"
                        str_file_instance.name = createRandAlpha(7) + "." + extension
                        dataContainerCopy[var_name][0] = str_file_instance

                    # Create the mutant
                    freq_copy = freq.copy()
                    m = mutantClass(freq_copy)
                    m.setVar(parameter_name, index=element_index)
                    m.setDc(dataContainerCopy)
                    m.setOriginalValue(original_value)
                    m.setModValue(mutant_str)

                    # Done, add it to the result
                    result.append(m)

    return result
Ejemplo n.º 4
0
def _createMutantsWorker( freq, mutantClass, mutant_str_list, fuzzableParamList,append, dataContainer=None):
    '''
    An auxiliary function to createMutants.
    
    @return: A list of mutants.
    '''
    result = []
    if not dataContainer:
        dataContainer = freq.getDc()

    for parameter_name in dataContainer:
        
        #
        #   Ignore the banned parameter names
        #
        if parameter_name in IGNORED_PARAMETERS:
            continue
        
        # This for is to support repeated parameter names
        for element_index, element_value in enumerate(dataContainer[parameter_name]):
            
            for mutant_str in mutant_str_list:
                
                # Exclude the file parameters, those are fuzzed in _createFileContentMutants()
                # (if the framework if configured to do so)
                #
                # But if we have a form with files, then we have a multipart form, and we have to keep it
                # that way. If we don't send the multipart form as multipart, the remote programming
                # language may ignore all the request, and the parameter that we are
                # fuzzing (that's not the file content one) will be ignored too
                #
                # The "keeping the multipart form alive" thing is done some lines below, search for
                # the "__HERE__" string!
                #
                # The exclusion is done here:
                if parameter_name in freq.getFileVariables() and not hasattr(mutant_str, 'name'):
                    continue
                    
                # Only fuzz the specified parameters (if any)
                # or fuzz all of them (the fuzzableParamList == [] case)
                if parameter_name in fuzzableParamList or fuzzableParamList == []:
                    
                    dataContainerCopy = dataContainer.copy()
                    original_value = element_value
                    
                    if append :
                        dataContainerCopy[parameter_name][element_index] += mutant_str
                    else:
                        dataContainerCopy[parameter_name][element_index] = mutant_str

                    # Ok, now we have a data container with the mutant string, but it's possible that
                    # all the other fields of the data container are empty (think about a form)
                    # We need to fill those in, with something *useful* to get around the easiest
                    # developer checks like: "parameter A was filled".
                    
                    # But I only perform this task in HTML forms, everything else is left as it is:
                    if isinstance( dataContainerCopy, form ):
                        for var_name_dc in dataContainerCopy:
                            for element_index_dc, element_value_dc in enumerate(dataContainerCopy[var_name_dc]):
                                if (var_name_dc, element_index_dc) != (parameter_name, element_index) and\
                                dataContainerCopy.getType(var_name_dc) not in ['checkbox', 'radio', 'select', 'file' ]:
                                    
                                    #   Fill only if the parameter does NOT have a value set.
                                    #
                                    #   The reason of having this already set would be that the form
                                    #   has something like this:
                                    #
                                    #   <input type="text" name="p" value="foobar">
                                    #
                                    if dataContainerCopy[var_name_dc][element_index_dc] == '':
                                        #
                                        #   Fill it smartly
                                        #
                                        dataContainerCopy[var_name_dc][element_index_dc] = smartFill(var_name_dc)

                    # __HERE__
                    # Please see the comment above for an explanation of what we are doing here:
                    for var_name in freq.getFileVariables():
                        # I have to create the string_file with a "name" attr.
                        # This is needed for MultipartPostHandler
                        str_file_instance = string_file( '' )
                        extension = cf.cf.getData('fuzzFCExt' ) or 'txt'
                        str_file_instance.name = createRandAlpha( 7 ) + '.' + extension
                        dataContainerCopy[var_name][0] = str_file_instance
                    
                    # Create the mutant
                    freq_copy = freq.copy()
                    m = mutantClass( freq_copy )
                    m.setVar( parameter_name, index=element_index )
                    m.setDc( dataContainerCopy )
                    m.setOriginalValue( original_value )
                    m.setModValue( mutant_str )
                    
                    # Done, add it to the result
                    result.append( m )

    return result
Ejemplo n.º 5
0
def _createMutantsWorker(freq, mutantClass, mutant_str_list,
                         fuzzableParamList, append, dataContainer=None):
    '''
    An auxiliary function to createMutants.
    
    @return: A list of mutants.

    >>> from core.data.request.fuzzableRequest import fuzzableRequest
    >>> from core.data.parsers.urlParser import url_object
    >>> from core.data.dc.dataContainer import DataContainer

    Mutant creation
    >>> d = DataContainer()
    >>> d['a'] = ['1',]
    >>> d['b'] = ['2',]
    >>> freq = fuzzableRequest(url_object('http://www.w3af.com/'), dc=d)
    >>> f = _createMutantsWorker( freq, mutantQs, ['abc', 'def'], [], False)
    >>> [ i.getDc() for i in f ]
    [DataContainer({'a': ['abc'], 'b': ['2']}), DataContainer({'a': ['def'], 'b': ['2']}), DataContainer({'a': ['1'], 'b': ['abc']}), DataContainer({'a': ['1'], 'b': ['def']})]

    Append
    >>> d = DataContainer()
    >>> d['a'] = ['1',]
    >>> d['b'] = ['2',]
    >>> freq = fuzzableRequest(url_object('http://www.w3af.com/'), dc=d)
    >>> f = _createMutantsWorker( freq, mutantQs, ['abc', 'def'], [], True)
    >>> [ i.getDc() for i in f ]
    [DataContainer({'a': ['1abc'], 'b': ['2']}), DataContainer({'a': ['1def'], 'b': ['2']}), DataContainer({'a': ['1'], 'b': ['2abc']}), DataContainer({'a': ['1'], 'b': ['2def']})]

    Repeated parameters
    >>> d = DataContainer()
    >>> d['a'] = ['1','2','3']
    >>> freq.setDc(d)
    >>> f = _createMutantsWorker( freq, mutantQs, ['abc', 'def'], [], False)
    >>> [ i.getDc() for i in f ]
    [DataContainer({'a': ['abc', '2', '3']}), DataContainer({'a': ['def', '2', '3']}), DataContainer({'a': ['1', 'abc', '3']}), DataContainer({'a': ['1', 'def', '3']}), DataContainer({'a': ['1', '2', 'abc']}), DataContainer({'a': ['1', '2', 'def']})]

    SmartFill of parameters
    >>> from core.data.dc.form import Form
    >>> from core.data.request.httpPostDataRequest import httpPostDataRequest
    >>> f = Form()
    >>> _ = f.addInput( [("name", "address") , ("type", "text")] )
    >>> _ = f.addInput( [("name", "foo") , ("type", "text")] )
    >>> pdr = httpPostDataRequest(url_object('http://www.w3af.com/'), dc=f)
    >>> f = _createMutantsWorker( pdr, mutantPostData, ['abc', 'def'], [], False)
    >>> [ i.getDc() for i in f ]
    [Form({'address': ['abc'], 'foo': ['56']}), Form({'address': ['def'], 'foo': ['56']}), Form({'address': ['Bonsai Street 123'], 'foo': ['abc']}), Form({'address': ['Bonsai Street 123'], 'foo': ['def']})]

    Support for HTTP requests that have both QS and POST-Data
    >>> f = Form()
    >>> _ = f.addInput( [("name", "password") , ("type", "password")] )
    >>> pdr = httpPostDataRequest(url_object('http://www.w3af.com/foo.bar?action=login'), dc=f)
    >>> mutants = _createMutantsWorker( pdr, mutantPostData, ['abc', 'def'], [], False)
    >>> [ i.getURI() for i in mutants ]
    [<url_object for "http://www.w3af.com/foo.bar?action=login">, <url_object for "http://www.w3af.com/foo.bar?action=login">]
    >>> [ i.getDc() for i in mutants ]
    [Form({'password': ['abc']}), Form({'password': ['def']})]
    '''
    result = []
    if not dataContainer:
        dataContainer = freq.getDc()

    for pname in dataContainer:
        
        #
        # Ignore the banned parameter names
        #
        if pname in IGNORED_PARAMETERS:
            continue
        
        # This for is to support repeated parameter names
        for element_index, element_value in _enumRepeatedParams(dataContainer[pname]):
            
            for mutant_str in mutant_str_list:
                
                # Exclude the file parameters, those are fuzzed in _createFileContentMutants()
                # (if the framework if configured to do so)
                #
                # But if we have a form with files, then we have a multipart form, and we have to keep it
                # that way. If we don't send the multipart form as multipart, the remote programming
                # language may ignore all the request, and the parameter that we are
                # fuzzing (that's not the file content one) will be ignored too
                #
                # The "keeping the multipart form alive" thing is done some lines below, search for
                # the "__HERE__" string!
                #
                # The exclusion is done here:
                if pname in freq.getFileVariables() and not hasattr(mutant_str, 'name'):
                    continue
                    
                # Only fuzz the specified parameters (if any)
                # or fuzz all of them (the fuzzableParamList == [] case)
                if pname in fuzzableParamList or fuzzableParamList == []:
                    
                    dc_copy = dataContainer.copy()
                    original_value = element_value
                    
                    # Ok, now we have a data container with the mutant string, but it's possible that
                    # all the other fields of the data container are empty (think about a form)
                    # We need to fill those in, with something *useful* to get around the easiest
                    # developer checks like: "parameter A was filled".
                    
                    # But I only perform this task in HTML forms, everything else is left as it is:
                    if isinstance(dc_copy, Form):
                        for var_name_dc in dc_copy:
                            for element_index_dc, element_value_dc in enumerate(dc_copy[var_name_dc]):
                                if (var_name_dc, element_index_dc) != (pname, element_index) and\
                                dc_copy.getType(var_name_dc) not in ['checkbox', 'radio', 'select', 'file' ]:
                                    
                                    #   Fill only if the parameter does NOT have a value set.
                                    #
                                    #   The reason of having this already set would be that the form
                                    #   has something like this:
                                    #
                                    #   <input type="text" name="p" value="foobar">
                                    #
                                    if dc_copy[var_name_dc][element_index_dc] == '':
                                        #
                                        #   Fill it smartly
                                        #
                                        dc_copy[var_name_dc][element_index_dc] = smartFill(var_name_dc)

                    # __HERE__
                    # Please see the comment above for an explanation of what we are doing here:
                    for var_name in freq.getFileVariables():
                        # I have to create the NamedStringIO with a "name".
                        # This is needed for MultipartPostHandler
                        fname = "%s.%s" % (createRandAlpha(7), 
                                           cf.cf.getData('fuzzFCExt' ) or 'txt') 
                        str_file = NamedStringIO('', name=fname)
                        dc_copy[var_name][0] = str_file
                    
                    if append:
                        mutant_str = original_value + mutant_str
                    dc_copy[pname][element_index] = mutant_str
                    
                    # Create the mutant
                    freq_copy = freq.copy()
                    m = mutantClass( freq_copy )
                    m.setVar( pname, index=element_index )
                    m.setDc( dc_copy )
                    m.setOriginalValue( original_value )
                    m.setModValue( mutant_str )
                    
                    # Done, add it to the result
                    result.append( m )

    return result