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
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import re
|
|
2
|
+
import httpx
|
|
2
3
|
|
|
3
4
|
from ..bbot_fixtures import *
|
|
4
5
|
|
|
@@ -13,6 +14,7 @@ async def test_web_engine(bbot_scanner, bbot_httpserver, httpx_mock):
|
|
|
13
14
|
|
|
14
15
|
base_url = bbot_httpserver.url_for("/test/")
|
|
15
16
|
bbot_httpserver.expect_request(uri=re.compile(r"/test/\d+")).respond_with_handler(server_handler)
|
|
17
|
+
bbot_httpserver.expect_request(uri=re.compile(r"/nope")).respond_with_data("nope", status=500)
|
|
16
18
|
|
|
17
19
|
scan = bbot_scanner()
|
|
18
20
|
|
|
@@ -27,7 +29,7 @@ async def test_web_engine(bbot_scanner, bbot_httpserver, httpx_mock):
|
|
|
27
29
|
urls = [f"{base_url}{i}" for i in range(num_urls)]
|
|
28
30
|
responses = [r async for r in scan.helpers.request_batch(urls)]
|
|
29
31
|
assert len(responses) == 100
|
|
30
|
-
assert all(
|
|
32
|
+
assert all(r[1].status_code == 200 and r[1].text.startswith(f"{r[0]}: ") for r in responses)
|
|
31
33
|
|
|
32
34
|
# request_batch w/ cancellation
|
|
33
35
|
agen = scan.helpers.request_batch(urls)
|
|
@@ -49,15 +51,45 @@ async def test_web_engine(bbot_scanner, bbot_httpserver, httpx_mock):
|
|
|
49
51
|
assert response.text.startswith(f"{url}: ")
|
|
50
52
|
assert f"H{custom_tracker}: v{custom_tracker}" in response.text
|
|
51
53
|
|
|
54
|
+
# request with raise_error=True
|
|
55
|
+
with pytest.raises(WebError):
|
|
56
|
+
await scan.helpers.request("http://www.example.com/", raise_error=True)
|
|
57
|
+
try:
|
|
58
|
+
await scan.helpers.request("http://www.example.com/", raise_error=True)
|
|
59
|
+
except WebError as e:
|
|
60
|
+
assert hasattr(e, "response")
|
|
61
|
+
assert e.response is None
|
|
62
|
+
with pytest.raises(httpx.HTTPStatusError):
|
|
63
|
+
response = await scan.helpers.request(bbot_httpserver.url_for("/nope"), raise_error=True)
|
|
64
|
+
response.raise_for_status()
|
|
65
|
+
try:
|
|
66
|
+
response = await scan.helpers.request(bbot_httpserver.url_for("/nope"), raise_error=True)
|
|
67
|
+
response.raise_for_status()
|
|
68
|
+
except httpx.HTTPStatusError as e:
|
|
69
|
+
assert hasattr(e, "response")
|
|
70
|
+
assert e.response.status_code == 500
|
|
71
|
+
|
|
52
72
|
# download
|
|
53
73
|
url = f"{base_url}999"
|
|
54
74
|
filename = await scan.helpers.download(url)
|
|
55
75
|
file_content = open(filename).read()
|
|
56
76
|
assert file_content.startswith(f"{url}: ")
|
|
57
77
|
|
|
58
|
-
# raise_error=True
|
|
78
|
+
# download with raise_error=True
|
|
59
79
|
with pytest.raises(WebError):
|
|
60
|
-
await scan.helpers.
|
|
80
|
+
await scan.helpers.download("http://www.example.com/", raise_error=True)
|
|
81
|
+
try:
|
|
82
|
+
await scan.helpers.download("http://www.example.com/", raise_error=True)
|
|
83
|
+
except WebError as e:
|
|
84
|
+
assert hasattr(e, "response")
|
|
85
|
+
assert e.response is None
|
|
86
|
+
with pytest.raises(WebError):
|
|
87
|
+
await scan.helpers.download(bbot_httpserver.url_for("/nope"), raise_error=True)
|
|
88
|
+
try:
|
|
89
|
+
await scan.helpers.download(bbot_httpserver.url_for("/nope"), raise_error=True)
|
|
90
|
+
except WebError as e:
|
|
91
|
+
assert hasattr(e, "response")
|
|
92
|
+
assert e.response.status_code == 500
|
|
61
93
|
|
|
62
94
|
await scan._cleanup()
|
|
63
95
|
|
|
@@ -121,9 +153,12 @@ async def test_web_helpers(bbot_scanner, bbot_httpserver, httpx_mock):
|
|
|
121
153
|
|
|
122
154
|
await scan._cleanup()
|
|
123
155
|
|
|
124
|
-
scan1 = bbot_scanner("8.8.8.8")
|
|
156
|
+
scan1 = bbot_scanner("8.8.8.8", modules=["ipneighbor"])
|
|
125
157
|
scan2 = bbot_scanner("127.0.0.1")
|
|
126
158
|
|
|
159
|
+
await scan1._prep()
|
|
160
|
+
module = scan1.modules["ipneighbor"]
|
|
161
|
+
|
|
127
162
|
web_config = CORE.config.get("web", {})
|
|
128
163
|
user_agent = web_config.get("user_agent", "")
|
|
129
164
|
headers = {"User-Agent": user_agent}
|
|
@@ -176,14 +211,14 @@ async def test_web_helpers(bbot_scanner, bbot_httpserver, httpx_mock):
|
|
|
176
211
|
url = bbot_httpserver.url_for(path)
|
|
177
212
|
bbot_httpserver.expect_request(uri=path).respond_with_data(download_content, status=200)
|
|
178
213
|
webpage = await scan1.helpers.request(url)
|
|
179
|
-
assert webpage,
|
|
214
|
+
assert webpage, "Webpage is False"
|
|
180
215
|
soup = scan1.helpers.beautifulsoup(webpage, "html.parser")
|
|
181
|
-
assert soup,
|
|
216
|
+
assert soup, "Soup is False"
|
|
182
217
|
# pretty_print = soup.prettify()
|
|
183
218
|
# assert pretty_print, f"PrettyPrint is False"
|
|
184
219
|
# scan1.helpers.log.info(f"{pretty_print}")
|
|
185
220
|
html_text = soup.find(text="Example Domain")
|
|
186
|
-
assert html_text,
|
|
221
|
+
assert html_text, "Find HTML Text is False"
|
|
187
222
|
|
|
188
223
|
# 404
|
|
189
224
|
path = "/test_http_helpers_download_404"
|
|
@@ -220,7 +255,7 @@ async def test_web_helpers(bbot_scanner, bbot_httpserver, httpx_mock):
|
|
|
220
255
|
uri=f"{base_path}/3", query_string={"page_size": "100", "offset": "200"}
|
|
221
256
|
).respond_with_data("page3")
|
|
222
257
|
results = []
|
|
223
|
-
agen =
|
|
258
|
+
agen = module.api_page_iter(template_url)
|
|
224
259
|
try:
|
|
225
260
|
async for result in agen:
|
|
226
261
|
if result and result.text.startswith("page"):
|
|
@@ -230,7 +265,7 @@ async def test_web_helpers(bbot_scanner, bbot_httpserver, httpx_mock):
|
|
|
230
265
|
finally:
|
|
231
266
|
await agen.aclose()
|
|
232
267
|
assert not results
|
|
233
|
-
agen =
|
|
268
|
+
agen = module.api_page_iter(template_url, json=False)
|
|
234
269
|
try:
|
|
235
270
|
async for result in agen:
|
|
236
271
|
if result and result.text.startswith("page"):
|
|
@@ -354,7 +389,7 @@ async def test_web_http_compare(httpx_mock, bbot_scanner):
|
|
|
354
389
|
await compare_helper.compare("http://www.example.com", check_reflection=True)
|
|
355
390
|
compare_helper.compare_body({"asdf": "fdsa"}, {"fdsa": "asdf"})
|
|
356
391
|
for mode in ("getparam", "header", "cookie"):
|
|
357
|
-
assert await compare_helper.canary_check("http://www.example.com", mode=mode)
|
|
392
|
+
assert await compare_helper.canary_check("http://www.example.com", mode=mode) is True
|
|
358
393
|
|
|
359
394
|
await scan._cleanup()
|
|
360
395
|
|
|
@@ -436,6 +471,9 @@ async def test_web_cookies(bbot_scanner, httpx_mock):
|
|
|
436
471
|
# but that they're not sent in the response
|
|
437
472
|
with pytest.raises(httpx.TimeoutException):
|
|
438
473
|
r = await client2.get(url="http://www2.evilcorp.com/cookies/test")
|
|
474
|
+
# make sure cookies are sent
|
|
475
|
+
r = await client2.get(url="http://www2.evilcorp.com/cookies/test", cookies={"wats": "fdsa"})
|
|
476
|
+
assert r.status_code == 200
|
|
439
477
|
# make sure we can manually send cookies
|
|
440
478
|
httpx_mock.add_response(url="http://www2.evilcorp.com/cookies/test2", match_headers={"Cookie": "fdsa=wats"})
|
|
441
479
|
r = await client2.get(url="http://www2.evilcorp.com/cookies/test2", cookies={"fdsa": "wats"})
|
|
@@ -11,17 +11,6 @@ from bbot.core.helpers.misc import rand_string
|
|
|
11
11
|
log = logging.getLogger("bbot.test.modules")
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
def tempwordlist(content):
|
|
15
|
-
from bbot.core.helpers.misc import rand_string
|
|
16
|
-
|
|
17
|
-
filename = bbot_test_dir / f"{rand_string(8)}"
|
|
18
|
-
with open(filename, "w", errors="ignore") as f:
|
|
19
|
-
for c in content:
|
|
20
|
-
line = f"{c}\n"
|
|
21
|
-
f.write(line)
|
|
22
|
-
return filename
|
|
23
|
-
|
|
24
|
-
|
|
25
14
|
class ModuleTestBase:
|
|
26
15
|
targets = ["blacklanternsecurity.com"]
|
|
27
16
|
scan_name = None
|
|
@@ -31,6 +20,8 @@ class ModuleTestBase:
|
|
|
31
20
|
config_overrides = {}
|
|
32
21
|
modules_overrides = None
|
|
33
22
|
log = logging.getLogger("bbot")
|
|
23
|
+
# if True, the test will be skipped (useful for tests that require docker)
|
|
24
|
+
skip_distro_tests = False
|
|
34
25
|
|
|
35
26
|
class ModuleTest:
|
|
36
27
|
def __init__(
|
|
@@ -82,10 +73,10 @@ class ModuleTestBase:
|
|
|
82
73
|
def set_expect_requests_handler(self, expect_args=None, request_handler=None):
|
|
83
74
|
self.httpserver.expect_request(expect_args).respond_with_handler(request_handler)
|
|
84
75
|
|
|
85
|
-
async def mock_dns(self, mock_data, scan=None):
|
|
76
|
+
async def mock_dns(self, mock_data, custom_lookup_fn=None, scan=None):
|
|
86
77
|
if scan is None:
|
|
87
78
|
scan = self.scan
|
|
88
|
-
await scan.helpers.dns._mock_dns(mock_data)
|
|
79
|
+
await scan.helpers.dns._mock_dns(mock_data, custom_lookup_fn=custom_lookup_fn)
|
|
89
80
|
|
|
90
81
|
def mock_interactsh(self, name):
|
|
91
82
|
from ...conftest import Interactsh_mock
|
|
@@ -100,33 +91,39 @@ class ModuleTestBase:
|
|
|
100
91
|
async def module_test(
|
|
101
92
|
self, httpx_mock, bbot_httpserver, bbot_httpserver_ssl, monkeypatch, request, caplog, capsys
|
|
102
93
|
):
|
|
94
|
+
# Skip dastardly test if we're in the distro tests (because dastardly uses docker)
|
|
95
|
+
if os.getenv("BBOT_DISTRO_TESTS") and self.skip_distro_tests:
|
|
96
|
+
pytest.skip("Skipping module_test for dastardly module due to BBOT_DISTRO_TESTS environment variable")
|
|
97
|
+
|
|
103
98
|
self.log.info(f"Starting {self.name} module test")
|
|
104
99
|
module_test = self.ModuleTest(
|
|
105
100
|
self, httpx_mock, bbot_httpserver, bbot_httpserver_ssl, monkeypatch, request, caplog, capsys
|
|
106
101
|
)
|
|
107
|
-
self.log.debug(
|
|
102
|
+
self.log.debug("Mocking DNS")
|
|
108
103
|
await module_test.mock_dns({"blacklanternsecurity.com": {"A": ["127.0.0.88"]}})
|
|
109
|
-
self.log.debug(
|
|
104
|
+
self.log.debug("Executing setup_before_prep()")
|
|
110
105
|
await self.setup_before_prep(module_test)
|
|
111
|
-
self.log.debug(
|
|
106
|
+
self.log.debug("Executing scan._prep()")
|
|
112
107
|
await module_test.scan._prep()
|
|
113
|
-
self.log.debug(
|
|
108
|
+
self.log.debug("Executing setup_after_prep()")
|
|
114
109
|
await self.setup_after_prep(module_test)
|
|
115
|
-
self.log.debug(
|
|
110
|
+
self.log.debug("Starting scan")
|
|
116
111
|
module_test.events = [e async for e in module_test.scan.async_start()]
|
|
117
112
|
self.log.debug(f"Finished {module_test.name} module test")
|
|
118
113
|
yield module_test
|
|
119
114
|
|
|
120
115
|
@pytest.mark.asyncio
|
|
121
116
|
async def test_module_run(self, module_test):
|
|
122
|
-
|
|
117
|
+
from bbot.core.helpers.misc import execute_sync_or_async
|
|
118
|
+
|
|
119
|
+
await execute_sync_or_async(self.check, module_test, module_test.events)
|
|
123
120
|
module_test.log.info(f"Finished {self.name} module test")
|
|
124
121
|
current_task = asyncio.current_task()
|
|
125
122
|
tasks = [t for t in asyncio.all_tasks() if t != current_task]
|
|
126
123
|
if len(tasks):
|
|
127
124
|
module_test.log.info(f"Unfinished tasks detected: {tasks}")
|
|
128
125
|
else:
|
|
129
|
-
module_test.log.info(
|
|
126
|
+
module_test.log.info("No unfinished tasks detected")
|
|
130
127
|
|
|
131
128
|
def check(self, module_test, events):
|
|
132
129
|
assert False, f"Must override {self.name}.check()"
|
|
@@ -5,7 +5,7 @@ class TestAnubisdb(ModuleTestBase):
|
|
|
5
5
|
async def setup_after_prep(self, module_test):
|
|
6
6
|
module_test.module.abort_if = lambda e: False
|
|
7
7
|
module_test.httpx_mock.add_response(
|
|
8
|
-
url=
|
|
8
|
+
url="https://jldc.me/anubis/subdomains/blacklanternsecurity.com",
|
|
9
9
|
json=["asdf.blacklanternsecurity.com", "zzzz.blacklanternsecurity.com"],
|
|
10
10
|
)
|
|
11
11
|
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from .base import ModuleTestBase, tempapkfile
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class TestAPKPure(ModuleTestBase):
|
|
6
|
+
modules_overrides = ["apkpure", "google_playstore", "speculate"]
|
|
7
|
+
apk_file = tempapkfile()
|
|
8
|
+
|
|
9
|
+
async def setup_after_prep(self, module_test):
|
|
10
|
+
await module_test.mock_dns({"blacklanternsecurity.com": {"A": ["127.0.0.99"]}})
|
|
11
|
+
module_test.httpx_mock.add_response(
|
|
12
|
+
url="https://play.google.com/store/search?q=blacklanternsecurity&c=apps",
|
|
13
|
+
text="""<!DOCTYPE html>
|
|
14
|
+
<html>
|
|
15
|
+
<head>
|
|
16
|
+
<title>"blacklanternsecurity" - Android Apps on Google Play</title>
|
|
17
|
+
</head>
|
|
18
|
+
<body>
|
|
19
|
+
<a href="/store/apps/details?id=com.bbot.test&pcampaignid=dontmatchme&pli=1"/>
|
|
20
|
+
</body>
|
|
21
|
+
</html>""",
|
|
22
|
+
)
|
|
23
|
+
module_test.httpx_mock.add_response(
|
|
24
|
+
url="https://play.google.com/store/apps/details?id=com.bbot.test",
|
|
25
|
+
text="""<!DOCTYPE html>
|
|
26
|
+
<html>
|
|
27
|
+
<head>
|
|
28
|
+
<title>BBOT</title>
|
|
29
|
+
</head>
|
|
30
|
+
<body>
|
|
31
|
+
<meta name="appstore:developer_url" content="https://www.blacklanternsecurity.com">
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
</body>
|
|
35
|
+
</html>""",
|
|
36
|
+
)
|
|
37
|
+
module_test.httpx_mock.add_response(
|
|
38
|
+
url="https://d.apkpure.com/b/XAPK/com.bbot.test?version=latest",
|
|
39
|
+
content=self.apk_file,
|
|
40
|
+
headers={
|
|
41
|
+
"Content-Type": "application/vnd.android.package-archive",
|
|
42
|
+
"Content-Disposition": "attachment; filename=com.bbot.test.apk",
|
|
43
|
+
},
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
def check(self, module_test, events):
|
|
47
|
+
assert len(events) == 6
|
|
48
|
+
assert 1 == len(
|
|
49
|
+
[
|
|
50
|
+
e
|
|
51
|
+
for e in events
|
|
52
|
+
if e.type == "DNS_NAME" and e.data == "blacklanternsecurity.com" and e.scope_distance == 0
|
|
53
|
+
]
|
|
54
|
+
), "Failed to emit target DNS_NAME"
|
|
55
|
+
assert 1 == len(
|
|
56
|
+
[e for e in events if e.type == "ORG_STUB" and e.data == "blacklanternsecurity" and e.scope_distance == 0]
|
|
57
|
+
), "Failed to find ORG_STUB"
|
|
58
|
+
assert 1 == len(
|
|
59
|
+
[
|
|
60
|
+
e
|
|
61
|
+
for e in events
|
|
62
|
+
if e.type == "MOBILE_APP"
|
|
63
|
+
and "android" in e.tags
|
|
64
|
+
and e.data["id"] == "com.bbot.test"
|
|
65
|
+
and e.data["url"] == "https://play.google.com/store/apps/details?id=com.bbot.test"
|
|
66
|
+
]
|
|
67
|
+
), "Failed to find bbot android app"
|
|
68
|
+
filesystem_event = [e for e in events if e.type == "FILESYSTEM" and "com.bbot.test.apk" in e.data["path"]]
|
|
69
|
+
assert 1 == len(filesystem_event), "Failed to download apk"
|
|
70
|
+
file = Path(filesystem_event[0].data["path"])
|
|
71
|
+
assert file.is_file(), "Destination apk doesn't exist"
|
|
@@ -10,7 +10,6 @@ class TestAsset_Inventory(ModuleTestBase):
|
|
|
10
10
|
masscan_output = """{ "ip": "127.0.0.1", "timestamp": "1680197558", "ports": [ {"port": 9999, "proto": "tcp", "status": "open", "reason": "syn-ack", "ttl": 54} ] }"""
|
|
11
11
|
|
|
12
12
|
async def setup_before_prep(self, module_test):
|
|
13
|
-
|
|
14
13
|
async def run_masscan(command, *args, **kwargs):
|
|
15
14
|
if "masscan" in command[:2]:
|
|
16
15
|
targets = open(command[11]).read().splitlines()
|
|
@@ -22,7 +22,7 @@ class TestAzure_Realm(ModuleTestBase):
|
|
|
22
22
|
async def setup_after_prep(self, module_test):
|
|
23
23
|
await module_test.mock_dns({"evilcorp.com": {"A": ["127.0.0.5"]}})
|
|
24
24
|
module_test.httpx_mock.add_response(
|
|
25
|
-
url=
|
|
25
|
+
url="https://login.microsoftonline.com/getuserrealm.srf?login=test@evilcorp.com",
|
|
26
26
|
json=self.response_json,
|
|
27
27
|
)
|
|
28
28
|
|
|
@@ -31,9 +31,9 @@ class TestBaddns_cname_nxdomain(BaseTestBaddns):
|
|
|
31
31
|
module_test.monkeypatch.setattr(WhoisManager, "dispatchWHOIS", self.dispatchWHOIS)
|
|
32
32
|
|
|
33
33
|
def check(self, module_test, events):
|
|
34
|
-
assert any(
|
|
35
|
-
assert any(
|
|
36
|
-
assert any(
|
|
34
|
+
assert any(e.data == "baddns.azurewebsites.net" for e in events), "CNAME detection failed"
|
|
35
|
+
assert any(e.type == "VULNERABILITY" for e in events), "Failed to emit VULNERABILITY"
|
|
36
|
+
assert any("baddns-cname" in e.tags for e in events), "Failed to add baddns tag"
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
class TestBaddns_cname_signature(BaseTestBaddns):
|
|
@@ -60,8 +60,8 @@ class TestBaddns_cname_signature(BaseTestBaddns):
|
|
|
60
60
|
module_test.monkeypatch.setattr(WhoisManager, "dispatchWHOIS", self.dispatchWHOIS)
|
|
61
61
|
|
|
62
62
|
def check(self, module_test, events):
|
|
63
|
-
assert any(
|
|
63
|
+
assert any(e for e in events)
|
|
64
64
|
assert any(
|
|
65
|
-
|
|
65
|
+
e.type == "VULNERABILITY" and "bigcartel.com" in e.data["description"] for e in events
|
|
66
66
|
), "Failed to emit VULNERABILITY"
|
|
67
|
-
assert any(
|
|
67
|
+
assert any("baddns-cname" in e.tags for e in events), "Failed to add baddns tag"
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
from .base import ModuleTestBase
|
|
2
|
+
from bbot.modules.base import BaseModule
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class BaseTestBaddns(ModuleTestBase):
|
|
6
|
+
modules_overrides = ["baddns_direct"]
|
|
7
|
+
targets = ["bad.dns"]
|
|
8
|
+
config_overrides = {"dns": {"minimal": False}, "cloudcheck": True}
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class TestBaddns_direct_cloudflare(BaseTestBaddns):
|
|
12
|
+
targets = ["bad.dns:8888"]
|
|
13
|
+
modules_overrides = ["baddns_direct"]
|
|
14
|
+
|
|
15
|
+
async def dispatchWHOIS(self):
|
|
16
|
+
return None
|
|
17
|
+
|
|
18
|
+
class DummyModule(BaseModule):
|
|
19
|
+
watched_events = ["DNS_NAME"]
|
|
20
|
+
_name = "dummy_module"
|
|
21
|
+
events_seen = []
|
|
22
|
+
|
|
23
|
+
async def handle_event(self, event):
|
|
24
|
+
if event.data == "bad.dns":
|
|
25
|
+
await self.helpers.sleep(0.5)
|
|
26
|
+
self.events_seen.append(event.data)
|
|
27
|
+
url = "http://bad.dns:8888/"
|
|
28
|
+
url_event = self.scan.make_event(
|
|
29
|
+
url, "URL", parent=self.scan.root_event, tags=["cdn-cloudflare", "in-scope", "status-401"]
|
|
30
|
+
)
|
|
31
|
+
if url_event is not None:
|
|
32
|
+
await self.emit_event(url_event)
|
|
33
|
+
|
|
34
|
+
async def setup_after_prep(self, module_test):
|
|
35
|
+
from baddns.base import BadDNS_base
|
|
36
|
+
from baddns.lib.whoismanager import WhoisManager
|
|
37
|
+
|
|
38
|
+
def set_target(self, target):
|
|
39
|
+
return "127.0.0.1:8888"
|
|
40
|
+
|
|
41
|
+
self.module_test = module_test
|
|
42
|
+
|
|
43
|
+
self.dummy_module = self.DummyModule(module_test.scan)
|
|
44
|
+
module_test.scan.modules["dummy_module"] = self.dummy_module
|
|
45
|
+
|
|
46
|
+
expect_args = {"method": "GET", "uri": "/"}
|
|
47
|
+
respond_args = {"response_data": "The specified bucket does not exist", "status": 401}
|
|
48
|
+
module_test.set_expect_requests(expect_args=expect_args, respond_args=respond_args)
|
|
49
|
+
|
|
50
|
+
await module_test.mock_dns({"bad.dns": {"A": ["127.0.0.1"]}})
|
|
51
|
+
|
|
52
|
+
module_test.monkeypatch.setattr(BadDNS_base, "set_target", set_target)
|
|
53
|
+
module_test.monkeypatch.setattr(WhoisManager, "dispatchWHOIS", self.dispatchWHOIS)
|
|
54
|
+
|
|
55
|
+
def check(self, module_test, events):
|
|
56
|
+
assert any(
|
|
57
|
+
e.type == "FINDING"
|
|
58
|
+
and "Possible [AWS Bucket Takeover Detection] via direct BadDNS analysis. Indicator: [[Words: The specified bucket does not exist | Condition: and | Part: body] Matchers-Condition: and] Trigger: [self] baddns Module: [CNAME]"
|
|
59
|
+
in e.data["description"]
|
|
60
|
+
for e in events
|
|
61
|
+
), "Failed to emit FINDING"
|
|
62
|
+
assert any("baddns-cname" in e.tags for e in events), "Failed to add baddns tag"
|
|
@@ -1,12 +1,16 @@
|
|
|
1
|
+
import random
|
|
2
|
+
|
|
1
3
|
from .base import ModuleTestBase
|
|
2
4
|
|
|
3
5
|
|
|
4
6
|
class TestBeVigil(ModuleTestBase):
|
|
7
|
+
module_name = "bevigil"
|
|
5
8
|
config_overrides = {"modules": {"bevigil": {"api_key": "asdf", "urls": True}}}
|
|
6
9
|
|
|
7
10
|
async def setup_after_prep(self, module_test):
|
|
8
11
|
module_test.httpx_mock.add_response(
|
|
9
|
-
url=
|
|
12
|
+
url="https://osint.bevigil.com/api/blacklanternsecurity.com/subdomains/",
|
|
13
|
+
match_headers={"X-Access-Token": "asdf"},
|
|
10
14
|
json={
|
|
11
15
|
"domain": "blacklanternsecurity.com",
|
|
12
16
|
"subdomains": [
|
|
@@ -15,10 +19,33 @@ class TestBeVigil(ModuleTestBase):
|
|
|
15
19
|
},
|
|
16
20
|
)
|
|
17
21
|
module_test.httpx_mock.add_response(
|
|
18
|
-
url=
|
|
22
|
+
url="https://osint.bevigil.com/api/blacklanternsecurity.com/urls/",
|
|
19
23
|
json={"domain": "blacklanternsecurity.com", "urls": ["https://asdf.blacklanternsecurity.com"]},
|
|
20
24
|
)
|
|
21
25
|
|
|
22
26
|
def check(self, module_test, events):
|
|
23
27
|
assert any(e.data == "asdf.blacklanternsecurity.com" for e in events), "Failed to detect subdomain"
|
|
24
28
|
assert any(e.data == "https://asdf.blacklanternsecurity.com/" for e in events), "Failed to detect url"
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class TestBeVigilMultiKey(TestBeVigil):
|
|
32
|
+
api_keys = ["1234", "4321", "asdf", "fdsa"]
|
|
33
|
+
random.shuffle(api_keys)
|
|
34
|
+
config_overrides = {"modules": {"bevigil": {"api_key": api_keys, "urls": True}}}
|
|
35
|
+
|
|
36
|
+
async def setup_after_prep(self, module_test):
|
|
37
|
+
module_test.httpx_mock.add_response(
|
|
38
|
+
url="https://osint.bevigil.com/api/blacklanternsecurity.com/subdomains/",
|
|
39
|
+
match_headers={"X-Access-Token": "fdsa"},
|
|
40
|
+
json={
|
|
41
|
+
"domain": "blacklanternsecurity.com",
|
|
42
|
+
"subdomains": [
|
|
43
|
+
"asdf.blacklanternsecurity.com",
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
)
|
|
47
|
+
module_test.httpx_mock.add_response(
|
|
48
|
+
match_headers={"X-Access-Token": "asdf"},
|
|
49
|
+
url="https://osint.bevigil.com/api/blacklanternsecurity.com/urls/",
|
|
50
|
+
json={"domain": "blacklanternsecurity.com", "urls": ["https://asdf.blacklanternsecurity.com"]},
|
|
51
|
+
)
|
|
@@ -6,7 +6,8 @@ class TestBinaryEdge(ModuleTestBase):
|
|
|
6
6
|
|
|
7
7
|
async def setup_before_prep(self, module_test):
|
|
8
8
|
module_test.httpx_mock.add_response(
|
|
9
|
-
url=
|
|
9
|
+
url="https://api.binaryedge.io/v2/query/domains/subdomain/blacklanternsecurity.com",
|
|
10
|
+
match_headers={"X-Key": "asdf"},
|
|
10
11
|
json={
|
|
11
12
|
"query": "blacklanternsecurity.com",
|
|
12
13
|
"page": 1,
|
|
@@ -18,7 +19,8 @@ class TestBinaryEdge(ModuleTestBase):
|
|
|
18
19
|
},
|
|
19
20
|
)
|
|
20
21
|
module_test.httpx_mock.add_response(
|
|
21
|
-
url=
|
|
22
|
+
url="https://api.binaryedge.io/v2/user/subscription",
|
|
23
|
+
match_headers={"X-Key": "asdf"},
|
|
22
24
|
json={
|
|
23
25
|
"subscription": {"name": "Free"},
|
|
24
26
|
"end_date": "2023-06-17",
|
|
@@ -82,8 +82,8 @@ class Bucket_Amazon_Base(ModuleTestBase):
|
|
|
82
82
|
if e.type == "FINDING" and str(e.module) == self.module_name:
|
|
83
83
|
url = e.data.get("url", "")
|
|
84
84
|
assert self.random_bucket_2 in url
|
|
85
|
-
assert
|
|
86
|
-
assert
|
|
85
|
+
assert self.random_bucket_1 not in url
|
|
86
|
+
assert self.random_bucket_3 not in url
|
|
87
87
|
# make sure bucket mutations were found
|
|
88
88
|
assert any(
|
|
89
89
|
e.type == "STORAGE_BUCKET"
|
|
@@ -21,7 +21,7 @@ class TestBucket_Azure_NoDup(ModuleTestBase):
|
|
|
21
21
|
|
|
22
22
|
async def setup_before_prep(self, module_test):
|
|
23
23
|
module_test.httpx_mock.add_response(
|
|
24
|
-
url=
|
|
24
|
+
url="https://tesla.blob.core.windows.net/tesla?restype=container",
|
|
25
25
|
text="",
|
|
26
26
|
)
|
|
27
27
|
await module_test.mock_dns(
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
from .base import ModuleTestBase
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class TestBufferOverrun(ModuleTestBase):
|
|
5
|
+
config_overrides = {"modules": {"bufferoverrun": {"api_key": "asdf", "commercial": False}}}
|
|
6
|
+
|
|
7
|
+
async def setup_before_prep(self, module_test):
|
|
8
|
+
# Mock response for non-commercial API
|
|
9
|
+
module_test.httpx_mock.add_response(
|
|
10
|
+
url="https://tls.bufferover.run/dns?q=.blacklanternsecurity.com",
|
|
11
|
+
match_headers={"x-api-key": "asdf"},
|
|
12
|
+
json={"Results": ["1.2.3.4,example.com,*,*,sub.blacklanternsecurity.com"]},
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
def check(self, module_test, events):
|
|
16
|
+
assert any(e.data == "sub.blacklanternsecurity.com" for e in events), "Failed to detect subdomain for free API"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class TestBufferOverrunCommercial(ModuleTestBase):
|
|
20
|
+
modules_overrides = ["bufferoverrun"]
|
|
21
|
+
module_name = "bufferoverrun"
|
|
22
|
+
config_overrides = {"modules": {"bufferoverrun": {"api_key": "asdf", "commercial": True}}}
|
|
23
|
+
|
|
24
|
+
async def setup_before_prep(self, module_test):
|
|
25
|
+
# Mock response for commercial API
|
|
26
|
+
module_test.httpx_mock.add_response(
|
|
27
|
+
url="https://bufferover-run-tls.p.rapidapi.com/ipv4/dns?q=.blacklanternsecurity.com",
|
|
28
|
+
match_headers={"x-rapidapi-host": "bufferover-run-tls.p.rapidapi.com", "x-rapidapi-key": "asdf"},
|
|
29
|
+
json={"Results": ["5.6.7.8,blacklanternsecurity.com,*,*,sub.blacklanternsecurity.com"]},
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
def check(self, module_test, events):
|
|
33
|
+
assert any(
|
|
34
|
+
e.data == "sub.blacklanternsecurity.com" for e in events
|
|
35
|
+
), "Failed to detect subdomain for commercial API"
|
|
@@ -6,7 +6,7 @@ class TestBuiltWith(ModuleTestBase):
|
|
|
6
6
|
|
|
7
7
|
async def setup_after_prep(self, module_test):
|
|
8
8
|
module_test.httpx_mock.add_response(
|
|
9
|
-
url=
|
|
9
|
+
url="https://api.builtwith.com/v20/api.json?KEY=asdf&LOOKUP=blacklanternsecurity.com&NOMETA=yes&NOATTR=yes&HIDETEXT=yes&HIDEDL=yes",
|
|
10
10
|
json={
|
|
11
11
|
"Results": [
|
|
12
12
|
{
|
|
@@ -91,7 +91,7 @@ class TestBuiltWith(ModuleTestBase):
|
|
|
91
91
|
},
|
|
92
92
|
)
|
|
93
93
|
module_test.httpx_mock.add_response(
|
|
94
|
-
url=
|
|
94
|
+
url="https://api.builtwith.com/redirect1/api.json?KEY=asdf&LOOKUP=blacklanternsecurity.com",
|
|
95
95
|
json={
|
|
96
96
|
"Lookup": "blacklanternsecurity.com",
|
|
97
97
|
"Inbound": [
|
|
@@ -26,7 +26,7 @@ class TestBypass403_collapsethreshold(ModuleTestBase):
|
|
|
26
26
|
async def setup_after_prep(self, module_test):
|
|
27
27
|
respond_args = {"response_data": "alive"}
|
|
28
28
|
|
|
29
|
-
# some of these
|
|
29
|
+
# some of these won't work outside of the module because of the complex logic. This doesn't matter, we just need to get more alerts than the threshold.
|
|
30
30
|
|
|
31
31
|
query_payloads = [
|
|
32
32
|
"%09",
|