bbot 2.3.0.5364rc0__py3-none-any.whl → 2.3.0.5370rc0__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.5364rc"
2
+ __version__ = "v2.3.0.5370rc"
3
3
 
4
4
  from .scanner import Scanner, Preset
@@ -15,7 +15,7 @@ class nuclei(BaseModule):
15
15
  }
16
16
 
17
17
  options = {
18
- "version": "3.3.5",
18
+ "version": "3.3.6",
19
19
  "tags": "",
20
20
  "templates": "",
21
21
  "severity": "",
@@ -0,0 +1,144 @@
1
+ # dnstlsrpt.py
2
+ #
3
+ # Checks for and parses common TLS-RPT TXT records, e.g. _smtp._tls.target.domain
4
+ #
5
+ # TLS-RPT policies may contain email addresses or URL's for reporting destinations, typically the email addresses are software processed inboxes, but they may also be to individual humans or team inboxes.
6
+ #
7
+ # The domain portion of any email address or URL is also passively checked and added as appropriate, for additional inspection by other modules.
8
+ #
9
+ # Example records,
10
+ # _smtp._tls.example.com TXT "v=TLSRPTv1;rua=https://tlsrpt.azurewebsites.net/report"
11
+ # _smtp._tls.example.net TXT "v=TLSRPTv1; rua=mailto:sts-reports@example.net;"
12
+ #
13
+ # TODO: extract %{UNIQUE_ID}% from hosted services as ORG_STUB ?
14
+ # e.g. %{UNIQUE_ID}%@tlsrpt.hosted.service.provider is usually a tenant specific ID.
15
+ # e.g. tlsrpt@%{UNIQUE_ID}%.hosted.service.provider is usually a tenant specific ID.
16
+
17
+ from bbot.modules.base import BaseModule
18
+ from bbot.core.helpers.dns.helpers import service_record
19
+
20
+ import re
21
+
22
+ from bbot.core.helpers.regexes import email_regex, url_regexes
23
+
24
+ _tlsrpt_regex = r"^v=(?P<v>TLSRPTv[0-9]+); *(?P<kvps>.*)$"
25
+ tlsrpt_regex = re.compile(_tlsrpt_regex, re.I)
26
+
27
+ _tlsrpt_kvp_regex = r"(?P<k>\w+)=(?P<v>[^;]+);*"
28
+ tlsrpt_kvp_regex = re.compile(_tlsrpt_kvp_regex)
29
+
30
+ _csul = r"(?P<uri>[^, ]+)"
31
+ csul = re.compile(_csul)
32
+
33
+
34
+ class dnstlsrpt(BaseModule):
35
+ watched_events = ["DNS_NAME"]
36
+ produced_events = ["EMAIL_ADDRESS", "URL_UNVERIFIED", "RAW_DNS_RECORD"]
37
+ flags = ["subdomain-enum", "cloud-enum", "email-enum", "passive", "safe"]
38
+ meta = {
39
+ "description": "Check for TLS-RPT records",
40
+ "author": "@colin-stubbs",
41
+ "created_date": "2024-07-26",
42
+ }
43
+ options = {
44
+ "emit_emails": True,
45
+ "emit_raw_dns_records": False,
46
+ "emit_urls": True,
47
+ "emit_vulnerabilities": True,
48
+ }
49
+ options_desc = {
50
+ "emit_emails": "Emit EMAIL_ADDRESS events",
51
+ "emit_raw_dns_records": "Emit RAW_DNS_RECORD events",
52
+ "emit_urls": "Emit URL_UNVERIFIED events",
53
+ "emit_vulnerabilities": "Emit VULNERABILITY events",
54
+ }
55
+
56
+ async def setup(self):
57
+ self.emit_emails = self.config.get("emit_emails", True)
58
+ self.emit_raw_dns_records = self.config.get("emit_raw_dns_records", False)
59
+ self.emit_urls = self.config.get("emit_urls", True)
60
+ self.emit_vulnerabilities = self.config.get("emit_vulnerabilities", True)
61
+ return await super().setup()
62
+
63
+ def _incoming_dedup_hash(self, event):
64
+ # dedupe by parent
65
+ parent_domain = self.helpers.parent_domain(event.data)
66
+ return hash(parent_domain), "already processed parent domain"
67
+
68
+ async def filter_event(self, event):
69
+ if "_wildcard" in str(event.host).split("."):
70
+ return False, "event is wildcard"
71
+
72
+ # there's no value in inspecting service records
73
+ if service_record(event.host) == True:
74
+ return False, "service record detected"
75
+
76
+ return True
77
+
78
+ async def handle_event(self, event):
79
+ rdtype = "TXT"
80
+ tags = ["tlsrpt-record"]
81
+ hostname = f"_smtp._tls.{event.host}"
82
+
83
+ r = await self.helpers.resolve_raw(hostname, type=rdtype)
84
+
85
+ if r:
86
+ raw_results, errors = r
87
+ for answer in raw_results:
88
+ if self.emit_raw_dns_records:
89
+ await self.emit_event(
90
+ {"host": hostname, "type": rdtype, "answer": answer.to_text()},
91
+ "RAW_DNS_RECORD",
92
+ parent=event,
93
+ tags=tags.append(f"{rdtype.lower()}-record"),
94
+ context=f"{rdtype} lookup on {hostname} produced {{event.type}}",
95
+ )
96
+
97
+ # we need to fix TXT data that may have been split across two different rdata's
98
+ # e.g. we will get a single string, but within that string we may have two parts such as:
99
+ # answer = '"part 1 that was really long" "part 2 that did not fit in part 1"'
100
+ # NOTE: the leading and trailing double quotes are essential as part of a raw DNS TXT record, or another record type that contains a free form text string as a component.
101
+ s = answer.to_text().strip('"').replace('" "', "")
102
+
103
+ # validate TLSRPT record, tag appropriately
104
+ tlsrpt_match = tlsrpt_regex.search(s)
105
+
106
+ if (
107
+ tlsrpt_match
108
+ and tlsrpt_match.group("v")
109
+ and tlsrpt_match.group("kvps")
110
+ and tlsrpt_match.group("kvps") != ""
111
+ ):
112
+ for kvp_match in tlsrpt_kvp_regex.finditer(tlsrpt_match.group("kvps")):
113
+ key = kvp_match.group("k").lower()
114
+
115
+ if key == "rua":
116
+ for csul_match in csul.finditer(kvp_match.group("v")):
117
+ if csul_match.group("uri"):
118
+ for match in email_regex.finditer(csul_match.group("uri")):
119
+ start, end = match.span()
120
+ email = csul_match.group("uri")[start:end]
121
+
122
+ if self.emit_emails:
123
+ await self.emit_event(
124
+ email,
125
+ "EMAIL_ADDRESS",
126
+ tags=tags.append(f"tlsrpt-record-{key}"),
127
+ parent=event,
128
+ )
129
+
130
+ for url_regex in url_regexes:
131
+ for match in url_regex.finditer(csul_match.group("uri")):
132
+ start, end = match.span()
133
+ url = csul_match.group("uri")[start:end]
134
+
135
+ if self.emit_urls:
136
+ await self.emit_event(
137
+ url,
138
+ "URL_UNVERIFIED",
139
+ tags=tags.append(f"tlsrpt-record-{key}"),
140
+ parent=event,
141
+ )
142
+
143
+
144
+ # EOF
@@ -0,0 +1,64 @@
1
+ from .base import ModuleTestBase
2
+
3
+ raw_smtp_tls_txt = '"v=TLSRPTv1; rua=mailto:tlsrpt@sub.blacklanternsecurity.notreal,mailto:test@on.thirdparty.com, https://tlspost.example.com;"'
4
+
5
+
6
+ class TestDNSTLSRPT(ModuleTestBase):
7
+ targets = ["blacklanternsecurity.notreal"]
8
+ modules_overrides = ["dnstlsrpt", "speculate"]
9
+ config_overrides = {"modules": {"dnstlsrpt": {"emit_raw_dns_records": True}}, "scope": {"report_distance": 1}}
10
+
11
+ async def setup_after_prep(self, module_test):
12
+ await module_test.mock_dns(
13
+ {
14
+ "blacklanternsecurity.notreal": {
15
+ "A": ["127.0.0.11"],
16
+ },
17
+ "_tls.blacklanternsecurity.notreal": {
18
+ "A": ["127.0.0.22"],
19
+ },
20
+ "_smtp._tls.blacklanternsecurity.notreal": {
21
+ "A": ["127.0.0.33"],
22
+ "TXT": [raw_smtp_tls_txt],
23
+ },
24
+ "_tls._smtp._tls.blacklanternsecurity.notreal": {
25
+ "A": ["127.0.0.44"],
26
+ },
27
+ "_smtp._tls._smtp._tls.blacklanternsecurity.notreal": {
28
+ "TXT": [raw_smtp_tls_txt],
29
+ },
30
+ "sub.blacklanternsecurity.notreal": {
31
+ "A": ["127.0.0.55"],
32
+ },
33
+ }
34
+ )
35
+
36
+ def check(self, module_test, events):
37
+ assert any(
38
+ e.type == "RAW_DNS_RECORD" and e.data["answer"] == raw_smtp_tls_txt for e in events
39
+ ), "Failed to emit RAW_DNS_RECORD"
40
+ assert any(
41
+ e.type == "DNS_NAME" and e.data == "sub.blacklanternsecurity.notreal" for e in events
42
+ ), "Failed to detect sub-domain"
43
+ assert any(
44
+ e.type == "EMAIL_ADDRESS" and e.data == "tlsrpt@sub.blacklanternsecurity.notreal" for e in events
45
+ ), "Failed to detect email address"
46
+ assert any(
47
+ e.type == "EMAIL_ADDRESS" and e.data == "test@on.thirdparty.com" for e in events
48
+ ), "Failed to detect third party email address"
49
+ assert any(
50
+ e.type == "URL_UNVERIFIED" and e.data == "https://tlspost.example.com/" for e in events
51
+ ), "Failed to detect third party URL"
52
+
53
+
54
+ class TestDNSTLSRPTRecursiveRecursion(TestDNSTLSRPT):
55
+ config_overrides = {
56
+ "scope": {"report_distance": 1},
57
+ "modules": {"dnstlsrpt": {"emit_raw_dns_records": True}},
58
+ }
59
+
60
+ def check(self, module_test, events):
61
+ assert not any(
62
+ e.type == "RAW_DNS_RECORD" and e.data["host"] == "_mta-sts._mta-sts.blacklanternsecurity.notreal"
63
+ for e in events
64
+ ), "Unwanted recursion occurring"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: bbot
3
- Version: 2.3.0.5364rc0
3
+ Version: 2.3.0.5370rc0
4
4
  Summary: OSINT automation for hackers.
5
5
  Home-page: https://github.com/blacklanternsecurity/bbot
6
6
  License: GPL-3.0
@@ -1,4 +1,4 @@
1
- bbot/__init__.py,sha256=M7k_R43Aq4i4MJZlqrBLYyCYFZgSUh4EgEO6rIYhYyo,130
1
+ bbot/__init__.py,sha256=-4RgEPZs7AZwa-gBbOMU_EjzQ__Sc5_M3qkLxRutX8E,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
@@ -83,7 +83,7 @@ bbot/modules/credshed.py,sha256=HAF5wgRGKIIpdMAe4mIAtkZRLmFYjMFyXtjjst6RJ20,4203
83
83
  bbot/modules/crt.py,sha256=6Zm90VKXwYYN6Sab0gwwhTARrtnQIqALJTVtFWMMTGk,1369
84
84
  bbot/modules/deadly/dastardly.py,sha256=O3QKU9XxreKaYCeJ0KthafBhC8uWR6_dxFh8VSuRLCk,5315
85
85
  bbot/modules/deadly/ffuf.py,sha256=F6GHxxXg3OLerEEntUWO6QYM816ynx-b3f5TrOLAEmM,14254
86
- bbot/modules/deadly/nuclei.py,sha256=fH6oayOhPyd3z0edOvluef3K64FQ8JuQCcb_729u73M,17807
86
+ bbot/modules/deadly/nuclei.py,sha256=OWRodY25fuQFIzufweaucWcwpPNJJvTUlfr0mnfDq48,17807
87
87
  bbot/modules/deadly/vhost.py,sha256=lHKK5Gn9cOSeJT-8XvNnOAG97cB_zXJE1_j07KLKTqI,5462
88
88
  bbot/modules/dehashed.py,sha256=enDarOzlY84R4_ctp2fLVNLmjocaCh1j1x8nIKwEdHY,5064
89
89
  bbot/modules/digitorus.py,sha256=XQY0eAQrA7yo8S57tGncP1ARud-yG4LiWxx5VBYID34,1027
@@ -93,6 +93,7 @@ bbot/modules/dnsbrute_mutations.py,sha256=bOJidK_oKZe87u8e9t0mEFnyuBi93UiNsQvpZY
93
93
  bbot/modules/dnscaa.py,sha256=pyaLqHrdsVhqtd1JBZVjKKcuYT_ywUbFYkrnfXcGD5s,5014
94
94
  bbot/modules/dnscommonsrv.py,sha256=gEErfSur7Odkaif4CbXYx3OZ3FQrQESyiMGPbcDKSIg,1538
95
95
  bbot/modules/dnsdumpster.py,sha256=n-UP428_9kAmh_1gf55jeh-3uWyr1EZN0AYSnT3uOnU,3253
96
+ bbot/modules/dnstlsrpt.py,sha256=LW-8NTfUlYAlSlDrDBcELTe4LTrAI412J03xQfAL93Y,6427
96
97
  bbot/modules/docker_pull.py,sha256=Dp8de9UCCELcozwmZphA3lMh8qZaXyDo2kfwG45Wm3w,9069
97
98
  bbot/modules/dockerhub.py,sha256=ruvTP8Uz5LEuX-_SrKDzByvSNtd1ofZbX-lRTeKUB24,3491
98
99
  bbot/modules/dotnetnuke.py,sha256=XZysDA99ahQSLXR8RPROlmUwDxqrxvBFvscZMYBmsmc,10539
@@ -309,6 +310,7 @@ bbot/test/test_step_2/module_tests/test_module_dnscaa.py,sha256=5JaAYt-oFGON8Gc4
309
310
  bbot/test/test_step_2/module_tests/test_module_dnscommonsrv.py,sha256=rUGodidcI1vGMXadaaEKByXonjXiUYnl9bWOmuum6tU,8260
310
311
  bbot/test/test_step_2/module_tests/test_module_dnsdumpster.py,sha256=pgwOrfq_qNxbDBCAffspz6qlbd9MU5yZxguJizqHpFU,59749
311
312
  bbot/test/test_step_2/module_tests/test_module_dnsresolve.py,sha256=15LEcggP_eVYFQdMO1zHTvoGc6n8IaUjsQDmX0sZS4o,2077
313
+ bbot/test/test_step_2/module_tests/test_module_dnstlsrpt.py,sha256=tAXUcu66BrNOo4AWvJfHft8IWKJtL0pLhfWstpl5zUc,2640
312
314
  bbot/test/test_step_2/module_tests/test_module_docker_pull.py,sha256=-JSAo51dS3Ie9RaLBcWK0kfbg8bCPr7mohpFGAwOKPQ,27988
313
315
  bbot/test/test_step_2/module_tests/test_module_dockerhub.py,sha256=9T8CFcFP32MOppUmSVNBUSifnk2kMONqzW_7vvvKdpk,3907
314
316
  bbot/test/test_step_2/module_tests/test_module_dotnetnuke.py,sha256=UyVmrw22n7AfBoh_eEjDU_IBqyofXO2lV6GFFudaJTI,8116
@@ -412,8 +414,8 @@ bbot/wordlists/raft-small-extensions-lowercase_CLEANED.txt,sha256=ruUQwVfia1_m2u
412
414
  bbot/wordlists/top_open_ports_nmap.txt,sha256=LmdFYkfapSxn1pVuQC2LkOIY2hMLgG-Xts7DVtYzweM,42727
413
415
  bbot/wordlists/valid_url_schemes.txt,sha256=VciB-ww0y-O8Ii1wpTR6rJzGDiC2r-dhVsIJApS1ZYU,3309
414
416
  bbot/wordlists/wordninja_dns.txt.gz,sha256=DYHvvfW0TvzrVwyprqODAk4tGOxv5ezNmCPSdPuDUnQ,570241
415
- bbot-2.3.0.5364rc0.dist-info/LICENSE,sha256=GzeCzK17hhQQDNow0_r0L8OfLpeTKQjFQwBQU7ZUymg,32473
416
- bbot-2.3.0.5364rc0.dist-info/METADATA,sha256=2fTfVrrWm7qQev-Q0uIKaSz2fbq3FyaaWB6UajkaGCA,17893
417
- bbot-2.3.0.5364rc0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
418
- bbot-2.3.0.5364rc0.dist-info/entry_points.txt,sha256=cWjvcU_lLrzzJgjcjF7yeGuRA_eDS8pQ-kmPUAyOBfo,38
419
- bbot-2.3.0.5364rc0.dist-info/RECORD,,
417
+ bbot-2.3.0.5370rc0.dist-info/LICENSE,sha256=GzeCzK17hhQQDNow0_r0L8OfLpeTKQjFQwBQU7ZUymg,32473
418
+ bbot-2.3.0.5370rc0.dist-info/METADATA,sha256=t0uuV5Ozoe_aW7d-Ljic9Th548Kfy2Xc3_syClRYAhw,17893
419
+ bbot-2.3.0.5370rc0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
420
+ bbot-2.3.0.5370rc0.dist-info/entry_points.txt,sha256=cWjvcU_lLrzzJgjcjF7yeGuRA_eDS8pQ-kmPUAyOBfo,38
421
+ bbot-2.3.0.5370rc0.dist-info/RECORD,,