bbot 2.7.0.6962rc0__tar.gz → 2.7.0.6989rc0__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.7.0.6962rc0 → bbot-2.7.0.6989rc0}/PKG-INFO +1 -1
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/__init__.py +1 -1
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/files.py +2 -2
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/defaults.yml +4 -2
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/base.py +11 -5
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/graphql_introspection.py +1 -1
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/httpx.py +2 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/output/base.py +0 -5
- bbot-2.7.0.6989rc0/bbot/modules/retirejs.py +238 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/scanner/manager.py +7 -4
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/scanner/scanner.py +1 -1
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_1/test_bbot_fastapi.py +2 -2
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_1/test_events.py +0 -1
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_1/test_scan.py +1 -7
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/base.py +1 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_excavate.py +6 -6
- bbot-2.7.0.6989rc0/bbot/test/test_step_2/module_tests/test_module_retirejs.py +159 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/pyproject.toml +1 -1
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/LICENSE +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/README.md +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/cli.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/__init__.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/config/__init__.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/config/files.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/config/logger.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/core.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/engine.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/event/__init__.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/event/base.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/event/helpers.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/flags.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/__init__.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/async_helpers.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/bloom.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/cache.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/command.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/depsinstaller/__init__.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/depsinstaller/installer.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/depsinstaller/sudo_askpass.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/diff.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/dns/__init__.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/dns/brute.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/dns/dns.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/dns/engine.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/dns/helpers.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/dns/mock.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/helper.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/interactsh.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/libmagic.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/misc.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/names_generator.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/ntlm.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/process.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/ratelimiter.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/regex.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/regexes.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/url.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/validators.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/web/__init__.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/web/client.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/web/engine.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/web/envelopes.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/web/ssl_context.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/web/web.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/wordcloud.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/helpers/yara_helper.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/modules.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/multiprocess.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/core/shared_deps.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/db/sql/models.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/errors.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/logger.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/__init__.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/ajaxpro.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/anubisdb.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/apkpure.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/aspnet_bin_exposure.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/azure_realm.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/azure_tenant.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/baddns.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/baddns_direct.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/baddns_zone.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/badsecrets.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/bevigil.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/bucket_amazon.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/bucket_azure.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/bucket_digitalocean.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/bucket_file_enum.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/bucket_firebase.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/bucket_google.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/bufferoverrun.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/builtwith.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/bypass403.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/c99.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/censys.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/certspotter.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/chaos.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/code_repository.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/credshed.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/crt.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/crt_db.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/dehashed.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/digitorus.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/dnsbimi.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/dnsbrute.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/dnsbrute_mutations.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/dnscaa.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/dnscommonsrv.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/dnsdumpster.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/dnstlsrpt.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/docker_pull.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/dockerhub.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/dotnetnuke.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/emailformat.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/extractous.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/ffuf.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/ffuf_shortnames.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/filedownload.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/fingerprintx.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/fullhunt.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/generic_ssrf.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/git.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/git_clone.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/gitdumper.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/github_codesearch.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/github_org.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/github_usersearch.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/github_workflows.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/gitlab.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/google_playstore.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/gowitness.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/hackertarget.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/host_header.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/hunt.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/hunterio.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/iis_shortnames.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/internal/__init__.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/internal/aggregate.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/internal/base.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/internal/cloudcheck.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/internal/dnsresolve.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/internal/excavate.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/internal/speculate.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/internal/unarchive.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/ip2location.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/ipneighbor.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/ipstack.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/jadx.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/leakix.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/lightfuzz/lightfuzz.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/lightfuzz/submodules/__init__.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/lightfuzz/submodules/base.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/lightfuzz/submodules/cmdi.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/lightfuzz/submodules/crypto.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/lightfuzz/submodules/path.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/lightfuzz/submodules/serial.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/lightfuzz/submodules/sqli.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/lightfuzz/submodules/ssti.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/lightfuzz/submodules/xss.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/medusa.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/myssl.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/newsletters.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/ntlm.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/nuclei.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/oauth.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/otx.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/output/__init__.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/output/asset_inventory.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/output/csv.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/output/discord.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/output/emails.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/output/http.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/output/json.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/output/mysql.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/output/neo4j.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/output/nmap_xml.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/output/postgres.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/output/python.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/output/slack.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/output/splunk.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/output/sqlite.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/output/stdout.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/output/subdomains.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/output/teams.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/output/txt.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/output/web_parameters.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/output/web_report.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/output/websocket.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/paramminer_cookies.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/paramminer_getparams.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/paramminer_headers.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/passivetotal.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/pgp.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/portfilter.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/portscan.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/postman.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/postman_download.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/rapiddns.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/reflected_parameters.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/report/affiliates.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/report/asn.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/report/base.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/robots.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/securitytrails.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/securitytxt.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/shodan_dns.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/shodan_idb.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/sitedossier.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/skymem.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/smuggler.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/social.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/sslcert.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/subdomaincenter.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/subdomainradar.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/telerik.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/templates/bucket.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/templates/github.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/templates/postman.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/templates/shodan.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/templates/sql.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/templates/subdomain_enum.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/templates/webhook.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/trickest.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/trufflehog.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/url_manipulation.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/urlscan.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/vhost.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/viewdns.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/virustotal.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/wafw00f.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/wappalyzer.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/wayback.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/wpscan.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/modules/zoomeye.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/presets/baddns-intense.yml +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/presets/cloud-enum.yml +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/presets/code-enum.yml +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/presets/email-enum.yml +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/presets/fast.yml +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/presets/kitchen-sink.yml +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/presets/nuclei/nuclei-budget.yml +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/presets/nuclei/nuclei-intense.yml +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/presets/nuclei/nuclei-technology.yml +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/presets/nuclei/nuclei.yml +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/presets/spider-intense.yml +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/presets/spider.yml +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/presets/subdomain-enum.yml +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/presets/tech-detect.yml +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/presets/web/dirbust-heavy.yml +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/presets/web/dirbust-light.yml +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/presets/web/dotnet-audit.yml +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/presets/web/iis-shortnames.yml +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/presets/web/lightfuzz-heavy.yml +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/presets/web/lightfuzz-light.yml +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/presets/web/lightfuzz-medium.yml +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/presets/web/lightfuzz-superheavy.yml +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/presets/web/lightfuzz-xss.yml +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/presets/web/paramminer.yml +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/presets/web-basic.yml +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/presets/web-screenshots.yml +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/presets/web-thorough.yml +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/scanner/__init__.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/scanner/dispatcher.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/scanner/preset/__init__.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/scanner/preset/args.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/scanner/preset/conditions.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/scanner/preset/environ.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/scanner/preset/path.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/scanner/preset/preset.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/scanner/stats.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/scanner/target.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/scripts/docs.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/__init__.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/bbot_fixtures.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/conftest.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/coverage.cfg +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/fastapi_test.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/owasp_mastg.apk +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/run_tests.sh +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test.conf +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_output.ndjson +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_1/__init__.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_1/test__module__tests.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_1/test_bloom_filter.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_1/test_cli.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_1/test_command.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_1/test_config.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_1/test_depsinstaller.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_1/test_dns.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_1/test_docs.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_1/test_engine.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_1/test_event_seeds.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_1/test_files.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_1/test_helpers.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_1/test_manager_deduplication.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_1/test_manager_scope_accuracy.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_1/test_modules_basic.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_1/test_presets.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_1/test_python_api.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_1/test_regexes.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_1/test_scope.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_1/test_target.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_1/test_web.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_1/test_web_envelopes.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/__init__.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/__init__.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_affiliates.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_aggregate.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_ajaxpro.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_anubisdb.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_apkpure.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_asn.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_aspnet_bin_exposure.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_asset_inventory.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_azure_realm.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_azure_tenant.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_baddns.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_baddns_direct.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_baddns_zone.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_badsecrets.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_bevigil.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_bucket_amazon.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_bucket_azure.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_bucket_digitalocean.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_bucket_file_enum.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_bucket_firebase.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_bucket_google.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_bufferoverrun.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_builtwith.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_bypass403.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_c99.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_censys.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_certspotter.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_chaos.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_cloudcheck.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_code_repository.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_credshed.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_crt.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_crt_db.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_csv.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_dehashed.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_digitorus.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_discord.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_dnsbimi.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_dnsbrute.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_dnsbrute_mutations.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_dnscaa.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_dnscommonsrv.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_dnsdumpster.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_dnsresolve.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_dnstlsrpt.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_docker_pull.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_dockerhub.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_dotnetnuke.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_emailformat.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_emails.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_extractous.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_ffuf.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_ffuf_shortnames.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_filedownload.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_fingerprintx.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_fullhunt.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_generic_ssrf.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_git.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_git_clone.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_gitdumper.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_github_codesearch.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_github_org.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_github_usersearch.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_github_workflows.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_gitlab.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_google_playstore.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_gowitness.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_graphql_introspection.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_hackertarget.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_host_header.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_http.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_httpx.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_hunt.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_hunterio.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_iis_shortnames.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_ip2location.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_ipneighbor.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_ipstack.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_jadx.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_json.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_leakix.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_lightfuzz.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_medusa.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_mysql.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_myssl.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_neo4j.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_newsletters.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_nmap_xml.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_ntlm.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_nuclei.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_oauth.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_otx.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_paramminer_cookies.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_paramminer_getparams.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_paramminer_headers.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_passivetotal.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_pgp.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_portfilter.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_portscan.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_postgres.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_postman.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_postman_download.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_python.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_rapiddns.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_reflected_parameters.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_robots.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_securitytrails.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_securitytxt.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_shodan_dns.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_shodan_idb.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_sitedossier.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_skymem.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_slack.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_smuggler.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_social.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_speculate.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_splunk.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_sqlite.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_sslcert.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_stdout.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_subdomaincenter.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_subdomainradar.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_subdomains.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_teams.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_telerik.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_trickest.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_trufflehog.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_txt.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_unarchive.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_url_manipulation.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_urlscan.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_vhost.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_viewdns.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_virustotal.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_wafw00f.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_wappalyzer.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_wayback.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_web_parameters.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_web_report.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_websocket.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_wpscan.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_zoomeye.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/template_tests/__init__.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/template_tests/test_template_subdomain_enum.py +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/testsslcert.pem +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/testsslkey.pem +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/wordlists/devops_mutations.txt +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/wordlists/ms_on_prem_subdomains.txt +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/wordlists/nameservers.txt +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/wordlists/paramminer_headers.txt +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/wordlists/paramminer_parameters.txt +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/wordlists/raft-small-extensions-lowercase_CLEANED.txt +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/wordlists/top_open_ports_nmap.txt +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/wordlists/valid_url_schemes.txt +0 -0
- {bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/wordlists/wordninja_dns.txt.gz +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: bbot
|
|
3
|
-
Version: 2.7.0.
|
|
3
|
+
Version: 2.7.0.6989rc0
|
|
4
4
|
Summary: OSINT automation for hackers.
|
|
5
5
|
License: GPL-3.0
|
|
6
6
|
Keywords: python,cli,automation,osint,threat-intel,intelligence,neo4j,scanner,python-library,hacking,recursion,pentesting,recon,command-line-tool,bugbounty,subdomains,security-tools,subdomain-scanner,osint-framework,attack-surface,subdomain-enumeration,osint-tool
|
|
@@ -9,7 +9,7 @@ from .misc import rm_at_exit
|
|
|
9
9
|
log = logging.getLogger("bbot.core.helpers.files")
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
def tempfile(self, content, pipe=True):
|
|
12
|
+
def tempfile(self, content, pipe=True, extension=None):
|
|
13
13
|
"""
|
|
14
14
|
Creates a temporary file or named pipe and populates it with content.
|
|
15
15
|
|
|
@@ -29,7 +29,7 @@ def tempfile(self, content, pipe=True):
|
|
|
29
29
|
>>> tempfile(["Another", "temp", "file"], pipe=False)
|
|
30
30
|
'/home/user/.bbot/temp/someotherfile'
|
|
31
31
|
"""
|
|
32
|
-
filename = self.temp_filename()
|
|
32
|
+
filename = self.temp_filename(extension)
|
|
33
33
|
rm_at_exit(filename)
|
|
34
34
|
try:
|
|
35
35
|
if type(content) not in (set, list, tuple):
|
|
@@ -187,8 +187,10 @@ url_extension_blacklist:
|
|
|
187
187
|
- mov
|
|
188
188
|
- flv
|
|
189
189
|
- webm
|
|
190
|
-
|
|
191
|
-
|
|
190
|
+
|
|
191
|
+
# URLs with these extensions are not distributed to modules unless the module opts in via `accept_url_special = True`
|
|
192
|
+
# They are also excluded from output. If you want to see them in output, remove them from this list.
|
|
193
|
+
url_extension_special:
|
|
192
194
|
- js
|
|
193
195
|
|
|
194
196
|
# These url extensions are almost always static, so we exclude them from modules that fuzz things
|
|
@@ -53,6 +53,8 @@ class BaseModule:
|
|
|
53
53
|
|
|
54
54
|
in_scope_only (bool): Accept only explicitly in-scope events, regardless of the scan's search distance. Default is False.
|
|
55
55
|
|
|
56
|
+
accept_url_special (bool): Accept "special" URLs not typically distributed to web modules, e.g. JS URLs. Default is False.
|
|
57
|
+
|
|
56
58
|
options (Dict): Customizable options for the module, e.g., {"api_key": ""}. Empty dict by default.
|
|
57
59
|
|
|
58
60
|
options_desc (Dict): Descriptions for options, e.g., {"api_key": "API Key"}. Empty dict by default.
|
|
@@ -97,7 +99,7 @@ class BaseModule:
|
|
|
97
99
|
scope_distance_modifier = 0
|
|
98
100
|
target_only = False
|
|
99
101
|
in_scope_only = False
|
|
100
|
-
|
|
102
|
+
accept_url_special = False
|
|
101
103
|
_module_threads = 1
|
|
102
104
|
_batch_size = 1
|
|
103
105
|
|
|
@@ -785,10 +787,14 @@ class BaseModule:
|
|
|
785
787
|
if "target" not in event.tags:
|
|
786
788
|
return False, "it did not meet target_only filter criteria"
|
|
787
789
|
|
|
788
|
-
#
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
790
|
+
# limit js URLs to modules that opt in to receive them
|
|
791
|
+
if (not self.accept_url_special) and event.type.startswith("URL"):
|
|
792
|
+
extension = getattr(event, "url_extension", "")
|
|
793
|
+
if extension in self.scan.url_extension_special:
|
|
794
|
+
return (
|
|
795
|
+
False,
|
|
796
|
+
f"it is a special URL (extension {extension}) but the module does not opt in to receive special URLs",
|
|
797
|
+
)
|
|
792
798
|
|
|
793
799
|
return True, "precheck succeeded"
|
|
794
800
|
|
|
@@ -27,7 +27,6 @@ class graphql_introspection(BaseModule):
|
|
|
27
27
|
self.output_dir = Path(output_folder) / "graphql-schemas"
|
|
28
28
|
else:
|
|
29
29
|
self.output_dir = self.scan.home / "graphql-schemas"
|
|
30
|
-
self.helpers.mkdir(self.output_dir)
|
|
31
30
|
return True
|
|
32
31
|
|
|
33
32
|
async def filter_event(self, event):
|
|
@@ -128,6 +127,7 @@ fragment TypeRef on __Type {
|
|
|
128
127
|
self.debug(f"Failed to parse JSON for {url}")
|
|
129
128
|
continue
|
|
130
129
|
if response_json.get("data", {}).get("__schema", {}).get("types", []):
|
|
130
|
+
self.helpers.mkdir(self.output_dir)
|
|
131
131
|
filename = f"schema-{self.helpers.tagify(url)}.json"
|
|
132
132
|
filename = self.output_dir / filename
|
|
133
133
|
with open(filename, "w") as f:
|
|
@@ -38,11 +38,6 @@ class BaseOutputModule(BaseModule):
|
|
|
38
38
|
if self._is_graph_important(event):
|
|
39
39
|
return True, "event is critical to the graph"
|
|
40
40
|
|
|
41
|
-
# exclude certain URLs (e.g. javascript):
|
|
42
|
-
# TODO: revisit this after httpx rework
|
|
43
|
-
if event.type.startswith("URL") and self.name != "httpx" and "httpx-only" in event.tags:
|
|
44
|
-
return False, (f"Omitting {event} from output because it's marked as httpx-only")
|
|
45
|
-
|
|
46
41
|
# omit certain event types
|
|
47
42
|
if event._omit:
|
|
48
43
|
if "target" in event.tags:
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from enum import IntEnum
|
|
3
|
+
from bbot.modules.base import BaseModule
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class RetireJSSeverity(IntEnum):
|
|
7
|
+
NONE = 0
|
|
8
|
+
LOW = 1
|
|
9
|
+
MEDIUM = 2
|
|
10
|
+
HIGH = 3
|
|
11
|
+
CRITICAL = 4
|
|
12
|
+
|
|
13
|
+
@classmethod
|
|
14
|
+
def from_string(cls, severity_str):
|
|
15
|
+
try:
|
|
16
|
+
return cls[severity_str.upper()]
|
|
17
|
+
except (KeyError, AttributeError):
|
|
18
|
+
return cls.NONE
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class retirejs(BaseModule):
|
|
22
|
+
watched_events = ["URL_UNVERIFIED"]
|
|
23
|
+
produced_events = ["FINDING"]
|
|
24
|
+
flags = ["active", "safe", "web-thorough"]
|
|
25
|
+
meta = {
|
|
26
|
+
"description": "Detect vulnerable/out-of-date JavaScript libraries",
|
|
27
|
+
"created_date": "2025-08-19",
|
|
28
|
+
"author": "@liquidsec",
|
|
29
|
+
}
|
|
30
|
+
options = {
|
|
31
|
+
"version": "5.3.0",
|
|
32
|
+
"node_version": "18.19.1",
|
|
33
|
+
"severity": "medium",
|
|
34
|
+
}
|
|
35
|
+
options_desc = {
|
|
36
|
+
"version": "retire.js version",
|
|
37
|
+
"node_version": "Node.js version to install locally",
|
|
38
|
+
"severity": "Minimum severity level to report (none, low, medium, high, critical)",
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
deps_ansible = [
|
|
42
|
+
# Download Node.js binary (Linux x64)
|
|
43
|
+
{
|
|
44
|
+
"name": "Download Node.js binary (Linux x64)",
|
|
45
|
+
"get_url": {
|
|
46
|
+
"url": "https://nodejs.org/dist/v#{BBOT_MODULES_RETIREJS_NODE_VERSION}/node-v#{BBOT_MODULES_RETIREJS_NODE_VERSION}-linux-x64.tar.xz",
|
|
47
|
+
"dest": "#{BBOT_TEMP}/node-v#{BBOT_MODULES_RETIREJS_NODE_VERSION}-linux-x64.tar.xz",
|
|
48
|
+
"mode": "0644",
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
# Extract Node.js binary (x64)
|
|
52
|
+
{
|
|
53
|
+
"name": "Extract Node.js binary (x64)",
|
|
54
|
+
"unarchive": {
|
|
55
|
+
"src": "#{BBOT_TEMP}/node-v#{BBOT_MODULES_RETIREJS_NODE_VERSION}-linux-x64.tar.xz",
|
|
56
|
+
"dest": "#{BBOT_TOOLS}",
|
|
57
|
+
"remote_src": True,
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
# Remove existing node directory if it exists
|
|
61
|
+
{
|
|
62
|
+
"name": "Remove existing node directory",
|
|
63
|
+
"file": {"path": "#{BBOT_TOOLS}/node", "state": "absent"},
|
|
64
|
+
},
|
|
65
|
+
# Rename extracted directory to 'node' (x64)
|
|
66
|
+
{
|
|
67
|
+
"name": "Rename Node.js directory (x64)",
|
|
68
|
+
"command": "mv #{BBOT_TOOLS}/node-v#{BBOT_MODULES_RETIREJS_NODE_VERSION}-linux-x64 #{BBOT_TOOLS}/node",
|
|
69
|
+
},
|
|
70
|
+
# Make Node.js binary executable
|
|
71
|
+
{
|
|
72
|
+
"name": "Make Node.js binary executable",
|
|
73
|
+
"file": {"path": "#{BBOT_TOOLS}/node/bin/node", "mode": "0755"},
|
|
74
|
+
},
|
|
75
|
+
# Make npm executable
|
|
76
|
+
{
|
|
77
|
+
"name": "Make npm executable",
|
|
78
|
+
"file": {"path": "#{BBOT_TOOLS}/node/bin/npm", "mode": "0755"},
|
|
79
|
+
},
|
|
80
|
+
# Remove existing retirejs directory if it exists
|
|
81
|
+
{
|
|
82
|
+
"name": "Remove existing retirejs directory",
|
|
83
|
+
"file": {"path": "#{BBOT_TOOLS}/retirejs", "state": "absent"},
|
|
84
|
+
},
|
|
85
|
+
# Create retire.js local directory
|
|
86
|
+
{
|
|
87
|
+
"name": "Create retire.js directory in BBOT_TOOLS",
|
|
88
|
+
"file": {"path": "#{BBOT_TOOLS}/retirejs", "state": "directory", "mode": "0755"},
|
|
89
|
+
},
|
|
90
|
+
# Install retire.js locally using local Node.js
|
|
91
|
+
{
|
|
92
|
+
"name": "Install retire.js locally",
|
|
93
|
+
"shell": "cd #{BBOT_TOOLS}/retirejs && #{BBOT_TOOLS}/node/bin/node #{BBOT_TOOLS}/node/lib/node_modules/npm/bin/npm-cli.js install retire@#{BBOT_MODULES_RETIREJS_VERSION} --no-fund --no-audit --silent --no-optional",
|
|
94
|
+
"args": {"creates": "#{BBOT_TOOLS}/retirejs/node_modules/.bin/retire"},
|
|
95
|
+
"timeout": 600,
|
|
96
|
+
"ignore_errors": False,
|
|
97
|
+
},
|
|
98
|
+
# Fix retire script shebang to use our local node binary
|
|
99
|
+
{
|
|
100
|
+
"name": "Fix retire script shebang",
|
|
101
|
+
"shell": "sed -i '1s|#!/usr/bin/env node|#!#{BBOT_TOOLS}/node/bin/node|' #{BBOT_TOOLS}/retirejs/node_modules/.bin/retire",
|
|
102
|
+
},
|
|
103
|
+
# Make retire script executable
|
|
104
|
+
{
|
|
105
|
+
"name": "Make retire script executable",
|
|
106
|
+
"file": {"path": "#{BBOT_TOOLS}/retirejs/node_modules/.bin/retire", "mode": "0755"},
|
|
107
|
+
},
|
|
108
|
+
# Create retire cache directory
|
|
109
|
+
{
|
|
110
|
+
"name": "Create retire cache directory",
|
|
111
|
+
"file": {"path": "#{BBOT_CACHE}/retire_cache", "state": "directory", "mode": "0755"},
|
|
112
|
+
},
|
|
113
|
+
]
|
|
114
|
+
|
|
115
|
+
accept_url_special = True
|
|
116
|
+
scope_distance_modifier = 1
|
|
117
|
+
_module_threads = 4
|
|
118
|
+
|
|
119
|
+
async def setup(self):
|
|
120
|
+
excavate_enabled = self.scan.config.get("excavate")
|
|
121
|
+
if not excavate_enabled:
|
|
122
|
+
return None, "retirejs will not function without excavate enabled"
|
|
123
|
+
|
|
124
|
+
# Validate severity level
|
|
125
|
+
valid_severities = ["none", "low", "medium", "high", "critical"]
|
|
126
|
+
configured_severity = self.config.get("severity", "medium").lower()
|
|
127
|
+
if configured_severity not in valid_severities:
|
|
128
|
+
return (
|
|
129
|
+
False,
|
|
130
|
+
f"Invalid severity level '{configured_severity}'. Valid options are: {', '.join(valid_severities)}",
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
self.repofile = await self.helpers.download(
|
|
134
|
+
"https://raw.githubusercontent.com/RetireJS/retire.js/master/repository/jsrepository-v4.json", cache_hrs=24
|
|
135
|
+
)
|
|
136
|
+
if not self.repofile:
|
|
137
|
+
return False, "failed to download retire.js repository file"
|
|
138
|
+
return True
|
|
139
|
+
|
|
140
|
+
async def handle_event(self, event):
|
|
141
|
+
js_file = await self.helpers.request(event.data)
|
|
142
|
+
if js_file:
|
|
143
|
+
js_file_body = js_file.text
|
|
144
|
+
if js_file_body:
|
|
145
|
+
js_file_body_saved = self.helpers.tempfile(js_file_body, pipe=False, extension="js")
|
|
146
|
+
results = await self.execute_retirejs(js_file_body_saved)
|
|
147
|
+
if not results:
|
|
148
|
+
self.warning("no output from retire.js")
|
|
149
|
+
return
|
|
150
|
+
results_json = json.loads(results)
|
|
151
|
+
if results_json.get("data"):
|
|
152
|
+
for file_result in results_json["data"]:
|
|
153
|
+
for component_result in file_result.get("results", []):
|
|
154
|
+
component = component_result.get("component", "unknown")
|
|
155
|
+
version = component_result.get("version", "unknown")
|
|
156
|
+
vulnerabilities = component_result.get("vulnerabilities", [])
|
|
157
|
+
for vuln in vulnerabilities:
|
|
158
|
+
severity = vuln.get("severity", "unknown")
|
|
159
|
+
|
|
160
|
+
# Filter by minimum severity level
|
|
161
|
+
min_severity = RetireJSSeverity.from_string(self.config.get("severity", "medium"))
|
|
162
|
+
vuln_severity = RetireJSSeverity.from_string(severity)
|
|
163
|
+
if vuln_severity < min_severity:
|
|
164
|
+
self.debug(
|
|
165
|
+
f"Skipping vulnerability with severity '{severity}' (below minimum '{min_severity.name.lower()}')"
|
|
166
|
+
)
|
|
167
|
+
continue
|
|
168
|
+
|
|
169
|
+
identifiers = vuln.get("identifiers", {})
|
|
170
|
+
summary = identifiers.get("summary", "Unknown vulnerability")
|
|
171
|
+
cves = identifiers.get("CVE", [])
|
|
172
|
+
description_parts = [
|
|
173
|
+
f"Vulnerable JavaScript library detected: {component} v{version}",
|
|
174
|
+
f"Severity: {severity.upper()}",
|
|
175
|
+
f"Summary: {summary}",
|
|
176
|
+
f"JavaScript URL: {event.data}",
|
|
177
|
+
]
|
|
178
|
+
if cves:
|
|
179
|
+
description_parts.append(f"CVE(s): {', '.join(cves)}")
|
|
180
|
+
|
|
181
|
+
below_version = vuln.get("below", "")
|
|
182
|
+
at_or_above = vuln.get("atOrAbove", "")
|
|
183
|
+
if at_or_above and below_version:
|
|
184
|
+
description_parts.append(f"Affected versions: [{at_or_above} to {below_version})")
|
|
185
|
+
elif below_version:
|
|
186
|
+
description_parts.append(f"Affected versions: [< {below_version}]")
|
|
187
|
+
elif at_or_above:
|
|
188
|
+
description_parts.append(f"Affected versions: [>= {at_or_above}]")
|
|
189
|
+
description = " ".join(description_parts)
|
|
190
|
+
data = {
|
|
191
|
+
"description": description,
|
|
192
|
+
"severity": severity,
|
|
193
|
+
"component": component,
|
|
194
|
+
"url": event.parent.data["url"],
|
|
195
|
+
}
|
|
196
|
+
await self.emit_event(
|
|
197
|
+
data,
|
|
198
|
+
"FINDING",
|
|
199
|
+
parent=event,
|
|
200
|
+
context=f"{{module}} identified vulnerable JavaScript library {component} v{version} ({severity} severity)",
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
async def filter_event(self, event):
|
|
204
|
+
url_extension = getattr(event, "url_extension", "")
|
|
205
|
+
if url_extension != "js":
|
|
206
|
+
return False, f"it is a {url_extension} URL but retirejs only accepts js URLs"
|
|
207
|
+
return True
|
|
208
|
+
|
|
209
|
+
async def execute_retirejs(self, js_file):
|
|
210
|
+
cache_dir = self.helpers.cache_dir / "retire_cache"
|
|
211
|
+
retire_dir = self.scan.helpers.tools_dir / "retirejs"
|
|
212
|
+
|
|
213
|
+
# Use the retire CLI script directly with our local node binary
|
|
214
|
+
local_node_dir = self.scan.helpers.tools_dir / "node"
|
|
215
|
+
retire_cli_script = retire_dir / "node_modules" / "retire" / "lib" / "cli.js"
|
|
216
|
+
|
|
217
|
+
command = [
|
|
218
|
+
str(local_node_dir / "bin" / "node"),
|
|
219
|
+
str(retire_cli_script),
|
|
220
|
+
"--outputformat",
|
|
221
|
+
"json",
|
|
222
|
+
"--cachedir",
|
|
223
|
+
str(cache_dir),
|
|
224
|
+
"--path",
|
|
225
|
+
js_file,
|
|
226
|
+
"--jsrepo",
|
|
227
|
+
str(self.repofile),
|
|
228
|
+
]
|
|
229
|
+
|
|
230
|
+
proxy = self.scan.web_config.get("http_proxy")
|
|
231
|
+
if proxy:
|
|
232
|
+
command.extend(["--proxy", proxy])
|
|
233
|
+
|
|
234
|
+
self.verbose(f"Running retire.js on {js_file}")
|
|
235
|
+
self.verbose(f"retire.js command: {command}")
|
|
236
|
+
|
|
237
|
+
result = await self.run_process(command)
|
|
238
|
+
return result.stdout
|
|
@@ -94,10 +94,6 @@ class ScanIngress(BaseInterceptModule):
|
|
|
94
94
|
# special handling of URL extensions
|
|
95
95
|
url_extension = getattr(event, "url_extension", None)
|
|
96
96
|
if url_extension is not None:
|
|
97
|
-
if url_extension in self.scan.url_extension_httpx_only:
|
|
98
|
-
event.add_tag("httpx-only")
|
|
99
|
-
event._omit = True
|
|
100
|
-
|
|
101
97
|
# blacklist by extension
|
|
102
98
|
if url_extension in self.scan.url_extension_blacklist:
|
|
103
99
|
self.debug(
|
|
@@ -209,6 +205,13 @@ class ScanEgress(BaseInterceptModule):
|
|
|
209
205
|
)
|
|
210
206
|
event.internal = True
|
|
211
207
|
|
|
208
|
+
# mark special URLs (e.g. Javascript) as internal so they don't get output except when they're critical to the graph
|
|
209
|
+
if event.type.startswith("URL"):
|
|
210
|
+
extension = getattr(event, "url_extension", "")
|
|
211
|
+
if extension in self.scan.url_extension_special:
|
|
212
|
+
event.internal = True
|
|
213
|
+
self.debug(f"Making {event} internal because it is a special URL (extension {extension})")
|
|
214
|
+
|
|
212
215
|
if event.type in self.scan.omitted_event_types:
|
|
213
216
|
self.debug(f"Omitting {event} because its type is omitted in the config")
|
|
214
217
|
event._omit = True
|
|
@@ -230,8 +230,8 @@ class Scanner:
|
|
|
230
230
|
)
|
|
231
231
|
|
|
232
232
|
# url file extensions
|
|
233
|
+
self.url_extension_special = {e.lower() for e in self.config.get("url_extension_special", [])}
|
|
233
234
|
self.url_extension_blacklist = {e.lower() for e in self.config.get("url_extension_blacklist", [])}
|
|
234
|
-
self.url_extension_httpx_only = {e.lower() for e in self.config.get("url_extension_httpx_only", [])}
|
|
235
235
|
|
|
236
236
|
# url querystring behavior
|
|
237
237
|
self.url_querystring_remove = self.config.get("url_querystring_remove", True)
|
|
@@ -22,8 +22,8 @@ def test_bbot_multiprocess(bbot_httpserver):
|
|
|
22
22
|
queue = multiprocessing.Queue()
|
|
23
23
|
events_process = multiprocessing.Process(target=run_bbot_multiprocess, args=(queue,))
|
|
24
24
|
events_process.start()
|
|
25
|
-
events_process.join()
|
|
26
|
-
events = queue.get()
|
|
25
|
+
events_process.join(timeout=300)
|
|
26
|
+
events = queue.get(timeout=10)
|
|
27
27
|
assert len(events) >= 3
|
|
28
28
|
scan_events = [e for e in events if e["type"] == "SCAN"]
|
|
29
29
|
assert len(scan_events) == 2
|
|
@@ -209,7 +209,6 @@ async def test_events(events, helpers):
|
|
|
209
209
|
javascript_event = scan.make_event("http://evilcorp.com/asdf/a.js?b=c#d", "URL_UNVERIFIED", parent=scan.root_event)
|
|
210
210
|
assert "extension-js" in javascript_event.tags
|
|
211
211
|
await scan.ingress_module.handle_event(javascript_event)
|
|
212
|
-
assert "httpx-only" in javascript_event.tags
|
|
213
212
|
|
|
214
213
|
# scope distance
|
|
215
214
|
event1 = scan.make_event("1.2.3.4", dummy=True)
|
|
@@ -147,24 +147,18 @@ async def test_task_scan_handle_event_timeout(bbot_scanner):
|
|
|
147
147
|
|
|
148
148
|
@pytest.mark.asyncio
|
|
149
149
|
async def test_url_extension_handling(bbot_scanner):
|
|
150
|
-
scan = bbot_scanner(config={"url_extension_blacklist": ["css"]
|
|
150
|
+
scan = bbot_scanner(config={"url_extension_blacklist": ["css"]})
|
|
151
151
|
await scan._prep()
|
|
152
152
|
assert scan.url_extension_blacklist == {"css"}
|
|
153
|
-
assert scan.url_extension_httpx_only == {"js"}
|
|
154
153
|
good_event = scan.make_event("https://evilcorp.com/a.txt", "URL", tags=["status-200"], parent=scan.root_event)
|
|
155
154
|
bad_event = scan.make_event("https://evilcorp.com/a.css", "URL", tags=["status-200"], parent=scan.root_event)
|
|
156
|
-
httpx_event = scan.make_event("https://evilcorp.com/a.js", "URL", tags=["status-200"], parent=scan.root_event)
|
|
157
155
|
assert "blacklisted" not in bad_event.tags
|
|
158
|
-
assert "httpx-only" not in httpx_event.tags
|
|
159
156
|
result = await scan.ingress_module.handle_event(good_event)
|
|
160
157
|
assert result is None
|
|
161
158
|
result, reason = await scan.ingress_module.handle_event(bad_event)
|
|
162
159
|
assert result is False
|
|
163
160
|
assert reason == "event is blacklisted"
|
|
164
161
|
assert "blacklisted" in bad_event.tags
|
|
165
|
-
result = await scan.ingress_module.handle_event(httpx_event)
|
|
166
|
-
assert result is None
|
|
167
|
-
assert "httpx-only" in httpx_event.tags
|
|
168
162
|
|
|
169
163
|
await scan._cleanup()
|
|
170
164
|
|
|
@@ -61,6 +61,7 @@ class ModuleTestBase:
|
|
|
61
61
|
config=self.config,
|
|
62
62
|
whitelist=module_test_base.whitelist,
|
|
63
63
|
blacklist=module_test_base.blacklist,
|
|
64
|
+
force_start=getattr(module_test_base, "force_start", False),
|
|
64
65
|
)
|
|
65
66
|
self.events = []
|
|
66
67
|
self.log = logging.getLogger(f"bbot.test.{module_test_base.name}")
|
{bbot-2.7.0.6962rc0 → bbot-2.7.0.6989rc0}/bbot/test/test_step_2/module_tests/test_module_excavate.py
RENAMED
|
@@ -24,14 +24,13 @@ class TestExcavate(ModuleTestBase):
|
|
|
24
24
|
\\x3dwww6.test.notreal
|
|
25
25
|
%0awww7.test.notreal
|
|
26
26
|
\\u000awww8.test.notreal
|
|
27
|
-
# these ones shouldn't get emitted because they're .js (url_extension_httpx_only)
|
|
28
|
-
<a href="/a_relative.js">
|
|
29
|
-
<link href="/link_relative.js">
|
|
30
|
-
# these ones should
|
|
31
27
|
<a href="/a_relative.txt">
|
|
32
28
|
<link href="/link_relative.txt">
|
|
33
29
|
<a href="mailto:bob@evilcorp.org?subject=help">Help</a>
|
|
34
30
|
<li class="toctree-l3"><a class="reference internal" href="miscellaneous.html#x50-uart-driver">16x50 UART Driver</a></li>
|
|
31
|
+
# these ones should get emitted as URL_UNVERIFIED events (processed by httpx which has accept_js_url=True)
|
|
32
|
+
<a href="/a_relative.js">
|
|
33
|
+
<link href="/link_relative.js">
|
|
35
34
|
"""
|
|
36
35
|
expect_args = {"method": "GET", "uri": "/"}
|
|
37
36
|
respond_args = {"response_data": response_data}
|
|
@@ -63,8 +62,9 @@ class TestExcavate(ModuleTestBase):
|
|
|
63
62
|
assert "www6.test.notreal" in event_data
|
|
64
63
|
assert "www7.test.notreal" in event_data
|
|
65
64
|
assert "www8.test.notreal" in event_data
|
|
66
|
-
|
|
67
|
-
assert "http://127.0.0.1:8888/
|
|
65
|
+
# .js files should be emitted as URL_UNVERIFIED events (they are processed by httpx which has accept_js_url=True)
|
|
66
|
+
assert "http://127.0.0.1:8888/a_relative.js" in event_data
|
|
67
|
+
assert "http://127.0.0.1:8888/link_relative.js" in event_data
|
|
68
68
|
assert "http://127.0.0.1:8888/a_relative.txt" in event_data
|
|
69
69
|
assert "http://127.0.0.1:8888/link_relative.txt" in event_data
|
|
70
70
|
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
from .base import ModuleTestBase
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class TestRetireJS(ModuleTestBase):
|
|
5
|
+
targets = ["http://127.0.0.1:8888"]
|
|
6
|
+
modules_overrides = ["httpx", "excavate", "retirejs"]
|
|
7
|
+
|
|
8
|
+
# HTML page with vulnerable JavaScript libraries
|
|
9
|
+
vulnerable_html = """<!doctype html>
|
|
10
|
+
<html lang="en">
|
|
11
|
+
<head>
|
|
12
|
+
<meta charset="utf-8" />
|
|
13
|
+
<title>retire.js test page</title>
|
|
14
|
+
</head>
|
|
15
|
+
<body>
|
|
16
|
+
<h1>retire.js test page</h1>
|
|
17
|
+
<p>This page includes JavaScript libraries for testing.</p>
|
|
18
|
+
|
|
19
|
+
<!-- jQuery 3.4.1 -->
|
|
20
|
+
<script src="/jquery-3.4.1.min.js"></script>
|
|
21
|
+
|
|
22
|
+
<!-- Lodash 4.17.11 -->
|
|
23
|
+
<script src="/lodash.min.js"></script>
|
|
24
|
+
|
|
25
|
+
<!-- Handlebars 4.0.5 -->
|
|
26
|
+
<script src="/handlebars.min.js"></script>
|
|
27
|
+
|
|
28
|
+
<script>
|
|
29
|
+
console.log('Libraries loaded');
|
|
30
|
+
</script>
|
|
31
|
+
</body>
|
|
32
|
+
</html>"""
|
|
33
|
+
|
|
34
|
+
# Sample jQuery 3.4.1 content
|
|
35
|
+
jquery_content = """/*!
|
|
36
|
+
* jQuery JavaScript Library v3.4.1
|
|
37
|
+
* https://jquery.com/
|
|
38
|
+
*/
|
|
39
|
+
(function( global, factory ) {
|
|
40
|
+
"use strict";
|
|
41
|
+
factory( global );
|
|
42
|
+
})(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
|
|
43
|
+
var jQuery = function( selector, context ) {
|
|
44
|
+
return new jQuery.fn.init( selector, context );
|
|
45
|
+
};
|
|
46
|
+
jQuery.fn = jQuery.prototype = {};
|
|
47
|
+
jQuery.fn.jquery = "3.4.1";
|
|
48
|
+
if ( typeof noGlobal === "undefined" ) {
|
|
49
|
+
window.jQuery = window.$ = jQuery;
|
|
50
|
+
}
|
|
51
|
+
return jQuery;
|
|
52
|
+
});"""
|
|
53
|
+
|
|
54
|
+
# Sample Lodash 4.17.11 content
|
|
55
|
+
lodash_content = """/**
|
|
56
|
+
* @license
|
|
57
|
+
* Lodash lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE
|
|
58
|
+
*/
|
|
59
|
+
;(function(){
|
|
60
|
+
var i="4.17.11";
|
|
61
|
+
var Mn={VERSION:i};
|
|
62
|
+
if(typeof define=="function"&&define.amd)define(function(){return Mn});else if(typeof module=="object"&&module.exports)module.exports=Mn;else this._=Mn}());"""
|
|
63
|
+
|
|
64
|
+
# Sample Handlebars 4.0.5 content
|
|
65
|
+
handlebars_content = """/*!
|
|
66
|
+
handlebars v4.0.5
|
|
67
|
+
*/
|
|
68
|
+
!function(a,b){"object"==typeof exports&&"object"==typeof module?module.exports=b():"function"==typeof define&&define.amd?define([],b):"object"==typeof exports?exports.Handlebars=b():a.Handlebars=b()}(this,function(){
|
|
69
|
+
var Handlebars={};
|
|
70
|
+
Handlebars.VERSION="4.0.5";
|
|
71
|
+
return Handlebars;
|
|
72
|
+
});"""
|
|
73
|
+
|
|
74
|
+
async def setup_after_prep(self, module_test):
|
|
75
|
+
expect_args = {"uri": "/"}
|
|
76
|
+
respond_args = {"response_data": self.vulnerable_html}
|
|
77
|
+
module_test.set_expect_requests(expect_args, respond_args)
|
|
78
|
+
|
|
79
|
+
expect_args = {"uri": "/jquery-3.4.1.min.js"}
|
|
80
|
+
respond_args = {"response_data": self.jquery_content}
|
|
81
|
+
module_test.set_expect_requests(expect_args, respond_args)
|
|
82
|
+
|
|
83
|
+
expect_args = {"uri": "/lodash.min.js"}
|
|
84
|
+
respond_args = {"response_data": self.lodash_content}
|
|
85
|
+
module_test.set_expect_requests(expect_args, respond_args)
|
|
86
|
+
|
|
87
|
+
expect_args = {"uri": "/handlebars.min.js"}
|
|
88
|
+
respond_args = {"response_data": self.handlebars_content}
|
|
89
|
+
module_test.set_expect_requests(expect_args, respond_args)
|
|
90
|
+
|
|
91
|
+
def check(self, module_test, events):
|
|
92
|
+
# Check that excavate found the JavaScript URLs
|
|
93
|
+
url_unverified_events = [e for e in events if e.type == "URL_UNVERIFIED"]
|
|
94
|
+
js_url_events = [e for e in url_unverified_events if "extension-js" in e.tags]
|
|
95
|
+
|
|
96
|
+
# We should have found the JavaScript URLs
|
|
97
|
+
assert len(url_unverified_events) > 0, "No URL_UNVERIFIED events found - excavate may not be working"
|
|
98
|
+
assert len(js_url_events) >= 3, f"Expected at least 3 JavaScript URLs, found {len(js_url_events)}"
|
|
99
|
+
|
|
100
|
+
# Check for FINDING events generated by retirejs
|
|
101
|
+
finding_events = [e for e in events if e.type == "FINDING"]
|
|
102
|
+
retirejs_findings = [
|
|
103
|
+
e
|
|
104
|
+
for e in finding_events
|
|
105
|
+
if "vulnerable javascript library detected:" in e.data.get("description", "").lower()
|
|
106
|
+
]
|
|
107
|
+
|
|
108
|
+
# We should have at least some findings from our vulnerable libraries
|
|
109
|
+
assert len(retirejs_findings) > 0, (
|
|
110
|
+
f"Expected retirejs to find vulnerabilities, but got {len(retirejs_findings)} findings"
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
# Check for specific expected vulnerability descriptions
|
|
114
|
+
descriptions = [finding.data.get("description", "") for finding in retirejs_findings]
|
|
115
|
+
all_descriptions = "\n".join(descriptions)
|
|
116
|
+
|
|
117
|
+
# Look for specific vulnerabilities we expect to find
|
|
118
|
+
expected_handlebars_vuln = "Vulnerable JavaScript library detected: handlebars v4.0.5 Severity: HIGH Summary: Regular Expression Denial of Service in Handlebars JavaScript URL: http://127.0.0.1:8888/handlebars.min.js CVE(s): CVE-2019-20922 Affected versions: [4.0.0 to 4.4.5)"
|
|
119
|
+
expected_jquery_vuln = "Vulnerable JavaScript library detected: jquery v3.4.1 Severity: MEDIUM Summary: Regex in its jQuery.htmlPrefilter sometimes may introduce XSS JavaScript URL: http://127.0.0.1:8888/jquery-3.4.1.min.js CVE(s): CVE-2020-11022 Affected versions: [1.2.0 to 3.5.0)"
|
|
120
|
+
|
|
121
|
+
# Verify at least one of the expected vulnerabilities is found
|
|
122
|
+
handlebars_found = expected_handlebars_vuln in all_descriptions
|
|
123
|
+
jquery_found = expected_jquery_vuln in all_descriptions
|
|
124
|
+
|
|
125
|
+
assert handlebars_found and jquery_found, (
|
|
126
|
+
f"Expected to find specific vulnerabilities but didn't find them. Found descriptions:\n{all_descriptions}"
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
# Basic validation of findings structure
|
|
130
|
+
for finding in retirejs_findings:
|
|
131
|
+
assert "description" in finding.data, "Finding should have description"
|
|
132
|
+
assert "url" in finding.data, "Finding should have url"
|
|
133
|
+
assert finding.parent.type == "URL_UNVERIFIED", "Parent should be URL_UNVERIFIED"
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
class TestRetireJSNoExcavate(ModuleTestBase):
|
|
137
|
+
targets = ["http://127.0.0.1:8888"]
|
|
138
|
+
modules_overrides = ["httpx", "retirejs"]
|
|
139
|
+
force_start = True # Allow scan to continue even if modules fail setup
|
|
140
|
+
config_overrides = {
|
|
141
|
+
"excavate": False,
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
def check(self, module_test, events):
|
|
145
|
+
# When excavate is disabled, retirejs should fail setup but scan should still run
|
|
146
|
+
retirejs_module = module_test.scan.modules.get("retirejs")
|
|
147
|
+
|
|
148
|
+
if retirejs_module:
|
|
149
|
+
# Check that the module exists but setup failed
|
|
150
|
+
setup_status = getattr(retirejs_module, "_setup_status", None)
|
|
151
|
+
if setup_status is not None:
|
|
152
|
+
success, error_msg = setup_status
|
|
153
|
+
assert success is False, "retirejs setup should have failed without excavate"
|
|
154
|
+
expected_error = "retirejs will not function without excavate enabled"
|
|
155
|
+
assert error_msg == expected_error, f"Expected error message '{expected_error}', but got '{error_msg}'"
|
|
156
|
+
|
|
157
|
+
# No retirejs findings should be generated since setup failed
|
|
158
|
+
retirejs_findings = [e for e in events if e.type == "FINDING" and getattr(e, "module", None) == "retirejs"]
|
|
159
|
+
assert len(retirejs_findings) == 0, "retirejs should not generate findings when setup fails"
|