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 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 def test_fetch_files_do_not_output_redirects(self, output_found, loop): files = ["/admin/resource", "/admin/file"] self.setUpFetcher(loop) self.setup_hammertime_heuristics(add_before_defaults=[SetResponseCode(302)]) await self.file_fetcher.fetch_files(create_json_data(files)) output_found.assert_not_called()
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 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 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 def test_only_add_string_match_flag_for_file(self): path = create_json_data(["/path/"])[0] match_string = MatchString() response = StaticResponse(200, {}, content="") entry = Entry.create("http://example.com/file", arguments={"path": path}, response=response) await match_string.after_response(entry) self.assertFalse(hasattr(entry.result, "string_match"))
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 def test_set_string_match_to_false_if_no_match_string_in_file(self): file_to_fetch = create_json_data(["file"])[0] match_string = MatchString() response = StaticResponse(200, {}, content="content") entry = Entry.create("http://example.com/file", arguments={"file": file_to_fetch}, response=response) await match_string.after_response(entry) self.assertFalse(entry.result.string_match)
async def test_set_string_match_flag_in_entry_result_to_false_if_string_to_match_found_in_response_content(self): file_to_fetch = create_json_data(["file"], match_string="abc123")[0] match_string = MatchString() response = StaticResponse(200, {}, content="Content is not matching") entry = Entry.create("http://example.com/file", arguments={"file": file_to_fetch}, response=response) await match_string.after_response(entry) self.assertFalse(entry.result.string_match)
async def test_fetch_files_do_not_reject_soft_404_if_string_match_is_true(self, output_found, loop): file = create_json_data(["file"])[0] self.setUpFetcher(loop) self.setup_hammertime_heuristics(add_before_defaults=[SetFlagInResult("soft404", True), SetFlagInResult("string_match", True)]) await self.file_fetcher.fetch_files([file]) output_found.assert_has_calls([self.to_output_found_call(file)])
async def test_match_bytes_with_binary_response(self): file_to_fetch = create_json_data(["file"], match_bytes="0102030405060708090a0b0c0d0e0f10")[0] match_string = MatchString() response = StaticResponse(200, {}) response.raw = b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15' entry = Entry.create("http://example.com/file", arguments={"file": file_to_fetch}, response=response) await match_string.after_response(entry) self.assertTrue(entry.result.string_match)
async def test_match_bytes_with_string(self): bytes_as_string = binascii.hexlify(b"abc123").decode("utf-8") file_to_fetch = create_json_data(["file"], match_bytes=bytes_as_string)[0] match_string = MatchString() response = StaticResponse(200, {}, content="abc123") entry = Entry.create("http://example.com/file", arguments={"file": file_to_fetch}, response=response) await match_string.after_response(entry) self.assertTrue(entry.result.string_match)
async def test_fetch_files_output_empty_response(self, output_found, loop): file_list = create_json_data(["empty-file"]) self.setUpFetcher(loop) self.setup_hammertime_heuristics(add_after_defaults=[SetResponseContent("")]) await self.file_fetcher.fetch_files(file_list) file = file_list[0] call = self.to_output_found_call(file, "Empty ") output_found.assert_has_calls([call])
async def test_fetch_files_reject_error_behavior(self, output_found, loop): file = create_json_data(["file"])[0] self.setUpFetcher(loop) set_error_behavior = SetFlagInResult("error_behavior", True) with patch("tachyon.config.DetectBehaviorChange", new=MagicMock(return_value=set_error_behavior)): self.setup_hammertime_heuristics() await self.file_fetcher.fetch_files([file]) output_found.assert_not_called()
async def test_fetch_files_output_responses_with_error_code_500(self, output_found, loop): file_list = create_json_data(["config", ".htaccess"]) self.setUpFetcher(loop) self.setup_hammertime_heuristics(add_before_defaults=[SetResponseCode(500)]) await self.file_fetcher.fetch_files(file_list) calls = [] for file in file_list: calls.append(self.to_output_found_call(file, prefix="ISE, ", status_code=500)) output_found.assert_has_calls(calls, any_order=True)
async def test_set_string_match_flag_in_entry_result_to_false_if_string_to_match_found_in_response_content( self): file_to_fetch = create_json_data(["file"], match_string="abc123")[0] match_string = MatchString() response = StaticResponse(200, {}, content="Content is not matching") entry = Entry.create("http://example.com/file", arguments={"file": file_to_fetch}, response=response) await match_string.after_response(entry) self.assertFalse(entry.result.string_match)
async def test_match_bytes_with_binary_response(self): file_to_fetch = create_json_data( ["file"], match_bytes="0102030405060708090a0b0c0d0e0f10")[0] match_string = MatchString() response = StaticResponse(200, {}) response.raw = b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15' entry = Entry.create("http://example.com/file", arguments={"file": file_to_fetch}, response=response) await match_string.after_response(entry) self.assertTrue(entry.result.string_match)
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 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 setUp(self): self.host = "http://www.example.com" self.files = create_json_data(["config", ".htaccess", "data", "files"])