Пример #1
0
    def test_add_HTTPPostDataRequest(self):
        ds = DiskSet()

        uri = URL('http://w3af.org/?id=2')
        hdr = Headers([('Referer', 'http://w3af.org/')])

        pdr1 = HTTPPostDataRequest(uri, method='GET', headers=hdr)

        uri = URL('http://w3af.org/?id=3')
        pdr2 = HTTPPostDataRequest(uri, method='GET', headers=hdr)

        uri = URL('http://w3af.org/?id=7')
        pdr3 = HTTPPostDataRequest(uri, method='FOO', headers=hdr)

        ds.add(pdr1)
        ds.add(pdr2)
        ds.add(pdr2)
        ds.add(pdr1)

        self.assertEqual(ds[0], pdr1)
        self.assertEqual(ds[1], pdr2)
        self.assertFalse(pdr3 in ds)
        self.assertTrue(pdr2 in ds)
        self.assertEqual(len(ds), 2)

        # This forces an internal change in the URL object
        pdr2.get_url().url_string
        self.assertTrue(pdr2 in ds)
Пример #2
0
 def __init__(self, xml, uri, method='POST', headers=Headers()):
     '''
     :param xml: The original XML string that represents
                 the call to the RPC.
     '''
     HTTPPostDataRequest.__init__(self, uri)
     self._xml = xml
Пример #3
0
 def __init__(self, xml, uri, method='POST', headers=Headers()):
     '''
     :param xml: The original XML string that represents
                 the call to the RPC.
     '''
     HTTPPostDataRequest.__init__(self, uri)
     self._xml = xml
Пример #4
0
 def __init__(self, url, action, params,
              ns, meth_name, headers=Headers()):
     HTTPPostDataRequest.__init__(self, url, headers=headers)
     self._action = action
     self._NS = ns
     self._name = meth_name
     self.set_parameters(params)
Пример #5
0
    def test_mutant_creation_post_data(self):
        original_form = Form()
        original_form.add_input([("name", "username"), ("value", "")])
        original_form.add_input([("name", "address"), ("value", "")])
        original_form.add_file_input([("name", "file"), ("type", "file")])

        freq = HTTPPostDataRequest(self.url, dc=original_form)

        created_mutants = Mutant.create_mutants(freq, self.payloads, [], False,
                                                self.fuzzer_config)

        self.assertEqual(len(created_mutants), 4, created_mutants)

        expected_username_values = self.payloads + ['John8212'] * 2
        expected_address_values = ['Bonsai Street 123'] * 2 + self.payloads
        expected_file_values = ['GIF89a'] * 4

        created_dc_lst = [i.get_dc() for i in created_mutants]
        generated_username_values = [
            dc['username'][0] for dc in created_dc_lst
        ]
        generated_address_values = [dc['address'][0] for dc in created_dc_lst]
        generated_file_values = [dc['file'][0] for dc in created_dc_lst]

        self.assertEqual(expected_username_values, generated_username_values)
        self.assertEqual(expected_address_values, generated_address_values)
        for index, gen_file_value in enumerate(generated_file_values):
            startswith = gen_file_value.startswith(expected_file_values[index])
            self.assertTrue(startswith, gen_file_value)

        self.assertTrue(
            all(str_file.name[-4:].startswith('.gif')
                for str_file in generated_file_values))
Пример #6
0
    def test_mutant_creation_qs_and_postdata(self):
        original_form = Form()
        original_form.add_input([("name", "username"), ("value", "")])
        original_form.add_input([("name", "password"), ("value", "")])

        url = URL('http://moth/foo.bar?action=login')

        freq = HTTPPostDataRequest(url, dc=original_form)

        created_mutants = Mutant.create_mutants(freq, self.payloads, [], False,
                                                self.fuzzer_config)

        expected_dc_lst = [
            Form([('username', ['abc']), ('password', ['FrAmE30.'])]),
            Form([('username', ['def']), ('password', ['FrAmE30.'])]),
            Form([('username', ['John8212']), ('password', ['abc'])]),
            Form([('username', ['John8212']), ('password', ['def'])]),
        ]

        created_dc_lst = [i.get_dc() for i in created_mutants]
        created_urls = [i.get_uri() for i in created_mutants]

        self.assertEqual(created_urls, [
            url,
        ] * 4)
        self.assertEqual(created_dc_lst, expected_dc_lst)
