예제 #1
0
    async def test_fetch_session_cookies_on_scan_start_if_no_user_supplied_cookies(self, loop):
        engine = FakeHammerTimeEngine()
        hammertime = HammerTime(request_engine=engine, loop=loop)
        hammertime.collect_successful_requests()

        await tachyon.scan(hammertime, cookies=None, accumulator=self.accumulator)

        tachyon.get_session_cookies.assert_called_once_with(hammertime)
예제 #2
0
    async def test_scan_file_only(self, loop):
        engine = FakeHammerTimeEngine()
        hammertime = HammerTime(request_engine=engine, loop=loop)
        hammertime.collect_successful_requests()

        await tachyon.scan(hammertime, files_only=True, accumulator=self.accumulator)

        tachyon.test_file_exists.assert_called_with(hammertime, accumulator=self.accumulator)
        tachyon.test_paths_exists.assert_not_called()
예제 #3
0
    async def test_fetch_session_cookies_on_scan_start_if_no_user_supplied_cookies(
            self, loop):
        engine = FakeHammerTimeEngine()
        hammertime = HammerTime(request_engine=engine, loop=loop)
        hammertime.collect_successful_requests()

        await tachyon.scan(hammertime,
                           cookies=None,
                           accumulator=self.accumulator)

        tachyon.get_session_cookies.assert_called_once_with(hammertime)
예제 #4
0
    async def test_successful_requests_return_if_no_pending_requests(
            self, loop):
        h = HammerTime(loop=loop, request_engine=FakeEngine())
        h.collect_successful_requests()

        try:
            with async_timeout.timeout(0.001):
                async for entry in h.successful_requests():
                    entry.request
        except asyncio.TimeoutError:
            self.fail("Function blocked.")
예제 #5
0
    async def test_use_user_supplied_cookies_if_available(self, loop):
        database.session_cookie = "my-cookies=123"
        cookies = "test-cookie=true"
        engine = FakeHammerTimeEngine()
        hammertime = HammerTime(request_engine=engine, loop=loop)
        hammertime.collect_successful_requests()

        with patch("tachyon.config.add_http_header") as add_http_header:
            await tachyon.scan(hammertime, cookies=cookies, accumulator=self.accumulator)

            add_http_header.assert_any_call(ANY, "Cookie", "test-cookie=true")
예제 #6
0
    async def test_scan_plugins_only(self, loop):
        engine = FakeHammerTimeEngine()
        hammertime = HammerTime(request_engine=engine, loop=loop)
        hammertime.collect_successful_requests()

        await tachyon.scan(hammertime,
                           plugins_only=True,
                           accumulator=self.accumulator)

        tachyon.load_execute_host_plugins.assert_called_once_with(hammertime)
        tachyon.test_file_exists.assert_not_called()
        tachyon.test_paths_exists.assert_not_called()
예제 #7
0
    async def test_use_user_supplied_cookies_if_available(self, loop):
        database.session_cookie = "my-cookies=123"
        cookies = "test-cookie=true"
        engine = FakeHammerTimeEngine()
        hammertime = HammerTime(request_engine=engine, loop=loop)
        hammertime.collect_successful_requests()

        with patch("tachyon.config.add_http_header") as add_http_header:
            await tachyon.scan(hammertime,
                               cookies=cookies,
                               accumulator=self.accumulator)

            add_http_header.assert_any_call(ANY, "Cookie", "test-cookie=true")
예제 #8
0
    async def test_loop_over_results(self, loop):
        h = HammerTime(loop=loop, request_engine=FakeEngine())
        h.collect_successful_requests()
        h.request("http://example.com/1")
        h.request("http://example.com/2")

        out = set()

        async for entry in h.successful_requests():
            out.add(entry.response.content)

        self.assertEqual(out, {"http://example.com/1", "http://example.com/2"})
        self.assertEqual(h.completed_count, 2)
예제 #9
0
    async def test_no_successful_request_returned_when_requests_are_cancelled(
            self, loop):
        engine = MagicMock()
        engine.perform = make_mocked_coro(
            raise_exception=asyncio.CancelledError)
        hammertime = HammerTime(loop=loop, request_engine=engine)
        hammertime.collect_successful_requests()

        for i in range(5):
            hammertime.request("http://example.com")

        successful_requests = []
        async for request in hammertime.successful_requests():
            successful_requests.append(request)

        self.assertEqual(successful_requests, [])
