bbot 2.3.0.5467rc0__py3-none-any.whl → 2.3.0.5477rc0__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.0.5467rc"
2
+ __version__ = "v2.3.0.5477rc"
3
3
 
4
4
  from .scanner import Scanner, Preset
bbot/cli.py CHANGED
@@ -260,9 +260,7 @@ async def _main():
260
260
  finally:
261
261
  # save word cloud
262
262
  with suppress(BaseException):
263
- save_success, filename = scan.helpers.word_cloud.save()
264
- if save_success:
265
- log_to_stderr(f"Saved word cloud ({len(scan.helpers.word_cloud):,} words) to {filename}")
263
+ scan.helpers.word_cloud.save()
266
264
  # remove output directory if empty
267
265
  with suppress(BaseException):
268
266
  scan.home.rmdir()
@@ -3,7 +3,11 @@ 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", "created_date": "2024-11-13", "author": "@TheTechromancer"}
6
+ meta = {
7
+ "description": "Output scan data to a MySQL database",
8
+ "created_date": "2024-11-13",
9
+ "author": "@TheTechromancer",
10
+ }
7
11
  options = {
8
12
  "username": "root",
9
13
  "password": "bbotislife",
@@ -135,14 +135,17 @@ class BBOTArgs:
135
135
  args_preset.core.merge_custom({"modules": {"stdout": {"event_types": self.parsed.event_types}}})
136
136
 
137
137
  # dependencies
138
+ deps_config = args_preset.core.custom_config.get("deps", {})
138
139
  if self.parsed.retry_deps:
139
- args_preset.core.custom_config["deps_behavior"] = "retry_failed"
140
+ deps_config["behavior"] = "retry_failed"
140
141
  elif self.parsed.force_deps:
141
- args_preset.core.custom_config["deps_behavior"] = "force_install"
142
+ deps_config["behavior"] = "force_install"
142
143
  elif self.parsed.no_deps:
143
- args_preset.core.custom_config["deps_behavior"] = "disable"
144
+ deps_config["behavior"] = "disable"
144
145
  elif self.parsed.ignore_failed_deps:
145
- args_preset.core.custom_config["deps_behavior"] = "ignore_failed"
146
+ deps_config["behavior"] = "ignore_failed"
147
+ if deps_config:
148
+ args_preset.core.merge_custom({"deps": deps_config})
146
149
 
147
150
  # other scan options
148
151
  if self.parsed.name is not None:
@@ -295,6 +298,12 @@ class BBOTArgs:
295
298
  )
296
299
 
297
300
  output = p.add_argument_group(title="Output")
301
+ output.add_argument(
302
+ "-o",
303
+ "--output-dir",
304
+ help="Directory to output scan results",
305
+ metavar="DIR",
306
+ )
298
307
  output.add_argument(
299
308
  "-om",
300
309
  "--output-modules",
@@ -304,12 +313,6 @@ class BBOTArgs:
304
313
  metavar="MODULE",
305
314
  )
306
315
  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
- )
313
316
  output.add_argument("--json", "-j", action="store_true", help="Output scan data in JSON format")
314
317
  output.add_argument("--brief", "-br", action="store_true", help="Output only the data itself")
315
318
  output.add_argument("--event-types", nargs="+", default=[], help="Choose which event types to display")
@@ -798,7 +798,7 @@ class Preset:
798
798
  # misc scan options
799
799
  if self.scan_name:
800
800
  preset_dict["scan_name"] = self.scan_name
801
- if self.scan_name:
801
+ if self.scan_name and self.output_dir is not None:
802
802
  preset_dict["output_dir"] = self.output_dir
803
803
 
804
804
  # conditions
bbot/scanner/scanner.py CHANGED
@@ -124,6 +124,7 @@ class Scanner:
124
124
  self.duration_seconds = None
125
125
 
126
126
  self._success = False
127
+ self._scan_finish_status_message = None
127
128
 
