Skip to content

Commit 277a82f

Browse files
committed
Lint fix
1 parent 85a7b66 commit 277a82f

File tree

9 files changed

+226
-126
lines changed

9 files changed

+226
-126
lines changed

sharehound/__main__.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -303,8 +303,12 @@ def parseArgs():
303303
)
304304
):
305305
parser.print_help()
306-
print("\n[!] No targets specified. Either provide targets with -tt/--target or -tf/--targets-file,")
307-
print(" or provide AD credentials (-ai, -au, -ap/-ah) to scan all computers from Active Directory.")
306+
print(
307+
"\n[!] No targets specified. Either provide targets with -tt/--target or -tf/--targets-file,"
308+
)
309+
print(
310+
" or provide AD credentials (-ai, -au, -ap/-ah) to scan all computers from Active Directory."
311+
)
308312
sys.exit(0)
309313

310314
if (args.auth_password is not None) and (args.auth_hashes is not None):
@@ -358,6 +362,7 @@ def main():
358362
logger.error("Failed to load targets: %s" % str(err))
359363
if options.debug:
360364
import traceback
365+
361366
traceback.print_exc()
362367
sys.exit(1)
363368
logger.info("Targeting %d hosts" % len(targets))

sharehound/collector/collect_contents_at_depth.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
import ntpath
88
import os
9-
from threading import Lock, Event
9+
from threading import Event, Lock
1010
from typing import Optional
1111

1212
from bhopengraph.Node import Node

sharehound/collector/collect_contents_in_share.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# Author : Remi Gascou (@podalirius_)
55
# Date created : 12 Aug 2025
66

7-
from threading import Lock, Event
7+
from threading import Event, Lock
88
from typing import Optional
99

1010
from shareql.evaluate.evaluator import RulesEvaluator

sharehound/collector/collect_share_rights.py

