bbot 2.0.1.4720rc0__py3-none-any.whl → 2.3.0.5401rc0__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 -4
- bbot/core/engine.py +9 -8
- bbot/core/event/base.py +131 -52
- bbot/core/helpers/bloom.py +10 -3
- bbot/core/helpers/command.py +8 -7
- bbot/core/helpers/depsinstaller/installer.py +31 -13
- bbot/core/helpers/diff.py +10 -10
- bbot/core/helpers/dns/brute.py +7 -4
- bbot/core/helpers/dns/dns.py +1 -2
- bbot/core/helpers/dns/engine.py +4 -6
- bbot/core/helpers/dns/helpers.py +2 -2
- bbot/core/helpers/dns/mock.py +0 -1
- 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 +1 -2
- bbot/core/helpers/web/web.py +4 -114
- 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 +12 -10
- 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 +20 -21
- 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 +29 -12
- bbot/modules/internal/dnsresolve.py +22 -22
- bbot/modules/internal/excavate.py +97 -59
- bbot/modules/internal/speculate.py +41 -32
- 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 -1
- 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 +8 -11
- 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 +18 -11
- bbot/modules/robots.py +3 -3
- bbot/modules/securitytrails.py +7 -10
- bbot/modules/securitytxt.py +1 -1
- 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 +51 -16
- bbot/modules/templates/webhook.py +2 -4
- bbot/modules/trickest.py +8 -37
- bbot/modules/trufflehog.py +10 -12
- 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 -2
- bbot/presets/spider.yml +4 -0
- bbot/presets/subdomain-enum.yml +7 -7
- bbot/presets/web/dotnet-audit.yml +0 -1
- bbot/scanner/manager.py +5 -16
- bbot/scanner/preset/args.py +46 -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 +172 -62
- bbot/scanner/target.py +236 -434
- bbot/scripts/docs.py +1 -1
- bbot/test/bbot_fixtures.py +13 -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__module__tests.py +0 -1
- bbot/test/test_step_1/test_bbot_fastapi.py +79 -0
- bbot/test/test_step_1/test_bloom_filter.py +2 -1
- bbot/test/test_step_1/test_cli.py +138 -64
- bbot/test/test_step_1/test_dns.py +61 -27
- bbot/test/test_step_1/test_engine.py +17 -19
- bbot/test/test_step_1/test_events.py +183 -30
- bbot/test/test_step_1/test_helpers.py +64 -29
- bbot/test/test_step_1/test_manager_deduplication.py +1 -1
- bbot/test/test_step_1/test_manager_scope_accuracy.py +333 -330
- bbot/test/test_step_1/test_modules_basic.py +68 -70
- bbot/test/test_step_1/test_presets.py +183 -100
- 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 +4 -3
- bbot/test/test_step_1/test_target.py +242 -145
- bbot/test/test_step_1/test_web.py +14 -10
- bbot/test/test_step_2/module_tests/base.py +15 -7
- 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 +28 -48
- 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 -6
- 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 +22 -9
- 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 +16 -16
- bbot/test/test_step_2/module_tests/test_module_ntlm.py +8 -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_pgp.py +2 -2
- 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_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 +14 -14
- bbot/test/test_step_2/module_tests/test_module_social.py +11 -1
- bbot/test/test_step_2/module_tests/test_module_speculate.py +4 -8
- 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 -14
- bbot/test/test_step_2/module_tests/test_module_viewdns.py +1 -1
- 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 +2 -2
- bbot/wordlists/devops_mutations.txt +1 -1
- bbot/wordlists/ffuf_shortname_candidates.txt +1 -1
- bbot/wordlists/nameservers.txt +1 -1
- bbot/wordlists/paramminer_headers.txt +1 -1
- bbot/wordlists/paramminer_parameters.txt +1 -1
- bbot/wordlists/raft-small-extensions-lowercase_CLEANED.txt +1 -1
- bbot/wordlists/valid_url_schemes.txt +1 -1
- {bbot-2.0.1.4720rc0.dist-info → bbot-2.3.0.5401rc0.dist-info}/METADATA +48 -18
- bbot-2.3.0.5401rc0.dist-info/RECORD +421 -0
- {bbot-2.0.1.4720rc0.dist-info → bbot-2.3.0.5401rc0.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.4720rc0.dist-info/RECORD +0 -387
- {bbot-2.0.1.4720rc0.dist-info → bbot-2.3.0.5401rc0.dist-info}/LICENSE +0 -0
- {bbot-2.0.1.4720rc0.dist-info → bbot-2.3.0.5401rc0.dist-info}/entry_points.txt +0 -0
|
@@ -2,11 +2,12 @@ from .base import ModuleTestBase
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
class TestCensys(ModuleTestBase):
|
|
5
|
-
config_overrides = {"modules": {"censys": {"
|
|
5
|
+
config_overrides = {"modules": {"censys": {"api_key": "api_id:api_secret"}}}
|
|
6
6
|
|
|
7
7
|
async def setup_before_prep(self, module_test):
|
|
8
8
|
module_test.httpx_mock.add_response(
|
|
9
9
|
url="https://search.censys.io/api/v1/account",
|
|
10
|
+
match_headers={"Authorization": "Basic YXBpX2lkOmFwaV9zZWNyZXQ="},
|
|
10
11
|
json={
|
|
11
12
|
"email": "info@blacklanternsecurity.com",
|
|
12
13
|
"login": "nope",
|
|
@@ -17,6 +18,7 @@ class TestCensys(ModuleTestBase):
|
|
|
17
18
|
)
|
|
18
19
|
module_test.httpx_mock.add_response(
|
|
19
20
|
url="https://search.censys.io/api/v2/certificates/search",
|
|
21
|
+
match_headers={"Authorization": "Basic YXBpX2lkOmFwaV9zZWNyZXQ="},
|
|
20
22
|
match_content=b'{"q": "names: blacklanternsecurity.com", "per_page": 100}',
|
|
21
23
|
json={
|
|
22
24
|
"code": 200,
|
|
@@ -45,6 +47,7 @@ class TestCensys(ModuleTestBase):
|
|
|
45
47
|
)
|
|
46
48
|
module_test.httpx_mock.add_response(
|
|
47
49
|
url="https://search.censys.io/api/v2/certificates/search",
|
|
50
|
+
match_headers={"Authorization": "Basic YXBpX2lkOmFwaV9zZWNyZXQ="},
|
|
48
51
|
match_content=b'{"q": "names: blacklanternsecurity.com", "per_page": 100, "cursor": "NextToken"}',
|
|
49
52
|
json={
|
|
50
53
|
"code": 200,
|
|
@@ -51,6 +51,10 @@ class TestCloudCheck(ModuleTestBase):
|
|
|
51
51
|
await module.handle_event(event)
|
|
52
52
|
assert "cloud-amazon" in event.tags, f"{event} was not properly cloud-tagged"
|
|
53
53
|
|
|
54
|
+
assert "cloud-domain" in aws_event1.tags
|
|
55
|
+
assert "cloud-ip" in other_event2.tags
|
|
56
|
+
assert "cloud-cname" in other_event3.tags
|
|
57
|
+
|
|
54
58
|
for event in (aws_event3, other_event1):
|
|
55
59
|
await module.handle_event(event)
|
|
56
60
|
assert "cloud-amazon" not in event.tags, f"{event} was improperly cloud-tagged"
|
|
@@ -14,13 +14,14 @@ class TestCodeRepository(ModuleTestBase):
|
|
|
14
14
|
<a href="https://gitlab.com/blacklanternsecurity/bbot"/>
|
|
15
15
|
<a href="https://gitlab.org/blacklanternsecurity/bbot"/>
|
|
16
16
|
<a href="https://hub.docker.com/r/blacklanternsecurity/bbot"/>
|
|
17
|
+
<a href="https://www.postman.com/blacklanternsecurity/bbot"/>
|
|
17
18
|
</html>
|
|
18
19
|
"""
|
|
19
20
|
}
|
|
20
21
|
module_test.set_expect_requests(expect_args=expect_args, respond_args=respond_args)
|
|
21
22
|
|
|
22
23
|
def check(self, module_test, events):
|
|
23
|
-
assert
|
|
24
|
+
assert 5 == len([e for e in events if e.type == "CODE_REPOSITORY"])
|
|
24
25
|
assert 1 == len(
|
|
25
26
|
[
|
|
26
27
|
e
|
|
@@ -57,3 +58,12 @@ class TestCodeRepository(ModuleTestBase):
|
|
|
57
58
|
and e.data["url"] == "https://hub.docker.com/r/blacklanternsecurity/bbot"
|
|
58
59
|
]
|
|
59
60
|
)
|
|
61
|
+
assert 1 == len(
|
|
62
|
+
[
|
|
63
|
+
e
|
|
64
|
+
for e in events
|
|
65
|
+
if e.type == "CODE_REPOSITORY"
|
|
66
|
+
and "postman" in e.tags
|
|
67
|
+
and e.data["url"] == "https://www.postman.com/blacklanternsecurity/bbot"
|
|
68
|
+
]
|
|
69
|
+
)
|
|
@@ -4,7 +4,7 @@ from .base import ModuleTestBase
|
|
|
4
4
|
class TestColumbus(ModuleTestBase):
|
|
5
5
|
async def setup_after_prep(self, module_test):
|
|
6
6
|
module_test.httpx_mock.add_response(
|
|
7
|
-
url=
|
|
7
|
+
url="https://columbus.elmasy.com/api/lookup/blacklanternsecurity.com?days=365",
|
|
8
8
|
json=["asdf", "zzzz"],
|
|
9
9
|
)
|
|
10
10
|
|
|
@@ -58,18 +58,18 @@ class TestCredshed(ModuleTestBase):
|
|
|
58
58
|
|
|
59
59
|
async def setup_before_prep(self, module_test):
|
|
60
60
|
module_test.httpx_mock.add_response(
|
|
61
|
-
url=
|
|
61
|
+
url="https://credshed.com/api/auth",
|
|
62
62
|
json=credshed_auth_response,
|
|
63
63
|
method="POST",
|
|
64
64
|
)
|
|
65
65
|
module_test.httpx_mock.add_response(
|
|
66
|
-
url=
|
|
66
|
+
url="https://credshed.com/api/search",
|
|
67
67
|
json=credshed_response,
|
|
68
68
|
method="POST",
|
|
69
69
|
)
|
|
70
70
|
|
|
71
71
|
def check(self, module_test, events):
|
|
72
|
-
assert len(events) ==
|
|
72
|
+
assert len(events) == 11
|
|
73
73
|
assert 1 == len([e for e in events if e.type == "EMAIL_ADDRESS" and e.data == "bob@blacklanternsecurity.com"])
|
|
74
74
|
assert 1 == len([e for e in events if e.type == "EMAIL_ADDRESS" and e.data == "judy@blacklanternsecurity.com"])
|
|
75
75
|
assert 1 == len([e for e in events if e.type == "EMAIL_ADDRESS" and e.data == "tim@blacklanternsecurity.com"])
|
|
@@ -7,6 +7,7 @@ from .base import ModuleTestBase
|
|
|
7
7
|
class TestDastardly(ModuleTestBase):
|
|
8
8
|
targets = ["http://127.0.0.1:5556/"]
|
|
9
9
|
modules_overrides = ["httpx", "dastardly"]
|
|
10
|
+
skip_distro_tests = True
|
|
10
11
|
|
|
11
12
|
web_response = """<!DOCTYPE html>
|
|
12
13
|
<html>
|
|
@@ -44,7 +45,7 @@ class TestDastardly(ModuleTestBase):
|
|
|
44
45
|
|
|
45
46
|
# get docker IP
|
|
46
47
|
docker_ip = await self.get_docker_ip(module_test)
|
|
47
|
-
module_test.scan.target.add(docker_ip)
|
|
48
|
+
module_test.scan.target.seeds.add(docker_ip)
|
|
48
49
|
|
|
49
50
|
# replace 127.0.0.1 with docker host IP to allow dastardly access to local http server
|
|
50
51
|
old_filter_event = module_test.module.filter_event
|
|
@@ -45,7 +45,7 @@ class TestDehashed(ModuleTestBase):
|
|
|
45
45
|
|
|
46
46
|
async def setup_before_prep(self, module_test):
|
|
47
47
|
module_test.httpx_mock.add_response(
|
|
48
|
-
url=
|
|
48
|
+
url="https://api.dehashed.com/search?query=domain:blacklanternsecurity.com&size=10000&page=1",
|
|
49
49
|
json=dehashed_domain_response,
|
|
50
50
|
)
|
|
51
51
|
await module_test.mock_dns(
|
|
@@ -56,7 +56,7 @@ class TestDehashed(ModuleTestBase):
|
|
|
56
56
|
)
|
|
57
57
|
|
|
58
58
|
def check(self, module_test, events):
|
|
59
|
-
assert len(events) ==
|
|
59
|
+
assert len(events) == 12
|
|
60
60
|
assert 1 == len([e for e in events if e.type == "DNS_NAME" and e.data == "blacklanternsecurity.com"])
|
|
61
61
|
assert 1 == len([e for e in events if e.type == "ORG_STUB" and e.data == "blacklanternsecurity"])
|
|
62
62
|
assert 1 == len(
|
|
@@ -11,7 +11,7 @@ class TestDigitorus(ModuleTestBase):
|
|
|
11
11
|
|
|
12
12
|
async def setup_after_prep(self, module_test):
|
|
13
13
|
module_test.httpx_mock.add_response(
|
|
14
|
-
url=
|
|
14
|
+
url="https://certificatedetails.com/blacklanternsecurity.com",
|
|
15
15
|
text=self.web_response,
|
|
16
16
|
)
|
|
17
17
|
|
|
@@ -29,7 +29,7 @@ class TestDiscord(ModuleTestBase):
|
|
|
29
29
|
if module_test.request_count == 2:
|
|
30
30
|
return httpx.Response(status_code=429, json={"retry_after": 0.01})
|
|
31
31
|
else:
|
|
32
|
-
return httpx.Response(status_code=
|
|
32
|
+
return httpx.Response(status_code=200)
|
|
33
33
|
|
|
34
34
|
module_test.httpx_mock.add_callback(custom_response, url=self.webhook_url)
|
|
35
35
|
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
from .base import ModuleTestBase
|
|
2
|
+
|
|
3
|
+
raw_bimi_txt_default = (
|
|
4
|
+
'"v=BIMI1;l=https://bimi.test.localdomain/logo.svg; a=https://bimi.test.localdomain/certificate.pem"'
|
|
5
|
+
)
|
|
6
|
+
raw_bimi_txt_nondefault = '"v=BIMI1; l=https://nondefault.thirdparty.tld/brand/logo.svg;a=https://nondefault.thirdparty.tld/brand/certificate.pem;"'
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TestBIMI(ModuleTestBase):
|
|
10
|
+
targets = ["test.localdomain"]
|
|
11
|
+
modules_overrides = ["dnsbimi", "speculate"]
|
|
12
|
+
config_overrides = {
|
|
13
|
+
"modules": {"dnsbimi": {"emit_raw_dns_records": True, "selectors": "default,nondefault"}},
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async def setup_after_prep(self, module_test):
|
|
17
|
+
await module_test.mock_dns(
|
|
18
|
+
{
|
|
19
|
+
"test.localdomain": {
|
|
20
|
+
"A": ["127.0.0.11"],
|
|
21
|
+
},
|
|
22
|
+
"bimi.test.localdomain": {
|
|
23
|
+
"A": ["127.0.0.22"],
|
|
24
|
+
},
|
|
25
|
+
"_bimi.test.localdomain": {
|
|
26
|
+
"A": ["127.0.0.33"],
|
|
27
|
+
},
|
|
28
|
+
"default._bimi.test.localdomain": {
|
|
29
|
+
"A": ["127.0.0.44"],
|
|
30
|
+
"TXT": [raw_bimi_txt_default],
|
|
31
|
+
},
|
|
32
|
+
"nondefault._bimi.test.localdomain": {
|
|
33
|
+
"A": ["127.0.0.44"],
|
|
34
|
+
"TXT": [raw_bimi_txt_nondefault],
|
|
35
|
+
},
|
|
36
|
+
"_bimi.default._bimi.test.localdomain": {
|
|
37
|
+
"A": ["127.0.0.44"],
|
|
38
|
+
"TXT": [raw_bimi_txt_default],
|
|
39
|
+
},
|
|
40
|
+
"_bimi.nondefault._bimi.test.localdomain": {
|
|
41
|
+
"A": ["127.0.0.44"],
|
|
42
|
+
"TXT": [raw_bimi_txt_default],
|
|
43
|
+
},
|
|
44
|
+
"default._bimi.default._bimi.test.localdomain": {
|
|
45
|
+
"A": ["127.0.0.44"],
|
|
46
|
+
"TXT": [raw_bimi_txt_default],
|
|
47
|
+
},
|
|
48
|
+
"nondefault._bimi.nondefault._bimi.test.localdomain": {
|
|
49
|
+
"A": ["127.0.0.44"],
|
|
50
|
+
"TXT": [raw_bimi_txt_nondefault],
|
|
51
|
+
},
|
|
52
|
+
}
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
def check(self, module_test, events):
|
|
56
|
+
assert any(
|
|
57
|
+
e.type == "RAW_DNS_RECORD"
|
|
58
|
+
and e.data["host"] == "default._bimi.test.localdomain"
|
|
59
|
+
and e.data["type"] == "TXT"
|
|
60
|
+
and e.data["answer"] == raw_bimi_txt_default
|
|
61
|
+
for e in events
|
|
62
|
+
), "Failed to emit RAW_DNS_RECORD"
|
|
63
|
+
assert any(
|
|
64
|
+
e.type == "RAW_DNS_RECORD"
|
|
65
|
+
and e.data["host"] == "nondefault._bimi.test.localdomain"
|
|
66
|
+
and e.data["type"] == "TXT"
|
|
67
|
+
and e.data["answer"] == raw_bimi_txt_nondefault
|
|
68
|
+
for e in events
|
|
69
|
+
), "Failed to emit RAW_DNS_RECORD"
|
|
70
|
+
|
|
71
|
+
assert any(
|
|
72
|
+
e.type == "DNS_NAME" and e.data == "bimi.test.localdomain" for e in events
|
|
73
|
+
), "Failed to emit DNS_NAME"
|
|
74
|
+
|
|
75
|
+
# This should be filtered by a default BBOT configuration
|
|
76
|
+
assert not any(str(e.data) == "https://nondefault.thirdparty.tld/brand/logo.svg" for e in events)
|
|
77
|
+
|
|
78
|
+
# This should not be filtered by a default BBOT configuration
|
|
79
|
+
assert any(
|
|
80
|
+
e.type == "URL_UNVERIFIED" and e.data == "https://bimi.test.localdomain/certificate.pem" for e in events
|
|
81
|
+
), "Failed to emit URL_UNVERIFIED"
|
|
82
|
+
|
|
83
|
+
# These should be filtered simply due to distance
|
|
84
|
+
assert not any(str(e.data) == "https://nondefault.thirdparty.tld/brand/logo.svg" for e in events)
|
|
85
|
+
assert not any(str(e.data) == "https://nondefault.thirdparty.tld/certificate.pem" for e in events)
|
|
86
|
+
|
|
87
|
+
# These should have been filtered via filter_event()
|
|
88
|
+
assert not any(
|
|
89
|
+
e.type == "RAW_DNS_RECORD" and e.data["host"] == "default._bimi.default._bimi.test.localdomain"
|
|
90
|
+
for e in events
|
|
91
|
+
), "Unwanted recursion occurring"
|
|
92
|
+
assert not any(
|
|
93
|
+
e.type == "RAW_DNS_RECORD" and e.data["host"] == "nondefault._bimi.nondefault._bimi.test.localdomain"
|
|
94
|
+
for e in events
|
|
95
|
+
), "Unwanted recursion occurring"
|
|
96
|
+
assert not any(
|
|
97
|
+
e.type == "RAW_DNS_RECORD" and e.data["host"] == "nondefault._bimi.default._bimi.test.localdomain"
|
|
98
|
+
for e in events
|
|
99
|
+
), "Unwanted recursion occurring"
|
|
100
|
+
assert not any(
|
|
101
|
+
e.type == "RAW_DNS_RECORD" and e.data["host"] == "default._bimi.nondefault._bimi.test.localdomain"
|
|
102
|
+
for e in events
|
|
103
|
+
), "Unwanted recursion occurring"
|
|
@@ -7,7 +7,6 @@ class TestDnsbrute(ModuleTestBase):
|
|
|
7
7
|
config_overrides = {"modules": {"dnsbrute": {"wordlist": str(subdomain_wordlist), "max_depth": 3}}}
|
|
8
8
|
|
|
9
9
|
async def setup_after_prep(self, module_test):
|
|
10
|
-
|
|
11
10
|
old_run_live = module_test.scan.helpers.run_live
|
|
12
11
|
|
|
13
12
|
async def new_run_live(*command, check=False, text=True, **kwargs):
|
|
@@ -57,42 +56,42 @@ class TestDnsbrute(ModuleTestBase):
|
|
|
57
56
|
event = module_test.scan.make_event("blacklanternsecurity.com", "DNS_NAME", parent=module_test.scan.root_event)
|
|
58
57
|
event.scope_distance = 0
|
|
59
58
|
result, reason = await module_test.module.filter_event(event)
|
|
60
|
-
assert result
|
|
59
|
+
assert result is True
|
|
61
60
|
event = module_test.scan.make_event(
|
|
62
61
|
"www.blacklanternsecurity.com", "DNS_NAME", parent=module_test.scan.root_event
|
|
63
62
|
)
|
|
64
63
|
event.scope_distance = 0
|
|
65
64
|
result, reason = await module_test.module.filter_event(event)
|
|
66
|
-
assert result
|
|
65
|
+
assert result is True
|
|
67
66
|
event = module_test.scan.make_event(
|
|
68
67
|
"test.www.blacklanternsecurity.com", "DNS_NAME", parent=module_test.scan.root_event
|
|
69
68
|
)
|
|
70
69
|
event.scope_distance = 0
|
|
71
70
|
result, reason = await module_test.module.filter_event(event)
|
|
72
|
-
assert result
|
|
71
|
+
assert result is True
|
|
73
72
|
event = module_test.scan.make_event(
|
|
74
73
|
"asdf.test.www.blacklanternsecurity.com", "DNS_NAME", parent=module_test.scan.root_event
|
|
75
74
|
)
|
|
76
75
|
event.scope_distance = 0
|
|
77
76
|
result, reason = await module_test.module.filter_event(event)
|
|
78
|
-
assert result
|
|
77
|
+
assert result is True
|
|
79
78
|
event = module_test.scan.make_event(
|
|
80
79
|
"wat.asdf.test.www.blacklanternsecurity.com", "DNS_NAME", parent=module_test.scan.root_event
|
|
81
80
|
)
|
|
82
81
|
event.scope_distance = 0
|
|
83
82
|
result, reason = await module_test.module.filter_event(event)
|
|
84
|
-
assert result
|
|
85
|
-
assert reason ==
|
|
83
|
+
assert result is False
|
|
84
|
+
assert reason == "subdomain depth of *.asdf.test.www.blacklanternsecurity.com (4) > max_depth (3)"
|
|
86
85
|
event = module_test.scan.make_event(
|
|
87
86
|
"hmmm.ptr1234.blacklanternsecurity.com", "DNS_NAME", parent=module_test.scan.root_event
|
|
88
87
|
)
|
|
89
88
|
event.scope_distance = 0
|
|
90
89
|
result, reason = await module_test.module.filter_event(event)
|
|
91
|
-
assert result
|
|
92
|
-
assert reason ==
|
|
90
|
+
assert result is False
|
|
91
|
+
assert reason == '"ptr1234.blacklanternsecurity.com" looks like an autogenerated PTR'
|
|
93
92
|
|
|
94
93
|
def check(self, module_test, events):
|
|
95
|
-
assert len(events) ==
|
|
94
|
+
assert len(events) == 4
|
|
96
95
|
assert 1 == len(
|
|
97
96
|
[e for e in events if e.data == "asdf.blacklanternsecurity.com" and str(e.module) == "dnsbrute"]
|
|
98
97
|
)
|
|
@@ -11,7 +11,6 @@ class TestDnsbrute_mutations(ModuleTestBase):
|
|
|
11
11
|
]
|
|
12
12
|
|
|
13
13
|
async def setup_after_prep(self, module_test):
|
|
14
|
-
|
|
15
14
|
old_run_live = module_test.scan.helpers.run_live
|
|
16
15
|
|
|
17
16
|
async def new_run_live(*command, check=False, text=True, **kwargs):
|
|
@@ -47,7 +46,7 @@ class TestDnsbrute_mutations(ModuleTestBase):
|
|
|
47
46
|
)
|
|
48
47
|
|
|
49
48
|
def check(self, module_test, events):
|
|
50
|
-
assert len(events) ==
|
|
49
|
+
assert len(events) == 10
|
|
51
50
|
assert 1 == len(
|
|
52
51
|
[
|
|
53
52
|
e
|
|
@@ -8,7 +8,6 @@ class TestDNSCommonSRV(ModuleTestBase):
|
|
|
8
8
|
config_overrides = {"dns": {"minimal": False}}
|
|
9
9
|
|
|
10
10
|
async def setup_after_prep(self, module_test):
|
|
11
|
-
|
|
12
11
|
old_run_live = module_test.scan.helpers.run_live
|
|
13
12
|
|
|
14
13
|
async def new_run_live(*command, check=False, text=True, **kwargs):
|
|
@@ -56,7 +55,7 @@ class TestDNSCommonSRV(ModuleTestBase):
|
|
|
56
55
|
)
|
|
57
56
|
|
|
58
57
|
def check(self, module_test, events):
|
|
59
|
-
assert len(events) ==
|
|
58
|
+
assert len(events) == 20
|
|
60
59
|
assert 1 == len([e for e in events if e.type == "DNS_NAME" and e.data == "blacklanternsecurity.com"])
|
|
61
60
|
assert 1 == len(
|
|
62
61
|
[
|