示例#1
0
文件: test_csrf.py 项目: zsdlove/w3af
    def test_is_suitable(self):
        url = URL('http://www.w3af.com/')
        headers = Headers([('content-type', 'text/html')])

        res = HTTPResponse(200, 'body', headers, url, url)

        # False because no cookie is set and no QS nor post-data
        url = URL('http://moth/')
        req = FuzzableRequest(url, method='GET')
        suitable = self.csrf_plugin._is_suitable(req, res)
        self.assertFalse(suitable)

        # False because no cookie is set
        url = URL('http://moth/?id=3')
        req = FuzzableRequest(url, method='GET')
        suitable = self.csrf_plugin._is_suitable(req, res)
        self.assertFalse(suitable)

        url_sends_cookie = URL(
            get_w3af_moth_http('/w3af/core/cookie_handler/set-cookie.php'))
        self.uri_opener.GET(url_sends_cookie)

        # Still false because it doesn't have any QS or POST data
        url = URL('http://moth/')
        req = FuzzableRequest(url, method='GET')
        suitable = self.csrf_plugin._is_suitable(req, res)
        self.assertFalse(suitable)

        self.csrf_plugin._strict_mode = True

        # Still false because of the strict mode
        url = URL('http://moth/?id=3')
        req = FuzzableRequest(url, method='GET')
        suitable = self.csrf_plugin._is_suitable(req, res)
        self.assertFalse(suitable)

        # False, no items in post-data
        url = URL('http://moth/')
        req = FuzzableRequest(url, method='POST', post_data=URLEncodedForm())
        suitable = self.csrf_plugin._is_suitable(req, res)
        self.assertFalse(suitable)

        # True, items in DC, POST (passes strict mode) and cookies
        url = URL('http://moth/')
        form_params = FormParameters()
        form_params.add_field_by_attr_items([('name', 'test'),
                                             ('type', 'text')])
        form = URLEncodedForm(form_params)
        req = FuzzableRequest(url, method='POST', post_data=form)
        suitable = self.csrf_plugin._is_suitable(req, res)
        self.assertTrue(suitable)

        self.csrf_plugin._strict_mode = False

        # True now that we have strict mode off, cookies and QS
        url = URL('http://moth/?id=3')
        req = FuzzableRequest(url, method='GET')
        suitable = self.csrf_plugin._is_suitable(req, res)
        self.assertTrue(suitable)
示例#2
0
    def test_is_suitable(self):
        # False because no cookie is set and no QS nor post-data
        url = URL('http://moth/')
        req = FuzzableRequest(url, method='GET')
        suitable = self.csrf_plugin._is_suitable(req)
        self.assertFalse(suitable)

        # False because no cookie is set
        url = URL('http://moth/?id=3')
        req = FuzzableRequest(url, method='GET')
        suitable = self.csrf_plugin._is_suitable(req)
        self.assertFalse(suitable)

        url_sends_cookie = URL(
            'http://moth/w3af/core/cookie_handler/set-cookie.php')
        self.uri_opener.GET(url_sends_cookie)

        # Still false because it doesn't have any QS or POST data
        url = URL('http://moth/')
        req = FuzzableRequest(url, method='GET')
        suitable = self.csrf_plugin._is_suitable(req)
        self.assertFalse(suitable)

        self.csrf_plugin._strict_mode = True

        # Still false because of the strict mode
        url = URL('http://moth/?id=3')
        req = FuzzableRequest(url, method='GET')
        suitable = self.csrf_plugin._is_suitable(req)
        self.assertFalse(suitable)

        # False, no items in post-data
        url = URL('http://moth/')
        req = FuzzableRequest(url, method='POST', post_data=URLEncodedForm())
        suitable = self.csrf_plugin._is_suitable(req)
        self.assertFalse(suitable)

        # True, items in DC, POST (passes strict mode) and cookies
        url = URL('http://moth/')
        form_params = FormParameters()
        form_params.add_input([('name', 'test'), ('type', 'text')])
        form = URLEncodedForm(form_params)
        req = FuzzableRequest(url, method='POST', post_data=form)
        suitable = self.csrf_plugin._is_suitable(req)
        self.assertTrue(suitable)

        self.csrf_plugin._strict_mode = False

        # True now that we have strict mode off, cookies and QS
        url = URL('http://moth/?id=3')
        req = FuzzableRequest(url, method='GET')
        suitable = self.csrf_plugin._is_suitable(req)
        self.assertTrue(suitable)