128
129
  if scan_id is not None:
129
130
  self.id = str(scan_id)
@@ -425,14 +426,19 @@ class Scanner:
425
426
 
426
427
  self._stop_log_handlers()
427
428
 
429
+ if self._scan_finish_status_message:
430
+ log_fn = self.hugesuccess
431
+ if self.status.startswith("ABORT"):
432
+ log_fn = self.hugewarning
433
+ elif not self._success:
434
+ log_fn = self.critical
435
+ log_fn(self._scan_finish_status_message)
436
+
428
437
  async def _mark_finished(self):
429
- log_fn = self.hugesuccess
430
438
  if self.status == "ABORTING":
431
439
  status = "ABORTED"
432
- log_fn = self.hugewarning
433
440
  elif not self._success:
434
441
  status = "FAILED"
435
- log_fn = self.critical
436
442
  else:
437
443
  status = "FINISHED"
438
444
 
@@ -441,9 +447,9 @@ class Scanner:
441
447
  self.duration_seconds = self.duration.total_seconds()
442
448
  self.duration_human = self.helpers.human_timedelta(self.duration)
443
449
 
444
- status_message = f"Scan {self.name} completed in {self.duration_human} with status {status}"
450
+ self._scan_finish_status_message = f"Scan {self.name} completed in {self.duration_human} with status {status}"
445
451
 
446
- scan_finish_event = self.finish_event(status_message, status)
452
+ scan_finish_event = self.finish_event(self._scan_finish_status_message, status)
447
453
 
448
454
  # queue final scan event with output modules
449
455
  output_modules = [m for m in self.modules.values() if m._type == "output" and m.name != "python"]
@@ -457,7 +463,6 @@ class Scanner:
457
463
  await asyncio.sleep(0.05)
458
464
 
459
465
  self.status = status
460
- log_fn(status_message)
461
466
  return scan_finish_event
462
467
 
463
468
  def _start_modules(self):
bbot/scanner/target.py CHANGED
@@ -101,7 +101,7 @@ class BaseTarget(RadixTarget):
101
101
  events.add(event)
102
102
 
103
103
  # sort by host size to ensure consistency
104
- events = sorted(events, key=lambda e: (0 if not e.host else host_size_key(e.host)))
104
+ events = sorted(events, key=lambda e: ((0, 0) if not e.host else host_size_key(e.host)))
105
105
  for event in events:
106
106
  self.events.add(event)
107
107
  self._add(event.host, data=event)
@@ -1,3 +1,5 @@
1
+ import yaml
2
+
1
3
  from ..bbot_fixtures import *
2
4
 
3
5
  from bbot import cli
@@ -143,6 +145,20 @@ async def test_cli_args(monkeypatch, caplog, capsys, clean_default_config):
143
145
  assert len(out.splitlines()) == 1
144
146
  assert out.count(".") > 1
145
147
 
148
+ # deps behavior
149
+ monkeypatch.setattr("sys.argv", ["bbot", "-n", "depstest", "--retry-deps", "--current-preset"])
150
+ result = await cli._main()
151
+ assert result is None
152
+ out, err = capsys.readouterr()
153
+ print(out)
154
+ # parse YAML output
155
+ preset = yaml.safe_load(out)
156
+ assert preset == {
157
+ "description": "depstest",
158
+ "scan_name": "depstest",
159
+ "config": {"deps": {"behavior": "retry_failed"}},
160
+ }
161
+
146
162
  # list modules
147
163
  monkeypatch.setattr("sys.argv", ["bbot", "--list-modules"])
148
164
  result = await cli._main()
@@ -401,7 +417,6 @@ async def test_cli_args(monkeypatch, caplog, capsys, clean_default_config):
401
417
  async def test_cli_customheaders(monkeypatch, caplog, capsys):
402
418
  monkeypatch.setattr(sys, "exit", lambda *args, **kwargs: True)
