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
|
@@ -23,7 +23,7 @@ async def test_dns_engine(bbot_scanner):
|
|
|
23
23
|
)
|
|
24
24
|
result = await scan.helpers.resolve("one.one.one.one")
|
|
25
25
|
assert "1.1.1.1" in result
|
|
26
|
-
assert
|
|
26
|
+
assert "2606:4700:4700::1111" not in result
|
|
27
27
|
|
|
28
28
|
results = [_ async for _ in scan.helpers.resolve_batch(("one.one.one.one", "1.1.1.1"))]
|
|
29
29
|
pass_1 = False
|
|
@@ -85,12 +85,12 @@ async def test_dns_resolution(bbot_scanner):
|
|
|
85
85
|
for answer in answers:
|
|
86
86
|
responses += list(extract_targets(answer))
|
|
87
87
|
assert ("A", "1.1.1.1") in responses
|
|
88
|
-
assert
|
|
88
|
+
assert ("AAAA", "2606:4700:4700::1111") not in responses
|
|
89
89
|
answers, errors = await dnsengine.resolve_raw("one.one.one.one", type="AAAA")
|
|
90
90
|
responses = []
|
|
91
91
|
for answer in answers:
|
|
92
92
|
responses += list(extract_targets(answer))
|
|
93
|
-
assert
|
|
93
|
+
assert ("A", "1.1.1.1") not in responses
|
|
94
94
|
assert ("AAAA", "2606:4700:4700::1111") in responses
|
|
95
95
|
answers, errors = await dnsengine.resolve_raw("1.1.1.1")
|
|
96
96
|
responses = []
|
|
@@ -106,13 +106,14 @@ async def test_dns_resolution(bbot_scanner):
|
|
|
106
106
|
assert "2606:4700:4700::1111" in await dnsengine.resolve("one.one.one.one", type="AAAA")
|
|
107
107
|
assert "one.one.one.one" in await dnsengine.resolve("1.1.1.1")
|
|
108
108
|
for rdtype in ("NS", "SOA", "MX", "TXT"):
|
|
109
|
-
|
|
109
|
+
results = await dnsengine.resolve("google.com", type=rdtype)
|
|
110
|
+
assert len(results) > 0
|
|
110
111
|
|
|
111
112
|
# batch resolution
|
|
112
113
|
batch_results = [r async for r in dnsengine.resolve_batch(["1.1.1.1", "one.one.one.one"])]
|
|
113
114
|
assert len(batch_results) == 2
|
|
114
115
|
batch_results = dict(batch_results)
|
|
115
|
-
assert any(
|
|
116
|
+
assert any(x in batch_results["one.one.one.one"] for x in ("1.1.1.1", "1.0.0.1"))
|
|
116
117
|
assert "one.one.one.one" in batch_results["1.1.1.1"]
|
|
117
118
|
|
|
118
119
|
# custom batch resolution
|
|
@@ -140,11 +141,11 @@ async def test_dns_resolution(bbot_scanner):
|
|
|
140
141
|
assert hash(("1.1.1.1", "PTR")) in dnsengine._dns_cache
|
|
141
142
|
await dnsengine.resolve("one.one.one.one", type="A")
|
|
142
143
|
assert hash(("one.one.one.one", "A")) in dnsengine._dns_cache
|
|
143
|
-
assert
|
|
144
|
+
assert hash(("one.one.one.one", "AAAA")) not in dnsengine._dns_cache
|
|
144
145
|
dnsengine._dns_cache.clear()
|
|
145
146
|
await dnsengine.resolve("one.one.one.one", type="AAAA")
|
|
146
147
|
assert hash(("one.one.one.one", "AAAA")) in dnsengine._dns_cache
|
|
147
|
-
assert
|
|
148
|
+
assert hash(("one.one.one.one", "A")) not in dnsengine._dns_cache
|
|
148
149
|
|
|
149
150
|
await dnsengine._shutdown()
|
|
150
151
|
|
|
@@ -164,7 +165,7 @@ async def test_dns_resolution(bbot_scanner):
|
|
|
164
165
|
assert "A" in resolved_hosts_event1.raw_dns_records
|
|
165
166
|
assert "AAAA" in resolved_hosts_event1.raw_dns_records
|
|
166
167
|
assert "a-record" in resolved_hosts_event1.tags
|
|
167
|
-
assert
|
|
168
|
+
assert "a-record" not in resolved_hosts_event2.tags
|
|
168
169
|
|
|
169
170
|
scan2 = bbot_scanner("evilcorp.com", config={"dns": {"minimal": False}})
|
|
170
171
|
await scan2.helpers.dns._mock_dns(
|
|
@@ -184,7 +185,6 @@ async def test_dns_resolution(bbot_scanner):
|
|
|
184
185
|
|
|
185
186
|
@pytest.mark.asyncio
|
|
186
187
|
async def test_wildcards(bbot_scanner):
|
|
187
|
-
|
|
188
188
|
scan = bbot_scanner("1.1.1.1")
|
|
189
189
|
helpers = scan.helpers
|
|
190
190
|
|
|
@@ -197,7 +197,7 @@ async def test_wildcards(bbot_scanner):
|
|
|
197
197
|
assert len(dnsengine._wildcard_cache) == len(all_rdtypes) + (len(all_rdtypes) - 2)
|
|
198
198
|
for rdtype in all_rdtypes:
|
|
199
199
|
assert hash(("github.io", rdtype)) in dnsengine._wildcard_cache
|
|
200
|
-
if not
|
|
200
|
+
if rdtype not in ("A", "AAAA"):
|
|
201
201
|
assert hash(("asdf.github.io", rdtype)) in dnsengine._wildcard_cache
|
|
202
202
|
assert "github.io" in wildcard_domains
|
|
203
203
|
assert "A" in wildcard_domains["github.io"]
|
|
@@ -263,7 +263,7 @@ def custom_lookup(query, rdtype):
|
|
|
263
263
|
await scan.helpers.dns._mock_dns(mock_data, custom_lookup_fn=custom_lookup)
|
|
264
264
|
|
|
265
265
|
events = [e async for e in scan.async_start()]
|
|
266
|
-
assert len(events) ==
|
|
266
|
+
assert len(events) == 12
|
|
267
267
|
assert len([e for e in events if e.type == "DNS_NAME"]) == 5
|
|
268
268
|
assert len([e for e in events if e.type == "RAW_DNS_RECORD"]) == 4
|
|
269
269
|
assert sorted([e.data for e in events if e.type == "DNS_NAME"]) == [
|
|
@@ -320,7 +320,7 @@ def custom_lookup(query, rdtype):
|
|
|
320
320
|
await scan.helpers.dns._mock_dns(mock_data, custom_lookup_fn=custom_lookup)
|
|
321
321
|
|
|
322
322
|
events = [e async for e in scan.async_start()]
|
|
323
|
-
assert len(events) ==
|
|
323
|
+
assert len(events) == 12
|
|
324
324
|
assert len([e for e in events if e.type == "DNS_NAME"]) == 5
|
|
325
325
|
assert len([e for e in events if e.type == "RAW_DNS_RECORD"]) == 4
|
|
326
326
|
assert sorted([e.data for e in events if e.type == "DNS_NAME"]) == [
|
|
@@ -418,7 +418,7 @@ def custom_lookup(query, rdtype):
|
|
|
418
418
|
|
|
419
419
|
events = [e async for e in scan.async_start()]
|
|
420
420
|
|
|
421
|
-
assert len(events) ==
|
|
421
|
+
assert len(events) == 11
|
|
422
422
|
assert len([e for e in events if e.type == "DNS_NAME"]) == 5
|
|
423
423
|
assert len([e for e in events if e.type == "RAW_DNS_RECORD"]) == 4
|
|
424
424
|
assert sorted([e.data for e in events if e.type == "DNS_NAME"]) == [
|
|
@@ -546,8 +546,8 @@ def custom_lookup(query, rdtype):
|
|
|
546
546
|
)
|
|
547
547
|
await scan2.ingress_module.queue_event(other_event, {})
|
|
548
548
|
events = [e async for e in scan2.async_start()]
|
|
549
|
-
assert len(events) ==
|
|
550
|
-
assert
|
|
549
|
+
assert len(events) == 4
|
|
550
|
+
assert 2 == len([e for e in events if e.type == "SCAN"])
|
|
551
551
|
unmodified_wildcard_events = [
|
|
552
552
|
e for e in events if e.type == "DNS_NAME" and e.data == "asdfl.gashdgkjsadgsdf.github.io"
|
|
553
553
|
]
|
|
@@ -592,8 +592,8 @@ def custom_lookup(query, rdtype):
|
|
|
592
592
|
)
|
|
593
593
|
await scan2.ingress_module.queue_event(other_event, {})
|
|
594
594
|
events = [e async for e in scan2.async_start()]
|
|
595
|
-
assert len(events) ==
|
|
596
|
-
assert
|
|
595
|
+
assert len(events) == 4
|
|
596
|
+
assert 2 == len([e for e in events if e.type == "SCAN"])
|
|
597
597
|
unmodified_wildcard_events = [e for e in events if e.type == "DNS_NAME" and "_wildcard" not in e.data]
|
|
598
598
|
assert len(unmodified_wildcard_events) == 2
|
|
599
599
|
assert 1 == len(
|
|
@@ -632,8 +632,42 @@ def custom_lookup(query, rdtype):
|
|
|
632
632
|
|
|
633
633
|
|
|
634
634
|
@pytest.mark.asyncio
|
|
635
|
-
async def
|
|
635
|
+
async def test_wildcard_deduplication(bbot_scanner):
|
|
636
|
+
custom_lookup = """
|
|
637
|
+
def custom_lookup(query, rdtype):
|
|
638
|
+
if rdtype == "TXT" and query.strip(".").endswith("evilcorp.com"):
|
|
639
|
+
return {""}
|
|
640
|
+
"""
|
|
641
|
+
|
|
642
|
+
mock_data = {
|
|
643
|
+
"evilcorp.com": {"A": ["127.0.0.1"]},
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
from bbot.modules.base import BaseModule
|
|
647
|
+
|
|
648
|
+
class DummyModule(BaseModule):
|
|
649
|
+
watched_events = ["DNS_NAME"]
|
|
650
|
+
per_domain_only = True
|
|
651
|
+
|
|
652
|
+
async def handle_event(self, event):
|
|
653
|
+
for i in range(30):
|
|
654
|
+
await self.emit_event(f"www{i}.evilcorp.com", "DNS_NAME", parent=event)
|
|
655
|
+
|
|
656
|
+
# scan without omitted event type
|
|
657
|
+
scan = bbot_scanner(
|
|
658
|
+
"evilcorp.com", config={"dns": {"minimal": False, "wildcard_ignore": []}, "omit_event_types": []}
|
|
659
|
+
)
|
|
660
|
+
await scan.helpers.dns._mock_dns(mock_data, custom_lookup_fn=custom_lookup)
|
|
661
|
+
dummy_module = DummyModule(scan)
|
|
662
|
+
scan.modules["dummy_module"] = dummy_module
|
|
663
|
+
events = [e async for e in scan.async_start()]
|
|
664
|
+
dns_name_events = [e for e in events if e.type == "DNS_NAME"]
|
|
665
|
+
assert len(dns_name_events) == 2
|
|
666
|
+
assert 1 == len([e for e in dns_name_events if e.data == "_wildcard.evilcorp.com"])
|
|
667
|
+
|
|
636
668
|
|
|
669
|
+
@pytest.mark.asyncio
|
|
670
|
+
async def test_dns_raw_records(bbot_scanner):
|
|
637
671
|
from bbot.modules.base import BaseModule
|
|
638
672
|
|
|
639
673
|
class DummyModule(BaseModule):
|
|
@@ -696,7 +730,7 @@ async def test_dns_raw_records(bbot_scanner):
|
|
|
696
730
|
dummy_module = DummyModule(scan)
|
|
697
731
|
scan.modules["dummy_module"] = dummy_module
|
|
698
732
|
events = [e async for e in scan.async_start()]
|
|
699
|
-
# no raw records should be
|
|
733
|
+
# no raw records should be output
|
|
700
734
|
assert 0 == len([e for e in events if e.type == "RAW_DNS_RECORD"])
|
|
701
735
|
# but they should still make it to the module
|
|
702
736
|
assert 1 == len(
|
|
@@ -729,7 +763,7 @@ async def test_dns_graph_structure(bbot_scanner):
|
|
|
729
763
|
}
|
|
730
764
|
)
|
|
731
765
|
events = [e async for e in scan.async_start()]
|
|
732
|
-
assert len(events) ==
|
|
766
|
+
assert len(events) == 6
|
|
733
767
|
non_scan_events = [e for e in events if e.type != "SCAN"]
|
|
734
768
|
assert sorted([e.type for e in non_scan_events]) == ["DNS_NAME", "DNS_NAME", "DNS_NAME", "URL_UNVERIFIED"]
|
|
735
769
|
events_by_data = {e.data: e for e in non_scan_events}
|
|
@@ -744,16 +778,16 @@ async def test_dns_graph_structure(bbot_scanner):
|
|
|
744
778
|
|
|
745
779
|
@pytest.mark.asyncio
|
|
746
780
|
async def test_dns_helpers(bbot_scanner):
|
|
747
|
-
assert service_record("")
|
|
748
|
-
assert service_record("localhost")
|
|
749
|
-
assert service_record("www.example.com")
|
|
750
|
-
assert service_record("www.example.com", "SRV")
|
|
751
|
-
assert service_record("_custom._service.example.com", "SRV")
|
|
752
|
-
assert service_record("_custom._service.example.com", "A")
|
|
781
|
+
assert service_record("") is False
|
|
782
|
+
assert service_record("localhost") is False
|
|
783
|
+
assert service_record("www.example.com") is False
|
|
784
|
+
assert service_record("www.example.com", "SRV") is True
|
|
785
|
+
assert service_record("_custom._service.example.com", "SRV") is True
|
|
786
|
+
assert service_record("_custom._service.example.com", "A") is False
|
|
753
787
|
# top 100 most common SRV records
|
|
754
788
|
for srv_record in common_srvs[:100]:
|
|
755
789
|
hostname = f"{srv_record}.example.com"
|
|
756
|
-
assert service_record(hostname)
|
|
790
|
+
assert service_record(hostname) is True
|
|
757
791
|
|
|
758
792
|
# make sure system nameservers are excluded from use by DNS brute force
|
|
759
793
|
brute_nameservers = tempwordlist(["1.2.3.4", "8.8.4.4", "4.3.2.1", "8.8.8.8"])
|
|
@@ -14,7 +14,6 @@ async def test_engine():
|
|
|
14
14
|
return_errored = False
|
|
15
15
|
|
|
16
16
|
class TestEngineServer(EngineServer):
|
|
17
|
-
|
|
18
17
|
CMDS = {
|
|
19
18
|
0: "return_thing",
|
|
20
19
|
1: "yield_stuff",
|
|
@@ -54,7 +53,6 @@ async def test_engine():
|
|
|
54
53
|
raise
|
|
55
54
|
|
|
56
55
|
class TestEngineClient(EngineClient):
|
|
57
|
-
|
|
58
56
|
SERVER_CLASS = TestEngineServer
|
|
59
57
|
|
|
60
58
|
async def return_thing(self, n):
|
|
@@ -72,7 +70,7 @@ async def test_engine():
|
|
|
72
70
|
|
|
73
71
|
# test async generator
|
|
74
72
|
assert counter == 0
|
|
75
|
-
assert yield_cancelled
|
|
73
|
+
assert yield_cancelled is False
|
|
76
74
|
yield_res = [r async for r in test_engine.yield_stuff(13)]
|
|
77
75
|
assert yield_res == [f"thing{i}" for i in range(13)]
|
|
78
76
|
assert len(yield_res) == 13
|
|
@@ -88,8 +86,8 @@ async def test_engine():
|
|
|
88
86
|
await agen.aclose()
|
|
89
87
|
break
|
|
90
88
|
await asyncio.sleep(5)
|
|
91
|
-
assert yield_cancelled
|
|
92
|
-
assert yield_errored
|
|
89
|
+
assert yield_cancelled is True
|
|
90
|
+
assert yield_errored is False
|
|
93
91
|
assert counter < 15
|
|
94
92
|
|
|
95
93
|
# test async generator with error
|
|
@@ -99,8 +97,8 @@ async def test_engine():
|
|
|
99
97
|
with pytest.raises(BBOTEngineError):
|
|
100
98
|
async for _ in agen:
|
|
101
99
|
pass
|
|
102
|
-
assert yield_cancelled
|
|
103
|
-
assert yield_errored
|
|
100
|
+
assert yield_cancelled is False
|
|
101
|
+
assert yield_errored is True
|
|
104
102
|
|
|
105
103
|
# test return with cancellation
|
|
106
104
|
return_started = False
|
|
@@ -113,10 +111,10 @@ async def test_engine():
|
|
|
113
111
|
with pytest.raises(asyncio.CancelledError):
|
|
114
112
|
await task
|
|
115
113
|
await asyncio.sleep(0.1)
|
|
116
|
-
assert return_started
|
|
117
|
-
assert return_finished
|
|
118
|
-
assert return_cancelled
|
|
119
|
-
assert return_errored
|
|
114
|
+
assert return_started is True
|
|
115
|
+
assert return_finished is False
|
|
116
|
+
assert return_cancelled is True
|
|
117
|
+
assert return_errored is False
|
|
120
118
|
|
|
121
119
|
# test return with late cancellation
|
|
122
120
|
return_started = False
|
|
@@ -128,10 +126,10 @@ async def test_engine():
|
|
|
128
126
|
task.cancel()
|
|
129
127
|
result = await task
|
|
130
128
|
assert result == "thing1"
|
|
131
|
-
assert return_started
|
|
132
|
-
assert return_finished
|
|
133
|
-
assert return_cancelled
|
|
134
|
-
assert return_errored
|
|
129
|
+
assert return_started is True
|
|
130
|
+
assert return_finished is True
|
|
131
|
+
assert return_cancelled is False
|
|
132
|
+
assert return_errored is False
|
|
135
133
|
|
|
136
134
|
# test return with error
|
|
137
135
|
return_started = False
|
|
@@ -140,9 +138,9 @@ async def test_engine():
|
|
|
140
138
|
return_errored = False
|
|
141
139
|
with pytest.raises(BBOTEngineError):
|
|
142
140
|
result = await test_engine.return_thing(None)
|
|
143
|
-
assert return_started
|
|
144
|
-
assert return_finished
|
|
145
|
-
assert return_cancelled
|
|
146
|
-
assert return_errored
|
|
141
|
+
assert return_started is True
|
|
142
|
+
assert return_finished is False
|
|
143
|
+
assert return_cancelled is False
|
|
144
|
+
assert return_errored is True
|
|
147
145
|
|
|
148
146
|
await test_engine.shutdown()
|