Пример #7
0
    def test_mutant_creation(self):
        form = Form()
        form.add_input([("name", "username"), ("value", "")])
        form.add_input([("name", "address"), ("value", "")])

        freq = HTTPPostDataRequest(URL('http://www.w3af.com/?id=3'),
                                   dc=form,
                                   method='PUT')

        created_mutants = PostDataMutant.create_mutants(
            freq, self.payloads, [], False, self.fuzzer_config)

        expected_dc_lst = [
            Form([('username', ['abc']), ('address', ['Bonsai Street 123'])]),
            Form([('username', ['def']), ('address', ['Bonsai Street 123'])]),
            Form([('username', ['John8212']), ('address', ['abc'])]),
            Form([('username', ['John8212']), ('address', ['def'])])
        ]

        created_dc_lst = [i.get_dc() for i in created_mutants]

        self.assertEqual(created_dc_lst, expected_dc_lst)

        self.assertEqual(created_mutants[0].get_var(), 'username')
        self.assertEqual(created_mutants[0].get_var_index(), 0)
        self.assertEqual(created_mutants[0].get_original_value(), '')
        self.assertEqual(created_mutants[2].get_var(), 'address')
        self.assertEqual(created_mutants[2].get_var_index(), 0)
        self.assertEqual(created_mutants[2].get_original_value(), '')

        self.assertTrue(
            all(isinstance(m, PostDataMutant) for m in created_mutants))
        self.assertTrue(
            all(m.get_method().startswith('PUT') for m in created_mutants))
Пример #8
0
    def test_not_qs_request(self):
        fuzzer_config = {'fuzz_cookies': True}
        freq = HTTPPostDataRequest(URL('http://www.w3af.com/foo/bar'))

        generated_mutants = CookieMutant.create_mutants(
            freq, self.payloads, [], False, fuzzer_config)

        self.assertEqual(len(generated_mutants), 0, generated_mutants)
Пример #9
0
    def test_config_false(self):
        fuzzer_config = {'fuzz_form_files': False}
        freq = HTTPPostDataRequest(URL('http://www.w3af.com/foo/bar'))

        generated_mutants = FileContentMutant.create_mutants(
            freq, self.payloads, [], False, fuzzer_config)

        self.assertEqual(len(generated_mutants), 0, generated_mutants)
Пример #10
0
    def test_add_HTTPPostDataRequest(self):
        ds = DiskSet()

        uri = URL('http://w3af.org/?id=2')
        hdr = Headers([('Referer', 'http://w3af.org/')])

        pdr1 = HTTPPostDataRequest(uri, method='GET', headers=hdr)

        uri = URL('http://w3af.org/?id=3')
        pdr2 = HTTPPostDataRequest(uri, method='GET', headers=hdr)

        uri = URL('http://w3af.org/?id=7')
        pdr3 = HTTPPostDataRequest(uri, method='FOO', headers=hdr)

        ds.add(pdr1)
        ds.add(pdr2)
        ds.add(pdr2)
        ds.add(pdr1)

        self.assertEqual(ds[0], pdr1)
        self.assertEqual(ds[1], pdr2)
        self.assertFalse(pdr3 in ds)
        self.assertTrue(pdr2 in ds)
        self.assertEqual(len(ds), 2)

        # This forces an internal change in the URL object
        pdr2.get_url().url_string
        self.assertTrue(pdr2 in ds)
Пример #11
0
    def test_found_at(self):
        form = Form()
        form.add_input([("name", "username"), ("value", "")])
        form.add_input([("name", "address"), ("value", "")])

        freq = HTTPPostDataRequest(URL('http://www.w3af.com/?id=3'),
                                   dc=form,
                                   method='PUT')
        m = PostDataMutant(freq)
        m.set_var('username')

        expected = '"http://www.w3af.com/?id=3", using HTTP method PUT. '\
                   'The sent post-data was: "username=&address=" '\
                   'which modifies the "username" parameter.'
        self.assertEqual(m.found_at(), expected)