示例#3
0
    def test_form_with_plus_value(self):
        """
        This test verifies that a fix for the bug identified while scanning
        demo.testfire.net is still working as expected. The issue was that the
        site had a form that looked like:

        <form action="/xyz">
            <intput name="foo" value="bar+spam" type="hidden">
            <intput name="eggs" type="text">
            ...
        </form>

        And when trying to send a request to that form the "+" in the value
        was sent as %20. The input was an .NET's EVENTVALIDATION thus it was
        impossible to find any bugs in the "eggs" parameter.

        Please note that this is just a partial test, since there is much more
        going on in w3af than just creating a form and encoding it. A functional
        test for this issue can be found at test_special_chars.py
        """
        form_with_plus = [{
            'tagname': 'input',
            'name': 'foo',
            'type': 'hidden',
            'value': 'bar+spam'
        }, {
            'tagname': 'input',
            'name': 'eggs',
            'type': 'text'
        }]

        form = URLEncodedForm(create_form_params_helper(form_with_plus))
        self.assertEqual(str(form), 'eggs=&foo=bar%2Bspam')
示例#4
0
    def test_mutant_creation_repeated_parameter_name(self):
        form_params = FormParameters()
        form_params.add_field_by_attr_items([("name", "id"), ("value", "")])
        form_params.add_field_by_attr_items([("name", "id"), ("value", "")])

        form = URLEncodedForm(form_params)
        freq = FuzzableRequest(URL('http://w3af.com/?foo=3'),
                               post_data=form,
                               method='GET')

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

        expected_dcs = [
            'id=def&id=3419', 'id=3419&id=def', 'id=3419&id=abc',
            'id=abc&id=3419'
        ]

        created_dcs = [str(i.get_dc()) for i in created_mutants]

        self.assertEqual(set(created_dcs), set(expected_dcs))

        token = created_mutants[0].get_token()
        self.assertEqual(token.get_name(), 'id')
        self.assertEqual(token.get_original_value(), '')

        token = created_mutants[2].get_token()
        self.assertEqual(token.get_name(), 'id')
        self.assertEqual(token.get_original_value(), '')

        for m in created_mutants:
            self.assertIsInstance(m, PostDataMutant)

        for m in created_mutants:
            self.assertEqual(m.get_method(), 'GET')
示例#5
0
    def test_from_postdata_no_post_data(self):
        headers = Headers([('content-type', URLEncodedForm.ENCODING)])
        post_data = ''

        form = URLEncodedForm.from_postdata(headers, post_data)

        self.assertEqual(len(form), 0)
示例#6
0
    def test_mutant_creation_qs_and_postdata(self):
        form_params = FormParameters()
        form_params.add_field_by_attr_items([("name", "username"),
                                             ("value", "")])
        form_params.add_field_by_attr_items([("name", "password"),
                                             ("value", "")])

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

        form = URLEncodedForm(form_params)
        freq = FuzzableRequest(url, post_data=form)

        created_mutants = PostDataMutant.create_mutants(
            freq, self.payloads, [], False, self.fuzzer_config)
        created_dcs = [str(i.get_dc()) for i in created_mutants]

        expected_dcs = [
            'username=abc&password=FrAmE30.', 'username=John8212&password=abc',
            'username=def&password=FrAmE30.', 'username=John8212&password=def'
        ]

        self.assertEqual(created_dcs, expected_dcs)

        for m in created_mutants:
            self.assertEqual(m.get_uri(), url)
示例#7
0
    def test_from_postdata_no_post_data(self):
        headers = Headers([('content-type', URLEncodedForm.ENCODING)])
        post_data = ''

        form = URLEncodedForm.from_postdata(headers, post_data)

        self.assertEqual(len(form), 0)
示例#8
0
    def test_from_url_keep_form(self):
        o = URL('http://w3af.com/foo/bar.txt')
        o.querystring = URLEncodedForm()

        u = URL.from_URL(o)
        self.assertIsInstance(u.querystring, URLEncodedForm)
        self.assertIsNot(u.querystring, o.querystring)
        self.assertEqual(u.querystring, o.querystring)
