bbot 2.2.0.5242rc0__tar.gz → 2.2.0.5279rc0__tar.gz
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-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/PKG-INFO +1 -1
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/__init__.py +1 -1
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/config/logger.py +6 -3
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/core.py +20 -3
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/engine.py +3 -3
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/event/base.py +16 -12
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/helpers/command.py +4 -3
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/helpers/depsinstaller/installer.py +13 -5
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/helpers/misc.py +18 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/helpers/process.py +0 -18
- bbot-2.2.0.5279rc0/bbot/core/multiprocess.py +58 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/defaults.yml +3 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/censys.py +9 -13
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/internal/dnsresolve.py +12 -1
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/internal/speculate.py +33 -23
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/leakix.py +2 -3
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/passivetotal.py +9 -11
- bbot-2.2.0.5279rc0/bbot/presets/fast.yml +16 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/scanner/preset/args.py +17 -1
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/scanner/preset/preset.py +8 -8
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/scanner/scanner.py +4 -1
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/bbot_fixtures.py +5 -2
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/conftest.py +95 -84
- bbot-2.2.0.5279rc0/bbot/test/fastapi_test.py +17 -0
- bbot-2.2.0.5279rc0/bbot/test/test_step_1/test_bbot_fastapi.py +82 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_1/test_cli.py +29 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_1/test_dns.py +36 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_1/test_events.py +32 -1
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_1/test_modules_basic.py +0 -3
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_1/test_presets.py +1 -2
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_1/test_web.py +3 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_censys.py +4 -1
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_dotnetnuke.py +0 -6
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_leakix.py +5 -1
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_passivetotal.py +3 -1
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/pyproject.toml +4 -2
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/LICENSE +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/README.md +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/cli.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/__init__.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/config/__init__.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/config/files.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/event/__init__.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/event/helpers.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/flags.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/helpers/__init__.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/helpers/async_helpers.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/helpers/bloom.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/helpers/cache.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/helpers/depsinstaller/__init__.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/helpers/depsinstaller/sudo_askpass.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/helpers/diff.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/helpers/dns/__init__.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/helpers/dns/brute.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/helpers/dns/dns.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/helpers/dns/engine.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/helpers/dns/helpers.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/helpers/dns/mock.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/helpers/files.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/helpers/helper.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/helpers/interactsh.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/helpers/libmagic.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/helpers/names_generator.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/helpers/ntlm.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/helpers/ratelimiter.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/helpers/regex.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/helpers/regexes.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/helpers/url.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/helpers/validators.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/helpers/web/__init__.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/helpers/web/client.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/helpers/web/engine.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/helpers/web/ssl_context.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/helpers/web/web.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/helpers/wordcloud.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/modules.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/core/shared_deps.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/db/sql/models.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/errors.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/logger.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/__init__.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/ajaxpro.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/anubisdb.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/apkpure.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/azure_realm.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/azure_tenant.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/baddns.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/baddns_direct.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/baddns_zone.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/badsecrets.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/base.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/bevigil.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/binaryedge.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/bucket_amazon.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/bucket_azure.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/bucket_digitalocean.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/bucket_file_enum.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/bucket_firebase.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/bucket_google.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/bufferoverrun.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/builtwith.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/bypass403.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/c99.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/certspotter.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/chaos.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/code_repository.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/columbus.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/credshed.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/crt.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/deadly/dastardly.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/deadly/ffuf.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/deadly/nuclei.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/deadly/vhost.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/dehashed.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/digitorus.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/dnsbimi.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/dnsbrute.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/dnsbrute_mutations.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/dnscaa.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/dnscommonsrv.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/dnsdumpster.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/docker_pull.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/dockerhub.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/dotnetnuke.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/emailformat.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/extractous.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/ffuf_shortnames.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/filedownload.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/fingerprintx.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/fullhunt.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/generic_ssrf.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/git.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/git_clone.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/github_codesearch.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/github_org.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/github_workflows.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/gitlab.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/google_playstore.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/gowitness.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/hackertarget.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/host_header.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/httpx.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/hunt.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/hunterio.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/iis_shortnames.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/internal/__init__.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/internal/aggregate.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/internal/base.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/internal/cloudcheck.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/internal/excavate.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/internetdb.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/ip2location.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/ipneighbor.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/ipstack.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/jadx.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/myssl.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/newsletters.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/ntlm.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/oauth.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/otx.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/output/__init__.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/output/asset_inventory.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/output/base.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/output/csv.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/output/discord.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/output/emails.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/output/http.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/output/json.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/output/neo4j.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/output/python.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/output/slack.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/output/splunk.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/output/sqlite.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/output/stdout.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/output/subdomains.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/output/teams.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/output/txt.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/output/web_report.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/output/websocket.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/paramminer_cookies.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/paramminer_getparams.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/paramminer_headers.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/pgp.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/portscan.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/postman.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/postman_download.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/rapiddns.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/report/affiliates.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/report/asn.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/report/base.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/robots.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/secretsdb.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/securitytrails.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/securitytxt.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/shodan_dns.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/sitedossier.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/skymem.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/smuggler.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/social.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/sslcert.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/subdomaincenter.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/subdomainradar.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/telerik.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/templates/bucket.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/templates/github.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/templates/postman.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/templates/shodan.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/templates/sql.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/templates/subdomain_enum.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/templates/webhook.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/trickest.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/trufflehog.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/url_manipulation.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/urlscan.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/viewdns.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/virustotal.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/wafw00f.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/wappalyzer.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/wayback.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/wpscan.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/modules/zoomeye.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/presets/baddns-thorough.yml +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/presets/cloud-enum.yml +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/presets/code-enum.yml +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/presets/email-enum.yml +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/presets/kitchen-sink.yml +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/presets/spider.yml +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/presets/subdomain-enum.yml +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/presets/web/dirbust-heavy.yml +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/presets/web/dirbust-light.yml +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/presets/web/dotnet-audit.yml +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/presets/web/iis-shortnames.yml +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/presets/web/paramminer.yml +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/presets/web-basic.yml +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/presets/web-screenshots.yml +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/presets/web-thorough.yml +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/scanner/__init__.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/scanner/dispatcher.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/scanner/manager.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/scanner/preset/__init__.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/scanner/preset/conditions.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/scanner/preset/environ.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/scanner/preset/path.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/scanner/stats.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/scanner/target.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/scripts/docs.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/__init__.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/coverage.cfg +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/owasp_mastg.apk +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/run_tests.sh +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test.conf +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_output.ndjson +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_1/__init__.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_1/test__module__tests.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_1/test_bloom_filter.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_1/test_command.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_1/test_config.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_1/test_depsinstaller.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_1/test_docs.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_1/test_engine.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_1/test_files.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_1/test_helpers.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_1/test_manager_deduplication.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_1/test_manager_scope_accuracy.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_1/test_python_api.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_1/test_regexes.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_1/test_scan.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_1/test_scope.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_1/test_target.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/__init__.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/__init__.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/base.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_affiliates.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_aggregate.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_ajaxpro.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_anubisdb.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_apkpure.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_asn.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_asset_inventory.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_azure_realm.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_azure_tenant.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_baddns.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_baddns_direct.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_baddns_zone.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_badsecrets.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_bevigil.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_binaryedge.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_bucket_amazon.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_bucket_azure.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_bucket_digitalocean.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_bucket_file_enum.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_bucket_firebase.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_bucket_google.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_bufferoverrun.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_builtwith.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_bypass403.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_c99.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_certspotter.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_chaos.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_cloudcheck.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_code_repository.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_columbus.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_credshed.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_crt.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_csv.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_dastardly.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_dehashed.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_digitorus.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_discord.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_dnsbimi.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_dnsbrute.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_dnsbrute_mutations.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_dnscaa.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_dnscommonsrv.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_dnsdumpster.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_dnsresolve.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_docker_pull.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_dockerhub.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_emailformat.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_emails.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_excavate.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_extractous.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_ffuf.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_ffuf_shortnames.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_filedownload.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_fingerprintx.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_fullhunt.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_generic_ssrf.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_git.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_git_clone.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_github_codesearch.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_github_org.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_github_workflows.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_gitlab.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_google_playstore.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_gowitness.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_hackertarget.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_host_header.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_http.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_httpx.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_hunt.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_hunterio.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_iis_shortnames.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_internetdb.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_ip2location.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_ipneighbor.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_ipstack.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_jadx.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_json.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_myssl.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_neo4j.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_newsletters.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_ntlm.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_nuclei.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_oauth.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_otx.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_paramminer_cookies.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_paramminer_getparams.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_paramminer_headers.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_pgp.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_portscan.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_postman.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_postman_download.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_python.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_rapiddns.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_robots.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_secretsdb.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_securitytrails.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_securitytxt.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_shodan_dns.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_sitedossier.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_skymem.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_slack.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_smuggler.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_social.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_speculate.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_splunk.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_sqlite.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_sslcert.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_stdout.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_subdomaincenter.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_subdomainradar.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_subdomains.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_teams.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_telerik.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_trickest.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_trufflehog.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_txt.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_url_manipulation.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_urlscan.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_vhost.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_viewdns.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_virustotal.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_wafw00f.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_wappalyzer.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_wayback.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_web_report.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_websocket.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_wpscan.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/module_tests/test_module_zoomeye.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/template_tests/__init__.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/test_step_2/template_tests/test_template_subdomain_enum.py +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/testsslcert.pem +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/test/testsslkey.pem +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/wordlists/devops_mutations.txt +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/wordlists/ffuf_shortname_candidates.txt +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/wordlists/ms_on_prem_subdomains.txt +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/wordlists/nameservers.txt +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/wordlists/paramminer_headers.txt +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/wordlists/paramminer_parameters.txt +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/wordlists/raft-small-extensions-lowercase_CLEANED.txt +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/wordlists/top_open_ports_nmap.txt +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/wordlists/valid_url_schemes.txt +0 -0
- {bbot-2.2.0.5242rc0 → bbot-2.2.0.5279rc0}/bbot/wordlists/wordninja_dns.txt.gz +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import os
|
|
1
2
|
import sys
|
|
2
3
|
import atexit
|
|
3
4
|
import logging
|
|
@@ -9,6 +10,7 @@ from contextlib import suppress
|
|
|
9
10
|
|
|
10
11
|
from ..helpers.misc import mkdir, error_and_exit
|
|
11
12
|
from ...logger import colorize, loglevel_mapping
|
|
13
|
+
from ..multiprocess import SHARED_INTERPRETER_STATE
|
|
12
14
|
|
|
13
15
|
|
|
14
16
|
debug_format = logging.Formatter("%(asctime)s [%(levelname)s] %(name)s %(filename)s:%(lineno)s %(message)s")
|
|
@@ -65,8 +67,9 @@ class BBOTLogger:
|
|
|
65
67
|
|
|
66
68
|
self.listener = None
|
|
67
69
|
|
|
68
|
-
|
|
69
|
-
if
|
|
70
|
+
# if we haven't set up logging yet, do it now
|
|
71
|
+
if not "_BBOT_LOGGING_SETUP" in os.environ:
|
|
72
|
+
os.environ["_BBOT_LOGGING_SETUP"] = "1"
|
|
70
73
|
self.queue = multiprocessing.Queue()
|
|
71
74
|
self.setup_queue_handler()
|
|
72
75
|
# Start the QueueListener
|
|
@@ -113,7 +116,7 @@ class BBOTLogger:
|
|
|
113
116
|
|
|
114
117
|
self.core_logger.setLevel(log_level)
|
|
115
118
|
# disable asyncio logging for child processes
|
|
116
|
-
if
|
|
119
|
+
if not SHARED_INTERPRETER_STATE.is_main_process:
|
|
117
120
|
logging.getLogger("asyncio").setLevel(logging.ERROR)
|
|
118
121
|
|
|
119
122
|
def addLoggingLevel(self, levelName, levelNum, methodName=None):
|
|
@@ -6,6 +6,7 @@ from contextlib import suppress
|
|
|
6
6
|
from omegaconf import OmegaConf
|
|
7
7
|
|
|
8
8
|
from bbot.errors import BBOTError
|
|
9
|
+
from .multiprocess import SHARED_INTERPRETER_STATE
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
DEFAULT_CONFIG = None
|
|
@@ -41,9 +42,23 @@ class BBOTCore:
|
|
|
41
42
|
self.logger
|
|
42
43
|
self.log = logging.getLogger("bbot.core")
|
|
43
44
|
|
|
45
|
+
self._prep_multiprocessing()
|
|
46
|
+
|
|
47
|
+
def _prep_multiprocessing(self):
|
|
44
48
|
import multiprocessing
|
|
49
|
+
from .helpers.process import BBOTProcess
|
|
50
|
+
|
|
51
|
+
if SHARED_INTERPRETER_STATE.is_main_process:
|
|
52
|
+
# if this is the main bbot process, set the logger and queue for the first time
|
|
53
|
+
from functools import partialmethod
|
|
45
54
|
|
|
46
|
-
|
|
55
|
+
BBOTProcess.__init__ = partialmethod(
|
|
56
|
+
BBOTProcess.__init__, log_level=self.logger.log_level, log_queue=self.logger.queue
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
# this makes our process class the default for process pools, etc.
|
|
60
|
+
mp_context = multiprocessing.get_context("spawn")
|
|
61
|
+
mp_context.Process = BBOTProcess
|
|
47
62
|
|
|
48
63
|
@property
|
|
49
64
|
def home(self):
|
|
@@ -187,12 +202,14 @@ class BBOTCore:
|
|
|
187
202
|
if os.environ.get("BBOT_TESTING", "") == "True":
|
|
188
203
|
process = self.create_thread(*args, **kwargs)
|
|
189
204
|
else:
|
|
190
|
-
if
|
|
205
|
+
if SHARED_INTERPRETER_STATE.is_scan_process:
|
|
191
206
|
from .helpers.process import BBOTProcess
|
|
192
207
|
|
|
193
208
|
process = BBOTProcess(*args, **kwargs)
|
|
194
209
|
else:
|
|
195
|
-
|
|
210
|
+
import multiprocessing
|
|
211
|
+
|
|
212
|
+
raise BBOTError(f"Tried to start server from process {multiprocessing.current_process().name}")
|
|
196
213
|
process.daemon = True
|
|
197
214
|
return process
|
|
198
215
|
|
|
@@ -10,6 +10,7 @@ import traceback
|
|
|
10
10
|
import contextlib
|
|
11
11
|
import contextvars
|
|
12
12
|
import zmq.asyncio
|
|
13
|
+
import multiprocessing
|
|
13
14
|
from pathlib import Path
|
|
14
15
|
from concurrent.futures import CancelledError
|
|
15
16
|
from contextlib import asynccontextmanager, suppress
|
|
@@ -17,6 +18,7 @@ from contextlib import asynccontextmanager, suppress
|
|
|
17
18
|
from bbot.core import CORE
|
|
18
19
|
from bbot.errors import BBOTEngineError
|
|
19
20
|
from bbot.core.helpers.async_helpers import get_event_loop
|
|
21
|
+
from bbot.core.multiprocess import SHARED_INTERPRETER_STATE
|
|
20
22
|
from bbot.core.helpers.misc import rand_string, in_exception_chain
|
|
21
23
|
|
|
22
24
|
|
|
@@ -264,10 +266,8 @@ class EngineClient(EngineBase):
|
|
|
264
266
|
return [s for s in self.CMDS if isinstance(s, str)]
|
|
265
267
|
|
|
266
268
|
def start_server(self):
|
|
267
|
-
import multiprocessing
|
|
268
|
-
|
|
269
269
|
process_name = multiprocessing.current_process().name
|
|
270
|
-
if
|
|
270
|
+
if SHARED_INTERPRETER_STATE.is_scan_process:
|
|
271
271
|
kwargs = dict(self.server_kwargs)
|
|
272
272
|
# if we're in tests, we use a single event loop to avoid weird race conditions
|
|
273
273
|
# this allows us to more easily mock http, etc.
|
|
@@ -1003,13 +1003,15 @@ class ClosestHostEvent(DictHostEvent):
|
|
|
1003
1003
|
if parent_url is not None:
|
|
1004
1004
|
self.data["url"] = parent_url.geturl()
|
|
1005
1005
|
# inherit closest path
|
|
1006
|
-
if not "path" in self.data and isinstance(parent.data, dict):
|
|
1006
|
+
if not "path" in self.data and isinstance(parent.data, dict) and not parent.type == "HTTP_RESPONSE":
|
|
1007
1007
|
parent_path = parent.data.get("path", None)
|
|
1008
1008
|
if parent_path is not None:
|
|
1009
1009
|
self.data["path"] = parent_path
|
|
1010
1010
|
# inherit closest host
|
|
1011
1011
|
if parent.host:
|
|
1012
1012
|
self.data["host"] = str(parent.host)
|
|
1013
|
+
# we do this to refresh the hash
|
|
1014
|
+
self.data = self.data
|
|
1013
1015
|
break
|
|
1014
1016
|
# die if we still haven't found a host
|
|
1015
1017
|
if not self.host:
|
|
@@ -1559,6 +1561,8 @@ class FILESYSTEM(DictPathEvent):
|
|
|
1559
1561
|
self.add_tag("compressed")
|
|
1560
1562
|
self.add_tag(f"{compression}-archive")
|
|
1561
1563
|
self.data["compression"] = compression
|
|
1564
|
+
# refresh hash
|
|
1565
|
+
self.data = self.data
|
|
1562
1566
|
|
|
1563
1567
|
|
|
1564
1568
|
class RAW_DNS_RECORD(DictHostEvent, DnsEvent):
|
|
@@ -1639,23 +1643,23 @@ def make_event(
|
|
|
1639
1643
|
tags = set(tags)
|
|
1640
1644
|
|
|
1641
1645
|
if is_event(data):
|
|
1642
|
-
|
|
1643
|
-
if scan is not None and not
|
|
1644
|
-
|
|
1645
|
-
if scans is not None and not
|
|
1646
|
-
|
|
1646
|
+
event = copy(data)
|
|
1647
|
+
if scan is not None and not event.scan:
|
|
1648
|
+
event.scan = scan
|
|
1649
|
+
if scans is not None and not event.scans:
|
|
1650
|
+
event.scans = scans
|
|
1647
1651
|
if module is not None:
|
|
1648
|
-
|
|
1652
|
+
event.module = module
|
|
1649
1653
|
if parent is not None:
|
|
1650
|
-
|
|
1654
|
+
event.parent = parent
|
|
1651
1655
|
if context is not None:
|
|
1652
|
-
|
|
1656
|
+
event.discovery_context = context
|
|
1653
1657
|
if internal == True:
|
|
1654
|
-
|
|
1658
|
+
event.internal = True
|
|
1655
1659
|
if tags:
|
|
1656
|
-
|
|
1660
|
+
event.tags = tags.union(event.tags)
|
|
1657
1661
|
event_type = data.type
|
|
1658
|
-
return
|
|
1662
|
+
return event
|
|
1659
1663
|
else:
|
|
1660
1664
|
if event_type is None:
|
|
1661
1665
|
event_type, data = get_event_type(data)
|
|
@@ -210,9 +210,10 @@ async def _write_proc_line(proc, chunk):
|
|
|
210
210
|
return True
|
|
211
211
|
except Exception as e:
|
|
212
212
|
proc_args = [str(s) for s in getattr(proc, "args", [])]
|
|
213
|
-
command = " ".join(proc_args)
|
|
214
|
-
|
|
215
|
-
|
|
213
|
+
command = " ".join(proc_args).strip()
|
|
214
|
+
if command:
|
|
215
|
+
log.warning(f"Error writing line to stdin for command: {command}: {e}")
|
|
216
|
+
log.trace(traceback.format_exc())
|
|
216
217
|
return False
|
|
217
218
|
|
|
218
219
|
|
|
@@ -14,7 +14,7 @@ from secrets import token_bytes
|
|
|
14
14
|
from ansible_runner.interface import run
|
|
15
15
|
from subprocess import CalledProcessError
|
|
16
16
|
|
|
17
|
-
from ..misc import can_sudo_without_password, os_platform, rm_at_exit
|
|
17
|
+
from ..misc import can_sudo_without_password, os_platform, rm_at_exit, get_python_constraints
|
|
18
18
|
|
|
19
19
|
log = logging.getLogger("bbot.core.helpers.depsinstaller")
|
|
20
20
|
|
|
@@ -44,6 +44,11 @@ class DepsInstaller:
|
|
|
44
44
|
self.parent_helper.mkdir(self.command_status)
|
|
45
45
|
self.setup_status = self.read_setup_status()
|
|
46
46
|
|
|
47
|
+
# make sure we're using a minimal git config
|
|
48
|
+
self.minimal_git_config = self.data_dir / "minimal_git.config"
|
|
49
|
+
self.minimal_git_config.touch()
|
|
50
|
+
os.environ["GIT_CONFIG_GLOBAL"] = str(self.minimal_git_config)
|
|
51
|
+
|
|
47
52
|
self.deps_behavior = self.parent_helper.config.get("deps_behavior", "abort_on_failure").lower()
|
|
48
53
|
self.ansible_debug = self.core.logger.log_level <= logging.DEBUG
|
|
49
54
|
self.venv = ""
|
|
@@ -171,10 +176,13 @@ class DepsInstaller:
|
|
|
171
176
|
|
|
172
177
|
command = [sys.executable, "-m", "pip", "install", "--upgrade"] + packages
|
|
173
178
|
|
|
174
|
-
if constraints
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
179
|
+
# if no custom constraints are provided, use the constraints of the currently installed version of bbot
|
|
180
|
+
if constraints is not None:
|
|
181
|
+
constraints = get_python_constraints()
|
|
182
|
+
|
|
183
|
+
constraints_tempfile = self.parent_helper.tempfile(constraints, pipe=False)
|
|
184
|
+
command.append("--constraint")
|
|
185
|
+
command.append(constraints_tempfile)
|
|
178
186
|
|
|
179
187
|
process = None
|
|
180
188
|
try:
|
|
@@ -2807,3 +2807,21 @@ def safe_format(s, **kwargs):
|
|
|
2807
2807
|
Format string while ignoring unused keys (prevents KeyError)
|
|
2808
2808
|
"""
|
|
2809
2809
|
return s.format_map(SafeDict(kwargs))
|
|
2810
|
+
|
|
2811
|
+
|
|
2812
|
+
def get_python_constraints():
|
|
2813
|
+
req_regex = re.compile(r"([^(]+)\s*\((.*)\)", re.IGNORECASE)
|
|
2814
|
+
|
|
2815
|
+
def clean_requirement(req_string):
|
|
2816
|
+
# Extract package name and version constraints from format like "package (>=1.0,<2.0)"
|
|
2817
|
+
match = req_regex.match(req_string)
|
|
2818
|
+
if match:
|
|
2819
|
+
name, constraints = match.groups()
|
|
2820
|
+
return f"{name.strip()}{constraints}"
|
|
2821
|
+
|
|
2822
|
+
return req_string
|
|
2823
|
+
|
|
2824
|
+
from importlib.metadata import distribution
|
|
2825
|
+
|
|
2826
|
+
dist = distribution("bbot")
|
|
2827
|
+
return [clean_requirement(r) for r in dist.requires]
|
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import traceback
|
|
3
3
|
import threading
|
|
4
|
-
import multiprocessing
|
|
5
4
|
from multiprocessing.context import SpawnProcess
|
|
6
5
|
|
|
7
6
|
from .misc import in_exception_chain
|
|
8
7
|
|
|
9
8
|
|
|
10
|
-
current_process = multiprocessing.current_process()
|
|
11
|
-
|
|
12
|
-
|
|
13
9
|
class BBOTThread(threading.Thread):
|
|
14
10
|
|
|
15
11
|
default_name = "default bbot thread"
|
|
@@ -57,17 +53,3 @@ class BBOTProcess(SpawnProcess):
|
|
|
57
53
|
if not in_exception_chain(e, (KeyboardInterrupt,)):
|
|
58
54
|
log.warning(f"Error in {self.name}: {e}")
|
|
59
55
|
log.trace(traceback.format_exc())
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if current_process.name == "MainProcess":
|
|
63
|
-
# if this is the main bbot process, set the logger and queue for the first time
|
|
64
|
-
from bbot.core import CORE
|
|
65
|
-
from functools import partialmethod
|
|
66
|
-
|
|
67
|
-
BBOTProcess.__init__ = partialmethod(
|
|
68
|
-
BBOTProcess.__init__, log_level=CORE.logger.log_level, log_queue=CORE.logger.queue
|
|
69
|
-
)
|
|
70
|
-
|
|
71
|
-
# this makes our process class the default for process pools, etc.
|
|
72
|
-
mp_context = multiprocessing.get_context("spawn")
|
|
73
|
-
mp_context.Process = BBOTProcess
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import atexit
|
|
3
|
+
from contextlib import suppress
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class SharedInterpreterState:
|
|
7
|
+
"""
|
|
8
|
+
A class to track the primary BBOT process.
|
|
9
|
+
|
|
10
|
+
Used to prevent spawning multiple unwanted processes with multiprocessing.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
def __init__(self):
|
|
14
|
+
self.main_process_var_name = "_BBOT_MAIN_PID"
|
|
15
|
+
self.scan_process_var_name = "_BBOT_SCAN_PID"
|
|
16
|
+
atexit.register(self.cleanup)
|
|
17
|
+
|
|
18
|
+
@property
|
|
19
|
+
def is_main_process(self):
|
|
20
|
+
is_main_process = self.main_pid == os.getpid()
|
|
21
|
+
return is_main_process
|
|
22
|
+
|
|
23
|
+
@property
|
|
24
|
+
def is_scan_process(self):
|
|
25
|
+
is_scan_process = os.getpid() == self.scan_pid
|
|
26
|
+
return is_scan_process
|
|
27
|
+
|
|
28
|
+
@property
|
|
29
|
+
def main_pid(self):
|
|
30
|
+
main_pid = int(os.environ.get(self.main_process_var_name, 0))
|
|
31
|
+
if main_pid == 0:
|
|
32
|
+
main_pid = os.getpid()
|
|
33
|
+
# if main PID is not set, set it to the current PID
|
|
34
|
+
os.environ[self.main_process_var_name] = str(main_pid)
|
|
35
|
+
return main_pid
|
|
36
|
+
|
|
37
|
+
@property
|
|
38
|
+
def scan_pid(self):
|
|
39
|
+
scan_pid = int(os.environ.get(self.scan_process_var_name, 0))
|
|
40
|
+
if scan_pid == 0:
|
|
41
|
+
scan_pid = os.getpid()
|
|
42
|
+
# if scan PID is not set, set it to the current PID
|
|
43
|
+
os.environ[self.scan_process_var_name] = str(scan_pid)
|
|
44
|
+
return scan_pid
|
|
45
|
+
|
|
46
|
+
def update_scan_pid(self):
|
|
47
|
+
os.environ[self.scan_process_var_name] = str(os.getpid())
|
|
48
|
+
|
|
49
|
+
def cleanup(self):
|
|
50
|
+
with suppress(Exception):
|
|
51
|
+
if self.is_main_process:
|
|
52
|
+
with suppress(KeyError):
|
|
53
|
+
del os.environ[self.main_process_var_name]
|
|
54
|
+
with suppress(KeyError):
|
|
55
|
+
del os.environ[self.scan_process_var_name]
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
SHARED_INTERPRETER_STATE = SharedInterpreterState()
|
|
@@ -14,6 +14,9 @@ folder_blobs: false
|
|
|
14
14
|
### SCOPE ###
|
|
15
15
|
|
|
16
16
|
scope:
|
|
17
|
+
# strict scope means only exact DNS names are considered in-scope
|
|
18
|
+
# subdomains are not included unless they are explicitly provided in the target list
|
|
19
|
+
strict: false
|
|
17
20
|
# Filter by scope distance which events are displayed in the output
|
|
18
21
|
# 0 == show only in-scope events (affiliates are always shown)
|
|
19
22
|
# 1 == show all events up to distance-1 (1 hop from target)
|
|
@@ -15,25 +15,21 @@ class censys(subdomain_enum_apikey):
|
|
|
15
15
|
"author": "@TheTechromancer",
|
|
16
16
|
"auth_required": True,
|
|
17
17
|
}
|
|
18
|
-
options = {"
|
|
18
|
+
options = {"api_key": "", "max_pages": 5}
|
|
19
19
|
options_desc = {
|
|
20
|
-
"
|
|
21
|
-
"api_secret": "Censys.io API Secret",
|
|
20
|
+
"api_key": "Censys.io API Key in the format of 'key:secret'",
|
|
22
21
|
"max_pages": "Maximum number of pages to fetch (100 results per page)",
|
|
23
22
|
}
|
|
24
23
|
|
|
25
24
|
base_url = "https://search.censys.io/api"
|
|
26
25
|
|
|
27
26
|
async def setup(self):
|
|
28
|
-
self.api_id = self.config.get("api_id", "")
|
|
29
|
-
self.api_secret = self.config.get("api_secret", "")
|
|
30
|
-
self.auth = (self.api_id, self.api_secret)
|
|
31
27
|
self.max_pages = self.config.get("max_pages", 5)
|
|
32
28
|
return await super().setup()
|
|
33
29
|
|
|
34
30
|
async def ping(self):
|
|
35
31
|
url = f"{self.base_url}/v1/account"
|
|
36
|
-
resp = await self.
|
|
32
|
+
resp = await self.api_request(url)
|
|
37
33
|
d = resp.json()
|
|
38
34
|
assert isinstance(d, dict), f"Invalid response from {url}: {resp}"
|
|
39
35
|
quota = d.get("quota", {})
|
|
@@ -41,6 +37,11 @@ class censys(subdomain_enum_apikey):
|
|
|
41
37
|
allowance = int(quota.get("allowance", 0))
|
|
42
38
|
assert used < allowance, "No quota remaining"
|
|
43
39
|
|
|
40
|
+
def prepare_api_request(self, url, kwargs):
|
|
41
|
+
api_id, api_secret = self.api_key.split(":", 1)
|
|
42
|
+
kwargs["auth"] = (api_id, api_secret)
|
|
43
|
+
return url, kwargs
|
|
44
|
+
|
|
44
45
|
async def query(self, query):
|
|
45
46
|
results = set()
|
|
46
47
|
cursor = ""
|
|
@@ -52,11 +53,10 @@ class censys(subdomain_enum_apikey):
|
|
|
52
53
|
}
|
|
53
54
|
if cursor:
|
|
54
55
|
json_data.update({"cursor": cursor})
|
|
55
|
-
resp = await self.
|
|
56
|
+
resp = await self.api_request(
|
|
56
57
|
url,
|
|
57
58
|
method="POST",
|
|
58
59
|
json=json_data,
|
|
59
|
-
auth=self.auth,
|
|
60
60
|
)
|
|
61
61
|
|
|
62
62
|
if resp is None:
|
|
@@ -96,7 +96,3 @@ class censys(subdomain_enum_apikey):
|
|
|
96
96
|
break
|
|
97
97
|
|
|
98
98
|
return results
|
|
99
|
-
|
|
100
|
-
@property
|
|
101
|
-
def auth_secret(self):
|
|
102
|
-
return self.api_id and self.api_secret
|
|
@@ -79,7 +79,16 @@ class DNSResolve(BaseInterceptModule):
|
|
|
79
79
|
await self.resolve_event(main_host_event, types=non_minimal_rdtypes)
|
|
80
80
|
# check for wildcards if the event is within the scan's search distance
|
|
81
81
|
if new_event and main_host_event.scope_distance <= self.scan.scope_search_distance:
|
|
82
|
-
await self.handle_wildcard_event(main_host_event)
|
|
82
|
+
event_data_changed = await self.handle_wildcard_event(main_host_event)
|
|
83
|
+
if event_data_changed:
|
|
84
|
+
# since data has changed, we check again whether it's a duplicate
|
|
85
|
+
if self.scan.ingress_module.is_incoming_duplicate(event, add=True):
|
|
86
|
+
if not event._graph_important:
|
|
87
|
+
return False, "event was already emitted by its module"
|
|
88
|
+
else:
|
|
89
|
+
self.debug(
|
|
90
|
+
f"Event {event} was already emitted by its module, but it's graph-important so it gets a pass"
|
|
91
|
+
)
|
|
83
92
|
|
|
84
93
|
# if there weren't any DNS children and it's not an IP address, tag as unresolved
|
|
85
94
|
if not main_host_event.raw_dns_records and not event_is_ip:
|
|
@@ -152,6 +161,8 @@ class DNSResolve(BaseInterceptModule):
|
|
|
152
161
|
if wildcard_data != event.data:
|
|
153
162
|
self.debug(f'Wildcard detected, changing event.data "{event.data}" --> "{wildcard_data}"')
|
|
154
163
|
event.data = wildcard_data
|
|
164
|
+
return True
|
|
165
|
+
return False
|
|
155
166
|
|
|
156
167
|
async def emit_dns_children(self, event):
|
|
157
168
|
for rdtype, children in event.dns_children.items():
|
|
@@ -32,10 +32,11 @@ class speculate(BaseInternalModule):
|
|
|
32
32
|
"author": "@liquidsec",
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
options = {"max_hosts": 65536, "ports": "80,443"}
|
|
35
|
+
options = {"max_hosts": 65536, "ports": "80,443", "essential_only": False}
|
|
36
36
|
options_desc = {
|
|
37
37
|
"max_hosts": "Max number of IP_RANGE hosts to convert into IP_ADDRESS events",
|
|
38
38
|
"ports": "The set of ports to speculate on",
|
|
39
|
+
"essential_only": "Only enable essential speculate features (no extra discovery)",
|
|
39
40
|
}
|
|
40
41
|
scope_distance_modifier = 1
|
|
41
42
|
_priority = 4
|
|
@@ -52,6 +53,7 @@ class speculate(BaseInternalModule):
|
|
|
52
53
|
self.emit_open_ports = self.open_port_consumers and not self.portscanner_enabled
|
|
53
54
|
self.range_to_ip = True
|
|
54
55
|
self.dns_disable = self.scan.config.get("dns", {}).get("disable", False)
|
|
56
|
+
self.essential_only = self.config.get("essential_only", False)
|
|
55
57
|
self.org_stubs_seen = set()
|
|
56
58
|
|
|
57
59
|
port_string = self.config.get("ports", "80,443")
|
|
@@ -75,6 +77,14 @@ class speculate(BaseInternalModule):
|
|
|
75
77
|
return True
|
|
76
78
|
|
|
77
79
|
async def handle_event(self, event):
|
|
80
|
+
### BEGIN ESSENTIAL SPECULATION ###
|
|
81
|
+
# These features are required for smooth operation of bbot
|
|
82
|
+
# I.e. they are not "osinty" or intended to discover anything, they only compliment other modules
|
|
83
|
+
|
|
84
|
+
# we speculate on distance-1 stuff too, because distance-1 open ports are needed by certain modules like sslcert
|
|
85
|
+
event_in_scope_distance = event.scope_distance <= (self.scan.scope_search_distance + 1)
|
|
86
|
+
speculate_open_ports = self.emit_open_ports and event_in_scope_distance
|
|
87
|
+
|
|
78
88
|
# generate individual IP addresses from IP range
|
|
79
89
|
if event.type == "IP_RANGE" and self.range_to_ip:
|
|
80
90
|
net = ipaddress.ip_network(event.data)
|
|
@@ -89,6 +99,28 @@ class speculate(BaseInternalModule):
|
|
|
89
99
|
context=f"speculate converted range into individual IP_ADDRESS: {ip}",
|
|
90
100
|
)
|
|
91
101
|
|
|
102
|
+
# IP_ADDRESS / DNS_NAME --> OPEN_TCP_PORT
|
|
103
|
+
if speculate_open_ports:
|
|
104
|
+
# don't act on unresolved DNS_NAMEs
|
|
105
|
+
usable_dns = False
|
|
106
|
+
if event.type == "DNS_NAME":
|
|
107
|
+
if self.dns_disable or ("a-record" in event.tags or "aaaa-record" in event.tags):
|
|
108
|
+
usable_dns = True
|
|
109
|
+
|
|
110
|
+
if event.type == "IP_ADDRESS" or usable_dns:
|
|
111
|
+
for port in self.ports:
|
|
112
|
+
await self.emit_event(
|
|
113
|
+
self.helpers.make_netloc(event.data, port),
|
|
114
|
+
"OPEN_TCP_PORT",
|
|
115
|
+
parent=event,
|
|
116
|
+
internal=True,
|
|
117
|
+
context="speculated {event.type}: {event.data}",
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
### END ESSENTIAL SPECULATION ###
|
|
121
|
+
if self.essential_only:
|
|
122
|
+
return
|
|
123
|
+
|
|
92
124
|
# parent domains
|
|
93
125
|
if event.type.startswith("DNS_NAME"):
|
|
94
126
|
parent = self.helpers.parent_domain(event.host_original)
|
|
@@ -97,10 +129,6 @@ class speculate(BaseInternalModule):
|
|
|
97
129
|
parent, "DNS_NAME", parent=event, context=f"speculated parent {{event.type}}: {{event.data}}"
|
|
98
130
|
)
|
|
99
131
|
|
|
100
|
-
# we speculate on distance-1 stuff too, because distance-1 open ports are needed by certain modules like sslcert
|
|
101
|
-
event_in_scope_distance = event.scope_distance <= (self.scan.scope_search_distance + 1)
|
|
102
|
-
speculate_open_ports = self.emit_open_ports and event_in_scope_distance
|
|
103
|
-
|
|
104
132
|
# URL --> OPEN_TCP_PORT
|
|
105
133
|
event_is_url = event.type == "URL"
|
|
106
134
|
if event_is_url or (event.type == "URL_UNVERIFIED" and self.open_port_consumers):
|
|
@@ -144,24 +172,6 @@ class speculate(BaseInternalModule):
|
|
|
144
172
|
context="speculated {event.type}: {event.data}",
|
|
145
173
|
)
|
|
146
174
|
|
|
147
|
-
# IP_ADDRESS / DNS_NAME --> OPEN_TCP_PORT
|
|
148
|
-
if speculate_open_ports:
|
|
149
|
-
# don't act on unresolved DNS_NAMEs
|
|
150
|
-
usable_dns = False
|
|
151
|
-
if event.type == "DNS_NAME":
|
|
152
|
-
if self.dns_disable or ("a-record" in event.tags or "aaaa-record" in event.tags):
|
|
153
|
-
usable_dns = True
|
|
154
|
-
|
|
155
|
-
if event.type == "IP_ADDRESS" or usable_dns:
|
|
156
|
-
for port in self.ports:
|
|
157
|
-
await self.emit_event(
|
|
158
|
-
self.helpers.make_netloc(event.data, port),
|
|
159
|
-
"OPEN_TCP_PORT",
|
|
160
|
-
parent=event,
|
|
161
|
-
internal=True,
|
|
162
|
-
context="speculated {event.type}: {event.data}",
|
|
163
|
-
)
|
|
164
|
-
|
|
165
175
|
# ORG_STUB from TLD, SOCIAL, AZURE_TENANT
|
|
166
176
|
org_stubs = set()
|
|
167
177
|
if event.type == "DNS_NAME" and event.scope_distance == 0:
|
|
@@ -15,20 +15,19 @@ class leakix(subdomain_enum_apikey):
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
base_url = "https://leakix.net"
|
|
18
|
-
ping_url = f"{base_url}/host/1.
|
|
18
|
+
ping_url = f"{base_url}/host/1.1.1.1"
|
|
19
19
|
|
|
20
20
|
async def setup(self):
|
|
21
21
|
ret = await super(subdomain_enum_apikey, self).setup()
|
|
22
|
-
self.headers = {"Accept": "application/json"}
|
|
23
22
|
self.api_key = self.config.get("api_key", "")
|
|
24
23
|
if self.api_key:
|
|
25
|
-
self.headers["api-key"] = self.api_key
|
|
26
24
|
return await self.require_api_key()
|
|
27
25
|
return ret
|
|
28
26
|
|
|
29
27
|
def prepare_api_request(self, url, kwargs):
|
|
30
28
|
if self.api_key:
|
|
31
29
|
kwargs["headers"]["api-key"] = self.api_key
|
|
30
|
+
kwargs["headers"]["Accept"] = "application/json"
|
|
32
31
|
return url, kwargs
|
|
33
32
|
|
|
34
33
|
async def request_url(self, query):
|
|
@@ -11,36 +11,34 @@ class passivetotal(subdomain_enum_apikey):
|
|
|
11
11
|
"author": "@TheTechromancer",
|
|
12
12
|
"auth_required": True,
|
|
13
13
|
}
|
|
14
|
-
options = {"
|
|
15
|
-
options_desc = {"
|
|
14
|
+
options = {"api_key": ""}
|
|
15
|
+
options_desc = {"api_key": "PassiveTotal API Key in the format of 'username:api_key'"}
|
|
16
16
|
|
|
17
17
|
base_url = "https://api.passivetotal.org/v2"
|
|
18
18
|
|
|
19
19
|
async def setup(self):
|
|
20
|
-
self.username = self.config.get("username", "")
|
|
21
|
-
self.api_key = self.config.get("api_key", "")
|
|
22
|
-
self.auth = (self.username, self.api_key)
|
|
23
20
|
return await super().setup()
|
|
24
21
|
|
|
25
22
|
async def ping(self):
|
|
26
23
|
url = f"{self.base_url}/account/quota"
|
|
27
|
-
j = (await self.api_request(url
|
|
24
|
+
j = (await self.api_request(url)).json()
|
|
28
25
|
limit = j["user"]["limits"]["search_api"]
|
|
29
26
|
used = j["user"]["counts"]["search_api"]
|
|
30
27
|
assert used < limit, "No quota remaining"
|
|
31
28
|
|
|
29
|
+
def prepare_api_request(self, url, kwargs):
|
|
30
|
+
api_username, api_key = self.api_key.split(":", 1)
|
|
31
|
+
kwargs["auth"] = (api_username, api_key)
|
|
32
|
+
return url, kwargs
|
|
33
|
+
|
|
32
34
|
async def abort_if(self, event):
|
|
33
35
|
# RiskIQ is famous for their junk data
|
|
34
36
|
return await super().abort_if(event) or "unresolved" in event.tags
|
|
35
37
|
|
|
36
38
|
async def request_url(self, query):
|
|
37
39
|
url = f"{self.base_url}/enrichment/subdomains?query={self.helpers.quote(query)}"
|
|
38
|
-
return await self.api_request(url
|
|
40
|
+
return await self.api_request(url)
|
|
39
41
|
|
|
40
42
|
def parse_results(self, r, query):
|
|
41
43
|
for subdomain in r.json().get("subdomains", []):
|
|
42
44
|
yield f"{subdomain}.{query}"
|
|
43
|
-
|
|
44
|
-
@property
|
|
45
|
-
def auth_secret(self):
|
|
46
|
-
return self.username and self.api_key
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
description: Scan only the provided targets as fast as possible - no extra discovery
|
|
2
|
+
|
|
3
|
+
exclude_modules:
|
|
4
|
+
- excavate
|
|
5
|
+
|
|
6
|
+
config:
|
|
7
|
+
# only scan the exact targets specified
|
|
8
|
+
scope:
|
|
9
|
+
strict: true
|
|
10
|
+
# speed up dns resolution by doing A/AAAA only - not MX/NS/SRV/etc
|
|
11
|
+
dns:
|
|
12
|
+
minimal: true
|
|
13
|
+
# essential speculation only
|
|
14
|
+
modules:
|
|
15
|
+
speculate:
|
|
16
|
+
essential_only: true
|