bbot 2.3.0.5336rc0__py3-none-any.whl → 2.3.0.5362rc0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of bbot might be problematic. Click here for more details.
- bbot/__init__.py +1 -1
- bbot/core/helpers/depsinstaller/installer.py +2 -1
- bbot/db/sql/models.py +5 -5
- bbot/defaults.yml +7 -8
- bbot/modules/internal/cloudcheck.py +20 -5
- bbot/modules/output/mysql.py +51 -0
- bbot/modules/portscan.py +28 -2
- bbot/modules/templates/sql.py +5 -0
- bbot/modules/templates/subdomain_enum.py +1 -1
- bbot/test/test.conf +2 -0
- bbot/test/test_step_2/module_tests/test_module_cloudcheck.py +4 -0
- bbot/test/test_step_2/module_tests/test_module_mysql.py +76 -0
- bbot/test/test_step_2/module_tests/test_module_portscan.py +6 -4
- {bbot-2.3.0.5336rc0.dist-info → bbot-2.3.0.5362rc0.dist-info}/METADATA +21 -3
- {bbot-2.3.0.5336rc0.dist-info → bbot-2.3.0.5362rc0.dist-info}/RECORD +18 -16
- {bbot-2.3.0.5336rc0.dist-info → bbot-2.3.0.5362rc0.dist-info}/LICENSE +0 -0
- {bbot-2.3.0.5336rc0.dist-info → bbot-2.3.0.5362rc0.dist-info}/WHEEL +0 -0
- {bbot-2.3.0.5336rc0.dist-info → bbot-2.3.0.5362rc0.dist-info}/entry_points.txt +0 -0
bbot/__init__.py
CHANGED
|
@@ -49,7 +49,8 @@ class DepsInstaller:
|
|
|
49
49
|
self.minimal_git_config.touch()
|
|
50
50
|
os.environ["GIT_CONFIG_GLOBAL"] = str(self.minimal_git_config)
|
|
51
51
|
|
|
52
|
-
self.
|
|
52
|
+
self.deps_config = self.parent_helper.config.get("deps", {})
|
|
53
|
+
self.deps_behavior = self.deps_config.get("behavior", "abort_on_failure").lower()
|
|
53
54
|
self.ansible_debug = self.core.logger.log_level <= logging.DEBUG
|
|
54
55
|
self.venv = ""
|
|
55
56
|
if sys.prefix != sys.base_prefix:
|
bbot/db/sql/models.py
CHANGED
|
@@ -141,8 +141,8 @@ class Target(BBOTBaseModel, table=True):
|
|
|
141
141
|
seeds: List = Field(default=[], sa_type=JSON)
|
|
142
142
|
whitelist: List = Field(default=None, sa_type=JSON)
|
|
143
143
|
blacklist: List = Field(default=[], sa_type=JSON)
|
|
144
|
-
hash: str = Field(sa_column=Column("hash", String, unique=True, primary_key=True, index=True))
|
|
145
|
-
scope_hash: str = Field(sa_column=Column("scope_hash", String, index=True))
|
|
146
|
-
seed_hash: str = Field(sa_column=Column("seed_hashhash", String, index=True))
|
|
147
|
-
whitelist_hash: str = Field(sa_column=Column("whitelist_hash", String, index=True))
|
|
148
|
-
blacklist_hash: str = Field(sa_column=Column("blacklist_hash", String, index=True))
|
|
144
|
+
hash: str = Field(sa_column=Column("hash", String(length=255), unique=True, primary_key=True, index=True))
|
|
145
|
+
scope_hash: str = Field(sa_column=Column("scope_hash", String(length=255), index=True))
|
|
146
|
+
seed_hash: str = Field(sa_column=Column("seed_hashhash", String(length=255), index=True))
|
|
147
|
+
whitelist_hash: str = Field(sa_column=Column("whitelist_hash", String(length=255), index=True))
|
|
148
|
+
blacklist_hash: str = Field(sa_column=Column("blacklist_hash", String(length=255), index=True))
|
bbot/defaults.yml
CHANGED
|
@@ -112,6 +112,13 @@ engine:
|
|
|
112
112
|
deps:
|
|
113
113
|
ffuf:
|
|
114
114
|
version: "2.1.0"
|
|
115
|
+
# How to handle installation of module dependencies
|
|
116
|
+
# Choices are:
|
|
117
|
+
# - abort_on_failure (default) - if a module dependency fails to install, abort the scan
|
|
118
|
+
# - retry_failed - try again to install failed dependencies
|
|
119
|
+
# - ignore_failed - run the scan regardless of what happens with dependency installation
|
|
120
|
+
# - disable - completely disable BBOT's dependency system (you are responsible for installing tools, pip packages, etc.)
|
|
121
|
+
behavior: abort_on_failure
|
|
115
122
|
|
|
116
123
|
### ADVANCED OPTIONS ###
|
|
117
124
|
|
|
@@ -129,14 +136,6 @@ dnsresolve: True
|
|
|
129
136
|
# Cloud provider tagging
|
|
130
137
|
cloudcheck: True
|
|
131
138
|
|
|
132
|
-
# How to handle installation of module dependencies
|
|
133
|
-
# Choices are:
|
|
134
|
-
# - abort_on_failure (default) - if a module dependency fails to install, abort the scan
|
|
135
|
-
# - retry_failed - try again to install failed dependencies
|
|
136
|
-
# - ignore_failed - run the scan regardless of what happens with dependency installation
|
|
137
|
-
# - disable - completely disable BBOT's dependency system (you are responsible for installing tools, pip packages, etc.)
|
|
138
|
-
deps_behavior: abort_on_failure
|
|
139
|
-
|
|
140
139
|
# Strip querystring from URLs by default
|
|
141
140
|
url_querystring_remove: True
|
|
142
141
|
# When query string is retained, by default collapse parameter values down to a single value per parameter
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from contextlib import suppress
|
|
2
|
+
|
|
1
3
|
from bbot.modules.base import BaseInterceptModule
|
|
2
4
|
|
|
3
5
|
|
|
@@ -28,15 +30,28 @@ class CloudCheck(BaseInterceptModule):
|
|
|
28
30
|
if self.dummy_modules is None:
|
|
29
31
|
self.make_dummy_modules()
|
|
30
32
|
# cloud tagging by hosts
|
|
31
|
-
hosts_to_check = set(
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
hosts_to_check = set(event.resolved_hosts)
|
|
34
|
+
with suppress(KeyError):
|
|
35
|
+
hosts_to_check.remove(event.host_original)
|
|
36
|
+
hosts_to_check = [event.host_original] + list(hosts_to_check)
|
|
37
|
+
|
|
38
|
+
for i, host in enumerate(hosts_to_check):
|
|
39
|
+
host_is_ip = self.helpers.is_ip(host)
|
|
35
40
|
for provider, provider_type, subnet in self.helpers.cloudcheck(host):
|
|
36
41
|
if provider:
|
|
37
42
|
event.add_tag(f"{provider_type}-{provider}")
|
|
43
|
+
if host_is_ip:
|
|
44
|
+
event.add_tag(f"{provider_type}-ip")
|
|
45
|
+
else:
|
|
46
|
+
# if the original hostname is a cloud domain, tag it as such
|
|
47
|
+
if i == 0:
|
|
48
|
+
event.add_tag(f"{provider_type}-domain")
|
|
49
|
+
# any children are tagged as CNAMEs
|
|
50
|
+
else:
|
|
51
|
+
event.add_tag(f"{provider_type}-cname")
|
|
38
52
|
|
|
39
53
|
found = set()
|
|
54
|
+
str_hosts_to_check = [str(host) for host in hosts_to_check]
|
|
40
55
|
# look for cloud assets in hosts, http responses
|
|
41
56
|
# loop through each provider
|
|
42
57
|
for provider in self.helpers.cloud.providers.values():
|
|
@@ -54,7 +69,7 @@ class CloudCheck(BaseInterceptModule):
|
|
|
54
69
|
if event.type == "HTTP_RESPONSE":
|
|
55
70
|
matches = await self.helpers.re.findall(sig, event.data.get("body", ""))
|
|
56
71
|
elif event.type.startswith("DNS_NAME"):
|
|
57
|
-
for host in
|
|
72
|
+
for host in str_hosts_to_check:
|
|
58
73
|
match = sig.match(host)
|
|
59
74
|
if match:
|
|
60
75
|
matches.append(match.groups())
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
from bbot.modules.templates.sql import SQLTemplate
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class MySQL(SQLTemplate):
|
|
5
|
+
watched_events = ["*"]
|
|
6
|
+
meta = {"description": "Output scan data to a MySQL database"}
|
|
7
|
+
options = {
|
|
8
|
+
"username": "root",
|
|
9
|
+
"password": "bbotislife",
|
|
10
|
+
"host": "localhost",
|
|
11
|
+
"port": 3306,
|
|
12
|
+
"database": "bbot",
|
|
13
|
+
}
|
|
14
|
+
options_desc = {
|
|
15
|
+
"username": "The username to connect to MySQL",
|
|
16
|
+
"password": "The password to connect to MySQL",
|
|
17
|
+
"host": "The server running MySQL",
|
|
18
|
+
"port": "The port to connect to MySQL",
|
|
19
|
+
"database": "The database name to connect to",
|
|
20
|
+
}
|
|
21
|
+
deps_pip = ["sqlmodel", "aiomysql"]
|
|
22
|
+
protocol = "mysql+aiomysql"
|
|
23
|
+
|
|
24
|
+
async def create_database(self):
|
|
25
|
+
from sqlalchemy import text
|
|
26
|
+
from sqlalchemy.ext.asyncio import create_async_engine
|
|
27
|
+
|
|
28
|
+
# Create the engine for the initial connection to the server
|
|
29
|
+
initial_engine = create_async_engine(self.connection_string().rsplit("/", 1)[0])
|
|
30
|
+
|
|
31
|
+
async with initial_engine.connect() as conn:
|
|
32
|
+
# Check if the database exists
|
|
33
|
+
result = await conn.execute(text(f"SHOW DATABASES LIKE '{self.database}'"))
|
|
34
|
+
database_exists = result.scalar() is not None
|
|
35
|
+
|
|
36
|
+
# Create the database if it does not exist
|
|
37
|
+
if not database_exists:
|
|
38
|
+
# Use aiomysql directly to create the database
|
|
39
|
+
import aiomysql
|
|
40
|
+
|
|
41
|
+
raw_conn = await aiomysql.connect(
|
|
42
|
+
user=self.username,
|
|
43
|
+
password=self.password,
|
|
44
|
+
host=self.host,
|
|
45
|
+
port=self.port,
|
|
46
|
+
)
|
|
47
|
+
try:
|
|
48
|
+
async with raw_conn.cursor() as cursor:
|
|
49
|
+
await cursor.execute(f"CREATE DATABASE {self.database}")
|
|
50
|
+
finally:
|
|
51
|
+
await raw_conn.ensure_closed()
|
bbot/modules/portscan.py
CHANGED
|
@@ -6,6 +6,9 @@ from radixtarget import RadixTarget
|
|
|
6
6
|
from bbot.modules.base import BaseModule
|
|
7
7
|
|
|
8
8
|
|
|
9
|
+
# TODO: this module is getting big. It should probably be two modules: one for ping and one for SYN.
|
|
10
|
+
|
|
11
|
+
|
|
9
12
|
class portscan(BaseModule):
|
|
10
13
|
flags = ["active", "portscan", "safe"]
|
|
11
14
|
watched_events = ["IP_ADDRESS", "IP_RANGE", "DNS_NAME"]
|
|
@@ -27,6 +30,8 @@ class portscan(BaseModule):
|
|
|
27
30
|
"adapter_ip": "",
|
|
28
31
|
"adapter_mac": "",
|
|
29
32
|
"router_mac": "",
|
|
33
|
+
"cdn_tags": "cdn-",
|
|
34
|
+
"allowed_cdn_ports": None,
|
|
30
35
|
}
|
|
31
36
|
options_desc = {
|
|
32
37
|
"top_ports": "Top ports to scan (default 100) (to override, specify 'ports')",
|
|
@@ -39,6 +44,8 @@ class portscan(BaseModule):
|
|
|
39
44
|
"adapter_ip": "Send packets using this IP address. Not needed unless masscan's autodetection fails",
|
|
40
45
|
"adapter_mac": "Send packets using this as the source MAC address. Not needed unless masscan's autodetection fails",
|
|
41
46
|
"router_mac": "Send packets to this MAC address as the destination. Not needed unless masscan's autodetection fails",
|
|
47
|
+
"cdn_tags": "Comma-separated list of tags to skip, e.g. 'cdn,cloud'",
|
|
48
|
+
"allowed_cdn_ports": "Comma-separated list of ports that are allowed to be scanned for CDNs",
|
|
42
49
|
}
|
|
43
50
|
deps_common = ["masscan"]
|
|
44
51
|
batch_size = 1000000
|
|
@@ -60,7 +67,15 @@ class portscan(BaseModule):
|
|
|
60
67
|
try:
|
|
61
68
|
self.helpers.parse_port_string(self.ports)
|
|
62
69
|
except ValueError as e:
|
|
63
|
-
return False, f"Error parsing ports: {e}"
|
|
70
|
+
return False, f"Error parsing ports '{self.ports}': {e}"
|
|
71
|
+
self.cdn_tags = [t.strip() for t in self.config.get("cdn_tags", "").split(",")]
|
|
72
|
+
self.allowed_cdn_ports = self.config.get("allowed_cdn_ports", None)
|
|
73
|
+
if self.allowed_cdn_ports is not None:
|
|
74
|
+
try:
|
|
75
|
+
self.allowed_cdn_ports = [int(p.strip()) for p in self.allowed_cdn_ports.split(",")]
|
|
76
|
+
except Exception as e:
|
|
77
|
+
return False, f"Error parsing allowed CDN ports '{self.allowed_cdn_ports}': {e}"
|
|
78
|
+
|
|
64
79
|
# whether we've finished scanning our original scan targets
|
|
65
80
|
self.scanned_initial_targets = False
|
|
66
81
|
# keeps track of individual scanned IPs and their open ports
|
|
@@ -227,9 +242,20 @@ class portscan(BaseModule):
|
|
|
227
242
|
parent=parent_event,
|
|
228
243
|
context=f"{{module}} executed a {scan_type} scan against {parent_event.data} and found: {{event.type}}: {{event.data}}",
|
|
229
244
|
)
|
|
230
|
-
|
|
245
|
+
|
|
246
|
+
await self.emit_event(event, abort_if=self.abort_if)
|
|
231
247
|
return event
|
|
232
248
|
|
|
249
|
+
def abort_if(self, event):
|
|
250
|
+
if self.allowed_cdn_ports is not None:
|
|
251
|
+
# if the host is a CDN
|
|
252
|
+
for cdn_tag in self.cdn_tags:
|
|
253
|
+
if any(t.startswith(str(cdn_tag)) for t in event.tags):
|
|
254
|
+
# and if its port isn't in the list of allowed CDN ports
|
|
255
|
+
if event.port not in self.allowed_cdn_ports:
|
|
256
|
+
return True, "event is a CDN and port is not in the allowed list"
|
|
257
|
+
return False
|
|
258
|
+
|
|
233
259
|
def parse_json_line(self, line):
|
|
234
260
|
try:
|
|
235
261
|
j = json.loads(line)
|
bbot/modules/templates/sql.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from contextlib import suppress
|
|
1
2
|
from sqlmodel import SQLModel
|
|
2
3
|
from sqlalchemy.orm import sessionmaker
|
|
3
4
|
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
|
|
@@ -88,3 +89,7 @@ class SQLTemplate(BaseOutputModule):
|
|
|
88
89
|
if self.database:
|
|
89
90
|
connection_string += f"/{self.database}"
|
|
90
91
|
return connection_string
|
|
92
|
+
|
|
93
|
+
async def cleanup(self):
|
|
94
|
+
with suppress(Exception):
|
|
95
|
+
await self.engine.dispose()
|
|
@@ -169,7 +169,7 @@ class subdomain_enum(BaseModule):
|
|
|
169
169
|
if any(t.startswith("cloud-") for t in event.tags):
|
|
170
170
|
is_cloud = True
|
|
171
171
|
# reject if it's a cloud resource and not in our target
|
|
172
|
-
if is_cloud and event not in self.scan.target:
|
|
172
|
+
if is_cloud and event not in self.scan.target.whitelist:
|
|
173
173
|
return False, "Event is a cloud resource and not a direct target"
|
|
174
174
|
# optionally reject events with wildcards / errors
|
|
175
175
|
if self.reject_wildcards:
|
bbot/test/test.conf
CHANGED
|
@@ -51,6 +51,10 @@ class TestCloudCheck(ModuleTestBase):
|
|
|
51
51
|
await module.handle_event(event)
|
|
52
52
|
assert "cloud-amazon" in event.tags, f"{event} was not properly cloud-tagged"
|
|
53
53
|
|
|
54
|
+
assert "cloud-domain" in aws_event1.tags
|
|
55
|
+
assert "cloud-ip" in other_event2.tags
|
|
56
|
+
assert "cloud-cname" in other_event3.tags
|
|
57
|
+
|
|
54
58
|
for event in (aws_event3, other_event1):
|
|
55
59
|
await module.handle_event(event)
|
|
56
60
|
assert "cloud-amazon" not in event.tags, f"{event} was improperly cloud-tagged"
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import time
|
|
3
|
+
|
|
4
|
+
from .base import ModuleTestBase
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class TestMySQL(ModuleTestBase):
|
|
8
|
+
targets = ["evilcorp.com"]
|
|
9
|
+
skip_distro_tests = True
|
|
10
|
+
|
|
11
|
+
async def setup_before_prep(self, module_test):
|
|
12
|
+
process = await asyncio.create_subprocess_exec(
|
|
13
|
+
"docker",
|
|
14
|
+
"run",
|
|
15
|
+
"--name",
|
|
16
|
+
"bbot-test-mysql",
|
|
17
|
+
"--rm",
|
|
18
|
+
"-e",
|
|
19
|
+
"MYSQL_ROOT_PASSWORD=bbotislife",
|
|
20
|
+
"-e",
|
|
21
|
+
"MYSQL_DATABASE=bbot",
|
|
22
|
+
"-p",
|
|
23
|
+
"3306:3306",
|
|
24
|
+
"-d",
|
|
25
|
+
"mysql",
|
|
26
|
+
stdout=asyncio.subprocess.PIPE,
|
|
27
|
+
stderr=asyncio.subprocess.PIPE,
|
|
28
|
+
)
|
|
29
|
+
stdout, stderr = await process.communicate()
|
|
30
|
+
|
|
31
|
+
import aiomysql
|
|
32
|
+
|
|
33
|
+
# wait for the container to start
|
|
34
|
+
start_time = time.time()
|
|
35
|
+
while True:
|
|
36
|
+
try:
|
|
37
|
+
conn = await aiomysql.connect(user="root", password="bbotislife", db="bbot", host="localhost")
|
|
38
|
+
conn.close()
|
|
39
|
+
break
|
|
40
|
+
except Exception as e:
|
|
41
|
+
if time.time() - start_time > 60: # timeout after 60 seconds
|
|
42
|
+
self.log.error("MySQL server did not start in time.")
|
|
43
|
+
raise e
|
|
44
|
+
await asyncio.sleep(1)
|
|
45
|
+
|
|
46
|
+
if process.returncode != 0:
|
|
47
|
+
self.log.error(f"Failed to start MySQL server: {stderr.decode()}")
|
|
48
|
+
|
|
49
|
+
async def check(self, module_test, events):
|
|
50
|
+
import aiomysql
|
|
51
|
+
|
|
52
|
+
# Connect to the MySQL database
|
|
53
|
+
conn = await aiomysql.connect(user="root", password="bbotislife", db="bbot", host="localhost")
|
|
54
|
+
|
|
55
|
+
try:
|
|
56
|
+
async with conn.cursor() as cur:
|
|
57
|
+
await cur.execute("SELECT * FROM event")
|
|
58
|
+
events = await cur.fetchall()
|
|
59
|
+
assert len(events) == 3, "No events found in MySQL database"
|
|
60
|
+
|
|
61
|
+
await cur.execute("SELECT * FROM scan")
|
|
62
|
+
scans = await cur.fetchall()
|
|
63
|
+
assert len(scans) == 1, "No scans found in MySQL database"
|
|
64
|
+
|
|
65
|
+
await cur.execute("SELECT * FROM target")
|
|
66
|
+
targets = await cur.fetchall()
|
|
67
|
+
assert len(targets) == 1, "No targets found in MySQL database"
|
|
68
|
+
finally:
|
|
69
|
+
conn.close()
|
|
70
|
+
process = await asyncio.create_subprocess_exec(
|
|
71
|
+
"docker", "stop", "bbot-test-mysql", stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
|
|
72
|
+
)
|
|
73
|
+
stdout, stderr = await process.communicate()
|
|
74
|
+
|
|
75
|
+
if process.returncode != 0:
|
|
76
|
+
raise Exception(f"Failed to stop MySQL server: {stderr.decode()}")
|
|
@@ -109,10 +109,12 @@ class TestPortscan(ModuleTestBase):
|
|
|
109
109
|
if e.type == "DNS_NAME" and e.data == "dummy.asdf.evilcorp.net" and str(e.module) == "dummy_module"
|
|
110
110
|
]
|
|
111
111
|
)
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
assert 2 <= len([e for e in events if e.type == "IP_ADDRESS" and e.data == "8.8.
|
|
115
|
-
assert 2 <= len([e for e in events if e.type == "IP_ADDRESS" and e.data == "8.8.4.
|
|
112
|
+
# the reason these numbers aren't exactly predictable is because we can't predict which one arrives first
|
|
113
|
+
# to the portscan module. Sometimes, one that would normally be deduped is force-emitted because it led to a new open port.
|
|
114
|
+
assert 2 <= len([e for e in events if e.type == "IP_ADDRESS" and e.data == "8.8.8.8"]) <= 4
|
|
115
|
+
assert 2 <= len([e for e in events if e.type == "IP_ADDRESS" and e.data == "8.8.4.4"]) <= 4
|
|
116
|
+
assert 2 <= len([e for e in events if e.type == "IP_ADDRESS" and e.data == "8.8.4.5"]) <= 4
|
|
117
|
+
assert 2 <= len([e for e in events if e.type == "IP_ADDRESS" and e.data == "8.8.4.6"]) <= 4
|
|
116
118
|
assert 1 == len([e for e in events if e.type == "OPEN_TCP_PORT" and e.data == "8.8.8.8:443"])
|
|
117
119
|
assert 1 == len([e for e in events if e.type == "OPEN_TCP_PORT" and e.data == "8.8.4.5:80"])
|
|
118
120
|
assert 1 == len([e for e in events if e.type == "OPEN_TCP_PORT" and e.data == "8.8.4.6:631"])
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: bbot
|
|
3
|
-
Version: 2.3.0.
|
|
3
|
+
Version: 2.3.0.5362rc0
|
|
4
4
|
Summary: OSINT automation for hackers.
|
|
5
5
|
Home-page: https://github.com/blacklanternsecurity/bbot
|
|
6
6
|
License: GPL-3.0
|
|
@@ -249,10 +249,10 @@ flags:
|
|
|
249
249
|
|
|
250
250
|
```bash
|
|
251
251
|
# everything everywhere all at once
|
|
252
|
-
bbot -t evilcorp.com -p kitchen-sink
|
|
252
|
+
bbot -t evilcorp.com -p kitchen-sink --allow-deadly
|
|
253
253
|
|
|
254
254
|
# roughly equivalent to:
|
|
255
|
-
bbot -t evilcorp.com -p subdomain-enum cloud-enum code-enum email-enum spider web-basic paramminer dirbust-light web-screenshots
|
|
255
|
+
bbot -t evilcorp.com -p subdomain-enum cloud-enum code-enum email-enum spider web-basic paramminer dirbust-light web-screenshots --allow-deadly
|
|
256
256
|
```
|
|
257
257
|
|
|
258
258
|
<!-- BBOT KITCHEN-SINK PRESET EXPANDABLE -->
|
|
@@ -294,6 +294,24 @@ Click the graph below to explore the [inner workings](https://www.blacklanternse
|
|
|
294
294
|
|
|
295
295
|
[](https://www.blacklanternsecurity.com/bbot/Stable/how_it_works/)
|
|
296
296
|
|
|
297
|
+
## Output Modules
|
|
298
|
+
|
|
299
|
+
- [Neo4j](docs/scanning/output.md#neo4j)
|
|
300
|
+
- [Teams](docs/scanning/output.md#teams)
|
|
301
|
+
- [Discord](docs/scanning/output.md#discord)
|
|
302
|
+
- [Slack](docs/scanning/output.md#slack)
|
|
303
|
+
- [Postgres](docs/scanning/output.md#postgres)
|
|
304
|
+
- [MySQL](docs/scanning/output.md#mysql)
|
|
305
|
+
- [SQLite](docs/scanning/output.md#sqlite)
|
|
306
|
+
- [Splunk](docs/scanning/output.md#splunk)
|
|
307
|
+
- [Elasticsearch](docs/scanning/output.md#elasticsearch)
|
|
308
|
+
- [CSV](docs/scanning/output.md#csv)
|
|
309
|
+
- [JSON](docs/scanning/output.md#json)
|
|
310
|
+
- [HTTP](docs/scanning/output.md#http)
|
|
311
|
+
- [Websocket](docs/scanning/output.md#websocket)
|
|
312
|
+
|
|
313
|
+
...and [more](docs/scanning/output.md)!
|
|
314
|
+
|
|
297
315
|
## BBOT as a Python Library
|
|
298
316
|
|
|
299
317
|
#### Synchronous
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
bbot/__init__.py,sha256=
|
|
1
|
+
bbot/__init__.py,sha256=cXSoBnoReCQrZ5ttNvqBJmKPJ3U0D3JMFXjuq6LPrQs,130
|
|
2
2
|
bbot/cli.py,sha256=-9d6yCAYZaP0lIOCja-fSk3MiNclc-kbEgos10jYNUQ,10440
|
|
3
3
|
bbot/core/__init__.py,sha256=l255GJE_DvUnWvrRb0J5lG-iMztJ8zVvoweDOfegGtI,46
|
|
4
4
|
bbot/core/config/__init__.py,sha256=zYNw2Me6tsEr8hOOkLb4BQ97GB7Kis2k--G81S8vofU,342
|
|
@@ -16,7 +16,7 @@ bbot/core/helpers/bloom.py,sha256=JjAbHhV_q-ObLYKW87xgoYAcCZXZBEhn7IbKN-0afG4,27
|
|
|
16
16
|
bbot/core/helpers/cache.py,sha256=1aMr3HVD45cDtHEG5xlznDUCywRgO9oRFidscrs_5sA,1537
|
|
17
17
|
bbot/core/helpers/command.py,sha256=2i0hz-uo6zUV9oGtXf-9erh_g3SazDtYeh6pETlfPPA,12810
|
|
18
18
|
bbot/core/helpers/depsinstaller/__init__.py,sha256=2mx1nYylSyvwl0GCM9YDHqrFEt2_5dSWAjP1RmhmbQg,37
|
|
19
|
-
bbot/core/helpers/depsinstaller/installer.py,sha256=
|
|
19
|
+
bbot/core/helpers/depsinstaller/installer.py,sha256=5SR6xYBqyx-h1fj_pDC2REg8HhxFNUpjAZ94yAAeaNE,17180
|
|
20
20
|
bbot/core/helpers/depsinstaller/sudo_askpass.py,sha256=yGa2OQv30RO75QkMuG1iruKqb7amQxRVRRcHmvIeGhk,1276
|
|
21
21
|
bbot/core/helpers/diff.py,sha256=7waBeHFGnAKn-R-sBd-wc3yjwxT_umwy4YxfE7JFd6w,10599
|
|
22
22
|
bbot/core/helpers/dns/__init__.py,sha256=2JK8P0BUfPlh4CTuuOWQCOacwL7NEtGFYPJsxbA0Zwo,27
|
|
@@ -47,8 +47,8 @@ bbot/core/helpers/wordcloud.py,sha256=WdQwboCNcCxcUdLuB6MMMDQBL4ZshFM_f6GW7nUZEB
|
|
|
47
47
|
bbot/core/modules.py,sha256=OOUSncr-EM6bJBrI3iH5wvfnpTXKQ-A8OL8UMvkL0CU,31432
|
|
48
48
|
bbot/core/multiprocess.py,sha256=ocQHanskJ09gHwe7RZmwNdZyCOQyeyUoIHCtLbtvXUk,1771
|
|
49
49
|
bbot/core/shared_deps.py,sha256=A3vrI62uPTTayNIHhWAj6xz43cj--oXWC4prmDlgJnw,6958
|
|
50
|
-
bbot/db/sql/models.py,sha256=
|
|
51
|
-
bbot/defaults.yml,sha256=
|
|
50
|
+
bbot/db/sql/models.py,sha256=Y_Bx-BT51lEGZEuadKaeXHM9hcECUTSsbGf3ZnIxZ0g,4885
|
|
51
|
+
bbot/defaults.yml,sha256=d1uVZOWzaJ7IM5YF-Zpambb8Gdbas-aCInqoWElxsEw,6221
|
|
52
52
|
bbot/errors.py,sha256=xwQcD26nU9oc7-o0kv5jmEDTInmi8_W8eKAgQZZxdVM,953
|
|
53
53
|
bbot/logger.py,sha256=rLcLzNDvfR8rFj7_tZ-f5QB3Z8T0RVroact3W0ogjpA,1408
|
|
54
54
|
bbot/modules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -120,7 +120,7 @@ bbot/modules/iis_shortnames.py,sha256=NI0lAcTzUTJCkw9uJZJB6_OsOQ7J6bSGtZw_nAWHvo
|
|
|
120
120
|
bbot/modules/internal/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
121
121
|
bbot/modules/internal/aggregate.py,sha256=csWYIt2fUp9K_CRxP3bndUMIjpNIh8rmBubp5Fr1-nc,395
|
|
122
122
|
bbot/modules/internal/base.py,sha256=BXO4Hc7XKaAOaLzolF3krJX1KibPxtek2GTQUgnCHk0,387
|
|
123
|
-
bbot/modules/internal/cloudcheck.py,sha256=
|
|
123
|
+
bbot/modules/internal/cloudcheck.py,sha256=86wYVzoY8OeorpqQFger9UrdNdu2vTkd8XmC9xtplUc,4727
|
|
124
124
|
bbot/modules/internal/dnsresolve.py,sha256=UW88BlpJ7gOjPARrjVgtwpDIDPNQZRpuIRpL2yVP6T4,15251
|
|
125
125
|
bbot/modules/internal/excavate.py,sha256=XCwEreroQIRPBnKBNo1epLHcbycCZGYTuW73Zi8qZLU,51174
|
|
126
126
|
bbot/modules/internal/speculate.py,sha256=hOJPrmJP8-APqSEbmYsbKrvovLIGIz4dJUoZyusq0w0,9270
|
|
@@ -143,6 +143,7 @@ bbot/modules/output/discord.py,sha256=BzZW0T-DgZHo3xwaQbZ6DAA59wKIvCDV1LK82ev7A2
|
|
|
143
143
|
bbot/modules/output/emails.py,sha256=mzZideMCNfB8-naQANO5g8Y9HdgviAihRsdY_xPQjbQ,1095
|
|
144
144
|
bbot/modules/output/http.py,sha256=4UWKpbQx3EHpi24VIem6oSvXr0W0NZ3lDpJOmQ3Mwik,2582
|
|
145
145
|
bbot/modules/output/json.py,sha256=zvM2NwWScGk3pN4wF0mm-OqVW_0ADYy95Am4T02VVD4,1289
|
|
146
|
+
bbot/modules/output/mysql.py,sha256=iq_VRvuarEZJHR8_OWB2Z76-yQrxWqNGfPrPHOi9oiI,1884
|
|
146
147
|
bbot/modules/output/neo4j.py,sha256=u950eUwu8YMql_WaBA38TN2bUhx7xnZdIIvYfR3xVcY,6114
|
|
147
148
|
bbot/modules/output/postgres.py,sha256=2JdEF6mU-VmVqPrgEh5L2MGv-s0BoNwoz8EnG5i3u2s,1847
|
|
148
149
|
bbot/modules/output/python.py,sha256=RvK2KN-Zp0Vy_1zGSNioE5eeL5hIh6Z_riFtaTymyIM,270
|
|
@@ -160,7 +161,7 @@ bbot/modules/paramminer_getparams.py,sha256=_j6rgaqV5wGJoa8p5-KKbe2YsVGUtmWIanCV
|
|
|
160
161
|
bbot/modules/paramminer_headers.py,sha256=QEnWxveQVuS91MEYKYtfquqdNzimN7sQHuxpcqiTHpo,10305
|
|
161
162
|
bbot/modules/passivetotal.py,sha256=uGT6c_CUxBNInmClsTg8afIYA2ZykKYYCgjkyzujfHg,1653
|
|
162
163
|
bbot/modules/pgp.py,sha256=Xu2M9WEIlwTm5-Lv29g7BblI05tD9Dl0XsYSeY6UURs,2065
|
|
163
|
-
bbot/modules/portscan.py,sha256=
|
|
164
|
+
bbot/modules/portscan.py,sha256=2VSoxoh0AypE8DoGKHqE-a57G4Z91XEo3kquQ5OpM3Y,14656
|
|
164
165
|
bbot/modules/postman.py,sha256=tbLrxi5pOycLABvphORxyK9duTSBXZLgpf1vAZvOIa0,3512
|
|
165
166
|
bbot/modules/postman_download.py,sha256=dYKwZjM1Z8JTy8oKWha1WHZTetxVIYRM09-vsHBNNUI,9071
|
|
166
167
|
bbot/modules/rapiddns.py,sha256=uONESr0B5pv9cSAr7lF4WWV31APUhXyHexvI04rUcyk,787
|
|
@@ -184,8 +185,8 @@ bbot/modules/templates/bucket.py,sha256=x-c_iAeMILux6wRm0xkUUJkc2P69hYWS6DxqD7g5
|
|
|
184
185
|
bbot/modules/templates/github.py,sha256=ENnDWpzzmZBsTisDx6Cg9V_NwJKyVyPIOpGAPktigdI,1455
|
|
185
186
|
bbot/modules/templates/postman.py,sha256=oxwVusW2EdNotVX7xnnxCTnWtj3xNPbfs8aff9s4phs,614
|
|
186
187
|
bbot/modules/templates/shodan.py,sha256=BfI0mNPbqkykGmjMtARhmCGKmk1uq7yTlZoPgzzJ040,1175
|
|
187
|
-
bbot/modules/templates/sql.py,sha256=
|
|
188
|
-
bbot/modules/templates/subdomain_enum.py,sha256=
|
|
188
|
+
bbot/modules/templates/sql.py,sha256=o-CdyyoJvHJdJBKkj3CIGXYxUta4w2AB_2Vr-k7cDDU,3553
|
|
189
|
+
bbot/modules/templates/subdomain_enum.py,sha256=54prHdg_wgTBHIJLPLbDWBqq2x978NDfDOGG7R5A6fQ,8403
|
|
189
190
|
bbot/modules/templates/webhook.py,sha256=MYhKWrNYrsfM0a4PR6yVotudLyyCwgmy2eI-l9LvpBs,3706
|
|
190
191
|
bbot/modules/trickest.py,sha256=MRgLW0YiDWzlWdAjyqfPPLFb-a51r-Ffn_dphiJI_gA,1550
|
|
191
192
|
bbot/modules/trufflehog.py,sha256=yOoCszQe6ZoJGBUHfFp-lj5JH-Izp9R-CltsmZnI3Fw,8554
|
|
@@ -234,7 +235,7 @@ bbot/test/coverage.cfg,sha256=ko9RacAYsJxWJCL8aEuNtkAOtP9lexYiDbeFWe8Tp8Y,31
|
|
|
234
235
|
bbot/test/fastapi_test.py,sha256=9OhOFRyagXTshMsnuzuKIcR4uzS6VW65m7h9KgB4jSA,381
|
|
235
236
|
bbot/test/owasp_mastg.apk,sha256=Hai_V9JmEJ-aB8Ab9xEaGXXOAfGQudkUvNOuPb75byE,66651
|
|
236
237
|
bbot/test/run_tests.sh,sha256=0oprBl970NAqXS4YQa8nRUtKljPeS_WNSvd-QmO5FNY,945
|
|
237
|
-
bbot/test/test.conf,sha256=
|
|
238
|
+
bbot/test/test.conf,sha256=JX0-Wl7N7VN6x_hhkFL-RF4TDAHgL9OfNNdujfD7tHo,994
|
|
238
239
|
bbot/test/test_output.ndjson,sha256=Jfor8nUJ3QTEwXxD6UULrFXM4zhP5wflWo_UNekM3V8,323
|
|
239
240
|
bbot/test/test_step_1/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
240
241
|
bbot/test/test_step_1/test__module__tests.py,sha256=RpD4yuVuQRgbbUkfuasxUlyoVxhTm6TeDyi87y_AaK0,1461
|
|
@@ -291,7 +292,7 @@ bbot/test/test_step_2/module_tests/test_module_c99.py,sha256=-xyL1y3eX_rGuBR-U0N
|
|
|
291
292
|
bbot/test/test_step_2/module_tests/test_module_censys.py,sha256=RoFfLS0hgASdSoctJEzaKrHVqqRkuPRKPTYVCX2rZLo,4177
|
|
292
293
|
bbot/test/test_step_2/module_tests/test_module_certspotter.py,sha256=60jCOeK1yaUEgtTxYW-T47kZgKt9XxP2qBH9w-0MDBk,636
|
|
293
294
|
bbot/test/test_step_2/module_tests/test_module_chaos.py,sha256=9JRgtDEnnJgmEMCTB2bqRJRkBavLys-6ypHPxrM_hXk,956
|
|
294
|
-
bbot/test/test_step_2/module_tests/test_module_cloudcheck.py,sha256=
|
|
295
|
+
bbot/test/test_step_2/module_tests/test_module_cloudcheck.py,sha256=XWAkCpq0PMEGXksnK4tNR1IyPkjRd_anhCoT5tWmLU4,4074
|
|
295
296
|
bbot/test/test_step_2/module_tests/test_module_code_repository.py,sha256=i02Tgvr_F9_E4d6aEaXrfdk71NkoDvjzP4C98l2rNGg,2414
|
|
296
297
|
bbot/test/test_step_2/module_tests/test_module_columbus.py,sha256=JZG_EvDQoKGNcBhYOGaNr_FGU2s1BCzG6ePz4yfZcUg,564
|
|
297
298
|
bbot/test/test_step_2/module_tests/test_module_credshed.py,sha256=rlvKZERFoAS-gg7sdgk6Pa2JbySmHDPee3zKUYATWlw,3362
|
|
@@ -343,6 +344,7 @@ bbot/test/test_step_2/module_tests/test_module_ipstack.py,sha256=BgCeE9Bef2RM6ak
|
|
|
343
344
|
bbot/test/test_step_2/module_tests/test_module_jadx.py,sha256=qTBfDc_Iv03n8iGdyLm6kBaKeEdSxFYeKj5xL1PmyF0,2391
|
|
344
345
|
bbot/test/test_step_2/module_tests/test_module_json.py,sha256=gmlqge5ZJpjVMGs7OLZBsNlSFTTrKnKjIZMIU23o8VQ,3350
|
|
345
346
|
bbot/test/test_step_2/module_tests/test_module_leakix.py,sha256=Pg1vbmi5z6xIHV1X0z0VCqfpgxksCycrJI5p2ogiIpQ,1819
|
|
347
|
+
bbot/test/test_step_2/module_tests/test_module_mysql.py,sha256=4wAPjbjhlxmOkEhQnIQIBC2BLEaE57TX6lChGZ3zLsU,2630
|
|
346
348
|
bbot/test/test_step_2/module_tests/test_module_myssl.py,sha256=dweSmwUYEcC3DapozRSpHvvvdbw54HVlc_L2pC7ILew,1532
|
|
347
349
|
bbot/test/test_step_2/module_tests/test_module_neo4j.py,sha256=PaKSQWKJKY-5tQhDCGNu_uALlIJwjCVrEtv2grMK9wo,1332
|
|
348
350
|
bbot/test/test_step_2/module_tests/test_module_newsletters.py,sha256=4u2RghHpxlsOy859Fd-4_9EbRL9pupUDubHDJ6ym7YI,2305
|
|
@@ -355,7 +357,7 @@ bbot/test/test_step_2/module_tests/test_module_paramminer_getparams.py,sha256=mW
|
|
|
355
357
|
bbot/test/test_step_2/module_tests/test_module_paramminer_headers.py,sha256=qTT-5fyqw69LaZBxak3FvPfH7lh9W0KVBtJgslD-3eQ,5545
|
|
356
358
|
bbot/test/test_step_2/module_tests/test_module_passivetotal.py,sha256=fTGQECQ0OzcwiH64-0igFRKO-rs3kXScivZord_oWWU,1120
|
|
357
359
|
bbot/test/test_step_2/module_tests/test_module_pgp.py,sha256=-m-nPq6WR5UzPDuxeZbuzBQfFi1QfrZQ8RZH4g11ocE,1609
|
|
358
|
-
bbot/test/test_step_2/module_tests/test_module_portscan.py,sha256=
|
|
360
|
+
bbot/test/test_step_2/module_tests/test_module_portscan.py,sha256=MsemMkkKVCJBd3HuyP5FOasfDGCj-JK7bpiPjBpmTjk,7552
|
|
359
361
|
bbot/test/test_step_2/module_tests/test_module_postgres.py,sha256=6Seqq1Bq2FEXbJnTi_BYv8ZZPWdy-SfnY8UJN24Op0Q,2689
|
|
360
362
|
bbot/test/test_step_2/module_tests/test_module_postman.py,sha256=XvgfMgUhJuVgGkgT-JzxJyevNSVv7YvX1yLKJHmD3dw,5026
|
|
361
363
|
bbot/test/test_step_2/module_tests/test_module_postman_download.py,sha256=B_NajQaGQjwMSmcBCr37_7cvcnw4Zmh8k_hVoWL7bVI,21623
|
|
@@ -410,8 +412,8 @@ bbot/wordlists/raft-small-extensions-lowercase_CLEANED.txt,sha256=ruUQwVfia1_m2u
|
|
|
410
412
|
bbot/wordlists/top_open_ports_nmap.txt,sha256=LmdFYkfapSxn1pVuQC2LkOIY2hMLgG-Xts7DVtYzweM,42727
|
|
411
413
|
bbot/wordlists/valid_url_schemes.txt,sha256=VciB-ww0y-O8Ii1wpTR6rJzGDiC2r-dhVsIJApS1ZYU,3309
|
|
412
414
|
bbot/wordlists/wordninja_dns.txt.gz,sha256=DYHvvfW0TvzrVwyprqODAk4tGOxv5ezNmCPSdPuDUnQ,570241
|
|
413
|
-
bbot-2.3.0.
|
|
414
|
-
bbot-2.3.0.
|
|
415
|
-
bbot-2.3.0.
|
|
416
|
-
bbot-2.3.0.
|
|
417
|
-
bbot-2.3.0.
|
|
415
|
+
bbot-2.3.0.5362rc0.dist-info/LICENSE,sha256=GzeCzK17hhQQDNow0_r0L8OfLpeTKQjFQwBQU7ZUymg,32473
|
|
416
|
+
bbot-2.3.0.5362rc0.dist-info/METADATA,sha256=gnFIvrsMffMlGaxf84HaYo1z9txZPmfMwRzjlD-SbnA,17893
|
|
417
|
+
bbot-2.3.0.5362rc0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
|
418
|
+
bbot-2.3.0.5362rc0.dist-info/entry_points.txt,sha256=cWjvcU_lLrzzJgjcjF7yeGuRA_eDS8pQ-kmPUAyOBfo,38
|
|
419
|
+
bbot-2.3.0.5362rc0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|