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
|
@@ -10,9 +10,6 @@ from bbot.modules.internal.base import BaseInternalModule
|
|
|
10
10
|
|
|
11
11
|
@pytest.mark.asyncio
|
|
12
12
|
async def test_modules_basic_checks(events, httpx_mock):
|
|
13
|
-
for http_method in ("GET", "CONNECT", "HEAD", "POST", "PUT", "TRACE", "DEBUG", "PATCH", "DELETE", "OPTIONS"):
|
|
14
|
-
httpx_mock.add_response(method=http_method, url=re.compile(r".*"), json={"test": "test"})
|
|
15
|
-
|
|
16
13
|
from bbot.scanner import Scanner
|
|
17
14
|
|
|
18
15
|
scan = Scanner(config={"omit_event_types": ["URL_UNVERIFIED"]})
|
|
@@ -26,27 +23,27 @@ async def test_modules_basic_checks(events, httpx_mock):
|
|
|
26
23
|
localhost = scan.make_event("127.0.0.1", parent=scan.root_event)
|
|
27
24
|
# ip addresses should be accepted
|
|
28
25
|
result, reason = base_output_module_1._event_precheck(localhost)
|
|
29
|
-
assert result
|
|
26
|
+
assert result is True
|
|
30
27
|
assert reason == "precheck succeeded"
|
|
31
28
|
# internal events should be rejected
|
|
32
29
|
localhost._internal = True
|
|
33
30
|
result, reason = base_output_module_1._event_precheck(localhost)
|
|
34
|
-
assert result
|
|
31
|
+
assert result is False
|
|
35
32
|
assert reason == "_internal is True"
|
|
36
33
|
localhost._internal = False
|
|
37
34
|
result, reason = base_output_module_1._event_precheck(localhost)
|
|
38
|
-
assert result
|
|
35
|
+
assert result is True
|
|
39
36
|
assert reason == "precheck succeeded"
|
|
40
37
|
# unwatched events should be rejected
|
|
41
38
|
dns_name = scan.make_event("evilcorp.com", parent=scan.root_event)
|
|
42
39
|
result, reason = base_output_module_1._event_precheck(dns_name)
|
|
43
|
-
assert result
|
|
40
|
+
assert result is False
|
|
44
41
|
assert reason == "its type is not in watched_events"
|
|
45
42
|
# omitted events matching watched types should be accepted
|
|
46
43
|
url_unverified = scan.make_event("http://127.0.0.1", "URL_UNVERIFIED", parent=scan.root_event)
|
|
47
44
|
url_unverified._omit = True
|
|
48
45
|
result, reason = base_output_module_1._event_precheck(url_unverified)
|
|
49
|
-
assert result
|
|
46
|
+
assert result is True
|
|
50
47
|
assert reason == "its type is explicitly in watched_events"
|
|
51
48
|
|
|
52
49
|
base_output_module_2 = BaseOutputModule(scan)
|
|
@@ -54,42 +51,42 @@ async def test_modules_basic_checks(events, httpx_mock):
|
|
|
54
51
|
# normal events should be accepted
|
|
55
52
|
localhost = scan.make_event("127.0.0.1", parent=scan.root_event)
|
|
56
53
|
result, reason = base_output_module_2._event_precheck(localhost)
|
|
57
|
-
assert result
|
|
54
|
+
assert result is True
|
|
58
55
|
assert reason == "precheck succeeded"
|
|
59
56
|
# internal events should be rejected
|
|
60
57
|
localhost._internal = True
|
|
61
58
|
result, reason = base_output_module_2._event_precheck(localhost)
|
|
62
|
-
assert result
|
|
59
|
+
assert result is False
|
|
63
60
|
assert reason == "_internal is True"
|
|
64
61
|
localhost._internal = False
|
|
65
62
|
result, reason = base_output_module_2._event_precheck(localhost)
|
|
66
|
-
assert result
|
|
63
|
+
assert result is True
|
|
67
64
|
assert reason == "precheck succeeded"
|
|
68
65
|
# omitted events should be rejected
|
|
69
66
|
localhost._omit = True
|
|
70
67
|
result, reason = base_output_module_2._event_precheck(localhost)
|
|
71
|
-
assert result
|
|
68
|
+
assert result is False
|
|
72
69
|
assert reason == "_omit is True"
|
|
73
70
|
# normal event should be accepted
|
|
74
71
|
url_unverified = scan.make_event("http://127.0.0.1", "URL_UNVERIFIED", parent=scan.root_event)
|
|
75
72
|
result, reason = base_output_module_2._event_precheck(url_unverified)
|
|
76
|
-
assert result
|
|
73
|
+
assert result is True
|
|
77
74
|
assert reason == "precheck succeeded"
|
|
78
75
|
# omitted event types should be marked during scan egress
|
|
79
76
|
await scan.egress_module.handle_event(url_unverified)
|
|
80
77
|
result, reason = base_output_module_2._event_precheck(url_unverified)
|
|
81
|
-
assert result
|
|
78
|
+
assert result is False
|
|
82
79
|
assert reason == "_omit is True"
|
|
83
80
|
# omitted events that are targets should be accepted
|
|
84
81
|
dns_name = scan.make_event("evilcorp.com", "DNS_NAME", parent=scan.root_event)
|
|
85
82
|
dns_name._omit = True
|
|
86
83
|
result, reason = base_output_module_2._event_precheck(dns_name)
|
|
87
|
-
assert result
|
|
84
|
+
assert result is False
|
|
88
85
|
assert reason == "_omit is True"
|
|
89
86
|
# omitted results that are targets should be accepted
|
|
90
87
|
dns_name.add_tag("target")
|
|
91
88
|
result, reason = base_output_module_2._event_precheck(dns_name)
|
|
92
|
-
assert result
|
|
89
|
+
assert result is True
|
|
93
90
|
assert reason == "it's a target"
|
|
94
91
|
|
|
95
92
|
# common event filtering tests
|
|
@@ -100,18 +97,18 @@ async def test_modules_basic_checks(events, httpx_mock):
|
|
|
100
97
|
# base cases
|
|
101
98
|
base_module._watched_events = None
|
|
102
99
|
base_module.watched_events = ["*"]
|
|
103
|
-
assert base_module._event_precheck(events.emoji)[0]
|
|
100
|
+
assert base_module._event_precheck(events.emoji)[0] is True
|
|
104
101
|
base_module._watched_events = None
|
|
105
102
|
base_module.watched_events = ["IP_ADDRESS"]
|
|
106
|
-
assert base_module._event_precheck(events.ipv4)[0]
|
|
107
|
-
assert base_module._event_precheck(events.domain)[0]
|
|
108
|
-
assert base_module._event_precheck(events.localhost)[0]
|
|
109
|
-
assert base_module._event_precheck(localhost2)[0]
|
|
103
|
+
assert base_module._event_precheck(events.ipv4)[0] is True
|
|
104
|
+
assert base_module._event_precheck(events.domain)[0] is False
|
|
105
|
+
assert base_module._event_precheck(events.localhost)[0] is True
|
|
106
|
+
assert base_module._event_precheck(localhost2)[0] is True
|
|
110
107
|
# target only
|
|
111
108
|
base_module.target_only = True
|
|
112
|
-
assert base_module._event_precheck(localhost2)[0]
|
|
109
|
+
assert base_module._event_precheck(localhost2)[0] is False
|
|
113
110
|
localhost2.add_tag("target")
|
|
114
|
-
assert base_module._event_precheck(localhost2)[0]
|
|
111
|
+
assert base_module._event_precheck(localhost2)[0] is True
|
|
115
112
|
base_module.target_only = False
|
|
116
113
|
|
|
117
114
|
# in scope only
|
|
@@ -150,11 +147,11 @@ async def test_modules_basic_checks(events, httpx_mock):
|
|
|
150
147
|
for flag in flags:
|
|
151
148
|
all_flags.add(flag)
|
|
152
149
|
if preloaded["type"] == "scan":
|
|
153
|
-
assert ("active" in flags and
|
|
154
|
-
|
|
150
|
+
assert ("active" in flags and "passive" not in flags) or (
|
|
151
|
+
"active" not in flags and "passive" in flags
|
|
155
152
|
), f'module "{module_name}" must have either "active" or "passive" flag'
|
|
156
|
-
assert ("safe" in flags and
|
|
157
|
-
|
|
153
|
+
assert ("safe" in flags and "aggressive" not in flags) or (
|
|
154
|
+
"safe" not in flags and "aggressive" in flags
|
|
158
155
|
), f'module "{module_name}" must have either "safe" or "aggressive" flag'
|
|
159
156
|
assert not (
|
|
160
157
|
"web-basic" in flags and "web-thorough" in flags
|
|
@@ -177,15 +174,15 @@ async def test_modules_basic_checks(events, httpx_mock):
|
|
|
177
174
|
|
|
178
175
|
assert type(watched_events) == list
|
|
179
176
|
assert type(produced_events) == list
|
|
180
|
-
if
|
|
177
|
+
if preloaded.get("type", "") not in ("internal",):
|
|
181
178
|
assert watched_events, f"{module_name}.watched_events must not be empty"
|
|
182
179
|
assert type(watched_events) == list, f"{module_name}.watched_events must be of type list"
|
|
183
180
|
assert type(produced_events) == list, f"{module_name}.produced_events must be of type list"
|
|
184
181
|
assert all(
|
|
185
|
-
|
|
182
|
+
type(t) == str for t in watched_events
|
|
186
183
|
), f"{module_name}.watched_events entries must be of type string"
|
|
187
184
|
assert all(
|
|
188
|
-
|
|
185
|
+
type(t) == str for t in produced_events
|
|
189
186
|
), f"{module_name}.produced_events entries must be of type string"
|
|
190
187
|
|
|
191
188
|
assert type(preloaded.get("deps_pip", [])) == list, f"{module_name}.deps_pip must be of type list"
|
|
@@ -271,35 +268,35 @@ async def test_modules_basic_perhostonly(bbot_scanner):
|
|
|
271
268
|
valid_5, reason_5 = await module._event_postcheck(url_5)
|
|
272
269
|
|
|
273
270
|
if mod_name == "mod_normal":
|
|
274
|
-
assert valid_1
|
|
275
|
-
assert valid_2
|
|
276
|
-
assert valid_3
|
|
277
|
-
assert valid_4
|
|
278
|
-
assert valid_5
|
|
271
|
+
assert valid_1 is True
|
|
272
|
+
assert valid_2 is True
|
|
273
|
+
assert valid_3 is True
|
|
274
|
+
assert valid_4 is True
|
|
275
|
+
assert valid_5 is True
|
|
279
276
|
elif mod_name == "mod_host_only":
|
|
280
|
-
assert valid_1
|
|
281
|
-
assert valid_2
|
|
277
|
+
assert valid_1 is True
|
|
278
|
+
assert valid_2 is False
|
|
282
279
|
assert "per_host_only=True" in reason_2
|
|
283
|
-
assert valid_3
|
|
280
|
+
assert valid_3 is False
|
|
284
281
|
assert "per_host_only=True" in reason_3
|
|
285
|
-
assert valid_4
|
|
286
|
-
assert valid_5
|
|
282
|
+
assert valid_4 is True
|
|
283
|
+
assert valid_5 is True
|
|
287
284
|
elif mod_name == "mod_hostport_only":
|
|
288
|
-
assert valid_1
|
|
289
|
-
assert valid_2
|
|
285
|
+
assert valid_1 is True
|
|
286
|
+
assert valid_2 is False
|
|
290
287
|
assert "per_hostport_only=True" in reason_2
|
|
291
|
-
assert valid_3
|
|
292
|
-
assert valid_4
|
|
293
|
-
assert valid_5
|
|
288
|
+
assert valid_3 is True
|
|
289
|
+
assert valid_4 is True
|
|
290
|
+
assert valid_5 is True
|
|
294
291
|
elif mod_name == "mod_domain_only":
|
|
295
|
-
assert valid_1
|
|
296
|
-
assert valid_2
|
|
292
|
+
assert valid_1 is True
|
|
293
|
+
assert valid_2 is False
|
|
297
294
|
assert "per_domain_only=True" in reason_2
|
|
298
|
-
assert valid_3
|
|
295
|
+
assert valid_3 is False
|
|
299
296
|
assert "per_domain_only=True" in reason_3
|
|
300
|
-
assert valid_4
|
|
297
|
+
assert valid_4 is False
|
|
301
298
|
assert "per_domain_only=True" in reason_4
|
|
302
|
-
assert valid_5
|
|
299
|
+
assert valid_5 is True
|
|
303
300
|
|
|
304
301
|
await scan._cleanup()
|
|
305
302
|
|
|
@@ -334,15 +331,15 @@ async def test_modules_basic_perdomainonly(bbot_scanner, monkeypatch):
|
|
|
334
331
|
valid_1, reason_1 = await module._event_postcheck(url_1)
|
|
335
332
|
valid_2, reason_2 = await module._event_postcheck(url_2)
|
|
336
333
|
|
|
337
|
-
if module.per_domain_only
|
|
338
|
-
assert valid_1
|
|
339
|
-
assert valid_2
|
|
334
|
+
if module.per_domain_only is True:
|
|
335
|
+
assert valid_1 is True
|
|
336
|
+
assert valid_2 is False
|
|
340
337
|
assert hash("evilcorp.com") in module._per_host_tracker
|
|
341
338
|
assert reason_2 == "per_domain_only enabled and already seen domain"
|
|
342
339
|
|
|
343
340
|
else:
|
|
344
|
-
assert valid_1
|
|
345
|
-
assert valid_2
|
|
341
|
+
assert valid_1 is True
|
|
342
|
+
assert valid_2 is True
|
|
346
343
|
|
|
347
344
|
await per_domain_scan._cleanup()
|
|
348
345
|
|
|
@@ -380,26 +377,26 @@ async def test_modules_basic_stats(helpers, events, bbot_scanner, httpx_mock, mo
|
|
|
380
377
|
scan.modules["dummy"] = dummy(scan)
|
|
381
378
|
events = [e async for e in scan.async_start()]
|
|
382
379
|
|
|
383
|
-
assert len(events) ==
|
|
384
|
-
assert
|
|
385
|
-
assert
|
|
380
|
+
assert len(events) == 11
|
|
381
|
+
assert 2 == len([e for e in events if e.type == "SCAN"])
|
|
382
|
+
assert 4 == len([e for e in events if e.type == "DNS_NAME"])
|
|
386
383
|
# one from target and one from speculate
|
|
387
384
|
assert 2 == len([e for e in events if e.type == "DNS_NAME" and e.data == "evilcorp.com"])
|
|
388
|
-
|
|
389
|
-
assert 0 == len([e for e in events if e.type == "DNS_NAME" and e.data == "www.evilcorp.com"])
|
|
385
|
+
assert 1 == len([e for e in events if e.type == "DNS_NAME" and e.data == "www.evilcorp.com"])
|
|
390
386
|
assert 1 == len([e for e in events if e.type == "DNS_NAME" and e.data == "asdf.evilcorp.com"])
|
|
387
|
+
assert 1 == len([e for e in events if e.type == "OPEN_TCP_PORT" and e.data == "asdf.evilcorp.com:443"])
|
|
391
388
|
assert 1 == len([e for e in events if e.type == "ORG_STUB" and e.data == "evilcorp"])
|
|
392
389
|
assert 1 == len([e for e in events if e.type == "FINDING"])
|
|
393
390
|
assert 1 == len([e for e in events if e.type == "URL_UNVERIFIED"])
|
|
394
391
|
|
|
395
392
|
assert scan.stats.events_emitted_by_type == {
|
|
396
393
|
"SCAN": 1,
|
|
397
|
-
"DNS_NAME":
|
|
394
|
+
"DNS_NAME": 4,
|
|
398
395
|
"URL": 1,
|
|
396
|
+
"OPEN_TCP_PORT": 1,
|
|
399
397
|
"ORG_STUB": 1,
|
|
400
398
|
"URL_UNVERIFIED": 1,
|
|
401
399
|
"FINDING": 1,
|
|
402
|
-
"ORG_STUB": 1,
|
|
403
400
|
}
|
|
404
401
|
|
|
405
402
|
assert set(scan.stats.module_stats) == {"speculate", "host", "TARGET", "python", "dummy", "dnsresolve"}
|
|
@@ -414,7 +411,7 @@ async def test_modules_basic_stats(helpers, events, bbot_scanner, httpx_mock, mo
|
|
|
414
411
|
assert dummy_stats.produced == {"FINDING": 1, "URL": 1}
|
|
415
412
|
assert dummy_stats.produced_total == 2
|
|
416
413
|
assert dummy_stats.consumed == {
|
|
417
|
-
"DNS_NAME":
|
|
414
|
+
"DNS_NAME": 3,
|
|
418
415
|
"FINDING": 1,
|
|
419
416
|
"OPEN_TCP_PORT": 1,
|
|
420
417
|
"ORG_STUB": 1,
|
|
@@ -422,26 +419,27 @@ async def test_modules_basic_stats(helpers, events, bbot_scanner, httpx_mock, mo
|
|
|
422
419
|
"URL": 1,
|
|
423
420
|
"URL_UNVERIFIED": 1,
|
|
424
421
|
}
|
|
425
|
-
assert dummy_stats.consumed_total ==
|
|
422
|
+
assert dummy_stats.consumed_total == 9
|
|
426
423
|
|
|
427
424
|
python_stats = scan.stats.module_stats["python"]
|
|
428
425
|
assert python_stats.produced == {}
|
|
429
426
|
assert python_stats.produced_total == 0
|
|
430
427
|
assert python_stats.consumed == {
|
|
431
|
-
"DNS_NAME":
|
|
428
|
+
"DNS_NAME": 4,
|
|
432
429
|
"FINDING": 1,
|
|
430
|
+
"OPEN_TCP_PORT": 1,
|
|
433
431
|
"ORG_STUB": 1,
|
|
434
432
|
"SCAN": 1,
|
|
435
433
|
"URL": 1,
|
|
436
434
|
"URL_UNVERIFIED": 1,
|
|
437
435
|
}
|
|
438
|
-
assert python_stats.consumed_total ==
|
|
436
|
+
assert python_stats.consumed_total == 10
|
|
439
437
|
|
|
440
438
|
speculate_stats = scan.stats.module_stats["speculate"]
|
|
441
|
-
assert speculate_stats.produced == {"DNS_NAME": 1, "URL_UNVERIFIED": 1, "ORG_STUB": 1}
|
|
442
|
-
assert speculate_stats.produced_total ==
|
|
443
|
-
assert speculate_stats.consumed == {"URL": 1, "DNS_NAME":
|
|
444
|
-
assert speculate_stats.consumed_total ==
|
|
439
|
+
assert speculate_stats.produced == {"DNS_NAME": 1, "URL_UNVERIFIED": 1, "ORG_STUB": 1, "OPEN_TCP_PORT": 1}
|
|
440
|
+
assert speculate_stats.produced_total == 4
|
|
441
|
+
assert speculate_stats.consumed == {"URL": 1, "DNS_NAME": 3, "URL_UNVERIFIED": 1, "IP_ADDRESS": 3}
|
|
442
|
+
assert speculate_stats.consumed_total == 8
|
|
445
443
|
|
|
446
444
|
|
|
447
445
|
@pytest.mark.asyncio
|