bbot 2.4.2.6611rc0__py3-none-any.whl → 2.4.2.6615rc0__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/modules/dehashed.py +44 -39
- bbot/test/test_step_2/module_tests/test_module_dehashed.py +95 -38
- {bbot-2.4.2.6611rc0.dist-info → bbot-2.4.2.6615rc0.dist-info}/METADATA +1 -1
- {bbot-2.4.2.6611rc0.dist-info → bbot-2.4.2.6615rc0.dist-info}/RECORD +8 -8
- {bbot-2.4.2.6611rc0.dist-info → bbot-2.4.2.6615rc0.dist-info}/WHEEL +1 -1
- {bbot-2.4.2.6611rc0.dist-info → bbot-2.4.2.6615rc0.dist-info}/LICENSE +0 -0
- {bbot-2.4.2.6611rc0.dist-info → bbot-2.4.2.6615rc0.dist-info}/entry_points.txt +0 -0
bbot/__init__.py
CHANGED
bbot/modules/dehashed.py
CHANGED
|
@@ -13,23 +13,23 @@ class dehashed(subdomain_enum):
|
|
|
13
13
|
"author": "@SpamFaux",
|
|
14
14
|
"auth_required": True,
|
|
15
15
|
}
|
|
16
|
-
options = {"
|
|
17
|
-
options_desc = {"
|
|
16
|
+
options = {"api_key": ""}
|
|
17
|
+
options_desc = {"api_key": "DeHashed API Key"}
|
|
18
18
|
target_only = True
|
|
19
19
|
|
|
20
|
-
base_url = "https://api.dehashed.com/search"
|
|
20
|
+
base_url = "https://api.dehashed.com/v2/search"
|
|
21
21
|
|
|
22
22
|
async def setup(self):
|
|
23
|
-
self.username = self.config.get("username", "")
|
|
24
23
|
self.api_key = self.config.get("api_key", "")
|
|
25
|
-
self.auth = (self.username, self.api_key)
|
|
26
24
|
self.headers = {
|
|
27
25
|
"Accept": "application/json",
|
|
26
|
+
"Content-Type": "application/json",
|
|
27
|
+
"Dehashed-Api-Key": self.api_key,
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
# soft-fail if we don't have the necessary information to make queries
|
|
31
|
-
if not
|
|
32
|
-
return None, "No
|
|
31
|
+
if not self.api_key:
|
|
32
|
+
return None, "No API key set"
|
|
33
33
|
|
|
34
34
|
return await super().setup()
|
|
35
35
|
|
|
@@ -38,29 +38,31 @@ class dehashed(subdomain_enum):
|
|
|
38
38
|
async for entries in self.query(query):
|
|
39
39
|
for entry in entries:
|
|
40
40
|
# we have to clean up the email field because dehashed does a poor job of it
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
41
|
+
emails = []
|
|
42
|
+
for email in entry.get("email", []):
|
|
43
|
+
email_str = email.replace("\\", "")
|
|
44
|
+
found_emails = list(await self.helpers.re.extract_emails(email_str))
|
|
45
|
+
if not found_emails:
|
|
46
|
+
self.debug(f"Invalid email from dehashed.com: {email_str}")
|
|
47
|
+
continue
|
|
48
|
+
emails += found_emails
|
|
47
49
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
users = entry.get("username", [])
|
|
51
|
+
pws = entry.get("password", [])
|
|
52
|
+
h_pws = entry.get("hashed_password", [])
|
|
51
53
|
db_name = entry.get("database_name", "")
|
|
52
54
|
|
|
53
55
|
tags = []
|
|
54
56
|
if db_name:
|
|
55
57
|
tags = [f"db-{db_name}"]
|
|
56
|
-
|
|
58
|
+
for email in emails:
|
|
57
59
|
email_event = self.make_event(email, "EMAIL_ADDRESS", parent=event, tags=tags)
|
|
58
60
|
if email_event is not None:
|
|
59
61
|
await self.emit_event(
|
|
60
62
|
email_event,
|
|
61
63
|
context=f'{{module}} searched API for "{query}" and found {{event.type}}: {{event.data}}',
|
|
62
64
|
)
|
|
63
|
-
|
|
65
|
+
for user in users:
|
|
64
66
|
await self.emit_event(
|
|
65
67
|
f"{email}:{user}",
|
|
66
68
|
"USERNAME",
|
|
@@ -68,7 +70,7 @@ class dehashed(subdomain_enum):
|
|
|
68
70
|
tags=tags,
|
|
69
71
|
context=f"{{module}} found {email} with {{event.type}}: {{event.data}}",
|
|
70
72
|
)
|
|
71
|
-
|
|
73
|
+
for pw in pws:
|
|
72
74
|
await self.emit_event(
|
|
73
75
|
f"{email}:{pw}",
|
|
74
76
|
"PASSWORD",
|
|
@@ -76,7 +78,7 @@ class dehashed(subdomain_enum):
|
|
|
76
78
|
tags=tags,
|
|
77
79
|
context=f"{{module}} found {email} with {{event.type}}: {{event.data}}",
|
|
78
80
|
)
|
|
79
|
-
|
|
81
|
+
for h_pw in h_pws:
|
|
80
82
|
await self.emit_event(
|
|
81
83
|
f"{email}:{h_pw}",
|
|
82
84
|
"HASHED_PASSWORD",
|
|
@@ -86,30 +88,33 @@ class dehashed(subdomain_enum):
|
|
|
86
88
|
)
|
|
87
89
|
|
|
88
90
|
async def query(self, domain):
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
91
|
+
url = self.base_url
|
|
92
|
+
json = {
|
|
93
|
+
"query": "",
|
|
94
|
+
"page": 1,
|
|
95
|
+
"size": 10000, # The maximum permitted size and pagination.
|
|
96
|
+
}
|
|
97
|
+
json["query"] = f"domain:{domain}"
|
|
98
|
+
json["page"] = 1
|
|
99
|
+
max_pages = 1
|
|
100
|
+
agen = self.api_page_iter(url=url, headers=self.headers, _json=False, method="POST", json=json)
|
|
94
101
|
async for result in agen:
|
|
95
102
|
result_json = {}
|
|
96
103
|
with suppress(Exception):
|
|
97
104
|
result_json = result.json()
|
|
98
105
|
total = result_json.get("total", 0)
|
|
99
106
|
entries = result_json.get("entries", [])
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
)
|
|
107
|
+
json["page"] += 1
|
|
108
|
+
if result is not None and result.status_code != 200:
|
|
109
|
+
self.warning(
|
|
110
|
+
f"Error retrieving results from dehashed.com (status code {result.status_code}): {result.text}"
|
|
111
|
+
)
|
|
112
|
+
elif (json["page"] > max_pages) and (total > (json["size"] * max_pages)):
|
|
113
|
+
self.info(
|
|
114
|
+
f"{domain} has {total:,} results in Dehashed. The API can only process the first 10,000 results. Please check dehashed.com to get the remaining results."
|
|
115
|
+
)
|
|
116
|
+
if entries:
|
|
117
|
+
yield entries
|
|
118
|
+
if not entries or json["page"] > max_pages:
|
|
113
119
|
await agen.aclose()
|
|
114
120
|
break
|
|
115
|
-
yield entries
|
|
@@ -1,52 +1,44 @@
|
|
|
1
1
|
from .base import ModuleTestBase
|
|
2
2
|
|
|
3
|
-
dehashed_domain_response = {
|
|
4
|
-
"balance": 10000,
|
|
5
|
-
"entries": [
|
|
6
|
-
{
|
|
7
|
-
"id": "4363462346",
|
|
8
|
-
"email": "bob@blacklanternsecurity.com",
|
|
9
|
-
"ip_address": "",
|
|
10
|
-
"username": "bob@bob.com",
|
|
11
|
-
"password": "",
|
|
12
|
-
"hashed_password": "$2a$12$pVmwJ7pXEr3mE.DmCCE4fOUDdeadbeefd2KuCy/tq1ZUFyEOH2bve",
|
|
13
|
-
"name": "Bob Smith",
|
|
14
|
-
"vin": "",
|
|
15
|
-
"address": "",
|
|
16
|
-
"phone": "+91283423839",
|
|
17
|
-
"database_name": "eatstreet",
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
"id": "234623453454",
|
|
21
|
-
"email": "tim@blacklanternsecurity.com",
|
|
22
|
-
"ip_address": "",
|
|
23
|
-
"username": "timmy",
|
|
24
|
-
"password": "TimTamSlam69",
|
|
25
|
-
"hashed_password": "",
|
|
26
|
-
"name": "Tim Tam",
|
|
27
|
-
"vin": "",
|
|
28
|
-
"address": "",
|
|
29
|
-
"phone": "+123455667",
|
|
30
|
-
"database_name": "eatstreet",
|
|
31
|
-
},
|
|
32
|
-
],
|
|
33
|
-
"success": True,
|
|
34
|
-
"took": "61µs",
|
|
35
|
-
"total": 2,
|
|
36
|
-
}
|
|
37
|
-
|
|
38
3
|
|
|
39
4
|
class TestDehashed(ModuleTestBase):
|
|
40
5
|
modules_overrides = ["dehashed", "speculate"]
|
|
41
6
|
config_overrides = {
|
|
42
7
|
"scope": {"report_distance": 2},
|
|
43
|
-
"modules": {"dehashed": {"
|
|
8
|
+
"modules": {"dehashed": {"api_key": "deadbeef"}},
|
|
44
9
|
}
|
|
45
10
|
|
|
46
11
|
async def setup_before_prep(self, module_test):
|
|
47
12
|
module_test.httpx_mock.add_response(
|
|
48
|
-
url="https://api.dehashed.com/search
|
|
49
|
-
|
|
13
|
+
url="https://api.dehashed.com/v2/search",
|
|
14
|
+
method="POST",
|
|
15
|
+
json={
|
|
16
|
+
"balance": 10000,
|
|
17
|
+
"entries": [
|
|
18
|
+
{
|
|
19
|
+
"id": "4363462346",
|
|
20
|
+
"email": ["bob@blacklanternsecurity.com"],
|
|
21
|
+
"ip_address": ["127.0.0.9"],
|
|
22
|
+
"username": ["bob@bob.com"],
|
|
23
|
+
"hashed_password": ["$2a$12$pVmwJ7pXEr3mE.DmCCE4fOUDdeadbeefd2KuCy/tq1ZUFyEOH2bve"],
|
|
24
|
+
"name": ["Bob Smith"],
|
|
25
|
+
"phone": ["+91283423839"],
|
|
26
|
+
"database_name": "eatstreet",
|
|
27
|
+
"raw_record": {"le_only": True, "unstructured": True},
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"id": "234623453454",
|
|
31
|
+
"email": ["tim@blacklanternsecurity.com"],
|
|
32
|
+
"username": ["timmy"],
|
|
33
|
+
"password": ["TimTamSlam69"],
|
|
34
|
+
"name": "Tim Tam",
|
|
35
|
+
"phone": ["+123455667"],
|
|
36
|
+
"database_name": "eatstreet",
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
"took": "61ms",
|
|
40
|
+
"total": 2,
|
|
41
|
+
},
|
|
50
42
|
)
|
|
51
43
|
await module_test.mock_dns(
|
|
52
44
|
{
|
|
@@ -100,3 +92,68 @@ class TestDehashed(ModuleTestBase):
|
|
|
100
92
|
[e for e in events if e.type == "PASSWORD" and e.data == "tim@blacklanternsecurity.com:TimTamSlam69"]
|
|
101
93
|
)
|
|
102
94
|
assert 1 == len([e for e in events if e.type == "USERNAME" and e.data == "tim@blacklanternsecurity.com:timmy"])
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class TestDehashedBadEmail(TestDehashed):
|
|
98
|
+
async def setup_before_prep(self, module_test):
|
|
99
|
+
module_test.httpx_mock.add_response(
|
|
100
|
+
url="https://api.dehashed.com/v2/search",
|
|
101
|
+
method="POST",
|
|
102
|
+
json={
|
|
103
|
+
"balance": 10000,
|
|
104
|
+
"entries": [
|
|
105
|
+
{
|
|
106
|
+
"id": "EZxg4Lz-INLUt6uRXZaV",
|
|
107
|
+
"email": ["foo.example.com"],
|
|
108
|
+
"database_name": "Collections",
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
"took": "41ms",
|
|
112
|
+
"total": 1,
|
|
113
|
+
},
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
def check(self, module_test, events):
|
|
117
|
+
debug_log_content = open(module_test.scan.home / "debug.log").read()
|
|
118
|
+
assert "Invalid email from dehashed.com: foo.example.com" in debug_log_content
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
class TestDehashedHTTPError(TestDehashed):
|
|
122
|
+
async def setup_before_prep(self, module_test):
|
|
123
|
+
module_test.httpx_mock.add_response(
|
|
124
|
+
url="https://api.dehashed.com/v2/search",
|
|
125
|
+
method="POST",
|
|
126
|
+
json={"error": "issue with request body"},
|
|
127
|
+
status_code=400,
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
def check(self, module_test, events):
|
|
131
|
+
scan_log_content = open(module_test.scan.home / "scan.log").read()
|
|
132
|
+
assert (
|
|
133
|
+
'Error retrieving results from dehashed.com (status code 400): {"error":"issue with request body"}'
|
|
134
|
+
in scan_log_content
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class TestDehashedTooManyResults(TestDehashed):
|
|
139
|
+
async def setup_before_prep(self, module_test):
|
|
140
|
+
module_test.httpx_mock.add_response(
|
|
141
|
+
url="https://api.dehashed.com/v2/search",
|
|
142
|
+
method="POST",
|
|
143
|
+
json={
|
|
144
|
+
"balance": 10000,
|
|
145
|
+
"entries": [
|
|
146
|
+
{
|
|
147
|
+
"id": "VXhNxj46SGsW4Lworh-G",
|
|
148
|
+
"email": ["bob@bob.com"],
|
|
149
|
+
"database_name": "Collections",
|
|
150
|
+
},
|
|
151
|
+
],
|
|
152
|
+
"took": "40ms",
|
|
153
|
+
"total": 10001,
|
|
154
|
+
},
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
def check(self, module_test, events):
|
|
158
|
+
scan_log_content = open(module_test.scan.home / "scan.log").read()
|
|
159
|
+
assert "has 10,001 results in Dehashed. The API can only process the first 10,000 results." in scan_log_content
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: bbot
|
|
3
|
-
Version: 2.4.2.
|
|
3
|
+
Version: 2.4.2.6615rc0
|
|
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=WtQlPfgPAVNvoBoKj72lcIDazIAJx93c82MqqeYuhNU,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
|
|
@@ -83,7 +83,7 @@ bbot/modules/code_repository.py,sha256=x70Z45VnNNMF8BPkHfGWZXsZXw_fStGB3y0-8jbP1
|
|
|
83
83
|
bbot/modules/credshed.py,sha256=HAF5wgRGKIIpdMAe4mIAtkZRLmFYjMFyXtjjst6RJ20,4203
|
|
84
84
|
bbot/modules/crt.py,sha256=6Zm90VKXwYYN6Sab0gwwhTARrtnQIqALJTVtFWMMTGk,1369
|
|
85
85
|
bbot/modules/crt_db.py,sha256=xaIm2457_xGJjnKss73l1HpPn7pLPHksVzejsimTfZA,2198
|
|
86
|
-
bbot/modules/dehashed.py,sha256=
|
|
86
|
+
bbot/modules/dehashed.py,sha256=0lzcqMEgwRmprwurZ2-8Y8aOO4KTueJgpY_vh0DWQwA,5155
|
|
87
87
|
bbot/modules/digitorus.py,sha256=XQY0eAQrA7yo8S57tGncP1ARud-yG4LiWxx5VBYID34,1027
|
|
88
88
|
bbot/modules/dnsbimi.py,sha256=A4cqhvhytmEEd-tY4CgFwMLbsVtMjkRY9238Aj8aVtU,6921
|
|
89
89
|
bbot/modules/dnsbrute.py,sha256=Y2bSbG2IcwIJID1FSQ6Qe9fdpWwG7GIO-wVQw7MdQFM,2439
|
|
@@ -329,7 +329,7 @@ bbot/test/test_step_2/module_tests/test_module_credshed.py,sha256=ipkCFL7YmZBLWW
|
|
|
329
329
|
bbot/test/test_step_2/module_tests/test_module_crt.py,sha256=V15tE1jcXdXJEzEEdAJvSMRWhKBFtxBBUJ_eewvV3U4,717
|
|
330
330
|
bbot/test/test_step_2/module_tests/test_module_crt_db.py,sha256=R0CvLnzhN5T7XNPVSDRYD9vSwYMTNED6w-EPGoWPVII,849
|
|
331
331
|
bbot/test/test_step_2/module_tests/test_module_csv.py,sha256=UJqMqdiPjx-UjJw10OoVMAj378wu5mWIq0v04TCljTM,579
|
|
332
|
-
bbot/test/test_step_2/module_tests/test_module_dehashed.py,sha256=
|
|
332
|
+
bbot/test/test_step_2/module_tests/test_module_dehashed.py,sha256=Oi2McmPf873xWWUahYNh-CquDfLFamATyODjAZL33vU,6009
|
|
333
333
|
bbot/test/test_step_2/module_tests/test_module_digitorus.py,sha256=1GwxQGny6TxHsV8Fx7cR-aaLU8ZZkcF065VM_XoG1Hs,1612
|
|
334
334
|
bbot/test/test_step_2/module_tests/test_module_discord.py,sha256=Z66fGb-kkdZTQfUh6WZiM35Ad-gDyvwxlA7mUUB2vnQ,1838
|
|
335
335
|
bbot/test/test_step_2/module_tests/test_module_dnsbimi.py,sha256=nAhNAuH2hS7r4KYzhuPMocae1ifoIRMESYio8L577lg,4393
|
|
@@ -448,8 +448,8 @@ bbot/wordlists/raft-small-extensions-lowercase_CLEANED.txt,sha256=ZSIVebs7ptMvHx
|
|
|
448
448
|
bbot/wordlists/top_open_ports_nmap.txt,sha256=LmdFYkfapSxn1pVuQC2LkOIY2hMLgG-Xts7DVtYzweM,42727
|
|
449
449
|
bbot/wordlists/valid_url_schemes.txt,sha256=0B_VAr9Dv7aYhwi6JSBDU-3M76vNtzN0qEC_RNLo7HE,3310
|
|
450
450
|
bbot/wordlists/wordninja_dns.txt.gz,sha256=DYHvvfW0TvzrVwyprqODAk4tGOxv5ezNmCPSdPuDUnQ,570241
|
|
451
|
-
bbot-2.4.2.
|
|
452
|
-
bbot-2.4.2.
|
|
453
|
-
bbot-2.4.2.
|
|
454
|
-
bbot-2.4.2.
|
|
455
|
-
bbot-2.4.2.
|
|
451
|
+
bbot-2.4.2.6615rc0.dist-info/LICENSE,sha256=GzeCzK17hhQQDNow0_r0L8OfLpeTKQjFQwBQU7ZUymg,32473
|
|
452
|
+
bbot-2.4.2.6615rc0.dist-info/METADATA,sha256=zMFFr-b2zwl7kcxtDOUqz8TPuk0-KGGywvBGXnFJL90,18308
|
|
453
|
+
bbot-2.4.2.6615rc0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
454
|
+
bbot-2.4.2.6615rc0.dist-info/entry_points.txt,sha256=cWjvcU_lLrzzJgjcjF7yeGuRA_eDS8pQ-kmPUAyOBfo,38
|
|
455
|
+
bbot-2.4.2.6615rc0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|