From 24c93791808ef6cd661a44076c54aac968166ea1 Mon Sep 17 00:00:00 2001 From: liquidsec Date: Thu, 21 May 2026 18:34:29 -0400 Subject: [PATCH] remove passivetotal module --- bbot/modules/passivetotal.py | 46 ------------------- .../module_tests/test_module_passivetotal.py | 23 ---------- 2 files changed, 69 deletions(-) delete mode 100644 bbot/modules/passivetotal.py delete mode 100644 bbot/test/test_step_2/module_tests/test_module_passivetotal.py diff --git a/bbot/modules/passivetotal.py b/bbot/modules/passivetotal.py deleted file mode 100644 index 1010980945..0000000000 --- a/bbot/modules/passivetotal.py +++ /dev/null @@ -1,46 +0,0 @@ -from bbot.modules.templates.subdomain_enum import subdomain_enum_apikey - - -class passivetotal(subdomain_enum_apikey): - watched_events = ["DNS_NAME"] - produced_events = ["DNS_NAME"] - flags = ["safe", "subdomain-enum", "passive"] - meta = { - "description": "Query the PassiveTotal API for subdomains", - "created_date": "2022-08-08", - "author": "@TheTechromancer", - "auth_required": True, - } - options = {"api_key": ""} - options_desc = {"api_key": "PassiveTotal API Key in the format of 'username:api_key'"} - - base_url = "https://api.passivetotal.org/v2" - - async def setup(self): - return await super().setup() - - async def ping(self): - url = f"{self.base_url}/account/quota" - j = (await self.api_request(url, retry_on_http_429=False)).json() - limit = j["user"]["limits"]["search_api"] - used = j["user"]["counts"]["search_api"] - assert used < limit, "No quota remaining" - - def prepare_api_request(self, url, kwargs): - api_username, api_key = self.api_key.split(":", 1) - kwargs["auth"] = (api_username, api_key) - return url, kwargs - - async def abort_if(self, event): - # RiskIQ is famous for their junk data - return await super().abort_if(event) or "unresolved" in event.tags - - async def request_url(self, query): - url = f"{self.base_url}/enrichment/subdomains?query={self.helpers.quote(query)}" - return await self.api_request(url) - - async def parse_results(self, r, query): - results = set() - for subdomain in r.json().get("subdomains", []): - results.add(f"{subdomain}.{query}") - return results diff --git a/bbot/test/test_step_2/module_tests/test_module_passivetotal.py b/bbot/test/test_step_2/module_tests/test_module_passivetotal.py deleted file mode 100644 index ca185cb021..0000000000 --- a/bbot/test/test_step_2/module_tests/test_module_passivetotal.py +++ /dev/null @@ -1,23 +0,0 @@ -from .base import ModuleTestBase - - -class TestPassiveTotal(ModuleTestBase): - config_overrides = {"modules": {"passivetotal": {"api_key": "jon@bls.fakedomain:asdf"}}} - - async def setup_before_prep(self, module_test): - module_test.blasthttp_mock.add_response( - url="https://api.passivetotal.org/v2/account/quota", - match_headers={"Authorization": "Basic am9uQGJscy5mYWtlZG9tYWluOmFzZGY="}, - json={"user": {"counts": {"search_api": 10}, "limits": {"search_api": 20}}}, - ) - module_test.blasthttp_mock.add_response( - url="https://api.passivetotal.org/v2/enrichment/subdomains?query=blacklanternsecurity.com", - match_headers={"Authorization": "Basic am9uQGJscy5mYWtlZG9tYWluOmFzZGY="}, - json={"subdomains": ["asdf"]}, - ) - - async def setup_after_prep(self, module_test): - module_test.monkeypatch.setattr(module_test.scan.modules["passivetotal"], "abort_if", lambda e: False) - - def check(self, module_test, events): - assert any(e.data == "asdf.blacklanternsecurity.com" for e in events), "Failed to detect subdomain"