Пример #12
0
    def test_mutant_smart_fill_simple(self):
        original_form = Form()
        original_form.add_input([("name", "username"), ("value", "")])
        original_form.add_input([("name", "address"), ("value", "")])

        freq = HTTPPostDataRequest(self.url, dc=original_form)

        filled_form = mutant_smart_fill(freq, original_form, 'username', 0,
                                        self.fuzzer_config)

        self.assertEqual(id(original_form), id(filled_form))
        self.assertEqual(filled_form['username'], [
            '',
        ])
        self.assertEqual(filled_form['address'], [
            'Bonsai Street 123',
        ])
Пример #13
0
    def test_config_true(self):
        fuzzer_config = {
            'fuzz_form_files': True,
            'fuzzed_files_extension': 'gif'
        }

        form = Form()
        form.add_input([("name", "username"), ("value", "")])
        form.add_input([("name", "address"), ("value", "")])
        form.add_file_input([("name", "file"), ("type", "file")])

        freq = HTTPPostDataRequest(self.url, dc=form)

        generated_mutants = FileContentMutant.create_mutants(
            freq, self.payloads, [], False, fuzzer_config)

        self.assertNotEqual(len(generated_mutants), 0, generated_mutants)
Пример #14
0
    def test_mutant_smart_fill_with_file(self):
        original_form = Form()
        original_form.add_input([("name", "username"), ("value", "")])
        original_form.add_input([("name", "address"), ("value", "")])
        original_form.add_file_input([("name", "file"), ("type", "file")])

        freq = HTTPPostDataRequest(self.url, dc=original_form)

        filled_form = mutant_smart_fill(freq, original_form, 'username', 0,
                                        self.fuzzer_config)

        self.assertEqual(id(original_form), id(filled_form))
        self.assertEqual(filled_form['username'], [
            '',
        ])
        self.assertEqual(filled_form['address'], [
            'Bonsai Street 123',
        ])

        str_file = filled_form['file'][0]
        self.assertEqual(str_file.name[-4:], '.gif')
        self.assertIn('GIF', str_file)
Пример #15
0
    def test_mutant_creation_file(self):
        form = Form()
        form.add_input([("name", "username"), ("value", "default")])
        form.add_file_input([("name", "file_upload")])

        freq = HTTPPostDataRequest(URL('http://www.w3af.com/upload'),
                                   dc=form,
                                   method='POST')

        payloads = [
            file(__file__),
        ]
        created_mutants = PostDataMutant.create_mutants(
            freq, payloads, [
                'file_upload',
            ], False, self.fuzzer_config)

        self.assertEqual(len(created_mutants), 1, created_mutants)

        mutant = created_mutants[0]

        self.assertIsInstance(mutant.get_dc()['file_upload'][0], file)
        self.assertEqual(mutant.get_dc()['username'][0], 'default')
Пример #16
0
    def test_form_file_post_no_files(self):
        cf_singleton.save('fuzzable_headers', [])
        cf_singleton.save('fuzz_cookies', False)
        cf_singleton.save('fuzz_url_filenames', False)
        cf_singleton.save('fuzzed_files_extension', 'gif')
        cf_singleton.save('fuzz_form_files', True)  # This one changed
        cf_singleton.save('fuzz_url_parts', False)

        form = Form()
        form.add_input([("name", "username"), ("value", "")])
        form.add_input([("name", "address"), ("value", "")])

        freq = HTTPPostDataRequest(URL('http://www.w3af.com/?id=3'), dc=form,
                                   method='PUT')

        generated_mutants = create_mutants(freq, self.payloads)

        self.assertTrue(all('http://www.w3af.com/?id=3' == m.get_uri().url_string
                            for m in generated_mutants))

        self.assertTrue(all(isinstance(m, PostDataMutant)
                            for m in generated_mutants), generated_mutants)

        self.assertTrue(
            all(m.get_method() == 'PUT' for m in generated_mutants))

        expected_dc_lst = [Form(
            [('username', ['abc']), ('address', ['Bonsai Street 123'])]),
            Form([('username', [
                   'def']), ('address', ['Bonsai Street 123'])]),
            Form([('username', [
                   'John8212']), ('address', ['abc'])]),
            Form([('username', ['John8212']), ('address', ['def'])])]

        created_dc_lst = [i.get_dc() for i in generated_mutants]

        self.assertEqual(created_dc_lst, expected_dc_lst)