示例#9
0
    def test_POST(self):
        url = URL(get_moth_http('/audit/xss/simple_xss_form.py'))

        data = URLEncodedForm()
        data['text'] = ['123456abc']

        http_response = self.uri_opener.POST(url, data, cache=False)
        self.assertIn('123456abc', http_response.body)
示例#10
0
 def test_form_str_special_chars_1(self):
     form_data = [{
         'tagname': 'input',
         'type': 'text',
         'name': 'abc',
         'value': '1"2'
     }]
     form = URLEncodedForm(create_form_params_helper(form_data))
     self.assertEqual(str(form), 'abc=1%222')
示例#11
0
 def test_form_str_simple(self):
     form_data = [{
         'tagname': 'input',
         'type': 'text',
         'name': 'abc',
         'value': '123'
     }]
     form = URLEncodedForm(create_form_params_helper(form_data))
     self.assertEqual(str(form), 'abc=123')
示例#12
0
    def test_POST_special_chars(self):
        url = URL(get_moth_http('/audit/xss/simple_xss_form.py'))
        test_data = u'abc<def>"-á-'

        data = URLEncodedForm()
        data['text'] = [test_data]

        http_response = self.uri_opener.POST(url, data, cache=False)
        self.assertIn(test_data, http_response.body)
示例#13
0
    def test_php_serialized_objects_post_data(self):
        post_data = 'obj=%s' % base64.b64encode(SERIALIZED_PHP_OBJECTS[1])
        headers = Headers([('Content-Type', 'application/x-www-form-urlencoded')])

        form = URLEncodedForm.from_postdata(headers, post_data)
        request = FuzzableRequest(self.url, headers=headers, post_data=form)

        self.plugin.grep(request, self.response)

        self.assertEquals(len(kb.kb.get('serialized_object',
                                        'serialized_object')), 1)
示例#14
0
    def test_form_copy(self):
        headers = Headers([('content-type', URLEncodedForm.ENCODING)])
        post_data = 'a=2&c=3'

        form = URLEncodedForm.from_postdata(headers, post_data)
        form.set_token(('a', 0))

        form_copy = copy.deepcopy(form)

        self.assertEqual(form, form_copy)
        self.assertEqual(form.get_token(), form_copy.get_token())
        self.assertIsNot(None, form_copy.get_token())
示例#15
0
    def test_form_copy(self):
        headers = Headers([('content-type', URLEncodedForm.ENCODING)])
        post_data = 'a=2&c=3'

        form = URLEncodedForm.from_postdata(headers, post_data)
        form.set_token(('a', 0))

        form_copy = copy.deepcopy(form)

        self.assertEqual(form, form_copy)
        self.assertEqual(form.get_token(), form_copy.get_token())
        self.assertIsNot(None, form_copy.get_token())
示例#16
0
    def test_form_pickle(self):
        headers = Headers([('content-type', URLEncodedForm.ENCODING)])
        post_data = 'a=2&c=3'

        form = URLEncodedForm.from_postdata(headers, post_data)
        form.set_token(('a', 0))

        pickled_form = cPickle.dumps(form)
        unpickled_form = cPickle.loads(pickled_form)

        self.assertEqual(form, unpickled_form)
        self.assertEqual(form.get_token(), unpickled_form.get_token())
        self.assertIsNotNone(unpickled_form.get_token())
        self.assertEqual(unpickled_form.keys(), ['a', 'c'])
示例#17
0
    def test_form_pickle(self):
        headers = Headers([("content-type", URLEncodedForm.ENCODING)])
        post_data = "a=2&c=3"

        form = URLEncodedForm.from_postdata(headers, post_data)
        form.set_token(("a", 0))

        pickled_form = cPickle.dumps(form)
        unpickled_form = cPickle.loads(pickled_form)

        self.assertEqual(form, unpickled_form)
        self.assertEqual(form.get_token(), unpickled_form.get_token())
        self.assertIsNotNone(unpickled_form.get_token())
        self.assertEqual(unpickled_form.keys(), ["a", "c"])