403
419
  monkeypatch.setattr(os, "_exit", lambda *args, **kwargs: True)
404
- import yaml
405
420
 
406
421
  # test custom headers
407
422
  monkeypatch.setattr(
@@ -2,7 +2,7 @@ from ..bbot_fixtures import * # noqa: F401
2
2
 
3
3
 
4
4
  @pytest.mark.asyncio
5
- async def test_target(bbot_scanner):
5
+ async def test_target_basic(bbot_scanner):
6
6
  from radixtarget import RadixTarget
7
7
  from ipaddress import ip_address, ip_network
8
8
  from bbot.scanner.target import BBOTTarget, ScanSeeds
@@ -245,6 +245,17 @@ async def test_target(bbot_scanner):
245
245
  assert len(events) == 3
246
246
  assert {e.type for e in events} == {"SCAN", "USERNAME"}
247
247
 
248
+ # users + orgs + domains
249
+ scan = bbot_scanner("USER:evilcorp", "ORG:evilcorp", "evilcorp.com")
250
+ await scan.helpers.dns._mock_dns(
251
+ {
252
+ "evilcorp.com": {"A": ["1.2.3.4"]},
253
+ },
254
+ )
255
+ events = [e async for e in scan.async_start()]
256
+ assert len(events) == 5
257
+ assert {e.type for e in events} == {"SCAN", "USERNAME", "ORG_STUB", "DNS_NAME"}
258
+
248
259
  # verify hash values
249
260
  bbottarget = BBOTTarget(
250
261
  "1.2.3.0/24",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: bbot
3
- Version: 2.3.0.5467rc0
3
+ Version: 2.3.0.5477rc0
4
4
  Summary: OSINT automation for hackers.
5
5
  Home-page: https://github.com/blacklanternsecurity/bbot
6
6
  License: GPL-3.0
@@ -1,5 +1,5 @@
1
- bbot/__init__.py,sha256=o-HxRaR7bKz8Xphwgy9o1DxUfSQwwBitR7Gh9ipUc0Y,130
2
- bbot/cli.py,sha256=Qlgqabm8N6r6uO1RuwGaM7-VXDSP_NH-YUnDUTsDYPM,10877
1
+ bbot/__init__.py,sha256=MTz_psImn_Z-_kIMAfSOSiuE3o5a9IaHFnvrbZSsP38,130
2
+ bbot/cli.py,sha256=SUEd4CcI-9QzFnqXpezza1sq_TNPcfDtJaSwL4MAl9g,10717
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
@@ -144,7 +144,7 @@ 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=mdIdu17otSuElA-_1OwnB3DV31lL0WcMrti38vqGsrY,1944
147
+ bbot/modules/output/mysql.py,sha256=IbH_1f7Dgtx5bCfX3yN61jzDAi9tuHjZsBaf5Eco8Wo,1975
148
148
  bbot/modules/output/neo4j.py,sha256=u950eUwu8YMql_WaBA38TN2bUhx7xnZdIIvYfR3xVcY,6114
149
149
  bbot/modules/output/nmap_xml.py,sha256=RZx3LFNi_OWxd0lJXY6Nk-_sSQBRidRnoWKyZEaUXrQ,7048
150
150
  bbot/modules/output/postgres.py,sha256=vsz3Gl9SKoWKhDidMFczksJzTeM0TZ7G9qY2rIYETF0,1938
@@ -221,14 +221,14 @@ bbot/scanner/__init__.py,sha256=gCyAAbkNm8_KozNpDENCKqO3E3ZCgseplnz40AtiJ1U,56
221
221
  bbot/scanner/dispatcher.py,sha256=_hsIegfUDrt8CUdXqgRvp1J0UwwzqVSDxjQmiviO41c,793
222
222
  bbot/scanner/manager.py,sha256=_5FBfxOmSMUeGp_-ryyGGl0pxb_eu-NSWft-lH1Pyog,10466
223
223
  bbot/scanner/preset/__init__.py,sha256=Jf2hWsHlTFtWNXL6gXD8_ZbKPFUM564ppdSxHFYnIJU,27
224
- bbot/scanner/preset/args.py,sha256=pMJ0PfQDbLwOnggaKJl_CHz1SpQpqhhQQPvVWQaoIKA,16269
224
+ bbot/scanner/preset/args.py,sha256=K8ivx2HIJ3sgYy-dGq9LKxx_vxFT5koJodlWKkBghAY,16331
225
225
  bbot/scanner/preset/conditions.py,sha256=hFL9cSIWGEsv2TfM5UGurf0c91cyaM8egb5IngBmIjA,1569
226
226
  bbot/scanner/preset/environ.py,sha256=9KbEOLWkUdoAf5Ez_2A1NNm6QduQElbnNnrPi6VDhZs,4731
227
227
  bbot/scanner/preset/path.py,sha256=Q29MO8cOEn690yW6bB08P72kbZ3C-H_TOEoXuwWnFM8,2274
228
- bbot/scanner/preset/preset.py,sha256=R8-RNEstx4kLMZcfz878qzmTpEH45kgg3itRK-FWw5I,40038
229
- bbot/scanner/scanner.py,sha256=GTTimZPPjX7vFIAgmMpPcxnn4ZijHE3yjMEfTORKy88,53853
228
+ bbot/scanner/preset/preset.py,sha256=u4GpuydOZov1tEZpshQAB-LL8bZLJ3nyu-NmkBEBvEY,40070
229
+ bbot/scanner/scanner.py,sha256=9Lpl7N7lAurMB1gWknbxv3Ph28QQWoZlGmcwTQarHJY,54129
230
230
  bbot/scanner/stats.py,sha256=re93sArKXZSiD0Owgqk2J3Kdvfm3RL4Y9Qy_VOcaVk8,3623
231
- bbot/scanner/target.py,sha256=kYB2ItVzZDPaz1tj3iOe0LTkpntK7S8mfJ4qEJSOiSQ,11551
231
+ bbot/scanner/target.py,sha256=svWRL8CtmAhZ0gNjvslMp_GHtTUx9aysyiNENzPNwPQ,11556
232
232
  bbot/scripts/docs.py,sha256=ZLY9-O6OeEElzOUvTglO5EMkRv1s4aEuxJb2CthCVsI,10782
233
233
  bbot/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
234
234
  bbot/test/bbot_fixtures.py,sha256=PNIycAMcNWM8oZ6BvvQmSbif1sztdOgyQ_e9lfQA6gA,9981
@@ -243,7 +243,7 @@ bbot/test/test_step_1/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
243
243
  bbot/test/test_step_1/test__module__tests.py,sha256=uwuROxdXI52D-V9z3Q9VNslvBfaduj6MQS5tQ_UOqXA,1460
244
244
  bbot/test/test_step_1/test_bbot_fastapi.py,sha256=FNGvlax4lFZVd0T3HvV9SJh1lsngOX58GrUnJVzoy20,2531
245
245
  bbot/test/test_step_1/test_bloom_filter.py,sha256=GodseGF98sarWXZ5C3JCVWblnycS4BA75HEAzhx4xXg,2139
246
- bbot/test/test_step_1/test_cli.py,sha256=osCnJFA5S7NpGeAukVFTx3EkmLZPX6vITectU062Rsg,26299
246
+ bbot/test/test_step_1/test_cli.py,sha256=0OWNnfToVXN7tHzD00uOekjwNl5UjQAJxMQthW0JNJ0,26736
247
247
  bbot/test/test_step_1/test_command.py,sha256=5IeGV6TKB0xtFEsfsU_0mNrOmEdIQiQ3FHkUmsBNoOI,6485
248
248
  bbot/test/test_step_1/test_config.py,sha256=Q38hygpke2GDcv8OguVZuiSOnfDJxEMrRy20dN5Qsn0,887
249
249
  bbot/test/test_step_1/test_depsinstaller.py,sha256=zr9f-wJDotD1ZvKXGEuDRWzFYMAYBI6209mI_PWPtTQ,703
@@ -261,7 +261,7 @@ bbot/test/test_step_1/test_python_api.py,sha256=GM5Kp2AAFl92ozo1kL6axsM87F8Gdq2_
261
261
  bbot/test/test_step_1/test_regexes.py,sha256=34-BHzDE5qdltE-sQIzkrTmJTL49QUYoTn2uT1DZLwI,14356
262
262
  bbot/test/test_step_1/test_scan.py,sha256=h3JP5RXnOUH8dqqq2Q_7yLpx1LCAEvqfE1bpHL7bDS0,5756
263
263
  bbot/test/test_step_1/test_scope.py,sha256=S2nssENKJKCvgXUMyU8MFQmXHeUIz0C_sbWGkdYti2A,3063
264
- bbot/test/test_step_1/test_target.py,sha256=O-r7WxLdO6C3FmhjhA9rfRWb3uX4xW0eEQX4qCMFG7Q,19127
264
+ bbot/test/test_step_1/test_target.py,sha256=CDfcCTuhh1Z-MdcSHC3lZ94ucDI2M-xacdv6-SchqxE,19512
265
265
  bbot/test/test_step_1/test_web.py,sha256=n9p9WhsEyN5I7S8RUUOEzF8v1CyeJjkmk4l6hnpOblY,18804
266
266
  bbot/test/test_step_2/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
267
267
  bbot/test/test_step_2/module_tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -416,8 +416,8 @@ bbot/wordlists/raft-small-extensions-lowercase_CLEANED.txt,sha256=ZSIVebs7ptMvHx
416
416
  bbot/wordlists/top_open_ports_nmap.txt,sha256=LmdFYkfapSxn1pVuQC2LkOIY2hMLgG-Xts7DVtYzweM,42727
417
417
  bbot/wordlists/valid_url_schemes.txt,sha256=0B_VAr9Dv7aYhwi6JSBDU-3M76vNtzN0qEC_RNLo7HE,3310
418
418
  bbot/wordlists/wordninja_dns.txt.gz,sha256=DYHvvfW0TvzrVwyprqODAk4tGOxv5ezNmCPSdPuDUnQ,570241
419
- bbot-2.3.0.5467rc0.dist-info/LICENSE,sha256=GzeCzK17hhQQDNow0_r0L8OfLpeTKQjFQwBQU7ZUymg,32473
420
- bbot-2.3.0.5467rc0.dist-info/METADATA,sha256=juUHmsiQQ5xi4za6EaWNTkTxP4IIspwsACBxEOT5cAw,17988
421
- bbot-2.3.0.5467rc0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
422
- bbot-2.3.0.5467rc0.dist-info/entry_points.txt,sha256=cWjvcU_lLrzzJgjcjF7yeGuRA_eDS8pQ-kmPUAyOBfo,38
423
- bbot-2.3.0.5467rc0.dist-info/RECORD,,
419
+ bbot-2.3.0.5477rc0.dist-info/LICENSE,sha256=GzeCzK17hhQQDNow0_r0L8OfLpeTKQjFQwBQU7ZUymg,32473
420
+ bbot-2.3.0.5477rc0.dist-info/METADATA,sha256=kch07qk0LxOo2OnzeqKbj8xNRQXVOBMtpANudcaJLq0,17988
421
+ bbot-2.3.0.5477rc0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
422
+ bbot-2.3.0.5477rc0.dist-info/entry_points.txt,sha256=cWjvcU_lLrzzJgjcjF7yeGuRA_eDS8pQ-kmPUAyOBfo,38
423
+ bbot-2.3.0.5477rc0.dist-info/RECORD,,