bbot 2.0.1.4654rc0__py3-none-any.whl → 2.3.0.5397rc0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of bbot might be problematic. Click here for more details.
- bbot/__init__.py +1 -1
- bbot/cli.py +3 -7
- bbot/core/config/files.py +0 -1
- bbot/core/config/logger.py +34 -4
- bbot/core/core.py +21 -6
- bbot/core/engine.py +9 -8
- bbot/core/event/base.py +162 -63
- bbot/core/helpers/bloom.py +10 -3
- bbot/core/helpers/command.py +9 -8
- bbot/core/helpers/depsinstaller/installer.py +89 -32
- bbot/core/helpers/depsinstaller/sudo_askpass.py +38 -2
- bbot/core/helpers/diff.py +10 -10
- bbot/core/helpers/dns/brute.py +18 -14
- bbot/core/helpers/dns/dns.py +16 -15
- bbot/core/helpers/dns/engine.py +159 -132
- bbot/core/helpers/dns/helpers.py +2 -2
- bbot/core/helpers/dns/mock.py +26 -8
- bbot/core/helpers/files.py +1 -1
- bbot/core/helpers/helper.py +7 -4
- bbot/core/helpers/interactsh.py +3 -3
- bbot/core/helpers/libmagic.py +65 -0
- bbot/core/helpers/misc.py +65 -22
- bbot/core/helpers/names_generator.py +17 -3
- bbot/core/helpers/process.py +0 -20
- bbot/core/helpers/regex.py +1 -1
- bbot/core/helpers/regexes.py +12 -6
- bbot/core/helpers/validators.py +1 -2
- bbot/core/helpers/web/client.py +1 -1
- bbot/core/helpers/web/engine.py +18 -13
- bbot/core/helpers/web/web.py +25 -116
- bbot/core/helpers/wordcloud.py +5 -5
- bbot/core/modules.py +36 -27
- bbot/core/multiprocess.py +58 -0
- bbot/core/shared_deps.py +46 -3
- bbot/db/sql/models.py +147 -0
- bbot/defaults.yml +15 -10
- bbot/errors.py +0 -8
- bbot/modules/anubisdb.py +2 -2
- bbot/modules/apkpure.py +63 -0
- bbot/modules/azure_tenant.py +2 -2
- bbot/modules/baddns.py +35 -19
- bbot/modules/baddns_direct.py +92 -0
- bbot/modules/baddns_zone.py +3 -8
- bbot/modules/badsecrets.py +4 -3
- bbot/modules/base.py +195 -51
- bbot/modules/bevigil.py +7 -7
- bbot/modules/binaryedge.py +7 -4
- bbot/modules/bufferoverrun.py +47 -0
- bbot/modules/builtwith.py +6 -10
- bbot/modules/bypass403.py +5 -5
- bbot/modules/c99.py +10 -7
- bbot/modules/censys.py +9 -13
- bbot/modules/certspotter.py +5 -3
- bbot/modules/chaos.py +9 -7
- bbot/modules/code_repository.py +1 -0
- bbot/modules/columbus.py +3 -3
- bbot/modules/crt.py +5 -3
- bbot/modules/deadly/dastardly.py +1 -1
- bbot/modules/deadly/ffuf.py +9 -9
- bbot/modules/deadly/nuclei.py +3 -3
- bbot/modules/deadly/vhost.py +4 -3
- bbot/modules/dehashed.py +1 -1
- bbot/modules/digitorus.py +1 -1
- bbot/modules/dnsbimi.py +145 -0
- bbot/modules/dnscaa.py +3 -3
- bbot/modules/dnsdumpster.py +4 -4
- bbot/modules/dnstlsrpt.py +144 -0
- bbot/modules/docker_pull.py +7 -5
- bbot/modules/dockerhub.py +2 -2
- bbot/modules/dotnetnuke.py +18 -19
- bbot/modules/emailformat.py +1 -1
- bbot/modules/extractous.py +122 -0
- bbot/modules/filedownload.py +9 -7
- bbot/modules/fullhunt.py +7 -4
- bbot/modules/generic_ssrf.py +5 -5
- bbot/modules/github_codesearch.py +3 -2
- bbot/modules/github_org.py +4 -4
- bbot/modules/github_workflows.py +4 -4
- bbot/modules/gitlab.py +2 -5
- bbot/modules/google_playstore.py +93 -0
- bbot/modules/gowitness.py +48 -50
- bbot/modules/hackertarget.py +5 -3
- bbot/modules/host_header.py +5 -5
- bbot/modules/httpx.py +1 -4
- bbot/modules/hunterio.py +3 -9
- bbot/modules/iis_shortnames.py +19 -30
- bbot/modules/internal/cloudcheck.py +27 -12
- bbot/modules/internal/dnsresolve.py +250 -276
- bbot/modules/internal/excavate.py +100 -64
- bbot/modules/internal/speculate.py +42 -33
- bbot/modules/internetdb.py +4 -2
- bbot/modules/ip2location.py +3 -5
- bbot/modules/ipneighbor.py +1 -1
- bbot/modules/ipstack.py +3 -8
- bbot/modules/jadx.py +87 -0
- bbot/modules/leakix.py +11 -10
- bbot/modules/myssl.py +2 -2
- bbot/modules/newsletters.py +2 -2
- bbot/modules/otx.py +5 -3
- bbot/modules/output/asset_inventory.py +7 -7
- bbot/modules/output/base.py +1 -1
- bbot/modules/output/csv.py +1 -2
- bbot/modules/output/http.py +20 -14
- bbot/modules/output/mysql.py +51 -0
- bbot/modules/output/neo4j.py +7 -2
- bbot/modules/output/postgres.py +49 -0
- bbot/modules/output/slack.py +0 -1
- bbot/modules/output/sqlite.py +29 -0
- bbot/modules/output/stdout.py +2 -2
- bbot/modules/output/teams.py +107 -6
- bbot/modules/paramminer_headers.py +5 -8
- bbot/modules/passivetotal.py +13 -13
- bbot/modules/portscan.py +32 -6
- bbot/modules/postman.py +50 -126
- bbot/modules/postman_download.py +220 -0
- bbot/modules/rapiddns.py +3 -8
- bbot/modules/report/asn.py +11 -11
- bbot/modules/robots.py +3 -3
- bbot/modules/securitytrails.py +7 -10
- bbot/modules/securitytxt.py +128 -0
- bbot/modules/shodan_dns.py +7 -9
- bbot/modules/sitedossier.py +1 -1
- bbot/modules/skymem.py +2 -2
- bbot/modules/social.py +2 -1
- bbot/modules/subdomaincenter.py +1 -1
- bbot/modules/subdomainradar.py +160 -0
- bbot/modules/telerik.py +8 -8
- bbot/modules/templates/bucket.py +1 -1
- bbot/modules/templates/github.py +22 -14
- bbot/modules/templates/postman.py +21 -0
- bbot/modules/templates/shodan.py +14 -13
- bbot/modules/templates/sql.py +95 -0
- bbot/modules/templates/subdomain_enum.py +53 -17
- bbot/modules/templates/webhook.py +2 -4
- bbot/modules/trickest.py +8 -37
- bbot/modules/trufflehog.py +18 -3
- bbot/modules/url_manipulation.py +3 -3
- bbot/modules/urlscan.py +1 -1
- bbot/modules/viewdns.py +1 -1
- bbot/modules/virustotal.py +8 -30
- bbot/modules/wafw00f.py +1 -1
- bbot/modules/wayback.py +1 -1
- bbot/modules/wpscan.py +17 -11
- bbot/modules/zoomeye.py +11 -6
- bbot/presets/baddns-thorough.yml +12 -0
- bbot/presets/fast.yml +16 -0
- bbot/presets/kitchen-sink.yml +1 -0
- bbot/presets/spider.yml +4 -0
- bbot/presets/subdomain-enum.yml +7 -7
- bbot/scanner/manager.py +5 -16
- bbot/scanner/preset/args.py +44 -26
- bbot/scanner/preset/environ.py +7 -2
- bbot/scanner/preset/path.py +7 -4
- bbot/scanner/preset/preset.py +36 -23
- bbot/scanner/scanner.py +176 -63
- bbot/scanner/target.py +236 -434
- bbot/scripts/docs.py +1 -1
- bbot/test/bbot_fixtures.py +22 -3
- bbot/test/conftest.py +132 -100
- bbot/test/fastapi_test.py +17 -0
- bbot/test/owasp_mastg.apk +0 -0
- bbot/test/run_tests.sh +4 -4
- bbot/test/test.conf +2 -0
- bbot/test/test_step_1/test_bbot_fastapi.py +82 -0
- bbot/test/test_step_1/test_bloom_filter.py +2 -0
- bbot/test/test_step_1/test_cli.py +138 -64
- bbot/test/test_step_1/test_dns.py +392 -70
- bbot/test/test_step_1/test_engine.py +17 -17
- bbot/test/test_step_1/test_events.py +203 -37
- bbot/test/test_step_1/test_helpers.py +64 -28
- bbot/test/test_step_1/test_manager_deduplication.py +1 -1
- bbot/test/test_step_1/test_manager_scope_accuracy.py +336 -338
- bbot/test/test_step_1/test_modules_basic.py +69 -71
- bbot/test/test_step_1/test_presets.py +184 -96
- bbot/test/test_step_1/test_python_api.py +7 -2
- bbot/test/test_step_1/test_regexes.py +35 -5
- bbot/test/test_step_1/test_scan.py +39 -5
- bbot/test/test_step_1/test_scope.py +5 -4
- bbot/test/test_step_1/test_target.py +243 -145
- bbot/test/test_step_1/test_web.py +48 -10
- bbot/test/test_step_2/module_tests/base.py +17 -20
- bbot/test/test_step_2/module_tests/test_module_anubisdb.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_apkpure.py +71 -0
- bbot/test/test_step_2/module_tests/test_module_asset_inventory.py +0 -1
- bbot/test/test_step_2/module_tests/test_module_azure_realm.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_baddns.py +6 -6
- bbot/test/test_step_2/module_tests/test_module_baddns_direct.py +62 -0
- bbot/test/test_step_2/module_tests/test_module_bevigil.py +29 -2
- bbot/test/test_step_2/module_tests/test_module_binaryedge.py +4 -2
- bbot/test/test_step_2/module_tests/test_module_bucket_amazon.py +2 -2
- bbot/test/test_step_2/module_tests/test_module_bucket_azure.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_bufferoverrun.py +35 -0
- bbot/test/test_step_2/module_tests/test_module_builtwith.py +2 -2
- bbot/test/test_step_2/module_tests/test_module_bypass403.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_c99.py +126 -0
- bbot/test/test_step_2/module_tests/test_module_censys.py +4 -1
- bbot/test/test_step_2/module_tests/test_module_cloudcheck.py +4 -0
- bbot/test/test_step_2/module_tests/test_module_code_repository.py +11 -1
- bbot/test/test_step_2/module_tests/test_module_columbus.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_credshed.py +3 -3
- bbot/test/test_step_2/module_tests/test_module_dastardly.py +2 -1
- bbot/test/test_step_2/module_tests/test_module_dehashed.py +2 -2
- bbot/test/test_step_2/module_tests/test_module_digitorus.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_discord.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_dnsbimi.py +103 -0
- bbot/test/test_step_2/module_tests/test_module_dnsbrute.py +9 -10
- bbot/test/test_step_2/module_tests/test_module_dnsbrute_mutations.py +1 -2
- bbot/test/test_step_2/module_tests/test_module_dnscommonsrv.py +1 -2
- bbot/test/test_step_2/module_tests/test_module_dnsdumpster.py +4 -4
- bbot/test/test_step_2/module_tests/test_module_dnstlsrpt.py +64 -0
- bbot/test/test_step_2/module_tests/test_module_dotnetnuke.py +0 -8
- bbot/test/test_step_2/module_tests/test_module_excavate.py +17 -37
- bbot/test/test_step_2/module_tests/test_module_extractous.py +54 -0
- bbot/test/test_step_2/module_tests/test_module_ffuf_shortnames.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_filedownload.py +14 -14
- bbot/test/test_step_2/module_tests/test_module_git_clone.py +2 -2
- bbot/test/test_step_2/module_tests/test_module_github_org.py +19 -8
- bbot/test/test_step_2/module_tests/test_module_github_workflows.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_gitlab.py +9 -4
- bbot/test/test_step_2/module_tests/test_module_google_playstore.py +83 -0
- bbot/test/test_step_2/module_tests/test_module_gowitness.py +4 -4
- bbot/test/test_step_2/module_tests/test_module_host_header.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_http.py +4 -4
- bbot/test/test_step_2/module_tests/test_module_httpx.py +10 -8
- bbot/test/test_step_2/module_tests/test_module_hunterio.py +68 -4
- bbot/test/test_step_2/module_tests/test_module_jadx.py +55 -0
- bbot/test/test_step_2/module_tests/test_module_json.py +24 -11
- bbot/test/test_step_2/module_tests/test_module_leakix.py +7 -3
- bbot/test/test_step_2/module_tests/test_module_mysql.py +76 -0
- bbot/test/test_step_2/module_tests/test_module_myssl.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_neo4j.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_newsletters.py +6 -6
- bbot/test/test_step_2/module_tests/test_module_ntlm.py +7 -7
- bbot/test/test_step_2/module_tests/test_module_oauth.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_otx.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_paramminer_cookies.py +1 -2
- bbot/test/test_step_2/module_tests/test_module_paramminer_getparams.py +0 -6
- bbot/test/test_step_2/module_tests/test_module_paramminer_headers.py +2 -9
- bbot/test/test_step_2/module_tests/test_module_passivetotal.py +3 -1
- bbot/test/test_step_2/module_tests/test_module_portscan.py +9 -8
- bbot/test/test_step_2/module_tests/test_module_postgres.py +74 -0
- bbot/test/test_step_2/module_tests/test_module_postman.py +84 -253
- bbot/test/test_step_2/module_tests/test_module_postman_download.py +439 -0
- bbot/test/test_step_2/module_tests/test_module_rapiddns.py +93 -1
- bbot/test/test_step_2/module_tests/test_module_securitytxt.py +50 -0
- bbot/test/test_step_2/module_tests/test_module_shodan_dns.py +20 -1
- bbot/test/test_step_2/module_tests/test_module_sitedossier.py +2 -2
- bbot/test/test_step_2/module_tests/test_module_smuggler.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_social.py +11 -1
- bbot/test/test_step_2/module_tests/test_module_speculate.py +2 -6
- bbot/test/test_step_2/module_tests/test_module_splunk.py +4 -4
- bbot/test/test_step_2/module_tests/test_module_sqlite.py +18 -0
- bbot/test/test_step_2/module_tests/test_module_sslcert.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_stdout.py +5 -3
- bbot/test/test_step_2/module_tests/test_module_subdomaincenter.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_subdomainradar.py +208 -0
- bbot/test/test_step_2/module_tests/test_module_subdomains.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_teams.py +8 -6
- bbot/test/test_step_2/module_tests/test_module_telerik.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_trufflehog.py +317 -11
- bbot/test/test_step_2/module_tests/test_module_wayback.py +1 -1
- bbot/test/test_step_2/template_tests/test_template_subdomain_enum.py +135 -0
- {bbot-2.0.1.4654rc0.dist-info → bbot-2.3.0.5397rc0.dist-info}/METADATA +48 -18
- bbot-2.3.0.5397rc0.dist-info/RECORD +421 -0
- {bbot-2.0.1.4654rc0.dist-info → bbot-2.3.0.5397rc0.dist-info}/WHEEL +1 -1
- bbot/modules/unstructured.py +0 -163
- bbot/test/test_step_2/module_tests/test_module_unstructured.py +0 -102
- bbot-2.0.1.4654rc0.dist-info/RECORD +0 -385
- {bbot-2.0.1.4654rc0.dist-info → bbot-2.3.0.5397rc0.dist-info}/LICENSE +0 -0
- {bbot-2.0.1.4654rc0.dist-info → bbot-2.3.0.5397rc0.dist-info}/entry_points.txt +0 -0
|
@@ -2,15 +2,17 @@ from .base import ModuleTestBase
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
class TestPassiveTotal(ModuleTestBase):
|
|
5
|
-
config_overrides = {"modules": {"passivetotal": {"
|
|
5
|
+
config_overrides = {"modules": {"passivetotal": {"api_key": "jon@bls.fakedomain:asdf"}}}
|
|
6
6
|
|
|
7
7
|
async def setup_before_prep(self, module_test):
|
|
8
8
|
module_test.httpx_mock.add_response(
|
|
9
9
|
url="https://api.passivetotal.org/v2/account/quota",
|
|
10
|
+
match_headers={"Authorization": "Basic am9uQGJscy5mYWtlZG9tYWluOmFzZGY="},
|
|
10
11
|
json={"user": {"counts": {"search_api": 10}, "limits": {"search_api": 20}}},
|
|
11
12
|
)
|
|
12
13
|
module_test.httpx_mock.add_response(
|
|
13
14
|
url="https://api.passivetotal.org/v2/enrichment/subdomains?query=blacklanternsecurity.com",
|
|
15
|
+
match_headers={"Authorization": "Basic am9uQGJscy5mYWtlZG9tYWluOmFzZGY="},
|
|
14
16
|
json={"subdomains": ["asdf"]},
|
|
15
17
|
)
|
|
16
18
|
|
|
@@ -21,7 +21,6 @@ class TestPortscan(ModuleTestBase):
|
|
|
21
21
|
masscan_output_ping = """{ "ip": "8.8.8.8", "timestamp": "1719862594", "ports": [ {"port": 0, "proto": "icmp", "status": "open", "reason": "none", "ttl": 54} ] }"""
|
|
22
22
|
|
|
23
23
|
async def setup_after_prep(self, module_test):
|
|
24
|
-
|
|
25
24
|
from bbot.modules.base import BaseModule
|
|
26
25
|
|
|
27
26
|
class DummyModule(BaseModule):
|
|
@@ -109,10 +108,12 @@ class TestPortscan(ModuleTestBase):
|
|
|
109
108
|
if e.type == "DNS_NAME" and e.data == "dummy.asdf.evilcorp.net" and str(e.module) == "dummy_module"
|
|
110
109
|
]
|
|
111
110
|
)
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
assert 2 <= len([e for e in events if e.type == "IP_ADDRESS" and e.data == "8.8.
|
|
115
|
-
assert 2 <= len([e for e in events if e.type == "IP_ADDRESS" and e.data == "8.8.4.
|
|
111
|
+
# the reason these numbers aren't exactly predictable is because we can't predict which one arrives first
|
|
112
|
+
# to the portscan module. Sometimes, one that would normally be deduped is force-emitted because it led to a new open port.
|
|
113
|
+
assert 2 <= len([e for e in events if e.type == "IP_ADDRESS" and e.data == "8.8.8.8"]) <= 4
|
|
114
|
+
assert 2 <= len([e for e in events if e.type == "IP_ADDRESS" and e.data == "8.8.4.4"]) <= 4
|
|
115
|
+
assert 2 <= len([e for e in events if e.type == "IP_ADDRESS" and e.data == "8.8.4.5"]) <= 4
|
|
116
|
+
assert 2 <= len([e for e in events if e.type == "IP_ADDRESS" and e.data == "8.8.4.6"]) <= 4
|
|
116
117
|
assert 1 == len([e for e in events if e.type == "OPEN_TCP_PORT" and e.data == "8.8.8.8:443"])
|
|
117
118
|
assert 1 == len([e for e in events if e.type == "OPEN_TCP_PORT" and e.data == "8.8.4.5:80"])
|
|
118
119
|
assert 1 == len([e for e in events if e.type == "OPEN_TCP_PORT" and e.data == "8.8.4.6:631"])
|
|
@@ -121,7 +122,7 @@ class TestPortscan(ModuleTestBase):
|
|
|
121
122
|
assert 1 == len([e for e in events if e.type == "OPEN_TCP_PORT" and e.data == "asdf.evilcorp.net:80"])
|
|
122
123
|
assert 1 == len([e for e in events if e.type == "OPEN_TCP_PORT" and e.data == "dummy.asdf.evilcorp.net:80"])
|
|
123
124
|
assert 1 == len([e for e in events if e.type == "OPEN_TCP_PORT" and e.data == "dummy.evilcorp.com:631"])
|
|
124
|
-
assert not any(
|
|
125
|
+
assert not any(e for e in events if e.type == "OPEN_TCP_PORT" and e.host == "dummy.www.evilcorp.com")
|
|
125
126
|
|
|
126
127
|
|
|
127
128
|
class TestPortscanPingFirst(TestPortscan):
|
|
@@ -135,7 +136,7 @@ class TestPortscanPingFirst(TestPortscan):
|
|
|
135
136
|
assert self.ping_runs == 1
|
|
136
137
|
open_port_events = [e for e in events if e.type == "OPEN_TCP_PORT"]
|
|
137
138
|
assert len(open_port_events) == 3
|
|
138
|
-
assert
|
|
139
|
+
assert {e.data for e in open_port_events} == {"8.8.8.8:443", "evilcorp.com:443", "www.evilcorp.com:443"}
|
|
139
140
|
|
|
140
141
|
|
|
141
142
|
class TestPortscanPingOnly(TestPortscan):
|
|
@@ -153,4 +154,4 @@ class TestPortscanPingOnly(TestPortscan):
|
|
|
153
154
|
assert len(open_port_events) == 0
|
|
154
155
|
ip_events = [e for e in events if e.type == "IP_ADDRESS"]
|
|
155
156
|
assert len(ip_events) == 1
|
|
156
|
-
assert
|
|
157
|
+
assert {e.data for e in ip_events} == {"8.8.8.8"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import time
|
|
2
|
+
import asyncio
|
|
3
|
+
|
|
4
|
+
from .base import ModuleTestBase
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class TestPostgres(ModuleTestBase):
|
|
8
|
+
targets = ["evilcorp.com"]
|
|
9
|
+
skip_distro_tests = True
|
|
10
|
+
|
|
11
|
+
async def setup_before_prep(self, module_test):
|
|
12
|
+
process = await asyncio.create_subprocess_exec(
|
|
13
|
+
"docker",
|
|
14
|
+
"run",
|
|
15
|
+
"--name",
|
|
16
|
+
"bbot-test-postgres",
|
|
17
|
+
"--rm",
|
|
18
|
+
"-e",
|
|
19
|
+
"POSTGRES_PASSWORD=bbotislife",
|
|
20
|
+
"-e",
|
|
21
|
+
"POSTGRES_USER=postgres",
|
|
22
|
+
"-p",
|
|
23
|
+
"5432:5432",
|
|
24
|
+
"-d",
|
|
25
|
+
"postgres",
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
import asyncpg
|
|
29
|
+
|
|
30
|
+
# wait for the container to start
|
|
31
|
+
start_time = time.time()
|
|
32
|
+
while True:
|
|
33
|
+
try:
|
|
34
|
+
# Connect to the default 'postgres' database to create 'bbot'
|
|
35
|
+
conn = await asyncpg.connect(
|
|
36
|
+
user="postgres", password="bbotislife", database="postgres", host="127.0.0.1"
|
|
37
|
+
)
|
|
38
|
+
await conn.execute("CREATE DATABASE bbot")
|
|
39
|
+
await conn.close()
|
|
40
|
+
break
|
|
41
|
+
except asyncpg.exceptions.DuplicateDatabaseError:
|
|
42
|
+
# If the database already exists, break the loop
|
|
43
|
+
break
|
|
44
|
+
except Exception as e:
|
|
45
|
+
if time.time() - start_time > 60: # timeout after 60 seconds
|
|
46
|
+
self.log.error("PostgreSQL server did not start in time.")
|
|
47
|
+
raise e
|
|
48
|
+
await asyncio.sleep(1)
|
|
49
|
+
|
|
50
|
+
if process.returncode != 0:
|
|
51
|
+
self.log.error("Failed to start PostgreSQL server")
|
|
52
|
+
|
|
53
|
+
async def check(self, module_test, events):
|
|
54
|
+
import asyncpg
|
|
55
|
+
|
|
56
|
+
# Connect to the PostgreSQL database
|
|
57
|
+
conn = await asyncpg.connect(user="postgres", password="bbotislife", database="bbot", host="127.0.0.1")
|
|
58
|
+
|
|
59
|
+
try:
|
|
60
|
+
events = await conn.fetch("SELECT * FROM event")
|
|
61
|
+
assert len(events) == 3, "No events found in PostgreSQL database"
|
|
62
|
+
scans = await conn.fetch("SELECT * FROM scan")
|
|
63
|
+
assert len(scans) == 1, "No scans found in PostgreSQL database"
|
|
64
|
+
targets = await conn.fetch("SELECT * FROM target")
|
|
65
|
+
assert len(targets) == 1, "No targets found in PostgreSQL database"
|
|
66
|
+
finally:
|
|
67
|
+
await conn.close()
|
|
68
|
+
process = await asyncio.create_subprocess_exec(
|
|
69
|
+
"docker", "stop", "bbot-test-postgres", stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
|
|
70
|
+
)
|
|
71
|
+
stdout, stderr = await process.communicate()
|
|
72
|
+
|
|
73
|
+
if process.returncode != 0:
|
|
74
|
+
raise Exception(f"Failed to stop PostgreSQL server: {stderr.decode()}")
|
|
@@ -2,281 +2,112 @@ from .base import ModuleTestBase
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
class TestPostman(ModuleTestBase):
|
|
5
|
-
|
|
6
|
-
"omit_event_types": [],
|
|
7
|
-
"scope": {"report_distance": 1},
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
modules_overrides = ["postman", "httpx", "excavate"]
|
|
5
|
+
modules_overrides = ["postman", "speculate"]
|
|
11
6
|
|
|
12
7
|
async def setup_after_prep(self, module_test):
|
|
8
|
+
await module_test.mock_dns(
|
|
9
|
+
{"blacklanternsecurity.com": {"A": ["127.0.0.99"]}, "github.com": {"A": ["127.0.0.99"]}}
|
|
10
|
+
)
|
|
13
11
|
module_test.httpx_mock.add_response(
|
|
14
12
|
url="https://www.postman.com/_api/ws/proxy",
|
|
15
13
|
json={
|
|
16
14
|
"data": [
|
|
17
15
|
{
|
|
18
|
-
"score":
|
|
19
|
-
"normalizedScore":
|
|
16
|
+
"score": 611.41156,
|
|
17
|
+
"normalizedScore": 23,
|
|
20
18
|
"document": {
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"isBlacklisted": False,
|
|
43
|
-
"warehouse__updated_at_collection": "2023-12-11 02:00:00",
|
|
44
|
-
"isPrivateNetworkEntity": False,
|
|
45
|
-
"warehouse__updated_at_request": "2023-12-11 02:00:00",
|
|
46
|
-
"publisherName": "NA",
|
|
47
|
-
"name": "A test post request",
|
|
48
|
-
"privateNetworkMeta": "",
|
|
19
|
+
"watcherCount": 6,
|
|
20
|
+
"apiCount": 0,
|
|
21
|
+
"forkCount": 0,
|
|
22
|
+
"isblacklisted": "false",
|
|
23
|
+
"createdAt": "2021-06-15T14:03:51",
|
|
24
|
+
"publishertype": "team",
|
|
25
|
+
"publisherHandle": "blacklanternsecurity",
|
|
26
|
+
"id": "11498add-357d-4bc5-a008-0a2d44fb8829",
|
|
27
|
+
"slug": "bbot-public",
|
|
28
|
+
"updatedAt": "2024-07-30T11:00:35",
|
|
29
|
+
"entityType": "workspace",
|
|
30
|
+
"visibilityStatus": "public",
|
|
31
|
+
"forkcount": "0",
|
|
32
|
+
"tags": [],
|
|
33
|
+
"createdat": "2021-06-15T14:03:51",
|
|
34
|
+
"forkLabel": "",
|
|
35
|
+
"publisherName": "blacklanternsecurity",
|
|
36
|
+
"name": "BlackLanternSecurity BBOT [Public]",
|
|
37
|
+
"dependencyCount": 7,
|
|
38
|
+
"collectionCount": 6,
|
|
39
|
+
"warehouse__updated_at": "2024-07-30 11:00:00",
|
|
49
40
|
"privateNetworkFolders": [],
|
|
50
|
-
"documentType": "request",
|
|
51
|
-
"collection": {
|
|
52
|
-
"id": "28129865-d9f8833b-3dd2-4b07-9634-1831206d5205",
|
|
53
|
-
"name": "Secret Collection",
|
|
54
|
-
"tags": [],
|
|
55
|
-
"forkCount": 0,
|
|
56
|
-
"watcherCount": 0,
|
|
57
|
-
"views": 31,
|
|
58
|
-
"apiId": "",
|
|
59
|
-
"apiName": "",
|
|
60
|
-
},
|
|
61
|
-
},
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
"score": 498.22398,
|
|
65
|
-
"normalizedScore": 8.43312266976538,
|
|
66
|
-
"document": {
|
|
67
41
|
"isPublisherVerified": False,
|
|
68
|
-
"publisherType": "
|
|
42
|
+
"publisherType": "team",
|
|
69
43
|
"curatedInList": [],
|
|
70
|
-
"
|
|
71
|
-
"
|
|
44
|
+
"creatorId": "6900157",
|
|
45
|
+
"description": "",
|
|
46
|
+
"forklabel": "",
|
|
47
|
+
"publisherId": "299401",
|
|
72
48
|
"publisherLogo": "",
|
|
49
|
+
"popularity": 5,
|
|
73
50
|
"isPublic": True,
|
|
74
|
-
"
|
|
75
|
-
"
|
|
76
|
-
"
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
"name": "SpilledSecrets",
|
|
80
|
-
"id": "92d0451b-119d-4ef0-b74c-22c400e5ce05",
|
|
81
|
-
"slug": "spilledsecrets",
|
|
82
|
-
}
|
|
83
|
-
],
|
|
84
|
-
"collectionForkLabel": "",
|
|
85
|
-
"method": "POST",
|
|
86
|
-
"entityType": "request",
|
|
87
|
-
"url": "www.example.com/index",
|
|
51
|
+
"categories": [],
|
|
52
|
+
"universaltags": "",
|
|
53
|
+
"views": 5788,
|
|
54
|
+
"summary": "BLS public workspaces.",
|
|
55
|
+
"memberCount": 2,
|
|
88
56
|
"isBlacklisted": False,
|
|
89
|
-
"
|
|
57
|
+
"publisherid": "299401",
|
|
90
58
|
"isPrivateNetworkEntity": False,
|
|
91
|
-
"
|
|
92
|
-
"publisherName": "NA",
|
|
93
|
-
"name": "A test post request",
|
|
59
|
+
"isDomainNonTrivial": True,
|
|
94
60
|
"privateNetworkMeta": "",
|
|
95
|
-
"
|
|
96
|
-
"documentType": "
|
|
97
|
-
"collection": {
|
|
98
|
-
"id": "007e8d67-007e8d67-932b-46ff-b95c-a2aa216edaf3",
|
|
99
|
-
"name": "Secret Collection",
|
|
100
|
-
"tags": [],
|
|
101
|
-
"forkCount": 0,
|
|
102
|
-
"watcherCount": 0,
|
|
103
|
-
"views": 31,
|
|
104
|
-
"apiId": "",
|
|
105
|
-
"apiName": "",
|
|
106
|
-
},
|
|
61
|
+
"updatedat": "2021-10-20T16:19:29",
|
|
62
|
+
"documentType": "workspace",
|
|
107
63
|
},
|
|
108
|
-
|
|
64
|
+
"highlight": {"summary": "<b>BLS</b> BBOT api test."},
|
|
65
|
+
}
|
|
109
66
|
],
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
"createdBy": "28329861",
|
|
123
|
-
"updatedBy": "28329861",
|
|
124
|
-
"team": "28329861",
|
|
125
|
-
"createdAt": "2023-12-13T19:12:21.000Z",
|
|
126
|
-
"updatedAt": "2023-12-13T19:15:07.000Z",
|
|
127
|
-
"visibilityStatus": "public",
|
|
128
|
-
"profileInfo": {
|
|
129
|
-
"slug": "spilledsecrets",
|
|
130
|
-
"profileType": "team",
|
|
131
|
-
"profileId": "28329861",
|
|
132
|
-
"publicHandle": "https://www.postman.com/lunar-pizza-28329861",
|
|
133
|
-
"publicImageURL": "https://res.cloudinary.com/postman/image/upload/t_team_logo/v1/team/default-L4",
|
|
134
|
-
"publicName": "lunar-pizza-28329861",
|
|
135
|
-
"isVerified": False,
|
|
67
|
+
"meta": {
|
|
68
|
+
"queryText": "blacklanternsecurity",
|
|
69
|
+
"total": {
|
|
70
|
+
"collection": 0,
|
|
71
|
+
"request": 0,
|
|
72
|
+
"workspace": 1,
|
|
73
|
+
"api": 0,
|
|
74
|
+
"team": 0,
|
|
75
|
+
"user": 0,
|
|
76
|
+
"flow": 0,
|
|
77
|
+
"apiDefinition": 0,
|
|
78
|
+
"privateNetworkFolder": 0,
|
|
136
79
|
},
|
|
137
|
-
"
|
|
138
|
-
"
|
|
139
|
-
"
|
|
140
|
-
"
|
|
141
|
-
"
|
|
142
|
-
"
|
|
80
|
+
"state": "AQ4",
|
|
81
|
+
"spellCorrection": {"count": {"all": 1, "workspace": 1}, "correctedQueryText": None},
|
|
82
|
+
"featureFlags": {
|
|
83
|
+
"enabledPublicResultCuration": True,
|
|
84
|
+
"boostByPopularity": True,
|
|
85
|
+
"reRankPostNormalization": True,
|
|
86
|
+
"enableUrlBarHostNameSearch": True,
|
|
143
87
|
},
|
|
144
|
-
"members": {"users": {"28129865": {"id": "28129865"}}},
|
|
145
88
|
},
|
|
146
89
|
},
|
|
147
90
|
)
|
|
148
|
-
module_test.httpx_mock.add_response(
|
|
149
|
-
url="https://www.postman.com/_api/list/collection?workspace=afa061be-9cb0-4520-9d4d-fe63361daf0f",
|
|
150
|
-
json={
|
|
151
|
-
"data": [
|
|
152
|
-
{
|
|
153
|
-
"id": "28129865-d9f8833b-3dd2-4b07-9634-1831206d5205",
|
|
154
|
-
"name": "Secret Collection",
|
|
155
|
-
"folders_order": ["d6dd1092-94d4-462c-be48-4e3cad3b8612"],
|
|
156
|
-
"order": ["67c9db4c-d0ed-461c-86d2-9a8c5a5de896"],
|
|
157
|
-
"attributes": {
|
|
158
|
-
"permissions": {
|
|
159
|
-
"userCanUpdate": False,
|
|
160
|
-
"userCanDelete": False,
|
|
161
|
-
"userCanShare": False,
|
|
162
|
-
"userCanCreateMock": False,
|
|
163
|
-
"userCanCreateMonitor": False,
|
|
164
|
-
"anybodyCanView": True,
|
|
165
|
-
"teamCanView": True,
|
|
166
|
-
},
|
|
167
|
-
"fork": None,
|
|
168
|
-
"parent": {"type": "workspace", "id": "afa061be-9cb0-4520-9d4d-fe63361daf0f"},
|
|
169
|
-
"flags": {"isArchived": False, "isFavorite": False},
|
|
170
|
-
},
|
|
171
|
-
"folders": [
|
|
172
|
-
{
|
|
173
|
-
"id": "28129865-d6dd1092-94d4-462c-be48-4e3cad3b8612",
|
|
174
|
-
"name": "Nested folder",
|
|
175
|
-
"folder": None,
|
|
176
|
-
"collection": "28129865-d9f8833b-3dd2-4b07-9634-1831206d5205",
|
|
177
|
-
"folders_order": ["73a999c1-4246-4805-91bd-0232cc75958a"],
|
|
178
|
-
"order": ["3aa78b71-2c4f-4299-94df-287ed1036409"],
|
|
179
|
-
"folders": [
|
|
180
|
-
{
|
|
181
|
-
"id": "28129865-73a999c1-4246-4805-91bd-0232cc75958a",
|
|
182
|
-
"name": "Another Nested Folder",
|
|
183
|
-
"folder": "28129865-d6dd1092-94d4-462c-be48-4e3cad3b8612",
|
|
184
|
-
"collection": "28129865-d9f8833b-3dd2-4b07-9634-1831206d5205",
|
|
185
|
-
"folders_order": [],
|
|
186
|
-
"order": ["987c8ac8-bfa9-4bab-ade9-88ccf0597862"],
|
|
187
|
-
"folders": [],
|
|
188
|
-
"requests": [
|
|
189
|
-
{
|
|
190
|
-
"id": "28129865-987c8ac8-bfa9-4bab-ade9-88ccf0597862",
|
|
191
|
-
"name": "Delete User",
|
|
192
|
-
"method": "DELETE",
|
|
193
|
-
"collection": "28129865-d9f8833b-3dd2-4b07-9634-1831206d5205",
|
|
194
|
-
"folder": "28129865-73a999c1-4246-4805-91bd-0232cc75958a",
|
|
195
|
-
"responses_order": [],
|
|
196
|
-
"responses": [],
|
|
197
|
-
}
|
|
198
|
-
],
|
|
199
|
-
}
|
|
200
|
-
],
|
|
201
|
-
"requests": [
|
|
202
|
-
{
|
|
203
|
-
"id": "28129865-3aa78b71-2c4f-4299-94df-287ed1036409",
|
|
204
|
-
"name": "Login",
|
|
205
|
-
"method": "POST",
|
|
206
|
-
"collection": "28129865-d9f8833b-3dd2-4b07-9634-1831206d5205",
|
|
207
|
-
"folder": "28129865-d6dd1092-94d4-462c-be48-4e3cad3b8612",
|
|
208
|
-
"responses_order": [],
|
|
209
|
-
"responses": [],
|
|
210
|
-
}
|
|
211
|
-
],
|
|
212
|
-
}
|
|
213
|
-
],
|
|
214
|
-
"requests": [
|
|
215
|
-
{
|
|
216
|
-
"id": "28129865-67c9db4c-d0ed-461c-86d2-9a8c5a5de896",
|
|
217
|
-
"name": "Example Basic HTTP request",
|
|
218
|
-
"method": "GET",
|
|
219
|
-
"collection": "28129865-d9f8833b-3dd2-4b07-9634-1831206d5205",
|
|
220
|
-
"folder": None,
|
|
221
|
-
"responses_order": [],
|
|
222
|
-
"responses": [],
|
|
223
|
-
}
|
|
224
|
-
],
|
|
225
|
-
}
|
|
226
|
-
]
|
|
227
|
-
},
|
|
228
|
-
)
|
|
229
|
-
|
|
230
|
-
old_emit_event = module_test.module.emit_event
|
|
231
|
-
|
|
232
|
-
async def new_emit_event(event_data, event_type, **kwargs):
|
|
233
|
-
if event_data.startswith("https://www.postman.com"):
|
|
234
|
-
event_data = event_data.replace("https://www.postman.com", "http://127.0.0.1:8888")
|
|
235
|
-
await old_emit_event(event_data, event_type, **kwargs)
|
|
236
|
-
|
|
237
|
-
module_test.monkeypatch.setattr(module_test.module, "emit_event", new_emit_event)
|
|
238
|
-
await module_test.mock_dns(
|
|
239
|
-
{"blacklanternsecurity.com": {"A": ["127.0.0.1"]}, "asdf.blacklanternsecurity.com": {"A": ["127.0.0.1"]}}
|
|
240
|
-
)
|
|
241
|
-
|
|
242
|
-
request_args = dict(uri="/_api/request/28129865-987c8ac8-bfa9-4bab-ade9-88ccf0597862")
|
|
243
|
-
respond_args = dict(response_data="https://asdf.blacklanternsecurity.com")
|
|
244
|
-
module_test.set_expect_requests(request_args, respond_args)
|
|
245
91
|
|
|
246
92
|
def check(self, module_test, events):
|
|
247
|
-
assert
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
), "Failed to detect collection request #1"
|
|
269
|
-
assert any(
|
|
270
|
-
e.data == "http://127.0.0.1:8888/_api/request/28129865-3aa78b71-2c4f-4299-94df-287ed1036409"
|
|
271
|
-
for e in events
|
|
272
|
-
), "Failed to detect collection request #2"
|
|
273
|
-
assert any(
|
|
274
|
-
e.data == "http://127.0.0.1:8888/_api/request/28129865-67c9db4c-d0ed-461c-86d2-9a8c5a5de896"
|
|
275
|
-
for e in events
|
|
276
|
-
), "Failed to detect collection request #3"
|
|
277
|
-
assert any(
|
|
278
|
-
e.type == "HTTP_RESPONSE"
|
|
279
|
-
and e.data["url"] == "http://127.0.0.1:8888/_api/request/28129865-987c8ac8-bfa9-4bab-ade9-88ccf0597862"
|
|
280
|
-
for e in events
|
|
281
|
-
), "Failed to emit HTTP_RESPONSE"
|
|
282
|
-
assert any(e.data == "asdf.blacklanternsecurity.com" for e in events), "Failed to detect subdomain"
|
|
93
|
+
assert len(events) == 5
|
|
94
|
+
assert 1 == len(
|
|
95
|
+
[
|
|
96
|
+
e
|
|
97
|
+
for e in events
|
|
98
|
+
if e.type == "DNS_NAME" and e.data == "blacklanternsecurity.com" and e.scope_distance == 0
|
|
99
|
+
]
|
|
100
|
+
), "Failed to emit target DNS_NAME"
|
|
101
|
+
assert 1 == len(
|
|
102
|
+
[e for e in events if e.type == "ORG_STUB" and e.data == "blacklanternsecurity" and e.scope_distance == 0]
|
|
103
|
+
), "Failed to find ORG_STUB"
|
|
104
|
+
assert 1 == len(
|
|
105
|
+
[
|
|
106
|
+
e
|
|
107
|
+
for e in events
|
|
108
|
+
if e.type == "CODE_REPOSITORY"
|
|
109
|
+
and "postman" in e.tags
|
|
110
|
+
and e.data["url"] == "https://www.postman.com/blacklanternsecurity/bbot-public"
|
|
111
|
+
and e.scope_distance == 1
|
|
112
|
+
]
|
|
113
|
+
), "Failed to find blacklanternsecurity postman workspace"
|