示例#18
0
    def test_mutant_creation(self):
        form_params = FormParameters()
        form_params.add_field_by_attr_items([("name", "username"),
                                             ("value", "")])
        form_params.add_field_by_attr_items([("name", "address"),
                                             ("value", "")])

        form = URLEncodedForm(form_params)
        freq = FuzzableRequest(URL('http://www.w3af.com/?id=3'),
                               post_data=form,
                               method='PUT')

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

        expected_dcs = [
            'username=def&address=Bonsai%20Street%20123',
            'username=abc&address=Bonsai%20Street%20123',
            'username=John8212&address=def', 'username=John8212&address=abc'
        ]

        created_dcs = [str(i.get_dc()) for i in created_mutants]

        self.assertEqual(set(created_dcs), set(expected_dcs))

        token = created_mutants[0].get_token()
        self.assertEqual(token.get_name(), 'username')
        self.assertEqual(token.get_original_value(), '')
        self.assertEqual(token.get_value(), 'abc')

        token = created_mutants[1].get_token()
        self.assertEqual(token.get_name(), 'address')
        self.assertEqual(token.get_original_value(), '')
        self.assertEqual(token.get_value(), 'abc')

        token = created_mutants[2].get_token()
        self.assertEqual(token.get_name(), 'username')
        self.assertEqual(token.get_original_value(), '')
        self.assertEqual(token.get_value(), 'def')

        token = created_mutants[3].get_token()
        self.assertEqual(token.get_name(), 'address')
        self.assertEqual(token.get_original_value(), '')
        self.assertEqual(token.get_value(), 'def')

        for m in created_mutants:
            self.assertIsInstance(m, PostDataMutant)

        for m in created_mutants:
            self.assertEqual(m.get_method(), 'PUT')
示例#19
0
    def test_found_at(self):
        form_params = FormParameters()
        form_params.add_field_by_attr_items([("name", "username"), ("value", "")])
        form_params.add_field_by_attr_items([("name", "address"), ("value", "")])

        form = URLEncodedForm(form_params)
        freq = FuzzableRequest(URL('http://www.w3af.com/?id=3'), post_data=form,
                               method='PUT')
        m = PostDataMutant(freq)
        m.get_dc().set_token(('username', 0))

        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)
示例#20
0
    def test_from_postdata_ok(self):
        headers = Headers([("content-type", URLEncodedForm.ENCODING)])
        post_data = "a=2&c=3"

        form = URLEncodedForm.from_postdata(headers, post_data)

        self.assertEqual(form["a"], ["2"])
        self.assertEqual(form["c"], ["3"])

        self.assertFalse(form.is_login_form())
        self.assertFalse(form.is_password_change_form())
        self.assertFalse(form.is_registration_form())

        self.assertEqual(form.get_parameter_type("a"), INPUT_TYPE_TEXT)
        self.assertEqual(form.get_parameter_type("b"), INPUT_TYPE_TEXT)
示例#21
0
    def test_from_postdata_ok(self):
        headers = Headers([('content-type', URLEncodedForm.ENCODING)])
        post_data = 'a=2&c=3'

        form = URLEncodedForm.from_postdata(headers, post_data)

        self.assertEqual(form['a'], ['2'])
        self.assertEqual(form['c'], ['3'])

        self.assertFalse(form.is_login_form())
        self.assertFalse(form.is_password_change_form())
        self.assertFalse(form.is_registration_form())

        self.assertEqual(form.get_parameter_type('a'), INPUT_TYPE_TEXT)
        self.assertEqual(form.get_parameter_type('b'), INPUT_TYPE_TEXT)
示例#22
0
    def test_mutated_request(self):
        # Note that I'm sending the serialized object in reverse string order
        post_data = 'test=1&obj=%s' % base64.b64encode(
            SERIALIZED_PHP_OBJECTS[1])
        headers = Headers([('Content-Type',
                            'application/x-www-form-urlencoded')])

        form = URLEncodedForm.from_postdata(headers, post_data)
        request = FuzzableRequest(self.url, headers=headers, post_data=form)
        mutants = create_mutants(request, ['x'])

        for mutant in mutants:
            self.plugin.grep(mutant, self.response)

        self.assertEquals(
            len(kb.kb.get('serialized_object', 'serialized_object')), 1)
