bbot 2.3.2.5944rc0__py3-none-any.whl → 2.3.2.5958rc0__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 CHANGED
@@ -1,4 +1,4 @@
1
1
  # version placeholder (replaced by poetry-dynamic-versioning)
2
- __version__ = "v2.3.2.5944rc"
2
+ __version__ = "v2.3.2.5958rc"
3
3
 
4
4
  from .scanner import Scanner, Preset
bbot/modules/base.py CHANGED
@@ -71,7 +71,7 @@ class BaseModule:
71
71
 
72
72
  _qsize (int): Outgoing queue size (0 for infinite). Default is 0.
73
73
 
74
- _priority (int): Priority level of events raised by this module, 1-5. Default is 3.
74
+ _priority (int): Priority level of the module. Lower values are higher priority. Default is 3.
75
75
 
76
76
  _name (str): Module name, overridden automatically. Default is 'base'.
77
77
 
bbot/modules/crt.py CHANGED
@@ -1,3 +1,6 @@
1
+ import time
2
+ import asyncpg
3
+
1
4
  from bbot.modules.templates.subdomain_enum import subdomain_enum
2
5
 
3
6
 
@@ -11,30 +14,53 @@ class crt(subdomain_enum):
11
14
  "author": "@TheTechromancer",
12
15
  }
13
16
 
14
- base_url = "https://crt.sh"
17
+ deps_pip = ["asyncpg"]
18
+
19
+ db_host = "crt.sh"
20
+ db_port = 5432
21
+ db_user = "guest"
22
+ db_name = "certwatch"
15
23
  reject_wildcards = False
16
24
 
17
25
  async def setup(self):
18
- self.cert_ids = set()
26
+ self.db_conn = None
19
27
  return await super().setup()
20
28
 
21
29
  async def request_url(self, query):
22
- params = {"q": f"%.{query}", "output": "json"}
23
- url = self.helpers.add_get_params(self.base_url, params).geturl()
24
- return await self.api_request(url, timeout=self.http_timeout + 30)
25
-
26
- async def parse_results(self, r, query):
27
- results = set()
28
- j = r.json()
29
- for cert_info in j:
30
- if not type(cert_info) == dict:
31
- continue
32
- cert_id = cert_info.get("id")
33
- if cert_id:
34
- if hash(cert_id) not in self.cert_ids:
35
- self.cert_ids.add(hash(cert_id))
36
- domain = cert_info.get("name_value")
37
- if domain:
38
- for d in domain.splitlines():
39
- results.add(d.lower())
30
+ if not self.db_conn:
31
+ self.db_conn = await asyncpg.connect(
32
+ host=self.db_host, port=self.db_port, user=self.db_user, database=self.db_name
33
+ )
34
+
35
+ sql = """
36
+ WITH ci AS (
37
+ SELECT array_agg(DISTINCT sub.NAME_VALUE) NAME_VALUES
38
+ FROM (
39
+ SELECT DISTINCT cai.CERTIFICATE, cai.NAME_VALUE
40
+ FROM certificate_and_identities cai
41
+ WHERE plainto_tsquery('certwatch', $1) @@ identities(cai.CERTIFICATE)
42
+ AND cai.NAME_VALUE ILIKE ('%.' || $1)
43
+ LIMIT 50000
44
+ ) sub
45
+ GROUP BY sub.CERTIFICATE
46
+ )
47
+ SELECT DISTINCT unnest(NAME_VALUES) as name_value FROM ci;
48
+ """
49
+ start = time.time()
50
+ results = await self.db_conn.fetch(sql, query)
51
+ end = time.time()
52
+ self.verbose(f"SQL query executed in: {end - start} seconds with {len(results):,} results")
40
53
  return results
54
+
55
+ async def parse_results(self, results, query):
56
+ domains = set()
57
+ for row in results:
58
+ domain = row["name_value"]
59
+ if domain:
60
+ for d in domain.splitlines():
61
+ domains.add(d.lower())
62
+ return domains
63
+
64
+ async def cleanup(self):
65
+ if self.db_conn:
66
+ await self.db_conn.close()
@@ -18,6 +18,7 @@ class ffuf(BaseModule):
18
18
  "max_depth": 0,
19
19
  "extensions": "",
20
20
  "ignore_case": False,
21
+ "rate": 0,
21
22
  }
