bbot 2.3.0.5423rc0__py3-none-any.whl → 2.3.0.5445rc0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of bbot might be problematic. Click here for more details.
- bbot/__init__.py +1 -1
- bbot/cli.py +12 -2
- bbot/core/helpers/names_generator.py +1 -0
- bbot/modules/base.py +1 -1
- bbot/modules/extractous.py +1 -1
- bbot/modules/httpx.py +5 -5
- bbot/modules/internal/cloudcheck.py +9 -4
- bbot/modules/internal/dnsresolve.py +2 -0
- bbot/modules/internal/speculate.py +1 -1
- bbot/modules/output/mysql.py +1 -1
- bbot/modules/output/nmap_xml.py +171 -0
- bbot/modules/output/postgres.py +5 -1
- bbot/modules/output/sqlite.py +5 -1
- bbot/modules/output/stdout.py +1 -1
- bbot/modules/output/txt.py +1 -1
- bbot/scanner/preset/args.py +12 -6
- bbot/test/test_step_1/test_cli.py +14 -2
- bbot/test/test_step_1/test_modules_basic.py +9 -11
- bbot/test/test_step_2/module_tests/test_module_cloudcheck.py +1 -1
- bbot/test/test_step_2/module_tests/test_module_nmap_xml.py +85 -0
- {bbot-2.3.0.5423rc0.dist-info → bbot-2.3.0.5445rc0.dist-info}/METADATA +2 -1
- {bbot-2.3.0.5423rc0.dist-info → bbot-2.3.0.5445rc0.dist-info}/RECORD +25 -23
- {bbot-2.3.0.5423rc0.dist-info → bbot-2.3.0.5445rc0.dist-info}/LICENSE +0 -0
- {bbot-2.3.0.5423rc0.dist-info → bbot-2.3.0.5445rc0.dist-info}/WHEEL +0 -0
- {bbot-2.3.0.5423rc0.dist-info → bbot-2.3.0.5445rc0.dist-info}/entry_points.txt +0 -0
bbot/__init__.py
CHANGED
bbot/cli.py
CHANGED
|
@@ -78,7 +78,7 @@ async def _main():
|
|
|
78
78
|
return
|
|
79
79
|
|
|
80
80
|
# if we're listing modules or their options
|
|
81
|
-
if options.list_modules or options.list_module_options:
|
|
81
|
+
if options.list_modules or options.list_output_modules or options.list_module_options:
|
|
82
82
|
# if no modules or flags are specified, enable everything
|
|
83
83
|
if not (options.modules or options.output_modules or options.flags):
|
|
84
84
|
for module, preloaded in preset.module_loader.preloaded().items():
|
|
@@ -96,7 +96,17 @@ async def _main():
|
|
|
96
96
|
print("")
|
|
97
97
|
print("### MODULES ###")
|
|
98
98
|
print("")
|
|
99
|
-
|
|
99
|
+
modules = sorted(set(preset.scan_modules + preset.internal_modules))
|
|
100
|
+
for row in preset.module_loader.modules_table(modules).splitlines():
|
|
101
|
+
print(row)
|
|
102
|
+
return
|
|
103
|
+
|
|
104
|
+
# --list-output-modules
|
|
105
|
+
if options.list_output_modules:
|
|
106
|
+
print("")
|
|
107
|
+
print("### OUTPUT MODULES ###")
|
|
108
|
+
print("")
|
|
109
|
+
for row in preset.module_loader.modules_table(preset.output_modules).splitlines():
|
|
100
110
|
print(row)
|
|
101
111
|
return
|
|
102
112
|
|
bbot/modules/base.py
CHANGED
|
@@ -51,7 +51,7 @@ class BaseModule:
|
|
|
51
51
|
|
|
52
52
|
target_only (bool): Accept only the initial target event(s). Default is False.
|
|
53
53
|
|
|
54
|
-
in_scope_only (bool): Accept only explicitly in-scope events. Default is False.
|
|
54
|
+
in_scope_only (bool): Accept only explicitly in-scope events, regardless of the scan's search distance. Default is False.
|
|
55
55
|
|
|
56
56
|
options (Dict): Customizable options for the module, e.g., {"api_key": ""}. Empty dict by default.
|
|
57
57
|
|
bbot/modules/extractous.py
CHANGED
|
@@ -112,7 +112,7 @@ def extract_text(file_path):
|
|
|
112
112
|
result = ""
|
|
113
113
|
buffer = reader.read(4096)
|
|
114
114
|
while len(buffer) > 0:
|
|
115
|
-
result += buffer.decode("utf-8")
|
|
115
|
+
result += buffer.decode("utf-8", errors="ignore")
|
|
116
116
|
buffer = reader.read(4096)
|
|
117
117
|
|
|
118
118
|
return result.strip()
|
bbot/modules/httpx.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import re
|
|
2
|
-
import
|
|
2
|
+
import orjson
|
|
3
3
|
import tempfile
|
|
4
4
|
import subprocess
|
|
5
5
|
from pathlib import Path
|
|
@@ -142,11 +142,11 @@ class httpx(BaseModule):
|
|
|
142
142
|
proxy = self.scan.http_proxy
|
|
143
143
|
if proxy:
|
|
144
144
|
command += ["-http-proxy", proxy]
|
|
145
|
-
async for line in self.run_process_live(command, input=list(stdin), stderr=subprocess.DEVNULL):
|
|
145
|
+
async for line in self.run_process_live(command, text=False, input=list(stdin), stderr=subprocess.DEVNULL):
|
|
146
146
|
try:
|
|
147
|
-
j =
|
|
148
|
-
except
|
|
149
|
-
self.
|
|
147
|
+
j = await self.helpers.run_in_executor(orjson.loads, line)
|
|
148
|
+
except orjson.JSONDecodeError:
|
|
149
|
+
self.warning(f"httpx failed to decode line: {line}")
|
|
150
150
|
continue
|
|
151
151
|
|
|
152
152
|
url = j.get("url", "")
|
|
@@ -5,7 +5,11 @@ from bbot.modules.base import BaseInterceptModule
|
|
|
5
5
|
|
|
6
6
|
class CloudCheck(BaseInterceptModule):
|
|
7
7
|
watched_events = ["*"]
|
|
8
|
-
meta = {
|
|
8
|
+
meta = {
|
|
9
|
+
"description": "Tag events by cloud provider, identify cloud resources like storage buckets",
|
|
10
|
+
"created_date": "2024-07-07",
|
|
11
|
+
"author": "@TheTechromancer",
|
|
12
|
+
}
|
|
9
13
|
scope_distance_modifier = 1
|
|
10
14
|
_priority = 3
|
|
11
15
|
|
|
@@ -68,9 +72,10 @@ class CloudCheck(BaseInterceptModule):
|
|
|
68
72
|
base_kwargs["event_type"] = event_type
|
|
69
73
|
for sig in sigs:
|
|
70
74
|
matches = []
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
75
|
+
# TODO: convert this to an excavate YARA hook
|
|
76
|
+
# if event.type == "HTTP_RESPONSE":
|
|
77
|
+
# matches = await self.helpers.re.findall(sig, event.data.get("body", ""))
|
|
78
|
+
if event.type.startswith("DNS_NAME"):
|
|
74
79
|
for host in str_hosts_to_check:
|
|
75
80
|
match = sig.match(host)
|
|
76
81
|
if match:
|
|
@@ -9,6 +9,8 @@ from bbot.modules.base import BaseInterceptModule, BaseModule
|
|
|
9
9
|
|
|
10
10
|
class DNSResolve(BaseInterceptModule):
|
|
11
11
|
watched_events = ["*"]
|
|
12
|
+
produced_events = ["DNS_NAME", "IP_ADDRESS", "RAW_DNS_RECORD"]
|
|
13
|
+
meta = {"description": "Perform DNS resolution", "created_date": "2022-04-08", "author": "@TheTechromancer"}
|
|
12
14
|
_priority = 1
|
|
13
15
|
scope_distance_modifier = None
|
|
14
16
|
|
|
@@ -104,7 +104,7 @@ class speculate(BaseInternalModule):
|
|
|
104
104
|
# don't act on unresolved DNS_NAMEs
|
|
105
105
|
usable_dns = False
|
|
106
106
|
if event.type == "DNS_NAME":
|
|
107
|
-
if self.dns_disable or
|
|
107
|
+
if self.dns_disable or event.resolved_hosts:
|
|
108
108
|
usable_dns = True
|
|
109
109
|
|
|
110
110
|
if event.type == "IP_ADDRESS" or usable_dns:
|
bbot/modules/output/mysql.py
CHANGED
|
@@ -3,7 +3,7 @@ from bbot.modules.templates.sql import SQLTemplate
|
|
|
3
3
|
|
|
4
4
|
class MySQL(SQLTemplate):
|
|
5
5
|
watched_events = ["*"]
|
|
6
|
-
meta = {"description": "Output scan data to a MySQL database"}
|
|
6
|
+
meta = {"description": "Output scan data to a MySQL database", "created_date": "2024-11-13", "author": "@TheTechromancer"}
|
|
7
7
|
options = {
|
|
8
8
|
"username": "root",
|
|
9
9
|
"password": "bbotislife",
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
from xml.dom import minidom
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
from xml.etree.ElementTree import Element, SubElement, tostring
|
|
5
|
+
|
|
6
|
+
from bbot import __version__
|
|
7
|
+
from bbot.modules.output.base import BaseOutputModule
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class NmapHost:
|
|
11
|
+
__slots__ = ["hostnames", "open_ports"]
|
|
12
|
+
|
|
13
|
+
def __init__(self):
|
|
14
|
+
self.hostnames = set()
|
|
15
|
+
# a dict of {port: {protocol: banner}}
|
|
16
|
+
self.open_ports = dict()
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class Nmap_XML(BaseOutputModule):
|
|
20
|
+
watched_events = ["OPEN_TCP_PORT", "DNS_NAME", "IP_ADDRESS", "PROTOCOL", "HTTP_RESPONSE"]
|
|
21
|
+
meta = {"description": "Output to Nmap XML", "created_date": "2024-11-16", "author": "@TheTechromancer"}
|
|
22
|
+
output_filename = "output.nmap.xml"
|
|
23
|
+
in_scope_only = True
|
|
24
|
+
|
|
25
|
+
async def setup(self):
|
|
26
|
+
self.hosts = {}
|
|
27
|
+
self._prep_output_dir(self.output_filename)
|
|
28
|
+
return True
|
|
29
|
+
|
|
30
|
+
async def handle_event(self, event):
|
|
31
|
+
event_host = event.host
|
|
32
|
+
|
|
33
|
+
# we always record by IP
|
|
34
|
+
ips = []
|
|
35
|
+
for ip in event.resolved_hosts:
|
|
36
|
+
try:
|
|
37
|
+
ips.append(self.helpers.make_ip_type(ip))
|
|
38
|
+
except ValueError:
|
|
39
|
+
continue
|
|
40
|
+
if not ips and self.helpers.is_ip(event_host):
|
|
41
|
+
ips = [event_host]
|
|
42
|
+
|
|
43
|
+
for ip in ips:
|
|
44
|
+
try:
|
|
45
|
+
nmap_host = self.hosts[ip]
|
|
46
|
+
except KeyError:
|
|
47
|
+
nmap_host = NmapHost()
|
|
48
|
+
self.hosts[ip] = nmap_host
|
|
49
|
+
|
|
50
|
+
event_port = getattr(event, "port", None)
|
|
51
|
+
if event.type == "OPEN_TCP_PORT":
|
|
52
|
+
if event_port not in nmap_host.open_ports:
|
|
53
|
+
nmap_host.open_ports[event.port] = {}
|
|
54
|
+
elif event.type in ("PROTOCOL", "HTTP_RESPONSE"):
|
|
55
|
+
if event_port is not None:
|
|
56
|
+
try:
|
|
57
|
+
existing_services = nmap_host.open_ports[event.port]
|
|
58
|
+
except KeyError:
|
|
59
|
+
existing_services = {}
|
|
60
|
+
nmap_host.open_ports[event.port] = existing_services
|
|
61
|
+
if event.type == "PROTOCOL":
|
|
62
|
+
protocol = event.data["protocol"].lower()
|
|
63
|
+
banner = event.data.get("banner", None)
|
|
64
|
+
elif event.type == "HTTP_RESPONSE":
|
|
65
|
+
protocol = event.parsed_url.scheme.lower()
|
|
66
|
+
banner = event.http_title
|
|
67
|
+
if protocol not in existing_services:
|
|
68
|
+
existing_services[protocol] = banner
|
|
69
|
+
|
|
70
|
+
if self.helpers.is_ip(event_host):
|
|
71
|
+
if str(event.module) == "PTR":
|
|
72
|
+
nmap_host.hostnames.add(event.parent.data)
|
|
73
|
+
else:
|
|
74
|
+
nmap_host.hostnames.add(event_host)
|
|
75
|
+
|
|
76
|
+
async def report(self):
|
|
77
|
+
scan_start_time = str(int(self.scan.start_time.timestamp()))
|
|
78
|
+
scan_start_time_str = self.scan.start_time.strftime("%a %b %d %H:%M:%S %Y")
|
|
79
|
+
scan_end_time = datetime.now()
|
|
80
|
+
scan_end_time_str = scan_end_time.strftime("%a %b %d %H:%M:%S %Y")
|
|
81
|
+
scan_end_time_timestamp = str(scan_end_time.timestamp())
|
|
82
|
+
scan_duration = scan_end_time - self.scan.start_time
|
|
83
|
+
num_hosts_up = len(self.hosts)
|
|
84
|
+
|
|
85
|
+
# Create the root element
|
|
86
|
+
nmaprun = Element(
|
|
87
|
+
"nmaprun",
|
|
88
|
+
{
|
|
89
|
+
"scanner": "bbot",
|
|
90
|
+
"args": " ".join(sys.argv),
|
|
91
|
+
"start": scan_start_time,
|
|
92
|
+
"startstr": scan_start_time_str,
|
|
93
|
+
"version": str(__version__),
|
|
94
|
+
"xmloutputversion": "1.05",
|
|
95
|
+
},
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
ports_scanned = []
|
|
99
|
+
speculate_module = self.scan.modules.get("speculate", None)
|
|
100
|
+
if speculate_module is not None:
|
|
101
|
+
ports_scanned = speculate_module.ports
|
|
102
|
+
portscan_module = self.scan.modules.get("portscan", None)
|
|
103
|
+
if portscan_module is not None:
|
|
104
|
+
ports_scanned = self.helpers.parse_port_string(str(portscan_module.ports))
|
|
105
|
+
num_ports_scanned = len(sorted(ports_scanned))
|
|
106
|
+
ports_scanned = ",".join(str(x) for x in sorted(ports_scanned))
|
|
107
|
+
|
|
108
|
+
# Add scaninfo
|
|
109
|
+
SubElement(
|
|
110
|
+
nmaprun,
|
|
111
|
+
"scaninfo",
|
|
112
|
+
{"type": "syn", "protocol": "tcp", "numservices": str(num_ports_scanned), "services": ports_scanned},
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
# Add host information
|
|
116
|
+
for ip, nmap_host in self.hosts.items():
|
|
117
|
+
hostnames = sorted(nmap_host.hostnames)
|
|
118
|
+
ports = sorted(nmap_host.open_ports)
|
|
119
|
+
|
|
120
|
+
host_elem = SubElement(nmaprun, "host")
|
|
121
|
+
SubElement(host_elem, "status", {"state": "up", "reason": "user-set", "reason_ttl": "0"})
|
|
122
|
+
SubElement(host_elem, "address", {"addr": str(ip), "addrtype": f"ipv{ip.version}"})
|
|
123
|
+
|
|
124
|
+
if hostnames:
|
|
125
|
+
hostnames_elem = SubElement(host_elem, "hostnames")
|
|
126
|
+
for hostname in hostnames:
|
|
127
|
+
SubElement(hostnames_elem, "hostname", {"name": hostname, "type": "user"})
|
|
128
|
+
|
|
129
|
+
ports = SubElement(host_elem, "ports")
|
|
130
|
+
for port, protocols in nmap_host.open_ports.items():
|
|
131
|
+
port_elem = SubElement(ports, "port", {"protocol": "tcp", "portid": str(port)})
|
|
132
|
+
SubElement(port_elem, "state", {"state": "open", "reason": "syn-ack", "reason_ttl": "0"})
|
|
133
|
+
# <port protocol="tcp" portid="443"><state state="open" reason="syn-ack" reason_ttl="53"/><service name="http" product="AkamaiGHost" extrainfo="Akamai's HTTP Acceleration/Mirror service" tunnel="ssl" method="probed" conf="10"/></port>
|
|
134
|
+
for protocol, banner in protocols.items():
|
|
135
|
+
attrs = {"name": protocol, "method": "probed", "conf": "10"}
|
|
136
|
+
if banner is not None:
|
|
137
|
+
attrs["product"] = banner
|
|
138
|
+
attrs["extrainfo"] = banner
|
|
139
|
+
SubElement(port_elem, "service", attrs)
|
|
140
|
+
|
|
141
|
+
# Add runstats
|
|
142
|
+
runstats = SubElement(nmaprun, "runstats")
|
|
143
|
+
SubElement(
|
|
144
|
+
runstats,
|
|
145
|
+
"finished",
|
|
146
|
+
{
|
|
147
|
+
"time": scan_end_time_timestamp,
|
|
148
|
+
"timestr": scan_end_time_str,
|
|
149
|
+
"summary": f"BBOT done at {scan_end_time_str}; {num_hosts_up} scanned in {scan_duration} seconds",
|
|
150
|
+
"elapsed": str(scan_duration.total_seconds()),
|
|
151
|
+
"exit": "success",
|
|
152
|
+
},
|
|
153
|
+
)
|
|
154
|
+
SubElement(runstats, "hosts", {"up": str(num_hosts_up), "down": "0", "total": str(num_hosts_up)})
|
|
155
|
+
|
|
156
|
+
# make backup of the file
|
|
157
|
+
self.helpers.backup_file(self.output_file)
|
|
158
|
+
|
|
159
|
+
# Pretty-format the XML
|
|
160
|
+
rough_string = tostring(nmaprun, encoding="utf-8")
|
|
161
|
+
reparsed = minidom.parseString(rough_string)
|
|
162
|
+
|
|
163
|
+
# Create a new document with the doctype
|
|
164
|
+
doctype = minidom.DocumentType("nmaprun")
|
|
165
|
+
reparsed.insertBefore(doctype, reparsed.documentElement)
|
|
166
|
+
|
|
167
|
+
pretty_xml = reparsed.toprettyxml(indent=" ")
|
|
168
|
+
|
|
169
|
+
with open(self.output_file, "w") as f:
|
|
170
|
+
f.write(pretty_xml)
|
|
171
|
+
self.info(f"Saved Nmap XML output to {self.output_file}")
|
bbot/modules/output/postgres.py
CHANGED
|
@@ -3,7 +3,11 @@ from bbot.modules.templates.sql import SQLTemplate
|
|
|
3
3
|
|
|
4
4
|
class Postgres(SQLTemplate):
|
|
5
5
|
watched_events = ["*"]
|
|
6
|
-
meta = {
|
|
6
|
+
meta = {
|
|
7
|
+
"description": "Output scan data to a SQLite database",
|
|
8
|
+
"created_date": "2024-11-08",
|
|
9
|
+
"author": "@TheTechromancer",
|
|
10
|
+
}
|
|
7
11
|
options = {
|
|
8
12
|
"username": "postgres",
|
|
9
13
|
"password": "bbotislife",
|
bbot/modules/output/sqlite.py
CHANGED
|
@@ -5,7 +5,11 @@ from bbot.modules.templates.sql import SQLTemplate
|
|
|
5
5
|
|
|
6
6
|
class SQLite(SQLTemplate):
|
|
7
7
|
watched_events = ["*"]
|
|
8
|
-
meta = {
|
|
8
|
+
meta = {
|
|
9
|
+
"description": "Output scan data to a SQLite database",
|
|
10
|
+
"created_date": "2024-11-07",
|
|
11
|
+
"author": "@TheTechromancer",
|
|
12
|
+
}
|
|
9
13
|
options = {
|
|
10
14
|
"database": "",
|
|
11
15
|
}
|
bbot/modules/output/stdout.py
CHANGED
|
@@ -6,7 +6,7 @@ from bbot.modules.output.base import BaseOutputModule
|
|
|
6
6
|
|
|
7
7
|
class Stdout(BaseOutputModule):
|
|
8
8
|
watched_events = ["*"]
|
|
9
|
-
meta = {"description": "Output to text"}
|
|
9
|
+
meta = {"description": "Output to text", "created_date": "2024-04-03", "author": "@TheTechromancer"}
|
|
10
10
|
options = {"format": "text", "event_types": [], "event_fields": [], "in_scope_only": False, "accept_dupes": True}
|
|
11
11
|
options_desc = {
|
|
12
12
|
"format": "Which text format to display, choices: text,json",
|
bbot/modules/output/txt.py
CHANGED
|
@@ -5,7 +5,7 @@ from bbot.modules.output.base import BaseOutputModule
|
|
|
5
5
|
|
|
6
6
|
class TXT(BaseOutputModule):
|
|
7
7
|
watched_events = ["*"]
|
|
8
|
-
meta = {"description": "Output to text"}
|
|
8
|
+
meta = {"description": "Output to text", "created_date": "2024-04-03", "author": "@TheTechromancer"}
|
|
9
9
|
options = {"output_file": ""}
|
|
10
10
|
options_desc = {"output_file": "Output to file"}
|
|
11
11
|
|
bbot/scanner/preset/args.py
CHANGED
|
@@ -52,6 +52,11 @@ class BBOTArgs:
|
|
|
52
52
|
"",
|
|
53
53
|
"bbot -l",
|
|
54
54
|
),
|
|
55
|
+
(
|
|
56
|
+
"List output modules",
|
|
57
|
+
"",
|
|
58
|
+
"bbot -lo",
|
|
59
|
+
),
|
|
55
60
|
(
|
|
56
61
|
"List presets",
|
|
57
62
|
"",
|
|
@@ -290,12 +295,6 @@ class BBOTArgs:
|
|
|
290
295
|
)
|
|
291
296
|
|
|
292
297
|
output = p.add_argument_group(title="Output")
|
|
293
|
-
output.add_argument(
|
|
294
|
-
"-o",
|
|
295
|
-
"--output-dir",
|
|
296
|
-
help="Directory to output scan results",
|
|
297
|
-
metavar="DIR",
|
|
298
|
-
)
|
|
299
298
|
output.add_argument(
|
|
300
299
|
"-om",
|
|
301
300
|
"--output-modules",
|
|
@@ -304,6 +303,13 @@ class BBOTArgs:
|
|
|
304
303
|
help=f'Output module(s). Choices: {",".join(sorted(self.preset.module_loader.output_module_choices))}',
|
|
305
304
|
metavar="MODULE",
|
|
306
305
|
)
|
|
306
|
+
output.add_argument("-lo", "--list-output-modules", action="store_true", help="List available output modules")
|
|
307
|
+
output.add_argument(
|
|
308
|
+
"-o",
|
|
309
|
+
"--output-dir",
|
|
310
|
+
help="Directory to output scan results",
|
|
311
|
+
metavar="DIR",
|
|
312
|
+
)
|
|
307
313
|
output.add_argument("--json", "-j", action="store_true", help="Output scan data in JSON format")
|
|
308
314
|
output.add_argument("--brief", "-br", action="store_true", help="Output only the data itself")
|
|
309
315
|
output.add_argument("--event-types", nargs="+", default=[], help="Choose which event types to display")
|
|
@@ -150,11 +150,23 @@ async def test_cli_args(monkeypatch, caplog, capsys, clean_default_config):
|
|
|
150
150
|
out, err = capsys.readouterr()
|
|
151
151
|
# internal modules
|
|
152
152
|
assert "| excavate " in out
|
|
153
|
-
# output modules
|
|
154
|
-
assert "| csv " in out
|
|
153
|
+
# no output modules
|
|
154
|
+
assert not "| csv " in out
|
|
155
155
|
# scan modules
|
|
156
156
|
assert "| wayback " in out
|
|
157
157
|
|
|
158
|
+
# list output modules
|
|
159
|
+
monkeypatch.setattr("sys.argv", ["bbot", "--list-output-modules"])
|
|
160
|
+
result = await cli._main()
|
|
161
|
+
assert result == None
|
|
162
|
+
out, err = capsys.readouterr()
|
|
163
|
+
# no internal modules
|
|
164
|
+
assert not "| excavate " in out
|
|
165
|
+
# output modules
|
|
166
|
+
assert "| csv " in out
|
|
167
|
+
# no scan modules
|
|
168
|
+
assert not "| wayback " in out
|
|
169
|
+
|
|
158
170
|
# output dir and scan name
|
|
159
171
|
output_dir = bbot_test_dir / "bbot_cli_args_output"
|
|
160
172
|
scan_name = "bbot_cli_args_scan_name"
|
|
@@ -156,17 +156,15 @@ async def test_modules_basic_checks(events, httpx_mock):
|
|
|
156
156
|
assert not (
|
|
157
157
|
"web-basic" in flags and "web-thorough" in flags
|
|
158
158
|
), f'module "{module_name}" should have either "web-basic" or "web-thorough" flags, not both'
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
created_date
|
|
169
|
-
), f"{module_name}'s created_date must match the format YYYY-MM-DD"
|
|
159
|
+
meta = preloaded.get("meta", {})
|
|
160
|
+
# make sure every module has a description
|
|
161
|
+
assert meta.get("description", ""), f"{module_name} must have a description"
|
|
162
|
+
# make sure every module has an author
|
|
163
|
+
assert meta.get("author", ""), f"{module_name} must have an author"
|
|
164
|
+
# make sure every module has a created date
|
|
165
|
+
created_date = meta.get("created_date", "")
|
|
166
|
+
assert created_date, f"{module_name} must have a created date"
|
|
167
|
+
assert created_date_regex.match(created_date), f"{module_name}'s created_date must match the format YYYY-MM-DD"
|
|
170
168
|
|
|
171
169
|
# attribute checks
|
|
172
170
|
watched_events = preloaded.get("watched_events")
|
|
@@ -8,7 +8,7 @@ class TestCloudCheck(ModuleTestBase):
|
|
|
8
8
|
modules_overrides = ["httpx", "excavate", "cloudcheck"]
|
|
9
9
|
|
|
10
10
|
async def setup_after_prep(self, module_test):
|
|
11
|
-
module_test.set_expect_requests({"uri": "/"}, {"response_data": "<a href='asdf.s3.amazonaws.com'/>"})
|
|
11
|
+
module_test.set_expect_requests({"uri": "/"}, {"response_data": "<a href='http://asdf.s3.amazonaws.com'/>"})
|
|
12
12
|
|
|
13
13
|
scan = Scanner(config={"cloudcheck": True})
|
|
14
14
|
await scan._prep()
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import xml.etree.ElementTree as ET
|
|
2
|
+
|
|
3
|
+
from bbot.modules.base import BaseModule
|
|
4
|
+
from .base import ModuleTestBase
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class TestNmap_XML(ModuleTestBase):
|
|
8
|
+
modules_overrides = ["nmap_xml", "speculate"]
|
|
9
|
+
targets = ["blacklanternsecurity.com", "127.0.0.3"]
|
|
10
|
+
config_overrides = {"dns": {"minimal": False}}
|
|
11
|
+
|
|
12
|
+
class DummyModule(BaseModule):
|
|
13
|
+
watched_events = ["OPEN_TCP_PORT"]
|
|
14
|
+
_name = "dummy_module"
|
|
15
|
+
|
|
16
|
+
async def handle_event(self, event):
|
|
17
|
+
if event.port == 80:
|
|
18
|
+
await self.emit_event(
|
|
19
|
+
{"host": str(event.host), "port": event.port, "protocol": "http", "banner": "Apache"},
|
|
20
|
+
"PROTOCOL",
|
|
21
|
+
parent=event,
|
|
22
|
+
)
|
|
23
|
+
elif event.port == 443:
|
|
24
|
+
await self.emit_event(
|
|
25
|
+
{"host": str(event.host), "port": event.port, "protocol": "https"}, "PROTOCOL", parent=event
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
async def setup_before_prep(self, module_test):
|
|
29
|
+
self.dummy_module = self.DummyModule(module_test.scan)
|
|
30
|
+
module_test.scan.modules["dummy_module"] = self.dummy_module
|
|
31
|
+
await module_test.mock_dns(
|
|
32
|
+
{
|
|
33
|
+
"blacklanternsecurity.com": {"A": ["127.0.0.1", "127.0.0.2"]},
|
|
34
|
+
"3.0.0.127.in-addr.arpa": {"PTR": ["www.blacklanternsecurity.com"]},
|
|
35
|
+
"www.blacklanternsecurity.com": {"A": ["127.0.0.1"]},
|
|
36
|
+
}
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
def check(self, module_test, events):
|
|
40
|
+
nmap_xml_file = module_test.scan.modules["nmap_xml"].output_file
|
|
41
|
+
nmap_xml = open(nmap_xml_file).read()
|
|
42
|
+
|
|
43
|
+
# Parse the XML
|
|
44
|
+
root = ET.fromstring(nmap_xml)
|
|
45
|
+
|
|
46
|
+
# Expected IP addresses
|
|
47
|
+
expected_ips = {"127.0.0.1", "127.0.0.2", "127.0.0.3"}
|
|
48
|
+
found_ips = set()
|
|
49
|
+
|
|
50
|
+
# Iterate over each host in the XML
|
|
51
|
+
for host in root.findall("host"):
|
|
52
|
+
# Get the IP address
|
|
53
|
+
address = host.find("address").get("addr")
|
|
54
|
+
found_ips.add(address)
|
|
55
|
+
|
|
56
|
+
# Get hostnames if available
|
|
57
|
+
hostnames = sorted([hostname.get("name") for hostname in host.findall(".//hostname")])
|
|
58
|
+
|
|
59
|
+
# Get open ports and services
|
|
60
|
+
ports = []
|
|
61
|
+
for port in host.findall(".//port"):
|
|
62
|
+
port_id = port.get("portid")
|
|
63
|
+
state = port.find("state").get("state")
|
|
64
|
+
if state == "open":
|
|
65
|
+
service_name = port.find("service").get("name")
|
|
66
|
+
service_product = port.find("service").get("product", "")
|
|
67
|
+
service_extrainfo = port.find("service").get("extrainfo", "")
|
|
68
|
+
ports.append((port_id, service_name, service_product, service_extrainfo))
|
|
69
|
+
|
|
70
|
+
# Sort ports for consistency
|
|
71
|
+
ports.sort()
|
|
72
|
+
|
|
73
|
+
# Assertions
|
|
74
|
+
if address == "127.0.0.1":
|
|
75
|
+
assert hostnames == ["blacklanternsecurity.com", "www.blacklanternsecurity.com"]
|
|
76
|
+
assert ports == sorted([("80", "http", "Apache", "Apache"), ("443", "https", "", "")])
|
|
77
|
+
elif address == "127.0.0.2":
|
|
78
|
+
assert hostnames == sorted(["blacklanternsecurity.com"])
|
|
79
|
+
assert ports == sorted([("80", "http", "Apache", "Apache"), ("443", "https", "", "")])
|
|
80
|
+
elif address == "127.0.0.3":
|
|
81
|
+
assert hostnames == [] # No hostnames for this IP
|
|
82
|
+
assert ports == sorted([("80", "http", "Apache", "Apache"), ("443", "https", "", "")])
|
|
83
|
+
|
|
84
|
+
# Assert that all expected IPs were found
|
|
85
|
+
assert found_ips == expected_ips
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: bbot
|
|
3
|
-
Version: 2.3.0.
|
|
3
|
+
Version: 2.3.0.5445rc0
|
|
4
4
|
Summary: OSINT automation for hackers.
|
|
5
5
|
Home-page: https://github.com/blacklanternsecurity/bbot
|
|
6
6
|
License: GPL-3.0
|
|
@@ -29,6 +29,7 @@ Requires-Dist: jinja2 (>=3.1.3,<4.0.0)
|
|
|
29
29
|
Requires-Dist: lxml (>=4.9.2,<6.0.0)
|
|
30
30
|
Requires-Dist: mmh3 (>=4.1,<6.0)
|
|
31
31
|
Requires-Dist: omegaconf (>=2.3.0,<3.0.0)
|
|
32
|
+
Requires-Dist: orjson (>=3.10.12,<4.0.0)
|
|
32
33
|
Requires-Dist: psutil (>=5.9.4,<7.0.0)
|
|
33
34
|
Requires-Dist: puremagic (>=1.28,<2.0)
|
|
34
35
|
Requires-Dist: pycryptodome (>=3.17,<4.0)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
bbot/__init__.py,sha256=
|
|
2
|
-
bbot/cli.py,sha256=
|
|
1
|
+
bbot/__init__.py,sha256=JG68O_TRR-d3_m2mYrlMbXECV7BE7Shu8Dw0HiS3jeU,130
|
|
2
|
+
bbot/cli.py,sha256=Qlgqabm8N6r6uO1RuwGaM7-VXDSP_NH-YUnDUTsDYPM,10877
|
|
3
3
|
bbot/core/__init__.py,sha256=l255GJE_DvUnWvrRb0J5lG-iMztJ8zVvoweDOfegGtI,46
|
|
4
4
|
bbot/core/config/__init__.py,sha256=zYNw2Me6tsEr8hOOkLb4BQ97GB7Kis2k--G81S8vofU,342
|
|
5
5
|
bbot/core/config/files.py,sha256=zANvrTRLJQIOWSNkxd9MpWmf9cQFr0gRZLUxeIbTwQc,1412
|
|
@@ -30,7 +30,7 @@ bbot/core/helpers/helper.py,sha256=eD9yJUhrFUmmoXm4pyi31dulJ5W2eyS-YLGXmx7AyDQ,8
|
|
|
30
30
|
bbot/core/helpers/interactsh.py,sha256=VBYYH6-rWBofRsgemndK6iZNmyifOps8vgQOw2mac4k,12624
|
|
31
31
|
bbot/core/helpers/libmagic.py,sha256=QMHyxjgDLb2jyjBvK1MQ-xt6WkGXhKcHu9ZP1li-sik,3460
|
|
32
32
|
bbot/core/helpers/misc.py,sha256=156tWmNGZ0I1X537hQ8cAlShVq8D2dQVGz3DxaLh5d0,87734
|
|
33
|
-
bbot/core/helpers/names_generator.py,sha256=
|
|
33
|
+
bbot/core/helpers/names_generator.py,sha256=x6nZfEPKMwv3qR_RI4U6TBNbo6PgCF4fqbldtwilvpw,10334
|
|
34
34
|
bbot/core/helpers/ntlm.py,sha256=P2Xj4-GPos2iAzw4dfk0FJp6oGyycGhu2x6sLDVjYjs,2573
|
|
35
35
|
bbot/core/helpers/process.py,sha256=00uRpLMFi3Pt3uT8qXwAIhsXdoa7h-ifoXh0sGYgwqs,1702
|
|
36
36
|
bbot/core/helpers/ratelimiter.py,sha256=K8qFIyJPJtfdb9kSW6_lL6ahWqxR2uWyCBkDlg6uJgo,1990
|
|
@@ -61,7 +61,7 @@ bbot/modules/baddns.py,sha256=SP-o0M2dq5QIkaQZUKl9YZiOXdZasty-fHPxTJJAeR0,6378
|
|
|
61
61
|
bbot/modules/baddns_direct.py,sha256=pe_seO74XI4b6w4Q_IBDNvtBjmD-7it5ts0Z-FB0L6k,3818
|
|
62
62
|
bbot/modules/baddns_zone.py,sha256=IcewDBtA_-64NCNFojEFd9jt2YBek6ltB2mmqdDH6LE,1034
|
|
63
63
|
bbot/modules/badsecrets.py,sha256=JSukBYdD3yuvVy84DkyX48428R_LgQ7P39tjTRAD_Mo,5107
|
|
64
|
-
bbot/modules/base.py,sha256=
|
|
64
|
+
bbot/modules/base.py,sha256=Ala_jLu3I2iEadn_NNiOb4RnFdJPwlrtywASDvd-P6c,71143
|
|
65
65
|
bbot/modules/bevigil.py,sha256=0VLIxmeXRUI2-EoR6IzuHJMcX8KCHNNta-WYa3gVlDg,2862
|
|
66
66
|
bbot/modules/binaryedge.py,sha256=5F9LnZwRM_rZnzTv29hLJLI2GEQdzOwSpahPFC1kJC0,1397
|
|
67
67
|
bbot/modules/bucket_amazon.py,sha256=mwjYeEAcdfOpjbOa1sD8U9KBMMVY_c8FoHjSGR9GQbg,730
|
|
@@ -98,7 +98,7 @@ bbot/modules/docker_pull.py,sha256=T_xObzExDTZF-_HfgZSfrU199QgCME3rYmkVs1HigXQ,9
|
|
|
98
98
|
bbot/modules/dockerhub.py,sha256=yHKxV-uVubAUvYrIXizSZoLUiPKArTH2mCh5FjY4sas,3486
|
|
99
99
|
bbot/modules/dotnetnuke.py,sha256=rw_EchDg49VyQj5JiUh0AqUqtsuqLrhc-nwrybdzhZ8,10537
|
|
100
100
|
bbot/modules/emailformat.py,sha256=RLPJW-xitYB-VT4Lp08qVzFkXx_kMyV_035JT_Yf4fM,1082
|
|
101
|
-
bbot/modules/extractous.py,sha256=
|
|
101
|
+
bbot/modules/extractous.py,sha256=qE4h0reR51t9NSIcR4-VMMjc5t3H03bpW3fO0A6nb9c,4563
|
|
102
102
|
bbot/modules/ffuf_shortnames.py,sha256=9Kh0kJsw7XXpXmCkiB5eAhG4h9rSo8Y-mB3p0EDa_l0,12624
|
|
103
103
|
bbot/modules/filedownload.py,sha256=x2LmLcLD1FD2L9O6p58l21WYoqyxD5HgHg6P1g1RyxU,8180
|
|
104
104
|
bbot/modules/fingerprintx.py,sha256=rdlR9d64AntAhbS_eJzh8bZCeLPTJPSKdkdKdhH_qAo,3269
|
|
@@ -114,17 +114,17 @@ bbot/modules/google_playstore.py,sha256=N4QjzQag_bgDXfX17rytBiiWA-SQtYI2N0J_ZNEO
|
|
|
114
114
|
bbot/modules/gowitness.py,sha256=nLV2AFFK6hiQrQSoYlqY1Eo2BE3rAjYiiOKCtqAoRDc,11277
|
|
115
115
|
bbot/modules/hackertarget.py,sha256=IsKs9PtxUHdLJKZydlRdW_loBE2KphQYi3lKDAd4odc,1029
|
|
116
116
|
bbot/modules/host_header.py,sha256=uDjwidMdeNPMRfzQ2YW4REEGsZqnGOZHbOS6GgdNd9s,7686
|
|
117
|
-
bbot/modules/httpx.py,sha256=
|
|
117
|
+
bbot/modules/httpx.py,sha256=sNvtjIek2Io9BTle3MQUOj-0QYZvbsKL4et1Xd9vY1I,7642
|
|
118
118
|
bbot/modules/hunt.py,sha256=5giYoCuXWVCzxuHwF6DvA9UlJcenokZJU2-fsou_9zg,5933
|
|
119
119
|
bbot/modules/hunterio.py,sha256=Vp_QnxHSHLYmlUxPYozFVs1u-50UzRybq7Q7dWvCbFM,2638
|
|
120
120
|
bbot/modules/iis_shortnames.py,sha256=bIlmC21a0eK_cjMu1UQkDl9EfpfCN1SAggDqJL8LJfE,14493
|
|
121
121
|
bbot/modules/internal/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
122
122
|
bbot/modules/internal/aggregate.py,sha256=csWYIt2fUp9K_CRxP3bndUMIjpNIh8rmBubp5Fr1-nc,395
|
|
123
123
|
bbot/modules/internal/base.py,sha256=BXO4Hc7XKaAOaLzolF3krJX1KibPxtek2GTQUgnCHk0,387
|
|
124
|
-
bbot/modules/internal/cloudcheck.py,sha256=
|
|
125
|
-
bbot/modules/internal/dnsresolve.py,sha256=
|
|
124
|
+
bbot/modules/internal/cloudcheck.py,sha256=sr1_dj4eqcD3x8MigZkjf0AxZZWSJFzvRjYGl5uxVdk,4913
|
|
125
|
+
bbot/modules/internal/dnsresolve.py,sha256=1fwWChIGpSEIIkswueiIhEwIahQ7YngZ-njFK-RIsfU,15679
|
|
126
126
|
bbot/modules/internal/excavate.py,sha256=IazekmFOnjrqghTf9YhBbMM4dohv27vIEvfNZXJSZvg,51529
|
|
127
|
-
bbot/modules/internal/speculate.py,sha256=
|
|
127
|
+
bbot/modules/internal/speculate.py,sha256=NolqW2s8tokibc6gVM960KlrABkjhLB-7YlCdVx4O9s,9223
|
|
128
128
|
bbot/modules/internetdb.py,sha256=Edg0Z84dH8dPTZMd7RlzvYBYNq8JHs_ns_ldnFxwRKo,5415
|
|
129
129
|
bbot/modules/ip2location.py,sha256=yGivX9fzvwvLpnqmYCP2a8SPjTarzrZxfRluog-nkME,2628
|
|
130
130
|
bbot/modules/ipneighbor.py,sha256=b_0IhorihFLtXJZEz57EGXjXW30gIOEzzVgz2GFvM3A,1591
|
|
@@ -144,17 +144,18 @@ bbot/modules/output/discord.py,sha256=BzZW0T-DgZHo3xwaQbZ6DAA59wKIvCDV1LK82ev7A2
|
|
|
144
144
|
bbot/modules/output/emails.py,sha256=mzZideMCNfB8-naQANO5g8Y9HdgviAihRsdY_xPQjbQ,1095
|
|
145
145
|
bbot/modules/output/http.py,sha256=4UWKpbQx3EHpi24VIem6oSvXr0W0NZ3lDpJOmQ3Mwik,2582
|
|
146
146
|
bbot/modules/output/json.py,sha256=zvM2NwWScGk3pN4wF0mm-OqVW_0ADYy95Am4T02VVD4,1289
|
|
147
|
-
bbot/modules/output/mysql.py,sha256=
|
|
147
|
+
bbot/modules/output/mysql.py,sha256=mdIdu17otSuElA-_1OwnB3DV31lL0WcMrti38vqGsrY,1944
|
|
148
148
|
bbot/modules/output/neo4j.py,sha256=u950eUwu8YMql_WaBA38TN2bUhx7xnZdIIvYfR3xVcY,6114
|
|
149
|
-
bbot/modules/output/
|
|
149
|
+
bbot/modules/output/nmap_xml.py,sha256=RZx3LFNi_OWxd0lJXY6Nk-_sSQBRidRnoWKyZEaUXrQ,7048
|
|
150
|
+
bbot/modules/output/postgres.py,sha256=vsz3Gl9SKoWKhDidMFczksJzTeM0TZ7G9qY2rIYETF0,1938
|
|
150
151
|
bbot/modules/output/python.py,sha256=RvK2KN-Zp0Vy_1zGSNioE5eeL5hIh6Z_riFtaTymyIM,270
|
|
151
152
|
bbot/modules/output/slack.py,sha256=Ir_z11VYBdXDx8DwntWCv33Ic43vO1UIbxcp9gj0vvk,1181
|
|
152
153
|
bbot/modules/output/splunk.py,sha256=TjTCUmDwRwKOFKBJw-Xbjku64U77OauHjtR56gyaAPs,1952
|
|
153
|
-
bbot/modules/output/sqlite.py,sha256=
|
|
154
|
-
bbot/modules/output/stdout.py,sha256=
|
|
154
|
+
bbot/modules/output/sqlite.py,sha256=N0p6RRUcuCqGd4HIP0nG6JOPMs88LDQx4ImkdZVBM5E,979
|
|
155
|
+
bbot/modules/output/stdout.py,sha256=aLUtODqStdxmhh4lg7PRUsPEwTPLzdp3Hx7ZwbUvP_c,3084
|
|
155
156
|
bbot/modules/output/subdomains.py,sha256=3KZz4vD0itmqpo56uCyk43Z_zN1Q0Q_nyXjdnEublPA,1515
|
|
156
157
|
bbot/modules/output/teams.py,sha256=I2d52LqDC7e_oboLHoYBaRK6UpN0nkJ0uRnBXrhZf9E,4628
|
|
157
|
-
bbot/modules/output/txt.py,sha256=
|
|
158
|
+
bbot/modules/output/txt.py,sha256=I4zGvsFvqYZtruiCLg5spAYwR-wqjxCU0FRkPhqBUJo,976
|
|
158
159
|
bbot/modules/output/web_report.py,sha256=lZ0FqRZ7Jz1lljI9JMhH9gjtWLaTCSpSnAKQGAcPx-Q,3720
|
|
159
160
|
bbot/modules/output/websocket.py,sha256=sDTtHU-Ey_tvS0gMi6PVPV9L4qAmGyWeccxAKfEWCac,2278
|
|
160
161
|
bbot/modules/paramminer_cookies.py,sha256=q1PzftHQpCHLz81_VgLZsO6moia7ZtnU32igfcySi2w,1816
|
|
@@ -220,7 +221,7 @@ bbot/scanner/__init__.py,sha256=gCyAAbkNm8_KozNpDENCKqO3E3ZCgseplnz40AtiJ1U,56
|
|
|
220
221
|
bbot/scanner/dispatcher.py,sha256=_hsIegfUDrt8CUdXqgRvp1J0UwwzqVSDxjQmiviO41c,793
|
|
221
222
|
bbot/scanner/manager.py,sha256=_5FBfxOmSMUeGp_-ryyGGl0pxb_eu-NSWft-lH1Pyog,10466
|
|
222
223
|
bbot/scanner/preset/__init__.py,sha256=Jf2hWsHlTFtWNXL6gXD8_ZbKPFUM564ppdSxHFYnIJU,27
|
|
223
|
-
bbot/scanner/preset/args.py,sha256=
|
|
224
|
+
bbot/scanner/preset/args.py,sha256=pMJ0PfQDbLwOnggaKJl_CHz1SpQpqhhQQPvVWQaoIKA,16269
|
|
224
225
|
bbot/scanner/preset/conditions.py,sha256=hFL9cSIWGEsv2TfM5UGurf0c91cyaM8egb5IngBmIjA,1569
|
|
225
226
|
bbot/scanner/preset/environ.py,sha256=9KbEOLWkUdoAf5Ez_2A1NNm6QduQElbnNnrPi6VDhZs,4731
|
|
226
227
|
bbot/scanner/preset/path.py,sha256=Q29MO8cOEn690yW6bB08P72kbZ3C-H_TOEoXuwWnFM8,2274
|
|
@@ -242,7 +243,7 @@ bbot/test/test_step_1/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
|
|
|
242
243
|
bbot/test/test_step_1/test__module__tests.py,sha256=uwuROxdXI52D-V9z3Q9VNslvBfaduj6MQS5tQ_UOqXA,1460
|
|
243
244
|
bbot/test/test_step_1/test_bbot_fastapi.py,sha256=FNGvlax4lFZVd0T3HvV9SJh1lsngOX58GrUnJVzoy20,2531
|
|
244
245
|
bbot/test/test_step_1/test_bloom_filter.py,sha256=GodseGF98sarWXZ5C3JCVWblnycS4BA75HEAzhx4xXg,2139
|
|
245
|
-
bbot/test/test_step_1/test_cli.py,sha256=
|
|
246
|
+
bbot/test/test_step_1/test_cli.py,sha256=osCnJFA5S7NpGeAukVFTx3EkmLZPX6vITectU062Rsg,26299
|
|
246
247
|
bbot/test/test_step_1/test_command.py,sha256=5IeGV6TKB0xtFEsfsU_0mNrOmEdIQiQ3FHkUmsBNoOI,6485
|
|
247
248
|
bbot/test/test_step_1/test_config.py,sha256=Q38hygpke2GDcv8OguVZuiSOnfDJxEMrRy20dN5Qsn0,887
|
|
248
249
|
bbot/test/test_step_1/test_depsinstaller.py,sha256=zr9f-wJDotD1ZvKXGEuDRWzFYMAYBI6209mI_PWPtTQ,703
|
|
@@ -254,7 +255,7 @@ bbot/test/test_step_1/test_files.py,sha256=5Q_3jPpMXULxDHsanSDUaj8zF8bXzKdiJZHOm
|
|
|
254
255
|
bbot/test/test_step_1/test_helpers.py,sha256=6WG2rqnI7Jt0Z7Dc5AyqTDcL16QM0_WJ3CXE1M-xSMc,39506
|
|
255
256
|
bbot/test/test_step_1/test_manager_deduplication.py,sha256=hZQpDXzg6zvzxFolVOcJuY-ME8NXjZUsqS70BRNXp8A,15594
|
|
256
257
|
bbot/test/test_step_1/test_manager_scope_accuracy.py,sha256=JV1bQHt9EIM0GmGS4T4Brz_L2lfcwTxtNC06cfv7r64,79763
|
|
257
|
-
bbot/test/test_step_1/test_modules_basic.py,sha256=
|
|
258
|
+
bbot/test/test_step_1/test_modules_basic.py,sha256=hxXdsrBwme5elGQtvyvA52-KzahyQC3FlWQZ3T0EheA,19989
|
|
258
259
|
bbot/test/test_step_1/test_presets.py,sha256=CCwXb0gxTd8lSYtp0a_2PkfrwfdD5f9VngetbCLecL0,38211
|
|
259
260
|
bbot/test/test_step_1/test_python_api.py,sha256=GM5Kp2AAFl92ozo1kL6axsM87F8Gdq2_mWQvRnbXW_0,5503
|
|
260
261
|
bbot/test/test_step_1/test_regexes.py,sha256=34-BHzDE5qdltE-sQIzkrTmJTL49QUYoTn2uT1DZLwI,14356
|
|
@@ -293,7 +294,7 @@ bbot/test/test_step_2/module_tests/test_module_c99.py,sha256=F-46Kkwxe29xPZ-3kxC
|
|
|
293
294
|
bbot/test/test_step_2/module_tests/test_module_censys.py,sha256=RoFfLS0hgASdSoctJEzaKrHVqqRkuPRKPTYVCX2rZLo,4177
|
|
294
295
|
bbot/test/test_step_2/module_tests/test_module_certspotter.py,sha256=60jCOeK1yaUEgtTxYW-T47kZgKt9XxP2qBH9w-0MDBk,636
|
|
295
296
|
bbot/test/test_step_2/module_tests/test_module_chaos.py,sha256=9JRgtDEnnJgmEMCTB2bqRJRkBavLys-6ypHPxrM_hXk,956
|
|
296
|
-
bbot/test/test_step_2/module_tests/test_module_cloudcheck.py,sha256=
|
|
297
|
+
bbot/test/test_step_2/module_tests/test_module_cloudcheck.py,sha256=9DVhJfXaM42JXz577T0LdrrmArvhFXNdhICZP8aLLFU,4081
|
|
297
298
|
bbot/test/test_step_2/module_tests/test_module_code_repository.py,sha256=i02Tgvr_F9_E4d6aEaXrfdk71NkoDvjzP4C98l2rNGg,2414
|
|
298
299
|
bbot/test/test_step_2/module_tests/test_module_columbus.py,sha256=6CpIJCsykUfsn0CqxQWciIiNdM3Z73-HTnpBnVtS-L8,563
|
|
299
300
|
bbot/test/test_step_2/module_tests/test_module_credshed.py,sha256=ipkCFL7YmZBLWWoGyGr98saL_yh3E99EnLtagHqdY1g,3360
|
|
@@ -350,6 +351,7 @@ bbot/test/test_step_2/module_tests/test_module_mysql.py,sha256=4wAPjbjhlxmOkEhQn
|
|
|
350
351
|
bbot/test/test_step_2/module_tests/test_module_myssl.py,sha256=zRJ1sOEespWtBx2jA07bW5sHD1XQ9pV0PtHtGogo7Gs,1531
|
|
351
352
|
bbot/test/test_step_2/module_tests/test_module_neo4j.py,sha256=pUUaqxBsF6s11dEDhrETpvlR2pqiUcc0uvH8Z5GvVUQ,1332
|
|
352
353
|
bbot/test/test_step_2/module_tests/test_module_newsletters.py,sha256=uf5t2oRqxhNToPjEfkY9vMdOUzrSocvx8w5itS6HUaM,2295
|
|
354
|
+
bbot/test/test_step_2/module_tests/test_module_nmap_xml.py,sha256=KbUAjhARvtERv7Jx666n2hkuLOmK8Zah8RpLZqNyAuE,3548
|
|
353
355
|
bbot/test/test_step_2/module_tests/test_module_ntlm.py,sha256=tPUrsOnq8iV0l_qiD_4xkqp0-o_T2uI1e-yH22oNveA,1132
|
|
354
356
|
bbot/test/test_step_2/module_tests/test_module_nuclei.py,sha256=rLCTuKWnGWiGDcVnMjk4D7x6RGftEj3D4Woqpam-cgQ,7050
|
|
355
357
|
bbot/test/test_step_2/module_tests/test_module_oauth.py,sha256=pN1o0DmcwGCa985FrIhUuX1jIGriDjaxMzWozuv8pR0,9481
|
|
@@ -414,8 +416,8 @@ bbot/wordlists/raft-small-extensions-lowercase_CLEANED.txt,sha256=ZSIVebs7ptMvHx
|
|
|
414
416
|
bbot/wordlists/top_open_ports_nmap.txt,sha256=LmdFYkfapSxn1pVuQC2LkOIY2hMLgG-Xts7DVtYzweM,42727
|
|
415
417
|
bbot/wordlists/valid_url_schemes.txt,sha256=0B_VAr9Dv7aYhwi6JSBDU-3M76vNtzN0qEC_RNLo7HE,3310
|
|
416
418
|
bbot/wordlists/wordninja_dns.txt.gz,sha256=DYHvvfW0TvzrVwyprqODAk4tGOxv5ezNmCPSdPuDUnQ,570241
|
|
417
|
-
bbot-2.3.0.
|
|
418
|
-
bbot-2.3.0.
|
|
419
|
-
bbot-2.3.0.
|
|
420
|
-
bbot-2.3.0.
|
|
421
|
-
bbot-2.3.0.
|
|
419
|
+
bbot-2.3.0.5445rc0.dist-info/LICENSE,sha256=GzeCzK17hhQQDNow0_r0L8OfLpeTKQjFQwBQU7ZUymg,32473
|
|
420
|
+
bbot-2.3.0.5445rc0.dist-info/METADATA,sha256=TG1MVpP1_xg79xoc_MNMJtE8VrRLIGHNIHAq8oy9VW4,17990
|
|
421
|
+
bbot-2.3.0.5445rc0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
|
422
|
+
bbot-2.3.0.5445rc0.dist-info/entry_points.txt,sha256=cWjvcU_lLrzzJgjcjF7yeGuRA_eDS8pQ-kmPUAyOBfo,38
|
|
423
|
+
bbot-2.3.0.5445rc0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|