예제 #10
0
class TestDirectoryFetcher(TestCase):

    def setUp(self):
        valid_paths.clear()
        self.host = "http://example.com"

    def async_setup(self, loop):
        self.hammertime = HammerTime(loop=loop, request_engine=FakeHammerTimeEngine())
        self.hammertime.collect_successful_requests()
        self.hammertime.heuristics.add_multiple([SetFlagInResult("soft404", False),
                                                 SetFlagInResult("error_behavior", False)])
        self.directory_fetcher = DirectoryFetcher(self.host, self.hammertime)

    @async_test()
    async def test_fetch_paths_add_valid_path_to_database(self, output_result, loop):
        valid = ["/a", "b", "/c", "/1", "/2", "/3"]
        invalid = ["/d", "/e", "/4", "/5"]
        paths = valid + invalid
        self.async_setup(loop)
        self.hammertime.heuristics.add(RaiseForPaths(invalid, RejectRequest("Invalid path")))

        await self.directory_fetcher.fetch_paths(create_json_data(paths))

        self.assertEqual(len(valid), len(valid_paths))
        for path in valid_paths:
            self.assertIn(path["url"], valid)
            self.assertNotIn(path["url"], invalid)

    @async_test()
    async def test_fetch_paths_dont_add_path_if_response_code_is_401(self, output_result, loop):
        paths = ["/401"]
        self.async_setup(loop)
        self.hammertime.heuristics.add(SetResponseCode(401))

        await self.directory_fetcher.fetch_paths(create_json_data(paths))

        self.assertEqual(len(database.valid_paths), 0)

    @async_test()
    async def test_fetch_paths_output_found_directory(self, output_result, loop):
        found = ["/%d" % i for i in range(10)]
        not_found = ["/1%d" % i for i in range(10)]
        paths = found + not_found
        self.async_setup(loop)
        self.hammertime.heuristics.add(RaiseForPaths(not_found, RejectRequest("404 not found")))

        await self.directory_fetcher.fetch_paths(create_json_data(paths))

        calls = []
        for path in create_json_data(found):
            message, data = self.expected_output(path)
            calls.append(call(message, data=data))
        output_result.assert_has_calls(calls, any_order=True)

    @async_test()
    async def test_fetch_paths_does_not_output_root_path(self, output_result, loop):
        paths = create_json_data(["/"])
        self.async_setup(loop)

        await self.directory_fetcher.fetch_paths(paths)

        self.assertEqual(database.valid_paths, paths)
        output_result.assert_not_called()

    @async_test()
    async def test_fetch_paths_output_401_directory(self, output_result, loop):
        self.async_setup(loop)
        self.hammertime.heuristics.add(SetResponseCode(401))
        path_list = create_json_data(["/admin"])

        await self.directory_fetcher.fetch_paths(path_list)

        message, data = self.expected_output(path_list[0], code=401, message_prefix="Password Protected - ")
        output_result.assert_called_once_with(message, data=data)

    @async_test()
    async def test_fetch_paths_output_500_response(self, output_result, loop):
        self.async_setup(loop)
        self.hammertime.heuristics.add(SetResponseCode(500))
        path_list = create_json_data(["/server-error"])

        await self.directory_fetcher.fetch_paths(path_list)

        message, data = self.expected_output(path_list[0], message_prefix="ISE, ", code=500)
        output_result.assert_called_once_with(message, data=data)

    @async_test()
    async def test_fetch_paths_output_403_directory(self, output_result, loop):
        self.async_setup(loop)
        self.hammertime.heuristics.add(SetResponseCode(403))
        path_list = create_json_data(["/forbidden"])

        await self.directory_fetcher.fetch_paths(path_list)

        message, data = self.expected_output(path_list[0], message_prefix="*Forbidden* ", code=403)
        output_result.assert_called_once_with(message, data=data)

    @async_test()
    async def test_fetch_paths_append_slash_to_path(self, output_result, loop):
        paths = ["/a", "/b", "/c", "/1", "/2", "/3"]
        self.async_setup(loop)
        await self.directory_fetcher.fetch_paths(create_json_data(paths))
        requested = [url for url in self.hammertime.request_engine.request_engine.get_requested_urls()]
        self.assertEqual(len(paths), len(requested))
        for url, path in zip(requested, paths):
            self.assertEqual(url, "{}{}/".format(self.host, path))

    @async_test()
    async def test_fetch_paths_does_not_append_slash_to_root_path(self, output_result, loop):
        paths = ["/"]
        self.async_setup(loop)
        await self.directory_fetcher.fetch_paths(create_json_data(paths))
        requested = list(self.hammertime.request_engine.request_engine.get_requested_urls())[0]
        self.assertEqual(requested, self.host + "/")

    def expected_output(self, path, *, code=200, message_prefix=""):
        url = "{}{}/".format(self.host, path["url"])
        data = {"description": path["description"], "url": url, "severity": path["severity"], "code": code}
        message = "{prefix}{desc} at: {url}".format(prefix=message_prefix, desc=data["description"], url=url)
        return message, data