示例#23
0
    def test_from_postdata_ok(self):
        headers = Headers([('content-type', URLEncodedForm.ENCODING)])
        post_data = 'a=2&c=3'

        form = URLEncodedForm.from_postdata(headers, post_data)

        self.assertEqual(form['a'], ['2'])
        self.assertEqual(form['c'], ['3'])

        self.assertFalse(form.is_login_form())
        self.assertFalse(form.is_password_change_form())
        self.assertFalse(form.is_registration_form())

        self.assertEqual(form.get_parameter_type('a'),
                         FormParameters.INPUT_TYPE_TEXT)

        self.assertEqual(form.get_parameter_type('b'),
                         FormParameters.INPUT_TYPE_TEXT)
示例#24
0
    def test_should_inject_form_hidden(self):
        form_params = FormParameters()
        form_params.add_field_by_attr_items([("name", "username"),
                                             ("type", "text")])
        form_params.add_field_by_attr_items([("name", "csrf_token"),
                                             ("type", "hidden")])

        form = URLEncodedForm(form_params)
        freq = FuzzableRequest(URL('http://www.w3af.com/'),
                               post_data=form,
                               method='PUT')
        m = PostDataMutant(freq)
        m.get_dc().set_token(('username', 0))

        self.assertFalse(self.plugin._should_inject(m, 'python'))

        m.get_dc().set_token(('csrf_token', 0))
        self.assertTrue(self.plugin._should_inject(m, 'python'))
示例#25
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_params = FormParameters()
        form_params.add_field_by_attr_items([("name", "username"),
                                             ("value", "")])
        form_params.add_field_by_attr_items([("name", "address"),
                                             ("value", "")])

        form = URLEncodedForm(form_params)

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

        mutants = create_mutants(freq, self.payloads)

        self.assertTrue(all(isinstance(m, QSMutant) for m in mutants[:2]))
        self.assertTrue(all(
            isinstance(m, PostDataMutant) for m in mutants[4:]))

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

        expected_uris = {
            'http://www.w3af.com/?id=abc', 'http://www.w3af.com/?id=def',
            'http://www.w3af.com/?id=3', 'http://www.w3af.com/?id=3',
            'http://www.w3af.com/?id=3', 'http://www.w3af.com/?id=3'
        }
        created_uris = set([i.get_uri().url_string for i in mutants])
        self.assertEqual(expected_uris, created_uris)

        expected_dcs = {
            'id=abc', 'id=def', 'username=abc&address=Bonsai%20Street%20123',
            'username=def&address=Bonsai%20Street%20123',
            'username=John8212&address=abc', 'username=John8212&address=def'
        }

        created_dcs = set([str(i.get_dc()) for i in mutants])
        self.assertEqual(created_dcs, expected_dcs)
示例#26
0
def dc_from_form_params(form_parameters):
    """
    :param form_parameters: The form parameters is the result of parsing HTML,
                            and contains information such as the parameter names
                            and types.

    :return: An instance of URLEncodedForm or MultipartContainer
    """
    if form_parameters.get_file_vars():
        # If it has files, I don't care if the form encoding wasn't specified
        # we must send it as multipart.
        return MultipartContainer(form_parameters)

    if 'multipart' in form_parameters.get_form_encoding().lower():
        # If there are no files but the web developer specified the multipart
        # form encoding, then we'll use multipart also
        return MultipartContainer(form_parameters)

    return URLEncodedForm(form_parameters)
示例#27
0
    def test_form_str_special_chars_2(self):
        form_data = [{
            'tagname': 'input',
            'type': 'text',
            'name': 'v',
            'value': 'áéíóú'
        }, {
            'tagname': 'input',
            'type': 'hidden',
            'name': 'c',
            'value': 'ñçÑÇ'
        }]

        form_params = create_form_params_helper(form_data)
        form_params.add_field_by_attrs({'name': 'address', 'value': 'bsas'})

        form = URLEncodedForm(form_params)

        self.assertEqual(
            urllib.unquote(str(form)).decode('utf-8'),
            u'c=ñçÑÇ&address=bsas&v=áéíóú')
示例#28
0
 def test_form_str_radio_select(self):
     form_dict = form_with_radio + form_with_checkbox + form_select_cars
     form = URLEncodedForm(create_form_params_helper(form_dict))
     self.assertEqual(str(form), 'cars=volvo&vehicle=Bike&sex=male')