@@ -21,15 +21,30 @@ def options(self, context, module_options):
2121 """There are no module options."""
2222
2323 def on_admin_login (self , context , connection ):
24- admin_users = []
25-
2624 try :
27- string_binding = fr"ncacn_np:{ connection .kdcHost } [\pipe\samr]"
28- context .log .debug (f"Using string binding: { string_binding } " )
25+ admin_users = self .enumerate_admin_users (context , connection )
26+ if not admin_users :
27+ context .log .fail ("No admin users found." )
28+ return
29+
30+ # Update user objects to check if they are in tasklist or users directory
31+ self .check_users_directory (context , connection , admin_users )
32+ self .check_tasklist (context , connection , admin_users )
33+
34+ # print grouped/logged results nicely
35+ self .print_grouped_results (context , admin_users )
36+ except Exception as e :
37+ context .log .fail (str (e ))
38+ context .log .debug (traceback .format_exc ())
39+
40+ def enumerate_admin_users (self , context , connection ):
41+ admin_users = []
42+ string_binding = fr"ncacn_np:{ connection .kdcHost } [\pipe\samr]"
43+ context .log .debug (f"Using string binding: { string_binding } " )
2944
30- rpctransport = transport .DCERPCTransportFactory (string_binding )
31- rpctransport .setRemoteHost (connection .kdcHost )
32- rpctransport .set_credentials (
45+ rpctransport = transport .DCERPCTransportFactory (string_binding )
46+ rpctransport .setRemoteHost (connection .kdcHost )
47+ rpctransport .set_credentials (
3348 connection .username ,
3449 connection .password ,
3550 connection .domain ,
@@ -38,68 +53,60 @@ def on_admin_login(self, context, connection):
3853 aesKey = connection .aesKey ,
3954 )
4055
41- dce = rpctransport .get_dce_rpc ()
42- dce .set_auth_level (RPC_C_AUTHN_LEVEL_PKT_PRIVACY )
43- dce .connect ()
44- dce .bind (samr .MSRPC_UUID_SAMR )
56+ dce = rpctransport .get_dce_rpc ()
57+ dce .set_auth_level (RPC_C_AUTHN_LEVEL_PKT_PRIVACY )
58+ dce .connect ()
59+ dce .bind (samr .MSRPC_UUID_SAMR )
4560
46- try :
47- server_handle = samr .hSamrConnect2 (dce )["ServerHandle" ]
48- domain = samr .hSamrEnumerateDomainsInSamServer (dce , server_handle )["Buffer" ]["Buffer" ][0 ]["Name" ]
49- resp = samr .hSamrLookupDomainInSamServer (dce , server_handle , domain )
50- domain_sid = resp ["DomainId" ].formatCanonical ()
51- domain_handle = samr .hSamrOpenDomain (dce , server_handle , samr .DOMAIN_LOOKUP | samr .DOMAIN_LIST_ACCOUNTS , resp ["DomainId" ])["DomainHandle" ]
52- context .log .debug (f"Resolved domain SID for { domain } : { domain_sid } " )
53- except Exception as e :
54- context .log .fail (f"Failed to open domain { domain } : { e !s} " )
55- context .log .debug (traceback .format_exc ())
56- return
61+ try :
62+ server_handle = samr .hSamrConnect2 (dce )["ServerHandle" ]
63+ domain = samr .hSamrEnumerateDomainsInSamServer (dce , server_handle )["Buffer" ]["Buffer" ][0 ]["Name" ]
64+ resp = samr .hSamrLookupDomainInSamServer (dce , server_handle , domain )
65+ domain_sid = resp ["DomainId" ].formatCanonical ()
66+ domain_handle = samr .hSamrOpenDomain (dce , server_handle , samr .DOMAIN_LOOKUP | samr .DOMAIN_LIST_ACCOUNTS , resp ["DomainId" ])["DomainHandle" ]
67+ context .log .debug (f"Resolved domain SID for { domain } : { domain_sid } " )
68+ except Exception as e :
69+ context .log .fail (f"Failed to open domain { domain } : { e !s} " )
70+ context .log .debug (traceback .format_exc ())
71+ return []
5772
58- admin_rids = {
73+ admin_rids = {
5974 "Domain Admins" : 512 ,
6075 "Enterprise Admins" : 519 ,
6176 }
6277
63- # Enumerate admin groups and their members
64- for group_name , group_rid in admin_rids .items ():
65- context .log .debug (f"Looking up group: { group_name } with RID { group_rid } " )
66-
67- try :
68- group_handle = samr .hSamrOpenGroup (dce , domain_handle , samr .GROUP_LIST_MEMBERS , group_rid )["GroupHandle" ]
69- resp = samr .hSamrGetMembersInGroup (dce , group_handle )
70- for member in resp ["Members" ]["Members" ]:
71- rid = int .from_bytes (member .getData (), byteorder = "little" )
72- try :
73- user_handle = samr .hSamrOpenUser (dce , domain_handle , samr .MAXIMUM_ALLOWED , rid )["UserHandle" ]
74- username = samr .hSamrQueryInformationUser2 (dce , user_handle , samr .USER_INFORMATION_CLASS .UserAllInformation )["Buffer" ]["All" ]["UserName" ]
75-
76- # If user already exists, append group name
77- if any (u ["sid" ] == f"{ domain_sid } -{ rid } " for u in admin_users ):
78- user = next (u for u in admin_users if u ["sid" ] == f"{ domain_sid } -{ rid } " )
79- user ["group" ].append (group_name )
80- else :
81- admin_users .append ({"username" : username , "sid" : f"{ domain_sid } -{ rid } " , "domain" : domain , "group" : [group_name ], "in_tasks" : False , "in_directory" : False })
82- context .log .debug (f"Found user: { username } with RID { rid } in group { group_name } " )
83- except Exception as e :
84- context .log .debug (f"Failed to get user info for RID { rid } : { e !s} " )
85- finally :
86- with suppress (Exception ):
87- samr .hSamrCloseHandle (dce , user_handle )
88- except Exception as e :
89- context .log .debug (f"Failed to get members of group { group_name } : { e !s} " )
90- finally :
91- with suppress (Exception ):
92- samr .hSamrCloseHandle (dce , group_handle )
78+ # Enumerate admin groups and their members
79+ for group_name , group_rid in admin_rids .items ():
80+ context .log .debug (f"Looking up group: { group_name } with RID { group_rid } " )
9381
94- # Update user objects to check if they are in tasklist or users directory
95- self .check_users_directory (context , connection , admin_users )
96- self .check_tasklist (context , connection , admin_users )
82+ try :
83+ group_handle = samr .hSamrOpenGroup (dce , domain_handle , samr .GROUP_LIST_MEMBERS , group_rid )["GroupHandle" ]
84+ resp = samr .hSamrGetMembersInGroup (dce , group_handle )
85+ for member in resp ["Members" ]["Members" ]:
86+ rid = int .from_bytes (member .getData (), byteorder = "little" )
87+ try :
88+ user_handle = samr .hSamrOpenUser (dce , domain_handle , samr .MAXIMUM_ALLOWED , rid )["UserHandle" ]
89+ username = samr .hSamrQueryInformationUser2 (dce , user_handle , samr .USER_INFORMATION_CLASS .UserAllInformation )["Buffer" ]["All" ]["UserName" ]
90+
91+ # If user already exists, append group name
92+ if any (u ["sid" ] == f"{ domain_sid } -{ rid } " for u in admin_users ):
93+ user = next (u for u in admin_users if u ["sid" ] == f"{ domain_sid } -{ rid } " )
94+ user ["group" ].append (group_name )
95+ else :
96+ admin_users .append ({"username" : username , "sid" : f"{ domain_sid } -{ rid } " , "domain" : domain , "group" : [group_name ], "in_tasks" : False , "in_directory" : False })
97+ context .log .debug (f"Found user: { username } with RID { rid } in group { group_name } " )
98+ except Exception as e :
99+ context .log .debug (f"Failed to get user info for RID { rid } : { e !s} " )
100+ finally :
101+ with suppress (Exception ):
102+ samr .hSamrCloseHandle (dce , user_handle )
103+ except Exception as e :
104+ context .log .debug (f"Failed to get members of group { group_name } : { e !s} " )
105+ finally :
106+ with suppress (Exception ):
107+ samr .hSamrCloseHandle (dce , group_handle )
97108
98- # print grouped/logged results nicely
99- self .print_grouped_results (context , admin_users )
100- except Exception as e :
101- context .log .fail (str (e ))
102- context .log .debug (traceback .format_exc ())
109+ return admin_users
103110
104111 def check_users_directory (self , context , connection , admin_users ):
105112 dirs_found = set ()
0 commit comments