Lines changed: 58 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -120,21 +120,31 @@ def collect_share_rights(
120120
used_fallback = False
121121

122122
try:
123-
logger.debug(f"[collect_share_rights] Retrieving security descriptor for share: {share_name}")
123+
logger.debug(
124+
f"[collect_share_rights] Retrieving security descriptor for share: {share_name}"
125+
)
124126
sd = smb_session.get_share_security_descriptor(share_name)
125127

126128
if sd is None or len(sd) == 0:
127129
# Try fallback: get the root folder's security descriptor
128-
logger.debug(f"[collect_share_rights] Share-level security descriptor unavailable for '{share_name}', trying root folder fallback...")
130+
logger.debug(
131+
f"[collect_share_rights] Share-level security descriptor unavailable for '{share_name}', trying root folder fallback..."
132+
)
129133
sd = smb_session.get_share_root_security_descriptor(share_name)
130134
if sd is not None and len(sd) > 0:
131135
used_fallback = True
132-
logger.debug(f"[collect_share_rights] Using root folder NTFS permissions as fallback for share: {share_name}")
136+
logger.debug(
137+
f"[collect_share_rights] Using root folder NTFS permissions as fallback for share: {share_name}"
138+
)
133139
else:
134-
logger.warning(f"[collect_share_rights] Could not retrieve security descriptor for share: {share_name} (both share-level and root folder fallback failed). No share rights edges will be created. This may be due to insufficient privileges or the remote registry service being disabled.")
140+
logger.warning(
141+
f"[collect_share_rights] Could not retrieve security descriptor for share: {share_name} (both share-level and root folder fallback failed). No share rights edges will be created. This may be due to insufficient privileges or the remote registry service being disabled."
142+
)
135143
return share_rights
136144

137-
logger.debug(f"[collect_share_rights] Security descriptor retrieved ({len(sd)} bytes) for share: {share_name}{' (via root folder fallback)' if used_fallback else ''}")
145+
logger.debug(
146+
f"[collect_share_rights] Security descriptor retrieved ({len(sd)} bytes) for share: {share_name}{' (via root folder fallback)' if used_fallback else ''}"
147+
)
138148

139149
# Parse the security descriptor
140150
security_descriptor = ldaptypes.SR_SECURITY_DESCRIPTOR()
@@ -147,20 +157,28 @@ def collect_share_rights(
147157

148158
dacl_data = security_descriptor["Dacl"]["Data"]
149159
if dacl_data is None or len(dacl_data) == 0:
150-
logger.debug(f"[collect_share_rights] DACL is empty (no ACEs) for share: {share_name}")
160+
logger.debug(
161+
f"[collect_share_rights] DACL is empty (no ACEs) for share: {share_name}"
162+
)
151163
return share_rights
152164

153-
logger.debug(f"[collect_share_rights] DACL contains {len(dacl_data)} ACE(s) for share: {share_name}")
165+
logger.debug(
166+
f"[collect_share_rights] DACL contains {len(dacl_data)} ACE(s) for share: {share_name}"
167+
)
154168

155169
# Process each ACE in the DACL
156170
for ace_index, ace in enumerate(dacl_data):
157171
# Check if ACE has a valid SID
158172
if "Ace" not in ace.fields or "Sid" not in ace["Ace"].fields:
159-
logger.debug(f"[collect_share_rights] ACE #{ace_index}: Invalid ACE structure, skipping")
173+
logger.debug(
174+
f"[collect_share_rights] ACE #{ace_index}: Invalid ACE structure, skipping"
175+
)
160176
continue
161177

162178
if len(ace["Ace"]["Sid"]) == 0:
163-
logger.debug(f"[collect_share_rights] ACE #{ace_index}: Empty SID, skipping")
179+
logger.debug(
180+
f"[collect_share_rights] ACE #{ace_index}: Empty SID, skipping"
181+
)
164182
continue
165183

166184
aceType = ace["AceType"]
@@ -170,26 +188,38 @@ def collect_share_rights(
170188
sid = aceSid.formatCanonical()
171189

172190
# Log ACE type
173-
ace_type_name = "ACCESS_ALLOWED" if aceType == ACCESS_ALLOWED_ACE_TYPE else \
174-
"ACCESS_DENIED" if aceType == ACCESS_DENIED_ACE_TYPE else \
175-
f"UNKNOWN({aceType})"
176-
logger.debug(f"[collect_share_rights] ACE #{ace_index}: Type={ace_type_name}, SID={sid}, Mask=0x{maskValue:08X}")
191+
ace_type_name = (
192+
"ACCESS_ALLOWED"
193+
if aceType == ACCESS_ALLOWED_ACE_TYPE
194+
else (
195+
"ACCESS_DENIED"
196+
if aceType == ACCESS_DENIED_ACE_TYPE
197+
else f"UNKNOWN({aceType})"
198+
)
199+
)
200+
logger.debug(
201+
f"[collect_share_rights] ACE #{ace_index}: Type={ace_type_name}, SID={sid}, Mask=0x{maskValue:08X}"
202+
)
177203

178204
# Only process ACCESS_ALLOWED ACEs
179205
if aceType != ACCESS_ALLOWED_ACE_TYPE:
180-
logger.debug(f"[collect_share_rights] ACE #{ace_index}: Skipping non-ACCESS_ALLOWED ACE (type={aceType})")
206+
logger.debug(
207+
f"[collect_share_rights] ACE #{ace_index}: Skipping non-ACCESS_ALLOWED ACE (type={aceType})"
208+
)
181209
continue
182210

183211
# Check for specific rights and create edges
184-
access_flags = [
185-
flag for flag in AccessMaskFlags if flag.value & maskValue
186-
]
212+
access_flags = [flag for flag in AccessMaskFlags if flag.value & maskValue]
187213

188214
if len(access_flags) == 0:
189-
logger.debug(f"[collect_share_rights] ACE #{ace_index}: No matching access flags for mask 0x{maskValue:08X}")
215+
logger.debug(
216+
f"[collect_share_rights] ACE #{ace_index}: No matching access flags for mask 0x{maskValue:08X}"
217+
)
190218
continue
191219

192-
logger.debug(f"[collect_share_rights] ACE #{ace_index}: Matched flags: {[flag.name for flag in access_flags]}")
220+
logger.debug(
221+
f"[collect_share_rights] ACE #{ace_index}: Matched flags: {[flag.name for flag in access_flags]}"
222+
)
193223

194224
# Map access flags to edge kinds
195225
edges_added = []
@@ -201,14 +231,20 @@ def collect_share_rights(
201231
edges_added.append(edgeName)
202232

203233
if edges_added:
204-
logger.debug(f"[collect_share_rights] ACE #{ace_index}: Created {len(edges_added)} edge(s) for SID {sid}: {edges_added}")
234+
logger.debug(
235+
f"[collect_share_rights] ACE #{ace_index}: Created {len(edges_added)} edge(s) for SID {sid}: {edges_added}"
236+
)
205237

206238
# Summary
207239
total_edges = sum(len(edges) for edges in share_rights.values())
208-
logger.debug(f"[collect_share_rights] Summary for share '{share_name}': {len(share_rights)} SID(s), {total_edges} total edge(s)")
240+
logger.debug(
241+
f"[collect_share_rights] Summary for share '{share_name}': {len(share_rights)} SID(s), {total_edges} total edge(s)"
242+
)
209243

210244
except Exception as err:
211-
logger.debug(f"[collect_share_rights] Error processing share rights for {share_name}: {err}")
245+
logger.debug(
246+
f"[collect_share_rights] Error processing share rights for {share_name}: {err}"
247+
)
212248
raise err
213249

214250
return share_rights

sharehound/collector/collect_shares.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,13 @@ def collect_shares(
109109
logger.debug(f"[collect_shares] can_process({share_name}) = {can_process}")
110110
if can_process:
111111
ogc.add_path_to_graph()
112-
logger.debug(f"[collect_shares] Total edges created so far for share '{share_name}': {ogc.get_total_edges_created()}")
112+
logger.debug(
113+
f"[collect_shares] Total edges created so far for share '{share_name}': {ogc.get_total_edges_created()}"
114+
)
113115
else:
114-
logger.debug(f"[collect_shares] Skipping add_path_to_graph for share '{share_name}' because can_process returned False")
116+
logger.debug(
117+
f"[collect_shares] Skipping add_path_to_graph for share '{share_name}' because can_process returned False"
118+
)
115119

116120
# Collect contents of the share
117121
(

sharehound/collector/opengraph_context.py

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ class OpenGraphContext:
5555
logger: Optional[Union[Logger, TaskLogger]]
5656
total_edges_created: int
5757

58-
def __init__(self, graph: OpenGraph, logger: Optional[Union[Logger, TaskLogger]] = None):
58+
def __init__(
59+
self, graph: OpenGraph, logger: Optional[Union[Logger, TaskLogger]] = None
60+
):
5961
self.graph = graph
6062
self.host = (None, {})
6163
self.share = (None, {})
@@ -80,7 +82,7 @@ def add_path_to_graph(self) -> None:
8082
self.logger.debug("[add_path_to_graph] Host is None, skipping")
8183
return None
8284
self.graph.add_node_without_validation(self.host)
83-
85+
8486
# Add edge [HostsNetworkShare] from BloodHound Computer to NetworkShareHost
8587
# This links the ShareHound graph to existing BloodHound Computer nodes
8688
# by matching the Computer's name property (uppercase) to the NetworkShareHost's id
@@ -95,19 +97,27 @@ def add_path_to_graph(self) -> None:
9597
)
9698
self.total_edges_created += 1
9799
if self.logger:
98-
self.logger.debug(f"[add_path_to_graph] Created edge HostsNetworkShare: Computer(name={self.host.id.upper()}) -> NetworkShareHost(id={self.host.id})")
100+
self.logger.debug(
101+
f"[add_path_to_graph] Created edge HostsNetworkShare: Computer(name={self.host.id.upper()}) -> NetworkShareHost(id={self.host.id})"
102+
)
99103

100104
share_node, share_rights = self.share
101105
if share_node is None:
102106
if self.logger:
103107
self.logger.debug("[add_path_to_graph] Share node is None, skipping")
104108
return None
105109
self.graph.add_node_without_validation(share_node)
106-
110+
107111
if self.logger:
108-
rights_count = sum(len(edges) for edges in share_rights.values()) if share_rights else 0
109-
self.logger.debug(f"[add_path_to_graph] Adding share '{share_node.id}' with {len(share_rights)} SID(s) and {rights_count} rights edge(s)")
110-
112+
rights_count = (
113+
sum(len(edges) for edges in share_rights.values())
114+
if share_rights
115+
else 0
116+
)
117+
self.logger.debug(
118+
f"[add_path_to_graph] Adding share '{share_node.id}' with {len(share_rights)} SID(s) and {rights_count} rights edge(s)"
119+
)
120+
111121
self.add_rights_to_graph(share_node.id, share_rights, "share")
112122

113123
# Add edge [HasNetworkShare] from host to share
@@ -120,7 +130,9 @@ def add_path_to_graph(self) -> None:
120130
)
121131
self.total_edges_created += 1
122132
if self.logger:
123-
self.logger.debug(f"[add_path_to_graph] Created edge HasNetworkShare: {self.host.id} -> {share_node.id}")
133+
self.logger.debug(
134+
f"[add_path_to_graph] Created edge HasNetworkShare: {self.host.id} -> {share_node.id}"
135+
)
124136

125137
# At this point we have created
126138
# (Host) --[HasNetworkShare]--> ((NetworkShareSMB|NetworkShareDFS))
@@ -140,7 +152,9 @@ def add_path_to_graph(self) -> None:
140152
)
141153
self.total_edges_created += 1
142154
if self.logger:
143-
self.logger.debug(f"[add_path_to_graph] Created edge Contains: {parent_id} -> {directory_node.id}")
155+
self.logger.debug(
156+
f"[add_path_to_graph] Created edge Contains: {parent_id} -> {directory_node.id}"
157+
)
144158
parent_id = directory_node.id
145159

146160
# At this point we have created
@@ -163,12 +177,16 @@ def add_path_to_graph(self) -> None:
163177
)
164178
self.total_edges_created += 1
165179
if self.logger:
166-
self.logger.debug(f"[add_path_to_graph] Created edge Contains: {parent_id} -> {element_node.id}")
180+
self.logger.debug(
181+
f"[add_path_to_graph] Created edge Contains: {parent_id} -> {element_node.id}"
182+
)
167183

168184
# At this point we have created
169185
# (Host) --[Expose]--> ((NetworkShareSMB|NetworkShareDFS)) --[Contains]--> ((File)|(Directory))* --[Contains]--> ((File)|(Directory))
170186

171-
def add_rights_to_graph(self, element_id: str, rights: dict, element_type: str = "element") -> None:
187+
def add_rights_to_graph(
188+
self, element_id: str, rights: dict, element_type: str = "element"
189+
) -> None:
172190
"""
173191
Add rights to the graph
174192
@@ -183,12 +201,16 @@ def add_rights_to_graph(self, element_id: str, rights: dict, element_type: str =
183201

184202
if rights is None:
185203
if self.logger:
186-
self.logger.warning(f"[add_rights_to_graph] Rights is None for {element_type}: {element_id}")
204+
self.logger.warning(
205+
f"[add_rights_to_graph] Rights is None for {element_type}: {element_id}"
206+
)
187207
return
188208

189209
if len(rights) == 0:
190210
if self.logger:
191-
self.logger.debug(f"[add_rights_to_graph] No rights to add for {element_type}: {element_id}")
211+
self.logger.debug(
212+
f"[add_rights_to_graph] No rights to add for {element_type}: {element_id}"
213+
)
192214
return
193215

194216
edges_created_for_element = 0
@@ -206,10 +228,14 @@ def add_rights_to_graph(self, element_id: str, rights: dict, element_type: str =
206228
self.total_edges_created += 1
207229
edges_created_for_element += 1
208230
if self.logger:
209-
self.logger.debug(f"[add_rights_to_graph] Created edge: {sid} --[{right_edge}]--> {element_id}")
231+
self.logger.debug(
232+
f"[add_rights_to_graph] Created edge: {sid} --[{right_edge}]--> {element_id}"
233+
)
210234

211235
if self.logger:
212-
self.logger.debug(f"[add_rights_to_graph] Created {edges_created_for_element} rights edge(s) for {element_type}: {element_id}")
236+
self.logger.debug(
237+
f"[add_rights_to_graph] Created {edges_created_for_element} rights edge(s) for {element_type}: {element_id}"
238+
)
213239

214240
def push_path(self, node: Node, rights: dict):
215241
"""
@@ -461,4 +487,6 @@ def log_summary(self) -> None:
461487
None
462488
"""
463489
if self.logger:
464-
self.logger.debug(f"[OpenGraphContext] Total edges created in this context: {self.total_edges_created}")
490+
self.logger.debug(
491+
f"[OpenGraphContext] Total edges created in this context: {self.total_edges_created}"
492+
)

0 commit comments

Comments
 (0)