22
23
 
23
24
  options_desc = {
@@ -26,6 +27,7 @@ class ffuf(BaseModule):
26
27
  "max_depth": "the maximum directory depth to attempt to solve",
27
28
  "extensions": "Optionally include a list of extensions to extend the keyword with (comma separated)",
28
29
  "ignore_case": "Only put lowercase words into the wordlist",
30
+ "rate": "Rate of requests per second (default: 0)",
29
31
  }
30
32
 
31
33
  deps_common = ["ffuf"]
@@ -43,6 +45,7 @@ class ffuf(BaseModule):
43
45
  self.wordlist = await self.helpers.wordlist(wordlist_url)
44
46
  self.wordlist_lines = self.generate_wordlist(self.wordlist)
45
47
  self.tempfile, tempfile_len = self.generate_templist()
48
+ self.rate = self.config.get("rate", 0)
46
49
  self.verbose(f"Generated dynamic wordlist with length [{str(tempfile_len)}]")
47
50
  try:
48
51
  self.extensions = self.helpers.chain_lists(self.config.get("extensions", ""), validate=True)
@@ -245,6 +248,9 @@ class ffuf(BaseModule):
245
248
  self.debug("invalid mode specified, aborting")
246
249
  return
247
250
 
251
+ if self.rate > 0:
252
+ command += ["-rate", f"{self.rate}"]
253
+
248
254
  if self.proxy:
249
255
  command += ["-x", self.proxy]
250
256
 
@@ -26,6 +26,7 @@ class ffuf_shortnames(ffuf):
26
26
  "find_delimiters": True,
27
27
  "find_subwords": False,
28
28
  "max_predictions": 250,
29
+ "rate": 0,
29
30
  }
30
31
 
31
32
  options_desc = {
@@ -38,6 +39,7 @@ class ffuf_shortnames(ffuf):
38
39
  "find_delimiters": "Attempt to detect common delimiters and make additional ffuf runs against them",
39
40
  "find_subwords": "Attempt to detect subwords and make additional ffuf runs against them",
40
41
  "max_predictions": "The maximum number of predictions to generate per shortname prefix",
42
+ "rate": "Rate of requests per second (default: 0)",
41
43
  }
42
44
 
43
45
  deps_pip = ["numpy"]
@@ -96,6 +98,7 @@ class ffuf_shortnames(ffuf):
96
98
  self.ignore_redirects = self.config.get("ignore_redirects")
97
99
  self.max_predictions = self.config.get("max_predictions")
98
100
  self.find_subwords = self.config.get("find_subwords")
101
+ self.rate = self.config.get("rate", 0)
99
102
 
100
103
  class MinimalWordPredictor:
101
104
  def __init__(self):
@@ -18,6 +18,8 @@ class portfilter(BaseInterceptModule):
18
18
  "allowed_cdn_ports": "Comma-separated list of ports that are allowed to be scanned for CDNs",
19
19
  }
20
20
 
21
+ _priority = 4
22
+
21
23
  async def setup(self):
22
24
  self.cdn_tags = [t.strip() for t in self.config.get("cdn_tags", "").split(",")]
23
25
  self.allowed_cdn_ports = self.config.get("allowed_cdn_ports", "").strip()
bbot/scanner/scanner.py CHANGED
@@ -289,6 +289,7 @@ class Scanner:
289
289
 
290
290
  # intercept modules get sewn together like human centipede
291
291
  self.intercept_modules = [m for m in self.modules.values() if m._intercept]
292
+ self.intercept_modules.sort(key=lambda x: x.priority)
292
293
  for i, intercept_module in enumerate(self.intercept_modules[1:]):
293
294
  prev_intercept_module = self.intercept_modules[i]
