From 61755c144f06f6d2eb2f93132ed0c110de49271b Mon Sep 17 00:00:00 2001 From: domwhewell-sage <122788350+domwhewell-sage@users.noreply.github.com> Date: Tue, 5 Dec 2023 14:31:12 +0000 Subject: [PATCH 01/12] Create dastardly.py --- bbot/modules/deadly/dastardly.py | 126 +++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 bbot/modules/deadly/dastardly.py diff --git a/bbot/modules/deadly/dastardly.py b/bbot/modules/deadly/dastardly.py new file mode 100644 index 000000000..ec0f5e292 --- /dev/null +++ b/bbot/modules/deadly/dastardly.py @@ -0,0 +1,126 @@ +from lxml import etree +from bbot.modules.base import BaseModule + + +class dastardly(BaseModule): + watched_events = ["URL"] + produced_events = ["FINDING", "VULNERABILITY"] + flags = ["active", "aggressive"] + meta = {"description": "Lightweight web application security scanner"} + + deps_apt = ["docker.io"] + deps_pip = ["lxml~=4.9.2"] + deps_ansible = [ + { + "name": "Pull the dastardly image", + "docker_image": { + "name": "public.ecr.aws/portswigger/dastardly:latest" + }, + } + ] + in_scope_only = True + + async def setup(self): + self.helpers.depsinstaller.ensure_root(message="Dastardly: docker requires root privileges") + return True + + async def handle_event(self, event): + host = str(event.data) + command, output_file = self.construct_command(host) + try: + await self.helpers.run(command, sudo=True) + for testsuite in self.parse_dastardly_xml(output_file): + url = testcase.endpoint + for testcase in testsuite.testcases: + for failure in testcase.failures: + message = failure.instance + detail = failure.text + if failure.severity == "Info": + self.emit_event( + { + "host": str(event.host), + "url": url, + "description": message, + "detail": detail, + }, + "FINDING", + event, + ) + else: + self.emit_event( + { + "severity": severity, + "host": str(event.host), + "url": url, + "description": message, + "detail": detail, + }, + "VULNERABILITY", + event, + ) + finally: + output_file.unlink(missing_ok=True) + + def construct_command(self, target): + temp_filename = self.helpers.temp_filename(extension="xml") + command = [ + 'docker', + 'run', + '--user', + '$(id -u)', + '--rm', + '-v', + '$(pwd):/dastardly', + '-e', + 'BURP_START_URL={target}', + '-e', + 'BURP_REPORT_FILE_PATH=/dastardly/{temp_filename}', + 'public.ecr.aws/portswigger/dastardly:latest' + ] + return command, temp_filename + + def parse_dastardly_xml(self, xml_file): + try: + with open(xml_file, "rb") as f: + et = etree.parse(f) + for testsuite in et.iter("testsuite"): + yield TestSuite(testsuite) + except Exception as e: + self.warning(f"Error parsing Nmap XML at {xml_file}: {e}") + + async def cleanup(self): + resume_file = self.helpers.current_dir / "resume.cfg" + resume_file.unlink(missing_ok=True) + +class Failure: + def __init__(self, xml): + self.etree = xml + + # instance information + self.instance = self.etree.attrib.get("message", "") + self.severity = self.etree.attrib.get("type", "") + self.text = self.etree.text + +class TestCase: + def __init__(self, xml): + self.etree = xml + + # title information + self.title = self.etree.attrib.get("name", "") + + # findings / failures(as dastardly names them) + self.failures = [] + for failure in self.etree.findall("failure"): + self.testcases.append(Failure(failure)) + +class TestSuite: + def __init__(self, xml): + self.etree = xml + + # endpoint information + self.endpoint = self.etree.attrib.get("name", "") + + # test cases + self.testcases = [] + for testcase in self.etree.findall("testcase"): + self.testcases.append(TestCase(testcase)) \ No newline at end of file From 3f5f9cd683107c4032138c34dddc8e475e8e5fb2 Mon Sep 17 00:00:00 2001 From: Dom Whewell Date: Thu, 7 Dec 2023 14:41:32 +0000 Subject: [PATCH 02/12] Added dastardly module --- bbot/modules/deadly/dastardly.py | 52 +++++++++---------- .../module_tests/test_module_dastardly.py | 19 +++++++ 2 files changed, 44 insertions(+), 27 deletions(-) create mode 100644 bbot/test/test_step_2/module_tests/test_module_dastardly.py diff --git a/bbot/modules/deadly/dastardly.py b/bbot/modules/deadly/dastardly.py index ec0f5e292..a86514f9e 100644 --- a/bbot/modules/deadly/dastardly.py +++ b/bbot/modules/deadly/dastardly.py @@ -10,14 +10,7 @@ class dastardly(BaseModule): deps_apt = ["docker.io"] deps_pip = ["lxml~=4.9.2"] - deps_ansible = [ - { - "name": "Pull the dastardly image", - "docker_image": { - "name": "public.ecr.aws/portswigger/dastardly:latest" - }, - } - ] + deps_shell = ["docker pull public.ecr.aws/portswigger/dastardly:latest"] in_scope_only = True async def setup(self): @@ -30,7 +23,7 @@ async def handle_event(self, event): try: await self.helpers.run(command, sudo=True) for testsuite in self.parse_dastardly_xml(output_file): - url = testcase.endpoint + url = testsuite.endpoint for testcase in testsuite.testcases: for failure in testcase.failures: message = failure.instance @@ -49,7 +42,7 @@ async def handle_event(self, event): else: self.emit_event( { - "severity": severity, + "severity": failure.severity, "host": str(event.host), "url": url, "description": message, @@ -62,22 +55,24 @@ async def handle_event(self, event): output_file.unlink(missing_ok=True) def construct_command(self, target): - temp_filename = self.helpers.temp_filename(extension="xml") + temp_path = self.helpers.temp_filename(extension="xml") + filename = temp_path.name + temp_dir = temp_path.parent command = [ - 'docker', - 'run', - '--user', - '$(id -u)', - '--rm', - '-v', - '$(pwd):/dastardly', - '-e', - 'BURP_START_URL={target}', - '-e', - 'BURP_REPORT_FILE_PATH=/dastardly/{temp_filename}', - 'public.ecr.aws/portswigger/dastardly:latest' + "docker", + "run", + "--user", + "0", + "--rm", + "-v", + f"{temp_dir}:/dastardly", + "-e", + f"BURP_START_URL={target}", + "-e", + f"BURP_REPORT_FILE_PATH=/dastardly/{filename}", + "public.ecr.aws/portswigger/dastardly:latest", ] - return command, temp_filename + return command, temp_path def parse_dastardly_xml(self, xml_file): try: @@ -86,12 +81,13 @@ def parse_dastardly_xml(self, xml_file): for testsuite in et.iter("testsuite"): yield TestSuite(testsuite) except Exception as e: - self.warning(f"Error parsing Nmap XML at {xml_file}: {e}") + self.warning(f"Error parsing Dastardly XML at {xml_file}: {e}") async def cleanup(self): resume_file = self.helpers.current_dir / "resume.cfg" resume_file.unlink(missing_ok=True) + class Failure: def __init__(self, xml): self.etree = xml @@ -101,6 +97,7 @@ def __init__(self, xml): self.severity = self.etree.attrib.get("type", "") self.text = self.etree.text + class TestCase: def __init__(self, xml): self.etree = xml @@ -111,7 +108,8 @@ def __init__(self, xml): # findings / failures(as dastardly names them) self.failures = [] for failure in self.etree.findall("failure"): - self.testcases.append(Failure(failure)) + self.failures.append(Failure(failure)) + class TestSuite: def __init__(self, xml): @@ -123,4 +121,4 @@ def __init__(self, xml): # test cases self.testcases = [] for testcase in self.etree.findall("testcase"): - self.testcases.append(TestCase(testcase)) \ No newline at end of file + self.testcases.append(TestCase(testcase)) diff --git a/bbot/test/test_step_2/module_tests/test_module_dastardly.py b/bbot/test/test_step_2/module_tests/test_module_dastardly.py new file mode 100644 index 000000000..8f551bfff --- /dev/null +++ b/bbot/test/test_step_2/module_tests/test_module_dastardly.py @@ -0,0 +1,19 @@ +from .base import ModuleTestBase + + +class TestDastardly(ModuleTestBase): + targets = ["ginandjuice.shop"] + modules_overrides = ["nmap", "httpx", "dastardly"] + + def check(self, module_test, events): + reflected_xss = False + vulnerable_js = False + for e in events: + if e.type == "VULNERABILITY": + if "Cross-site scripting (reflected)" in e.data["description"]: + reflected_xss = True + if e.type == "VULNERABILITY": + if "Vulnerable JavaScript dependency" in e.data["description"]: + vulnerable_js = True + assert reflected_xss + assert vulnerable_js From 6f6fd96ccaf20252616eded40a948fcb2b4bb10d Mon Sep 17 00:00:00 2001 From: TheTechromancer Date: Mon, 11 Dec 2023 14:10:36 -0500 Subject: [PATCH 03/12] small tweaks, updated tests to use local server --- bbot/modules/deadly/dastardly.py | 115 ++++++++++-------- bbot/test/conftest.py | 2 +- .../module_tests/test_module_dastardly.py | 70 +++++++++-- 3 files changed, 124 insertions(+), 63 deletions(-) diff --git a/bbot/modules/deadly/dastardly.py b/bbot/modules/deadly/dastardly.py index a86514f9e..471314f1c 100644 --- a/bbot/modules/deadly/dastardly.py +++ b/bbot/modules/deadly/dastardly.py @@ -3,61 +3,82 @@ class dastardly(BaseModule): - watched_events = ["URL"] + watched_events = ["HTTP_RESPONSE"] produced_events = ["FINDING", "VULNERABILITY"] - flags = ["active", "aggressive"] + flags = ["active", "aggressive", "slow", "web-thorough"] meta = {"description": "Lightweight web application security scanner"} - deps_apt = ["docker.io"] deps_pip = ["lxml~=4.9.2"] - deps_shell = ["docker pull public.ecr.aws/portswigger/dastardly:latest"] - in_scope_only = True + deps_ansible = [ + { + "name": "Install Docker (Non-Debian)", + "package": {"name": "docker", "state": "present"}, + "become": True, + "when": "ansible_facts['os_family'] != 'Debian'", + }, + { + "name": "Install Docker (Debian)", + "package": { + "name": "docker.io", + "state": "present", + }, + "become": True, + "when": "ansible_facts['os_family'] == 'Debian'", + }, + ] + per_host_only = True async def setup(self): - self.helpers.depsinstaller.ensure_root(message="Dastardly: docker requires root privileges") + await self.helpers.run("systemctl", "start", "docker", sudo=True) + await self.helpers.run("docker", "pull", "public.ecr.aws/portswigger/dastardly:latest", sudo=True) + self.output_dir = self.scan.home / "dastardly" + self.helpers.mkdir(self.output_dir) + return True + + async def filter_event(self, event): + # Reject redirects. This helps to avoid scanning the same site twice. + is_redirect = str(event.data["status_code"]).startswith("30") + if is_redirect: + return False, "URL is a redirect" return True async def handle_event(self, event): - host = str(event.data) + host = event.parsed._replace(path="/").geturl() + self.verbose(f"Running Dastardly scan against {host}") command, output_file = self.construct_command(host) - try: - await self.helpers.run(command, sudo=True) - for testsuite in self.parse_dastardly_xml(output_file): - url = testsuite.endpoint - for testcase in testsuite.testcases: - for failure in testcase.failures: - message = failure.instance - detail = failure.text - if failure.severity == "Info": - self.emit_event( - { - "host": str(event.host), - "url": url, - "description": message, - "detail": detail, - }, - "FINDING", - event, - ) - else: - self.emit_event( - { - "severity": failure.severity, - "host": str(event.host), - "url": url, - "description": message, - "detail": detail, - }, - "VULNERABILITY", - event, - ) - finally: - output_file.unlink(missing_ok=True) + finished_proc = await self.helpers.run(command, sudo=True) + self.debug(f'dastardly stdout: {getattr(finished_proc, "stdout", "")}') + self.debug(f'dastardly stderr: {getattr(finished_proc, "stderr", "")}') + for testsuite in self.parse_dastardly_xml(output_file): + url = testsuite.endpoint + for testcase in testsuite.testcases: + for failure in testcase.failures: + if failure.severity == "Info": + self.emit_event( + { + "host": str(event.host), + "url": url, + "description": failure.instance, + }, + "FINDING", + event, + ) + else: + self.emit_event( + { + "severity": failure.severity, + "host": str(event.host), + "url": url, + "description": failure.instance, + }, + "VULNERABILITY", + event, + ) def construct_command(self, target): - temp_path = self.helpers.temp_filename(extension="xml") - filename = temp_path.name - temp_dir = temp_path.parent + date_time = self.helpers.make_date() + file_name = self.helpers.tagify(target) + temp_path = self.output_dir / f"{date_time}_{file_name}.xml" command = [ "docker", "run", @@ -65,11 +86,11 @@ def construct_command(self, target): "0", "--rm", "-v", - f"{temp_dir}:/dastardly", + f"{self.output_dir}:/dastardly", "-e", f"BURP_START_URL={target}", "-e", - f"BURP_REPORT_FILE_PATH=/dastardly/{filename}", + f"BURP_REPORT_FILE_PATH=/dastardly/{temp_path.name}", "public.ecr.aws/portswigger/dastardly:latest", ] return command, temp_path @@ -83,10 +104,6 @@ def parse_dastardly_xml(self, xml_file): except Exception as e: self.warning(f"Error parsing Dastardly XML at {xml_file}: {e}") - async def cleanup(self): - resume_file = self.helpers.current_dir / "resume.cfg" - resume_file.unlink(missing_ok=True) - class Failure: def __init__(self, xml): diff --git a/bbot/test/conftest.py b/bbot/test/conftest.py index 4dcf8ed21..fb612e00f 100644 --- a/bbot/test/conftest.py +++ b/bbot/test/conftest.py @@ -35,7 +35,7 @@ def assert_all_responses_were_requested() -> bool: @pytest.fixture def bbot_httpserver(): - server = HTTPServer(host="127.0.0.1", port=8888) + server = HTTPServer(host="0.0.0.0", port=8888) server.start() yield server diff --git a/bbot/test/test_step_2/module_tests/test_module_dastardly.py b/bbot/test/test_step_2/module_tests/test_module_dastardly.py index 8f551bfff..cabbadf41 100644 --- a/bbot/test/test_step_2/module_tests/test_module_dastardly.py +++ b/bbot/test/test_step_2/module_tests/test_module_dastardly.py @@ -1,19 +1,63 @@ +import json +from werkzeug import Response + from .base import ModuleTestBase class TestDastardly(ModuleTestBase): - targets = ["ginandjuice.shop"] - modules_overrides = ["nmap", "httpx", "dastardly"] + targets = ["http://127.0.0.1:8888/"] + modules_overrides = ["httpx", "dastardly"] + + web_response = """ + + + visit this + + """ + + def xss_handler(self, request): + response = f""" + + + Email Form + + + {request.args.get("test", "")} + + """ + return Response(response, content_type="text/html") + + async def get_docker_ip(self, module_test): + docker_ip = "172.17.0.1" + try: + ip_output = await module_test.scan.helpers.run(["ip", "-j", "-4", "a", "show", "dev", "docker0"]) + interface_json = json.loads(ip_output.stdout) + docker_ip = interface_json[0]["addr_info"][0]["local"] + except Exception: + pass + return docker_ip + + async def setup_after_prep(self, module_test): + module_test.httpserver.expect_request("/").respond_with_data(self.web_response) + module_test.httpserver.expect_request("/test").respond_with_handler(self.xss_handler) + + # get docker IP + docker_ip = await self.get_docker_ip(module_test) + module_test.scan.target.add_target(docker_ip) + + # replace 127.0.0.1 with docker host IP to allow dastardly access to local http server + old_filter_event = module_test.module.filter_event + + def new_filter_event(event): + self.new_url = f"http://{docker_ip}:8888/" + event.data["url"] = self.new_url + event.parsed = module_test.scan.helpers.urlparse(self.new_url) + return old_filter_event(event) + + module_test.monkeypatch.setattr(module_test.module, "filter_event", new_filter_event) def check(self, module_test, events): - reflected_xss = False - vulnerable_js = False - for e in events: - if e.type == "VULNERABILITY": - if "Cross-site scripting (reflected)" in e.data["description"]: - reflected_xss = True - if e.type == "VULNERABILITY": - if "Vulnerable JavaScript dependency" in e.data["description"]: - vulnerable_js = True - assert reflected_xss - assert vulnerable_js + assert 1 == len([e for e in events if e.type == "VULNERABILITY"]) + assert 1 == len( + [e for e in events if e.type == "VULNERABILITY" and f"{self.new_url}test" in e.data["description"]] + ) From b6654d8428e1bec9c02448675451d213b9d7df01 Mon Sep 17 00:00:00 2001 From: TheTechromancer Date: Mon, 11 Dec 2023 17:03:19 -0500 Subject: [PATCH 04/12] ansible troubleshooting --- bbot/core/helpers/depsinstaller/installer.py | 4 ++-- bbot/test/test.conf | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bbot/core/helpers/depsinstaller/installer.py b/bbot/core/helpers/depsinstaller/installer.py index 72f6b5575..8ba97819d 100644 --- a/bbot/core/helpers/depsinstaller/installer.py +++ b/bbot/core/helpers/depsinstaller/installer.py @@ -278,8 +278,8 @@ def ansible_run(self, tasks=None, module=None, args=None, ansible_args=None): success = res.status == "successful" err = "" for e in res.events: - # if self.ansible_debug and not success: - # log.debug(json.dumps(e, indent=4)) + if self.ansible_debug and not success: + log.debug(json.dumps(e, indent=4)) if e["event"] == "runner_on_failed": err = e["event_data"]["res"]["msg"] break diff --git a/bbot/test/test.conf b/bbot/test/test.conf index fe360effc..ba8367461 100644 --- a/bbot/test/test.conf +++ b/bbot/test/test.conf @@ -29,7 +29,7 @@ scope_search_distance: 0 scope_report_distance: 0 scope_dns_search_distance: 1 plumbus: asdf -dns_debug: true +dns_debug: false user_agent: "BBOT Test User-Agent" http_debug: false agent_url: ws://127.0.0.1:8765 @@ -48,4 +48,4 @@ dns_wildcard_ignore: - google - google.com - example.com - - evilcorp.com \ No newline at end of file + - evilcorp.com From 508262620f12e6ca949e6511846314f7b09e0c7a Mon Sep 17 00:00:00 2001 From: TheTechromancer Date: Mon, 11 Dec 2023 17:04:56 -0500 Subject: [PATCH 05/12] blacked --- bbot/core/helpers/depsinstaller/installer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bbot/core/helpers/depsinstaller/installer.py b/bbot/core/helpers/depsinstaller/installer.py index 8ba97819d..8864b5f0c 100644 --- a/bbot/core/helpers/depsinstaller/installer.py +++ b/bbot/core/helpers/depsinstaller/installer.py @@ -279,7 +279,7 @@ def ansible_run(self, tasks=None, module=None, args=None, ansible_args=None): err = "" for e in res.events: if self.ansible_debug and not success: - log.debug(json.dumps(e, indent=4)) + log.debug(json.dumps(e, indent=4)) if e["event"] == "runner_on_failed": err = e["event_data"]["res"]["msg"] break From acb904dd105a7c117cf381a2bdd321517153143c Mon Sep 17 00:00:00 2001 From: TheTechromancer Date: Mon, 11 Dec 2023 17:21:27 -0500 Subject: [PATCH 06/12] more debugging --- bbot/core/helpers/depsinstaller/installer.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bbot/core/helpers/depsinstaller/installer.py b/bbot/core/helpers/depsinstaller/installer.py index 8864b5f0c..d57ea8ed8 100644 --- a/bbot/core/helpers/depsinstaller/installer.py +++ b/bbot/core/helpers/depsinstaller/installer.py @@ -278,8 +278,9 @@ def ansible_run(self, tasks=None, module=None, args=None, ansible_args=None): success = res.status == "successful" err = "" for e in res.events: + log.critical(f"ANSIBLE DEBUG: {self.ansible_debug}, SUCCESS: {success}") if self.ansible_debug and not success: - log.debug(json.dumps(e, indent=4)) + log.critical(json.dumps(e, indent=4)) if e["event"] == "runner_on_failed": err = e["event_data"]["res"]["msg"] break From a55349388e66366d4f89cb70ff81d678a405cbeb Mon Sep 17 00:00:00 2001 From: TheTechromancer Date: Mon, 11 Dec 2023 18:49:12 -0500 Subject: [PATCH 07/12] enable debug for --install-all-deps --- bbot/core/helpers/depsinstaller/installer.py | 3 +-- bbot/test/test_step_1/test_cli.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/bbot/core/helpers/depsinstaller/installer.py b/bbot/core/helpers/depsinstaller/installer.py index d57ea8ed8..8864b5f0c 100644 --- a/bbot/core/helpers/depsinstaller/installer.py +++ b/bbot/core/helpers/depsinstaller/installer.py @@ -278,9 +278,8 @@ def ansible_run(self, tasks=None, module=None, args=None, ansible_args=None): success = res.status == "successful" err = "" for e in res.events: - log.critical(f"ANSIBLE DEBUG: {self.ansible_debug}, SUCCESS: {success}") if self.ansible_debug and not success: - log.critical(json.dumps(e, indent=4)) + log.debug(json.dumps(e, indent=4)) if e["event"] == "runner_on_failed": err = e["event_data"]["res"]["msg"] break diff --git a/bbot/test/test_step_1/test_cli.py b/bbot/test/test_step_1/test_cli.py index 0ccc94887..affedd403 100644 --- a/bbot/test/test_step_1/test_cli.py +++ b/bbot/test/test_step_1/test_cli.py @@ -71,7 +71,7 @@ async def test_cli(monkeypatch, bbot_config): await cli._main() # install all deps - monkeypatch.setattr("sys.argv", ["bbot", "--install-all-deps"]) + monkeypatch.setattr("sys.argv", ["bbot", "-d", "--install-all-deps"]) success = await cli._main() assert success, "--install-all-deps failed for at least one module" From b1c46d46737694b411a6f359c6da65047e491ce0 Mon Sep 17 00:00:00 2001 From: TheTechromancer Date: Mon, 11 Dec 2023 19:51:56 -0500 Subject: [PATCH 08/12] force ansible debug --- bbot/core/helpers/depsinstaller/installer.py | 2 +- bbot/test/test_step_1/test_cli.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bbot/core/helpers/depsinstaller/installer.py b/bbot/core/helpers/depsinstaller/installer.py index 8864b5f0c..00662b969 100644 --- a/bbot/core/helpers/depsinstaller/installer.py +++ b/bbot/core/helpers/depsinstaller/installer.py @@ -44,7 +44,7 @@ def __init__(self, parent_helper): self.setup_status = self.read_setup_status() self.no_deps = self.parent_helper.config.get("no_deps", False) - self.ansible_debug = self.parent_helper.config.get("debug", False) + self.ansible_debug = True self.force_deps = self.parent_helper.config.get("force_deps", False) self.retry_deps = self.parent_helper.config.get("retry_deps", False) self.ignore_failed_deps = self.parent_helper.config.get("ignore_failed_deps", False) diff --git a/bbot/test/test_step_1/test_cli.py b/bbot/test/test_step_1/test_cli.py index affedd403..0ccc94887 100644 --- a/bbot/test/test_step_1/test_cli.py +++ b/bbot/test/test_step_1/test_cli.py @@ -71,7 +71,7 @@ async def test_cli(monkeypatch, bbot_config): await cli._main() # install all deps - monkeypatch.setattr("sys.argv", ["bbot", "-d", "--install-all-deps"]) + monkeypatch.setattr("sys.argv", ["bbot", "--install-all-deps"]) success = await cli._main() assert success, "--install-all-deps failed for at least one module" From a48856a9604b8cec7aeba8118425efa478a3e5fe Mon Sep 17 00:00:00 2001 From: TheTechromancer Date: Mon, 11 Dec 2023 21:28:29 -0500 Subject: [PATCH 09/12] don't try to install docker if it's already installed --- bbot/modules/deadly/dastardly.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/bbot/modules/deadly/dastardly.py b/bbot/modules/deadly/dastardly.py index 471314f1c..8face65ab 100644 --- a/bbot/modules/deadly/dastardly.py +++ b/bbot/modules/deadly/dastardly.py @@ -10,11 +10,17 @@ class dastardly(BaseModule): deps_pip = ["lxml~=4.9.2"] deps_ansible = [ + { + "name": "Check if Docker is already installed", + "command": "docker --version", + "register": "docker_installed", + "ignore_errors": True, + }, { "name": "Install Docker (Non-Debian)", "package": {"name": "docker", "state": "present"}, "become": True, - "when": "ansible_facts['os_family'] != 'Debian'", + "when": "ansible_facts['os_family'] != 'Debian' and docker_installed.rc != 0", }, { "name": "Install Docker (Debian)", @@ -23,7 +29,7 @@ class dastardly(BaseModule): "state": "present", }, "become": True, - "when": "ansible_facts['os_family'] == 'Debian'", + "when": "ansible_facts['os_family'] == 'Debian' and docker_installed.rc != 0", }, ] per_host_only = True From 49e5df0e73919ae951b1d9ff62690ae4bd36e646 Mon Sep 17 00:00:00 2001 From: TheTechromancer Date: Tue, 12 Dec 2023 11:49:12 -0500 Subject: [PATCH 10/12] switch port of httpserver --- bbot/test/conftest.py | 15 +++++++++++++++ .../module_tests/test_module_dastardly.py | 9 +++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/bbot/test/conftest.py b/bbot/test/conftest.py index fb612e00f..6948ee0a0 100644 --- a/bbot/test/conftest.py +++ b/bbot/test/conftest.py @@ -74,6 +74,21 @@ def bbot_httpserver_ssl(): server.clear() +@pytest.fixture +def bbot_httpserver_allinterfaces(): + + server = HTTPServer(host="0.0.0.0", port=5556) + server.start() + + yield server + + server.clear() + if server.is_running(): + server.stop() + server.check_assertions() + server.clear() + + @pytest.fixture def interactsh_mock_instance(): interactsh_mock = Interactsh_mock() diff --git a/bbot/test/test_step_2/module_tests/test_module_dastardly.py b/bbot/test/test_step_2/module_tests/test_module_dastardly.py index cabbadf41..6ffb349bf 100644 --- a/bbot/test/test_step_2/module_tests/test_module_dastardly.py +++ b/bbot/test/test_step_2/module_tests/test_module_dastardly.py @@ -5,7 +5,7 @@ class TestDastardly(ModuleTestBase): - targets = ["http://127.0.0.1:8888/"] + targets = ["http://127.0.0.1:5556/"] modules_overrides = ["httpx", "dastardly"] web_response = """ @@ -38,8 +38,9 @@ async def get_docker_ip(self, module_test): return docker_ip async def setup_after_prep(self, module_test): - module_test.httpserver.expect_request("/").respond_with_data(self.web_response) - module_test.httpserver.expect_request("/test").respond_with_handler(self.xss_handler) + httpserver = module_test.request_fixture.getfixturevalue("bbot_httpserver_allinterfaces") + httpserver.expect_request("/").respond_with_data(self.web_response) + httpserver.expect_request("/test").respond_with_handler(self.xss_handler) # get docker IP docker_ip = await self.get_docker_ip(module_test) @@ -49,7 +50,7 @@ async def setup_after_prep(self, module_test): old_filter_event = module_test.module.filter_event def new_filter_event(event): - self.new_url = f"http://{docker_ip}:8888/" + self.new_url = f"http://{docker_ip}:5556/" event.data["url"] = self.new_url event.parsed = module_test.scan.helpers.urlparse(self.new_url) return old_filter_event(event) From 3e81efceb73c57ddbeae56ceb92e375f1c98e4f4 Mon Sep 17 00:00:00 2001 From: TheTechromancer Date: Tue, 12 Dec 2023 11:49:24 -0500 Subject: [PATCH 11/12] blacked --- bbot/test/conftest.py | 1 - 1 file changed, 1 deletion(-) diff --git a/bbot/test/conftest.py b/bbot/test/conftest.py index 6948ee0a0..3cee9d970 100644 --- a/bbot/test/conftest.py +++ b/bbot/test/conftest.py @@ -76,7 +76,6 @@ def bbot_httpserver_ssl(): @pytest.fixture def bbot_httpserver_allinterfaces(): - server = HTTPServer(host="0.0.0.0", port=5556) server.start() From 6007edd2052c7e880ebfe1ef77e045cb93c78540 Mon Sep 17 00:00:00 2001 From: TheTechromancer Date: Tue, 12 Dec 2023 12:39:04 -0500 Subject: [PATCH 12/12] put httpserver back on localhost --- bbot/test/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bbot/test/conftest.py b/bbot/test/conftest.py index 3cee9d970..684ec18a2 100644 --- a/bbot/test/conftest.py +++ b/bbot/test/conftest.py @@ -35,7 +35,7 @@ def assert_all_responses_were_requested() -> bool: @pytest.fixture def bbot_httpserver(): - server = HTTPServer(host="0.0.0.0", port=8888) + server = HTTPServer(host="127.0.0.1", port=8888) server.start() yield server