Пример #17
0
    def test_basics(self):
        form = Form()
        form.add_input([("name", "username"), ("value", "")])
        form.add_input([("name", "address"), ("value", "")])
        form.add_file_input([("name", "file"), ("type", "file")])

        freq = HTTPPostDataRequest(self.url, dc=form)

        m = FileContentMutant(freq)
        m.set_var('file', 0)
        m.set_mod_value('abc')
        self.assertEqual(m.get_url().url_string, 'http://moth/')

        expected_mod_value = 'The data that was sent is: "username=&file=abc&address=".'
        generated_mod_value = m.print_mod_value()

        self.assertEqual(generated_mod_value, expected_mod_value)

        expected_found_at = u'"http://moth/", using HTTP method POST. The'\
            ' sent post-data was: "username=&file=abc&address="'\
            ' which modifies the uploaded file content.'
        generated_found_at = m.found_at()

        self.assertEqual(generated_found_at, expected_found_at)
Пример #18
0
    def test_valid_results(self):
        form = Form()
        form.add_input([("name", "username"), ("value", "")])
        form.add_file_input([("name", "file"), ("type", "file")])

        freq = HTTPPostDataRequest(self.url, dc=form)

        generated_mutants = FileContentMutant.create_mutants(
            freq, self.payloads, [], False, self.fuzzer_config)

        self.assertEqual(len(generated_mutants), 2, generated_mutants)

        expected_data = [
            Form([('username', ['John8212']), ('file', ['abc'])]),
            Form([('username', ['John8212']), ('file', ['def'])]),
        ]

        generated_data = [m.get_data() for m in generated_mutants]

        self.assertEqual(expected_data, generated_data)

        str_file = generated_data[0]['file'][0]
        self.assertEqual(str_file.name[-4:], '.gif')
        self.assertIn('abc', str_file)
Пример #19
0
 def __init__(self, url, action, params, ns, meth_name, headers=Headers()):
     HTTPPostDataRequest.__init__(self, url, headers=headers)
     self._action = action
     self._NS = ns
     self._name = meth_name
     self.set_parameters(params)
Пример #20
0
def create_fuzzable_request_from_parts(url, method='GET', post_data='',
                                       add_headers=None):
    '''
    Creates a fuzzable request based on the input parameters.

    :param req_url: A URL object
    :param method: A string that represents the method ('GET', 'POST', etc)
    :param post_data: A string that represents the postdata.
    :param add_headers: A Headers object that holds the headers. If `req_url` is a
                        request then this dict will be merged with the request's
                        headers.
    '''
    if add_headers is not None and not isinstance(add_headers, Headers):
        raise ValueError('create_fuzzable_request requires Headers object.')
    
    if not isinstance(url, URL):
        raise TypeError('Requires URL to create FuzzableRequest.')

    headers = add_headers or Headers()

    # Just a query string request! No postdata
    if not post_data:
        return HTTPQSRequest(url, method, headers)

    else:
        # Seems to be something that has post data
        data = {}
        conttype, header_name = headers.iget('content-type', '')
        if conttype:
            del headers[header_name]

        contlen, header_name = headers.iget('content-length', '')
        if contlen:
            del headers[header_name]

        #
        # Case #1 - multipart form data - prepare data container
        #
        if conttype.startswith('multipart/form-data'):
            pdict = cgi.parse_header(conttype)[1]
            try:
                dc = cgi.parse_multipart(StringIO(post_data), pdict)
            except Exception, e:
                msg = 'Multipart form data is invalid, exception: "%s".' \
                      ' Returning our best match HTTPPostDataRequest.'
                om.out.debug(msg % e)

                empty_data = QueryString()
                return HTTPPostDataRequest(url, method, headers, dc=empty_data)
            else:
                data = QueryString()
                data.update(dc)

                # Please note that the QueryString is just a container for the
                # information. When the HTTPPostDataRequest is sent it should
                # be serialized into multipart again by the MultipartPostHandler
                # because the headers contain the multipart/form-data header
                headers['content-type'] = conttype

                return HTTPPostDataRequest(url, method, headers, dc=data)

        #
        # Case #2 - JSON request
        #
        try:
            data = json.loads(post_data)
        except:
            pass
        else:
            if data:
                return JSONPostDataRequest(url, method, headers, dc=data)

        #
        # Case #3 - XMLRPC request
        #
        if all(map(lambda stop: stop in post_data.lower(), XMLRPC_WORDS)):
            return XMLRPCRequest(post_data, url, method, headers)

        #
        # Case #4 - a typical post request
        #
        try:
            data = parse_qs(post_data)
        except:
            om.out.debug('Failed to create a data container that '
                         'can store this data: "' + post_data + '".')
        else:
            # Finally create request
            return HTTPPostDataRequest(url, method, headers, dc=data)

        return None