294
295
  self.debug(
@@ -3,12 +3,22 @@ from .base import ModuleTestBase
3
3
 
4
4
  class TestCRT(ModuleTestBase):
5
5
  async def setup_after_prep(self, module_test):
6
- module_test.module.abort_if = lambda e: False
7
- for t in self.targets:
8
- module_test.httpx_mock.add_response(
9
- url="https://crt.sh?q=%25.blacklanternsecurity.com&output=json",
10
- json=[{"id": 1, "name_value": "asdf.blacklanternsecurity.com\nzzzz.blacklanternsecurity.com"}],
11
- )
6
+ class AsyncMock:
7
+ async def fetch(self, *args, **kwargs):
8
+ print("mock_fetch", args, kwargs)
9
+ return [
10
+ {"name_value": "asdf.blacklanternsecurity.com"},
11
+ {"name_value": "zzzz.blacklanternsecurity.com"},
12
+ ]
13
+
14
+ async def close(self):
15
+ pass
16
+
17
+ async def mock_connect(*args, **kwargs):
18
+ print("mock_connect", args, kwargs)
19
+ return AsyncMock()
20
+
21
+ module_test.monkeypatch.setattr("asyncpg.connect", mock_connect)
12
22
 
13
23
  def check(self, module_test, events):
14
24
  assert any(e.data == "asdf.blacklanternsecurity.com" for e in events), "Failed to detect subdomain"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bbot
3
- Version: 2.3.2.5944rc0
3
+ Version: 2.3.2.5958rc0
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=hBISVROF7aBils6i28vrQzWohknYZpMQBE0w2_JRRb4,130
1
+ bbot/__init__.py,sha256=zs6Wq8dI1ItOD6H659-keQl5C_cvZ-SbzZvFI_4h338,130
2
2
  bbot/cli.py,sha256=H7L3yIoYuSpkrf1K1qqiBMQBTyt8UI9FfConpjqr7KI,11029
3
3
  bbot/core/__init__.py,sha256=l255GJE_DvUnWvrRb0J5lG-iMztJ8zVvoweDOfegGtI,46
4
4
  bbot/core/config/__init__.py,sha256=zYNw2Me6tsEr8hOOkLb4BQ97GB7Kis2k--G81S8vofU,342
@@ -61,7 +61,7 @@ bbot/modules/baddns.py,sha256=y6zTuE668MvNdaQszmkwYSwWzrjqit5X3zf5kLJbQC8,6692
61
61
  bbot/modules/baddns_direct.py,sha256=yoOSqi4Z1ZwrycGbwklCukDBjWRWlz6JV67v_xVwHbE,3818
62
62
  bbot/modules/baddns_zone.py,sha256=IcewDBtA_-64NCNFojEFd9jt2YBek6ltB2mmqdDH6LE,1034
63
63
  bbot/modules/badsecrets.py,sha256=LG37p48Rlxsfc3BmACMpkypsbuFTVvXqNhlP1IEsx0k,5109
64
- bbot/modules/base.py,sha256=fm-Z1mhqgYkJI_PEZwslMS9ThRsKIBTDvQAc1CWU9HI,72775
64
+ bbot/modules/base.py,sha256=ufqXGnY6W8-umqvaU5om6ghijv9sfJbqBNvnGQZzkM4,72786
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
@@ -79,9 +79,9 @@ bbot/modules/certspotter.py,sha256=AtL5BiOuDp4vu1-5fct4aQAGZM2qiODYsbgBsw0phoU,9
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
82
- bbot/modules/crt.py,sha256=6Zm90VKXwYYN6Sab0gwwhTARrtnQIqALJTVtFWMMTGk,1369
82
+ bbot/modules/crt.py,sha256=-_ZTmQofCqhtGl-Xp4kWmDndivAKZx71I1JwHWjl4Rg,2048
83
83
  bbot/modules/deadly/dastardly.py,sha256=dxPkJUfAsuddDDuI_uVyTUxkJ5eps92nSrPtpBOTlQg,5315
84
- bbot/modules/deadly/ffuf.py,sha256=sCledEgIi1ZgAhb-XlwbLIH3wBD5dSELZAEun_pNLOk,14745
84
+ bbot/modules/deadly/ffuf.py,sha256=VVehiHYEieVMuOjoAXD32NdgATW3aGg5PFm8NlQBjK0,14955
85
85
  bbot/modules/deadly/nuclei.py,sha256=-Ne3NMQwa55oMG_AkYWyxQMOA1j6Omkk7VHdSjh8isU,17808
86
86
  bbot/modules/deadly/vhost.py,sha256=m7RdR0w7Hs38IGVHUu_3Er-_5ABVdalRG_8znQepxD0,5456
87
87
  bbot/modules/dehashed.py,sha256=iyzWHmJs6zC7FsRhw9_AdkckQKCf_0oNnL9RwG409r0,5071
@@ -98,7 +98,7 @@ bbot/modules/dockerhub.py,sha256=JQkujjqvQRzQuvHjQ7JbFs_VlJj8dLRPRObAkBgUQhc,349
98
98
  bbot/modules/dotnetnuke.py,sha256=zipcHyNYr2FEecStb1Yrm938ps01RvHV8NnyqAvnGGc,10537
99
99
  bbot/modules/emailformat.py,sha256=RLPJW-xitYB-VT4Lp08qVzFkXx_kMyV_035JT_Yf4fM,1082
100
100
  bbot/modules/extractous.py,sha256=VSGKmHPAA_4r62jaN8Yqi3JcjehjxpI2lhe8i2j786s,4648
101
- bbot/modules/ffuf_shortnames.py,sha256=iJnm6bvFyQXfzOGnUioficE6v59QkaErY7mo4m6m7o0,18618
101
+ bbot/modules/ffuf_shortnames.py,sha256=VxAxSrkU_XqRrOdv03YgwPLgW4OD6VcVwYpyQ7kt6_U,18744
102
102
  bbot/modules/filedownload.py,sha256=TOxftfxguaRSEKI8oG79XVRQqUGg1_IhYDYl_Jw9eYc,8694
103
103
  bbot/modules/fingerprintx.py,sha256=rdlR9d64AntAhbS_eJzh8bZCeLPTJPSKdkdKdhH_qAo,3269
104
104
  bbot/modules/fullhunt.py,sha256=zeehQb9akBSbHW9dF4icH8Vfd8LqoTrpIvnQEEMWes8,1311
@@ -165,7 +165,7 @@ bbot/modules/paramminer_getparams.py,sha256=_j6rgaqV5wGJoa8p5-KKbe2YsVGUtmWIanCV
165
165
  bbot/modules/paramminer_headers.py,sha256=CuiqT3nY3eIrZhT4CAEkRDfCbCYci8CmnXsippf3Qb4,10450
166
166
  bbot/modules/passivetotal.py,sha256=uGT6c_CUxBNInmClsTg8afIYA2ZykKYYCgjkyzujfHg,1653
167
167
  bbot/modules/pgp.py,sha256=Xu2M9WEIlwTm5-Lv29g7BblI05tD9Dl0XsYSeY6UURs,2065
168
- bbot/modules/portfilter.py,sha256=FB1plaBTZxiJnLJ8RiyPyc2Hrh7N7_DRSiyfeQEAfms,1723
168
+ bbot/modules/portfilter.py,sha256=4ZJ6tE0opC07D3xNCEvEcRfhT_rHk-GCN8x46CkavrQ,1742
169
169
  bbot/modules/portscan.py,sha256=dM2p3tBGQKSdeZRMlCpOwqRpz0XJfIMwY2n3Ajaig_M,13441
170
170
  bbot/modules/postman.py,sha256=vo761Nzu3kPBzfCY3KJcvsGEsjImaa7iA2z-LyASBDc,4589
171
171
  bbot/modules/postman_download.py,sha256=LUB9cP-otkB1HaNACGS5YPwsxnwp1uSo28SpGvmQ60A,3467
@@ -234,7 +234,7 @@ bbot/scanner/preset/conditions.py,sha256=hFL9cSIWGEsv2TfM5UGurf0c91cyaM8egb5IngB
234
234
  bbot/scanner/preset/environ.py,sha256=9KbEOLWkUdoAf5Ez_2A1NNm6QduQElbnNnrPi6VDhZs,4731
235
235
  bbot/scanner/preset/path.py,sha256=Q29MO8cOEn690yW6bB08P72kbZ3C-H_TOEoXuwWnFM8,2274
236
236
  bbot/scanner/preset/preset.py,sha256=Xmh9mkO4c985sOG8BGRwujBUmO1jCpHRC_Sgq2fD_dY,40805
237
- bbot/scanner/scanner.py,sha256=goJbtDF0wiNZxjwmaAnA1t_F4ueIg30kjsf9S1giXf4,54551
237
+ bbot/scanner/scanner.py,sha256=O9LPaOa33yjdtolri3pcmQOBj4_8fMpMlwoYICZYK0M,54617
238
238
  bbot/scanner/stats.py,sha256=re93sArKXZSiD0Owgqk2J3Kdvfm3RL4Y9Qy_VOcaVk8,3623
239
239
  bbot/scanner/target.py,sha256=EQwtFZLDeNlqt8JupyBEksqeQ_c_i3NARSWf3mQQC4k,12128
240
240
  bbot/scripts/docs.py,sha256=ZLY9-O6OeEElzOUvTglO5EMkRv1s4aEuxJb2CthCVsI,10782
@@ -305,7 +305,7 @@ bbot/test/test_step_2/module_tests/test_module_chaos.py,sha256=9JRgtDEnnJgmEMCTB
305
305
  bbot/test/test_step_2/module_tests/test_module_cloudcheck.py,sha256=9KjGREpzOVByDVjIEWoaWbS3RwPlYLN3mw-OnRvD7sg,4083
306
306
  bbot/test/test_step_2/module_tests/test_module_code_repository.py,sha256=i02Tgvr_F9_E4d6aEaXrfdk71NkoDvjzP4C98l2rNGg,2414
307
307
  bbot/test/test_step_2/module_tests/test_module_credshed.py,sha256=ipkCFL7YmZBLWWoGyGr98saL_yh3E99EnLtagHqdY1g,3360
308
- bbot/test/test_step_2/module_tests/test_module_crt.py,sha256=V15tE1jcXdXJEzEEdAJvSMRWhKBFtxBBUJ_eewvV3U4,717
308
+ bbot/test/test_step_2/module_tests/test_module_crt.py,sha256=HOx8z9ZUWAvqhso3_xfgbUElL-KHw3yX_LgHTBGObPI,944
309
309
  bbot/test/test_step_2/module_tests/test_module_csv.py,sha256=UJqMqdiPjx-UjJw10OoVMAj378wu5mWIq0v04TCljTM,579
310
310
  bbot/test/test_step_2/module_tests/test_module_dastardly.py,sha256=jjpJD9mdCcbaJgnG63xE-J_Qqpjt9hpm_WvfHDLfTsc,2353
311
311
  bbot/test/test_step_2/module_tests/test_module_dehashed.py,sha256=BZ0LFO4xBwDsXzsqjZCYRMTbXdwwUEma2OeJh8YQIEs,3625
@@ -425,8 +425,8 @@ bbot/wordlists/raft-small-extensions-lowercase_CLEANED.txt,sha256=ZSIVebs7ptMvHx
425
425
  bbot/wordlists/top_open_ports_nmap.txt,sha256=LmdFYkfapSxn1pVuQC2LkOIY2hMLgG-Xts7DVtYzweM,42727
426
426
  bbot/wordlists/valid_url_schemes.txt,sha256=0B_VAr9Dv7aYhwi6JSBDU-3M76vNtzN0qEC_RNLo7HE,3310
427
427
  bbot/wordlists/wordninja_dns.txt.gz,sha256=DYHvvfW0TvzrVwyprqODAk4tGOxv5ezNmCPSdPuDUnQ,570241
428
- bbot-2.3.2.5944rc0.dist-info/LICENSE,sha256=GzeCzK17hhQQDNow0_r0L8OfLpeTKQjFQwBQU7ZUymg,32473
429
- bbot-2.3.2.5944rc0.dist-info/METADATA,sha256=XEPcMePFQCzHGB4gk2cT6pmxBgORqxqBzqfy_6pqEjs,18218
430
- bbot-2.3.2.5944rc0.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
431
- bbot-2.3.2.5944rc0.dist-info/entry_points.txt,sha256=cWjvcU_lLrzzJgjcjF7yeGuRA_eDS8pQ-kmPUAyOBfo,38
432
- bbot-2.3.2.5944rc0.dist-info/RECORD,,
428
+ bbot-2.3.2.5958rc0.dist-info/LICENSE,sha256=GzeCzK17hhQQDNow0_r0L8OfLpeTKQjFQwBQU7ZUymg,32473
429
+ bbot-2.3.2.5958rc0.dist-info/METADATA,sha256=lep2AMvMwyENAV8jiAp_X5sSGF8fCbGHXPaRSUp8yFU,18218
430
+ bbot-2.3.2.5958rc0.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
431
+ bbot-2.3.2.5958rc0.dist-info/entry_points.txt,sha256=cWjvcU_lLrzzJgjcjF7yeGuRA_eDS8pQ-kmPUAyOBfo,38
432
+ bbot-2.3.2.5958rc0.dist-info/RECORD,,