1- import socket
2- from nxc .logger import nxc_logger
3- from impacket .ldap .ldap import LDAPSearchError
1+ from nxc .parsers .ldap_results import parse_result_attributes
42from impacket .ldap .ldapasn1 import SearchResultEntry
5- import sys
63
74class NXCModule :
8-
95 name = "dump-computers"
106 description = "Dumps all computers in the domain"
117 supported_protocols = ["ldap" ]
@@ -16,61 +12,56 @@ def options(self, context, module_options):
1612 """
1713 dump-computers: Specify dump-computers to call the module
1814 Usage:
19- >prints fqdn and version
15+ > prints fqdn and machine version
2016 netexec ldap $DC-IP -u $username -p $password -M dump-computers
21-
22- >prints only netbios name
17+
18+ > prints only netbios name (no machine version)
2319 netexec ldap $DC-IP -u $username -p $password -M dump-computers -o TYPE=netbios
24-
25- >prints only fqdn
20+
21+ > prints only fqdn (no machine version)
2622 netexec ldap $DC-IP -u $username -p $password -M dump-computers -o TYPE=fqdn
27-
28- >prints fqdn and version, output to file
23+
24+ > prints fqdn and machine version, output to file
2925 netexec ldap $DC-IP -u $username -p $password -M dump-computers -o OUTPUT=<location>
30-
31- >prints only netbios name , output to file
26+
27+ > prints netbios or fqdn (no machine version) , output to file
3228 netexec ldap $DC-IP -u $username -p $password -M dump-computers -o TYPE=netbios OUTPUT=<location>
3329 netexec ldap $DC-IP -u $username -p $password -M dump-computers -o TYPE=fqdn OUTPUT=<location>
34-
3530 """
3631 self .output_file = None
3732 self .netbios_only = False
3833 self .fqdn_only = False
39-
34+
4035 if "OUTPUT" in module_options :
4136 self .output_file = module_options ["OUTPUT" ]
42- if "TYPE" in module_options and module_options ["TYPE" ].lower () == "netbios" :
43- self .netbios_only = True
44- if "TYPE" in module_options and module_options ["TYPE" ].lower () == "fqdn" :
45- self .fqdn_only = True
37+ if "TYPE" in module_options :
38+ t = module_options ["TYPE" ].lower ()
39+ if t == "netbios" :
40+ self .netbios_only = True
41+ elif t == "fqdn" :
42+ self .fqdn_only = True
4643
4744 def on_login (self , context , connection ):
4845 search_filter = "(objectCategory=computer)"
49-
50- try :
51- context .log .debug (f"Search Filter={ search_filter } " )
52- resp = connection .ldap_connection .search (searchFilter = search_filter , attributes = ["dNSHostName" , "operatingSystem" ], sizeLimit = 0 )
53- except LDAPSearchError as e :
54- if e .getErrorString ().find ("sizeLimitExceeded" ) >= 0 :
55- context .log .debug ("sizeLimitExceeded exception caught, giving up and processing the data received" )
56- resp = e .getAnswers ()
57- else :
58- nxc_logger .debug (e )
59- return False
46+ context .log .debug (f"Search Filter = { search_filter } " )
47+
48+ entries = connection .search (
49+ searchFilter = search_filter ,
50+ attributes = ["dNSHostName" , "operatingSystem" ]
51+ )
6052
6153 answers = []
62- context .log .debug (f"Total no. of records returned: { len (resp )} " )
63- for item in resp :
64- if isinstance (item , SearchResultEntry ) is not True :
54+ context .log .debug (f"Total number of records returned: { len (entries )} " )
55+
56+ for item in entries :
57+ if not isinstance (item , SearchResultEntry ):
6558 continue
66- dns_host_name = ""
67- operating_system = ""
59+
6860 try :
69- for attribute in item ["attributes" ]:
70- if str (attribute ["type" ]) == "dNSHostName" :
71- dns_host_name = str (attribute ["vals" ][0 ])
72- elif str (attribute ["type" ]) == "operatingSystem" :
73- operating_system = attribute ["vals" ][0 ]
61+ parsed = parse_result_attributes ([item ])[0 ]
62+ dns_host_name = parsed .get ("dNSHostName" , "" )
63+ operating_system = parsed .get ("operatingSystem" , "" )
64+
7465 if dns_host_name :
7566 netbios_name = dns_host_name .split ("." )[0 ]
7667 if self .netbios_only :
@@ -80,15 +71,14 @@ def on_login(self, context, connection):
8071 else :
8172 answer = f"{ dns_host_name } ({ operating_system } )"
8273 answers .append (answer )
83- except Exception as e :
84- context .log .debug ("Exception:" , exc_info = True )
85- context .log .debug (f"Skipping item, cannot process due to error { e } " )
86-
87- if len (answers ) > 0 :
88- context .log .success ("Found the following computers: " )
74+ except Exception :
75+ context .log .debug ("Failed to parse entry" , exc_info = True )
76+
77+ if answers :
78+ context .log .success ("Found the following computers:" )
8979 for answer in answers :
9080 context .log .highlight (answer )
91-
81+
9282 if self .output_file :
9383 try :
9484 with open (self .output_file , "w" ) as f :
0 commit comments