Пример #21
0
def create_fuzzable_requests(resp, request=None, add_self=True):
    '''
    Generates the fuzzable requests based on an HTTP response instance.

    :param resp: An HTTPResponse instance.
    :param request: The HTTP request that generated the resp
    :param add_self: If I should add the current HTTP request
                         (:param request) to the result on not.

    :return: A list of fuzzable requests.
    '''
    res = []

    # Headers for all fuzzable requests created here:
    # And add the fuzzable headers to the dict
    req_headers = dict((h, '') for h in cf.cf.get('fuzzable_headers'))
    req_headers.update(request and request.get_headers() or {})
    req_headers = Headers(req_headers.items())

    # Get the cookie!
    cookieObj = _create_cookie(resp)

    # Create the fuzzable request that represents the request object
    # passed as parameter
    if add_self:
        qsr = HTTPQSRequest(
            resp.get_uri(),
            headers=req_headers,
            cookie=cookieObj
        )
        res.append(qsr)

    # If response was a 30X (i.e. a redirect) then include the
    # corresponding fuzzable request.
    resp_headers = resp.get_headers()

    for url_header_name in URL_HEADERS:
        url_header_value, _ = resp_headers.iget(url_header_name, '')
        if url_header_value:
            url = smart_unicode(url_header_value, encoding=resp.charset)
            try:
                absolute_location = resp.get_url().url_join(url)
            except ValueError:
                msg = 'The application sent a "%s" redirect that w3af' \
                      ' failed to correctly parse as an URL, the header' \
                      ' value was: "%s"'
                om.out.debug(msg % (url_header_name, url))
            else:
                qsr = HTTPQSRequest(
                    absolute_location,
                    headers=req_headers,
                    cookie=cookieObj
                )
                res.append(qsr)

    # Try to find forms in the document
    try:
        dp = parser_cache.dpc.get_document_parser_for(resp)
    except w3afException:
        # Failed to find a suitable parser for the document
        form_list = []
    else:
        form_list = dp.get_forms()
        same_domain = lambda f: f.get_action(
        ).get_domain() == resp.get_url().get_domain()
        form_list = [f for f in form_list if same_domain(f)]

    if not form_list:
        # Check if its a wsdl file
        #TODO: Rewrite web service support
        '''
        wsdlp = WSDLParser()
        try:
            wsdlp.set_wsdl(resp.get_body())
        except w3afException:
            pass
        else:
            for rem_meth in wsdlp.get_methods():
                wspdr = WebServiceRequest(
                    rem_meth.get_location(),
                    rem_meth.get_action(),
                    rem_meth.get_parameters(),
                    rem_meth.get_namespace(),
                    rem_meth.get_methodName(),
                    req_headers
                )
                res.append(wspdr)
        '''
    else:
        # Create one HTTPPostDataRequest for each form variant
        mode = cf.cf.get('form_fuzzing_mode')
        for form in form_list:
            for variant in form.get_variants(mode):
                if form.get_method().upper() == 'POST':
                    r = HTTPPostDataRequest(
                        variant.get_action(),
                        variant.get_method(),
                        req_headers,
                        cookieObj,
                        variant)
                else:
                    # The default is a GET request
                    r = HTTPQSRequest(
                        variant.get_action(),
                        headers=req_headers,
                        cookie=cookieObj
                    )
                    r.set_dc(variant)

                res.append(r)
    return res