bbot 2.4.1.6095rc0__py3-none-any.whl → 2.4.1.6107rc0__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/defaults.yml +9 -1
- bbot/modules/base.py +14 -6
- bbot/modules/certspotter.py +1 -1
- bbot/modules/shodan_idb.py +29 -3
- bbot/modules/templates/webhook.py +5 -2
- {bbot-2.4.1.6095rc0.dist-info → bbot-2.4.1.6107rc0.dist-info}/METADATA +1 -1
- {bbot-2.4.1.6095rc0.dist-info → bbot-2.4.1.6107rc0.dist-info}/RECORD +11 -11
- {bbot-2.4.1.6095rc0.dist-info → bbot-2.4.1.6107rc0.dist-info}/LICENSE +0 -0
- {bbot-2.4.1.6095rc0.dist-info → bbot-2.4.1.6107rc0.dist-info}/WHEEL +0 -0
- {bbot-2.4.1.6095rc0.dist-info → bbot-2.4.1.6107rc0.dist-info}/entry_points.txt +0 -0
bbot/__init__.py
CHANGED
bbot/defaults.yml
CHANGED
|
@@ -92,10 +92,18 @@ web:
|
|
|
92
92
|
# These are attached to all in-scope HTTP requests
|
|
93
93
|
# Note that some modules (e.g. github) may end up sending these to out-of-scope resources
|
|
94
94
|
http_headers: {}
|
|
95
|
-
#
|
|
95
|
+
# How many times to retry API requests
|
|
96
|
+
# Note that this is a separate mechanism on top of HTTP retries
|
|
97
|
+
# which will retry API requests that don't return a successful status code
|
|
98
|
+
api_retries: 2
|
|
99
|
+
# HTTP retries - try again if the raw connection fails
|
|
96
100
|
http_retries: 1
|
|
97
101
|
# HTTP retries (for httpx)
|
|
98
102
|
httpx_retries: 1
|
|
103
|
+
# Default sleep interval when rate limited by 429 (and retry-after isn't provided)
|
|
104
|
+
429_sleep_interval: 30
|
|
105
|
+
# Maximum sleep interval when rate limited by 429 (and an excessive retry-after is provided)
|
|
106
|
+
429_max_sleep_interval: 60
|
|
99
107
|
# Enable/disable debug messages for web requests/responses
|
|
100
108
|
debug: false
|
|
101
109
|
# Maximum number of HTTP redirects to follow
|
bbot/modules/base.py
CHANGED
|
@@ -104,12 +104,8 @@ class BaseModule:
|
|
|
104
104
|
_batch_size = 1
|
|
105
105
|
batch_wait = 10
|
|
106
106
|
|
|
107
|
-
# API retries, etc.
|
|
108
|
-
_api_retries = 2
|
|
109
107
|
# disable the module after this many failed attempts in a row
|
|
110
108
|
_api_failure_abort_threshold = 3
|
|
111
|
-
# sleep for this many seconds after being rate limited
|
|
112
|
-
_429_sleep_interval = 30
|
|
113
109
|
|
|
114
110
|
default_discovery_context = "{module} discovered {event.type}: {event.data}"
|
|
115
111
|
|
|
@@ -159,12 +155,18 @@ class BaseModule:
|
|
|
159
155
|
# track number of failures (for .api_request())
|
|
160
156
|
self._api_request_failures = 0
|
|
161
157
|
|
|
158
|
+
self._default_api_retries = self.scan.config.get("web", {}).get("api_retries", 2)
|
|
159
|
+
|
|
162
160
|
self._tasks = []
|
|
163
161
|
self._event_received = None
|
|
164
162
|
|
|
165
163
|
# used for optional "per host" tracking
|
|
166
164
|
self._per_host_tracker = set()
|
|
167
165
|
|
|
166
|
+
# 429 rate limit handling
|
|
167
|
+
self._429_sleep_interval = self.scan.web_config.get("429_sleep_interval", 30)
|
|
168
|
+
self._429_max_sleep_interval = self.scan.web_config.get("429_max_sleep_interval", 60)
|
|
169
|
+
|
|
168
170
|
async def setup(self):
|
|
169
171
|
"""
|
|
170
172
|
Performs one-time setup tasks for the module.
|
|
@@ -338,7 +340,7 @@ class BaseModule:
|
|
|
338
340
|
|
|
339
341
|
@property
|
|
340
342
|
def api_retries(self):
|
|
341
|
-
return max(self.
|
|
343
|
+
return max(self._default_api_retries + 1, len(self._api_keys))
|
|
342
344
|
|
|
343
345
|
@property
|
|
344
346
|
def api_failure_abort_threshold(self):
|
|
@@ -1172,6 +1174,11 @@ class BaseModule:
|
|
|
1172
1174
|
retry_after = self._get_retry_after(r)
|
|
1173
1175
|
if retry_after or status_code == 429:
|
|
1174
1176
|
sleep_interval = int(retry_after) if retry_after is not None else self._429_sleep_interval
|
|
1177
|
+
if retry_after and retry_after > self._429_max_sleep_interval:
|
|
1178
|
+
self.verbose(
|
|
1179
|
+
f"Got an excessive retry-after header of {retry_after} from {new_url}, using {self._429_max_sleep_interval} instead"
|
|
1180
|
+
)
|
|
1181
|
+
sleep_interval = self._429_max_sleep_interval
|
|
1175
1182
|
self.verbose(
|
|
1176
1183
|
f"Sleeping for {sleep_interval:,} seconds due to rate limit (HTTP status: {status_code})"
|
|
1177
1184
|
)
|
|
@@ -1205,7 +1212,8 @@ class BaseModule:
|
|
|
1205
1212
|
return url, requests_kwargs
|
|
1206
1213
|
|
|
1207
1214
|
def _api_response_is_success(self, r):
|
|
1208
|
-
|
|
1215
|
+
# 404s typically indicate no data rather than an actual error with the API, so we don't want to retry them
|
|
1216
|
+
return getattr(r, "is_success", False) or getattr(r, "status_code", 0) == 404
|
|
1209
1217
|
|
|
1210
1218
|
async def api_page_iter(self, url, page_size=100, _json=True, next_key=None, iter_key=None, **requests_kwargs):
|
|
1211
1219
|
"""
|
bbot/modules/certspotter.py
CHANGED
|
@@ -15,7 +15,7 @@ class certspotter(subdomain_enum):
|
|
|
15
15
|
|
|
16
16
|
def request_url(self, query):
|
|
17
17
|
url = f"{self.base_url}/issuances?domain={self.helpers.quote(query)}&include_subdomains=true&expand=dns_names"
|
|
18
|
-
return self.api_request(url
|
|
18
|
+
return self.api_request(url)
|
|
19
19
|
|
|
20
20
|
async def parse_results(self, r, query):
|
|
21
21
|
results = set()
|
bbot/modules/shodan_idb.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from bbot.modules.base import BaseModule
|
|
2
|
+
import time
|
|
2
3
|
|
|
3
4
|
|
|
4
5
|
class shodan_idb(BaseModule):
|
|
@@ -46,23 +47,48 @@ class shodan_idb(BaseModule):
|
|
|
46
47
|
"created_date": "2023-12-22",
|
|
47
48
|
"author": "@TheTechromancer",
|
|
48
49
|
}
|
|
50
|
+
options = {"retries": None}
|
|
51
|
+
options_desc = {
|
|
52
|
+
"retries": "How many times to retry API requests (e.g. after a 429 error). Overrides the global web.api_retries setting."
|
|
53
|
+
}
|
|
49
54
|
|
|
50
|
-
# we
|
|
55
|
+
# we typically don't want to abort this module
|
|
51
56
|
_api_failure_abort_threshold = 9999999999
|
|
52
57
|
|
|
53
|
-
# there
|
|
54
|
-
|
|
58
|
+
# since there are rate limits, we set a lower qsize
|
|
59
|
+
# this way when our queue is full, we can give the API a break
|
|
60
|
+
_qsize = 100
|
|
55
61
|
|
|
56
62
|
base_url = "https://internetdb.shodan.io"
|
|
57
63
|
|
|
64
|
+
async def setup(self):
|
|
65
|
+
await super().setup()
|
|
66
|
+
self.last_request_time = 0
|
|
67
|
+
return True
|
|
68
|
+
|
|
58
69
|
def _incoming_dedup_hash(self, event):
|
|
59
70
|
return hash(self.get_ip(event))
|
|
60
71
|
|
|
72
|
+
@property
|
|
73
|
+
def api_retries(self):
|
|
74
|
+
# allow the module to override global retry setting
|
|
75
|
+
return self.config.get("retries", None) or super().api_retries
|
|
76
|
+
|
|
61
77
|
async def handle_event(self, event):
|
|
62
78
|
ip = self.get_ip(event)
|
|
63
79
|
if ip is None:
|
|
64
80
|
return
|
|
65
81
|
url = f"{self.base_url}/{ip}"
|
|
82
|
+
|
|
83
|
+
# Rate limiting: ensure at least 1 second between requests
|
|
84
|
+
current_time = time.time()
|
|
85
|
+
time_since_last = current_time - self.last_request_time
|
|
86
|
+
if time_since_last < 1:
|
|
87
|
+
await self.helpers.sleep(1 - time_since_last)
|
|
88
|
+
|
|
89
|
+
# Update the last request time
|
|
90
|
+
self.last_request_time = time.time()
|
|
91
|
+
|
|
66
92
|
r = await self.api_request(url)
|
|
67
93
|
if r is None:
|
|
68
94
|
self.debug(f"No response for {event.data}")
|
|
@@ -16,10 +16,9 @@ class WebhookOutputModule(BaseOutputModule):
|
|
|
16
16
|
# abort module after 10 failed requests (not including retries)
|
|
17
17
|
_api_failure_abort_threshold = 10
|
|
18
18
|
# retry each request up to 10 times, respecting the Retry-After header
|
|
19
|
-
|
|
19
|
+
_default_api_retries = 10
|
|
20
20
|
|
|
21
21
|
async def setup(self):
|
|
22
|
-
self._api_retries = self.config.get("retries", 10)
|
|
23
22
|
self.webhook_url = self.config.get("webhook_url", "")
|
|
24
23
|
self.min_severity = self.config.get("min_severity", "LOW").strip().upper()
|
|
25
24
|
assert self.min_severity in self.vuln_severities, (
|
|
@@ -31,6 +30,10 @@ class WebhookOutputModule(BaseOutputModule):
|
|
|
31
30
|
return False
|
|
32
31
|
return await super().setup()
|
|
33
32
|
|
|
33
|
+
@property
|
|
34
|
+
def api_retries(self):
|
|
35
|
+
return self.config.get("retries", self._default_api_retries)
|
|
36
|
+
|
|
34
37
|
async def handle_event(self, event):
|
|
35
38
|
message = self.format_message(event)
|
|
36
39
|
data = {self.content_key: message}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: bbot
|
|
3
|
-
Version: 2.4.1.
|
|
3
|
+
Version: 2.4.1.6107rc0
|
|
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
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
bbot/__init__.py,sha256=
|
|
1
|
+
bbot/__init__.py,sha256=sam4KorFe9w2RyVwBP9vdpFRehUOzVwRYur0Gh67BqY,163
|
|
2
2
|
bbot/cli.py,sha256=1QJbANVw9Q3GFM92H2QRV2ds5756ulm08CDZwzwPpeI,11888
|
|
3
3
|
bbot/core/__init__.py,sha256=l255GJE_DvUnWvrRb0J5lG-iMztJ8zVvoweDOfegGtI,46
|
|
4
4
|
bbot/core/config/__init__.py,sha256=zYNw2Me6tsEr8hOOkLb4BQ97GB7Kis2k--G81S8vofU,342
|
|
@@ -48,7 +48,7 @@ bbot/core/modules.py,sha256=U0Z2UoZAOPG9lLvR9Juc3UwdWCc_xbktF4t_NoiKPrY,31385
|
|
|
48
48
|
bbot/core/multiprocess.py,sha256=ocQHanskJ09gHwe7RZmwNdZyCOQyeyUoIHCtLbtvXUk,1771
|
|
49
49
|
bbot/core/shared_deps.py,sha256=mCMZeKSt46trzVqQDPGfXfEWg0Zw5YjiJx4BnsIRgHM,7640
|
|
50
50
|
bbot/db/sql/models.py,sha256=SrUdDOBCICzXJBY29p0VvILhMQ1JCuh725bqvIYogX0,4884
|
|
51
|
-
bbot/defaults.yml,sha256=
|
|
51
|
+
bbot/defaults.yml,sha256=wIiOAEvsnJi_Q7qXC1Pn1TCSWiSh8CagpwVvVIGefLs,7106
|
|
52
52
|
bbot/errors.py,sha256=xwQcD26nU9oc7-o0kv5jmEDTInmi8_W8eKAgQZZxdVM,953
|
|
53
53
|
bbot/logger.py,sha256=wE-532v5FyKuSSoTdyW1xSfaOnLZB1axAJnB-uW2xrI,2745
|
|
54
54
|
bbot/modules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -61,7 +61,7 @@ bbot/modules/baddns.py,sha256=ubO3KDfcIMJnMjyZX5FWZ4GWxLSekV_JQV7QvsPjtD0,6693
|
|
|
61
61
|
bbot/modules/baddns_direct.py,sha256=hWThpkXP87nnCRTlUh5qBJ1t4eo4l9kUmKNNxVNJI8A,3819
|
|
62
62
|
bbot/modules/baddns_zone.py,sha256=y1XaBUfFPnRbR2qaTqRyUsPgEL73722v2B8aS5YoGN4,1035
|
|
63
63
|
bbot/modules/badsecrets.py,sha256=LG37p48Rlxsfc3BmACMpkypsbuFTVvXqNhlP1IEsx0k,5109
|
|
64
|
-
bbot/modules/base.py,sha256=
|
|
64
|
+
bbot/modules/base.py,sha256=_RFTPNZ6X7mD7jBOTYZmjgzTSKWT9U_eYxL4gXIh8TE,75265
|
|
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
|
|
@@ -75,7 +75,7 @@ bbot/modules/builtwith.py,sha256=6ZQOc6vmSVc8LsdgsiuMWfDquGm5K0jxwsnL8MsKNWw,538
|
|
|
75
75
|
bbot/modules/bypass403.py,sha256=HyONgOYlZUET61FZ0QWE7zPGG-N6n0x_j9KUGw8kVxQ,6855
|
|
76
76
|
bbot/modules/c99.py,sha256=yHT9-eyqRODISV5eTi11uh-xwqX0JG7zey5AgcDYCdI,1448
|
|
77
77
|
bbot/modules/censys.py,sha256=J7NhPnSeoCuG_9FkLjFBIg-tqHAB21HjvQUw_6OQNZo,3311
|
|
78
|
-
bbot/modules/certspotter.py,sha256=
|
|
78
|
+
bbot/modules/certspotter.py,sha256=qdRGCkGyP07_cP9h2o_AEZwoiQPXtrC-Bel3vgh24x8,905
|
|
79
79
|
bbot/modules/chaos.py,sha256=JyuwytwE3IRmNbw-uyJ0gCaTnywhhsHzTiZ3OJ15PAw,1573
|
|
80
80
|
bbot/modules/code_repository.py,sha256=x70Z45VnNNMF8BPkHfGWZXsZXw_fStGB3y0-8jbP1Ns,2078
|
|
81
81
|
bbot/modules/credshed.py,sha256=HAF5wgRGKIIpdMAe4mIAtkZRLmFYjMFyXtjjst6RJ20,4203
|
|
@@ -177,7 +177,7 @@ bbot/modules/robots.py,sha256=LGG6ixsxrlaCk-mi4Lp6kB2RB1v-25NhTAQxdQEtH8s,2172
|
|
|
177
177
|
bbot/modules/securitytrails.py,sha256=5Jk_HTQP8FRq6A30sN19FU79uLJt7aiOsI2dxNkLDcM,1148
|
|
178
178
|
bbot/modules/securitytxt.py,sha256=nwaTOnRAl2NWcEc3i_I9agB56QjqK8dHqiKRHPPkCPE,4558
|
|
179
179
|
bbot/modules/shodan_dns.py,sha256=ETOyUhCiAETlGUAQhvAP47oEEPYss7fm_F_CAeCQyoI,842
|
|
180
|
-
bbot/modules/shodan_idb.py,sha256=
|
|
180
|
+
bbot/modules/shodan_idb.py,sha256=PB5vplwpjPjbfoMeez333rWYqFY5RuMp40ZN9hNCJAg,6088
|
|
181
181
|
bbot/modules/sitedossier.py,sha256=MR9fSkgE_3YGsUe7M-TyJ2GdpBtF3oLKDl9agAwzw5U,2284
|
|
182
182
|
bbot/modules/skymem.py,sha256=ZrxWcePFTCiDkFeAc3YLegFG-Tgw4C9af_JHiVonk84,1930
|
|
183
183
|
bbot/modules/smuggler.py,sha256=v8NCRgzd7wpEFZJUTAArG04bN8nNTGiHxYpGBapzi14,1580
|
|
@@ -192,7 +192,7 @@ bbot/modules/templates/postman.py,sha256=MIpz2q_r6LP0kIEgByo7oX5qHhMZLOhr7oKzJI9
|
|
|
192
192
|
bbot/modules/templates/shodan.py,sha256=MXBvlmfw3jZFqT47v10UkqMSyQR-zBIxMJmK7PWw6uw,1174
|
|
193
193
|
bbot/modules/templates/sql.py,sha256=o-CdyyoJvHJdJBKkj3CIGXYxUta4w2AB_2Vr-k7cDDU,3553
|
|
194
194
|
bbot/modules/templates/subdomain_enum.py,sha256=epyKSly08jqaINV_AMMWbNafIeQjJqvd3aj63KD0Mck,8402
|
|
195
|
-
bbot/modules/templates/webhook.py,sha256=
|
|
195
|
+
bbot/modules/templates/webhook.py,sha256=uGFmcJ81GzGN1UI2k2O7nQF_fyh4ehLDEg2NSXaPnhk,3373
|
|
196
196
|
bbot/modules/trickest.py,sha256=MRgLW0YiDWzlWdAjyqfPPLFb-a51r-Ffn_dphiJI_gA,1550
|
|
197
197
|
bbot/modules/trufflehog.py,sha256=KEObs5z0ce0Ck7gA3t3l66MJKUo6P_9TIfVOwFO28t4,8743
|
|
198
198
|
bbot/modules/url_manipulation.py,sha256=4J3oFkqTSJPPmbKEKAHJg2Q2w4QNKtQhiN03ZJq5VtI,4326
|
|
@@ -428,8 +428,8 @@ bbot/wordlists/raft-small-extensions-lowercase_CLEANED.txt,sha256=ZSIVebs7ptMvHx
|
|
|
428
428
|
bbot/wordlists/top_open_ports_nmap.txt,sha256=LmdFYkfapSxn1pVuQC2LkOIY2hMLgG-Xts7DVtYzweM,42727
|
|
429
429
|
bbot/wordlists/valid_url_schemes.txt,sha256=0B_VAr9Dv7aYhwi6JSBDU-3M76vNtzN0qEC_RNLo7HE,3310
|
|
430
430
|
bbot/wordlists/wordninja_dns.txt.gz,sha256=DYHvvfW0TvzrVwyprqODAk4tGOxv5ezNmCPSdPuDUnQ,570241
|
|
431
|
-
bbot-2.4.1.
|
|
432
|
-
bbot-2.4.1.
|
|
433
|
-
bbot-2.4.1.
|
|
434
|
-
bbot-2.4.1.
|
|
435
|
-
bbot-2.4.1.
|
|
431
|
+
bbot-2.4.1.6107rc0.dist-info/LICENSE,sha256=GzeCzK17hhQQDNow0_r0L8OfLpeTKQjFQwBQU7ZUymg,32473
|
|
432
|
+
bbot-2.4.1.6107rc0.dist-info/METADATA,sha256=Tbmi58DKjLEf9JRM2BKNULln0TwoEqeiPdGOMn3kQdU,18218
|
|
433
|
+
bbot-2.4.1.6107rc0.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
|
|
434
|
+
bbot-2.4.1.6107rc0.dist-info/entry_points.txt,sha256=cWjvcU_lLrzzJgjcjF7yeGuRA_eDS8pQ-kmPUAyOBfo,38
|
|
435
|
+
bbot-2.4.1.6107rc0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|