Migrating from BBOT 3.0 to 3.1
BBOT 3.1 is a minor release, but it includes a handful of changes that can affect existing presets, configs, custom modules, and anything that consumes scan output. This page lists them so you can check your setup before upgrading.
If a change is missing here, please open an issue.
Config and Presets
Custom module folders (module_dirs)
module_dirs is now only honored as a top-level preset key, loaded with -p:
module_dirs:
- /home/user/my_modules
| 3.0 | 3.1 |
|---|---|
config.module_dirs (in bbot.yml, under config: in a preset, or -c module_dirs=...) loaded custom modules |
deprecated and ignored, with a warning at scan start |
| custom modules loaded without asking | BBOT asks before loading each custom module folder |
| a custom module could replace a built-in module with the same name | refused with an error |
-S / --silent implied -y, auto-trusting custom module folders |
-S no longer implies -y; a silent run refuses an untrusted folder (with a visible error) unless -y is also passed |
Loading custom modules now works like this:
- Before anything in a custom module folder is read, BBOT lists its modules and asks
Do you trust this folder? [y/N]. Without a terminal (CI, cron, pipes), it refuses unless-yis passed. - A folder, parent folder, or module file that is world-writable is refused, with the
chmodcommand to fix it. Sticky parents like/tmpare allowed. Folders or files writable by a group are noted in the prompt. - If the folder is owned by another user (common with
sudo, or folders mounted into the Docker image), the prompt says so. - A custom module can't reuse the name of an existing module, built-in or custom. Rename it and leave the original off.
- A custom module folder can't be named
modules(it collides with BBOT's built-in module package). - Custom modules are loaded from source, not from any cached bytecode (
__pycache__).
-y trusts custom module folders
-y / --yes answers the trust prompt automatically. The warning still prints, but the modules load. Only pass -y with presets you trust. -S / --silent does not answer the prompt: a silent run without -y stops with an error.
See Custom Modules for details.
Preset conditions are read-only
Preset conditions can now only read the preset and config (plus warn() / abort()); they can no longer modify the preset or call its methods. A condition that changed the preset (like the old {{ preset.exclude_module("webbrute") }} example) now errors. Conditions that check config and warn or abort are unaffected.
version and home are validated
Because they're interpolated into dependency install commands, a module's version option and the global home option are now validated when the preset is checked: version must be a version-like string, and home can't contain shell metacharacters. A value that doesn't fit stops the scan before it starts instead of ending up in a shell command.
Deprecated retries options
The retries option on slack, discord, teams, and shodan_idb no longer does anything. Retries and rate limits are now handled by the shared API request logic. The option is still accepted, but it's ignored and BBOT warns about it at scan start.
Nuclei options are validated up front
modules.nuclei.severity, exclude_severity, and protocol_types are now checked when the preset is validated. A typo that used to fail partway into a scan now stops the scan before it starts.
CDN/WAF Port Filtering
CDN/WAF port filtering moved out of the portfilter module and into the core, and it's now on by default.
| 3.0 | 3.1 |
|---|---|
portfilter module (opt-in, enabled by some presets) |
removed; filtering is built in and on by default |
modules.portfilter.cdn_tags |
cdn_port_filter.tags |
modules.portfilter.allowed_cdn_ports |
cdn_port_filter.allowed_ports |
--exclude-cdn / -ec |
deprecated, does nothing |
| (no equivalent) | --allow-cdn-ports / cdn_port_filter.enabled: false turns the filter off |
By default, open ports other than 80 and 443 are dropped on hosts tagged cdn or waf. If you relied on seeing every port on CDN hosts, pass --allow-cdn-ports.
Remove portfilter from presets
Presets that list portfilter under modules need to be updated, since the module no longer exists.
Modules
dnsdumpster requires an API key
dnsdumpster no longer has a keyless mode. Set modules.dnsdumpster.api_key, or the module is disabled at setup.
waf_bypass only targets scan targets by default
modules.waf_bypass.scan_targets_only now defaults to true, so bypasses are only attempted against hosts named in the scan's targets or seeds. Set it to false for the old behavior.
wayback checks hosts before emitting URLs
With urls: true, wayback now probes each host once and drops URLs on hosts that don't respond. Expect fewer, but live, URLs from wayback.
Event Output
CPE-based technology names
TECHNOLOGY events from shodan_idb, shodan_enterprise, and censys_ip that come from a CPE now use the product name (e.g. jquery) instead of the raw CPE string. The CPE moves to a new cpe field. Anything that matched on the CPE string in technology should match on cpe instead.
No affiliate tag on in-scope events
In-scope events are no longer tagged affiliate. Filters that relied on that tag for in-scope events will need updating.
wayback HTTP_RESPONSE events
HTTP_RESPONSE events from wayback are now built the same way as those from http, so some keys in their data have changed. They also no longer include cert_info, which described archive.org's certificate rather than the target's.
Python API / Custom Modules
| 3.0 | 3.1 |
|---|---|
self.helpers.response_to_json(response) |
removed; use response_to_event_dict() from bbot.core.helpers.web.response_event |