Skip to content

Commit 266c671

Browse files
authored
Merge pull request Pennyw0rth#556 from crosscutsaw/dump-computers
new module: ldap > dump-computers
2 parents 9566b0d + e259128 commit 266c671

2 files changed

Lines changed: 69 additions & 0 deletions

File tree

nxc/modules/dump-computers.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
from nxc.parsers.ldap_results import parse_result_attributes
2+
3+
4+
class NXCModule:
5+
name = "dump-computers"
6+
description = "Dumps all computers in the domain"
7+
supported_protocols = ["ldap"]
8+
opsec_safe = True
9+
multiple_hosts = False
10+
11+
def options(self, context, module_options):
12+
"""
13+
TYPE Only dump NETBIOS or FQDN instead of 'FQDN (OS Version)'
14+
OUTPUT Output to file in addition to printing to console
15+
16+
Examples
17+
--------
18+
netexec ldap $DC-IP -u $username -p $password -M dump-computers
19+
netexec ldap $DC-IP -u $username -p $password -M dump-computers -o TYPE=netbios
20+
netexec ldap $DC-IP -u $username -p $password -M dump-computers -o TYPE=fqdn
21+
netexec ldap $DC-IP -u $username -p $password -M dump-computers -o TYPE=netbios OUTPUT=<location>
22+
"""
23+
self.output_file = None
24+
self.netbios_only = False
25+
self.fqdn_only = False
26+
27+
if "OUTPUT" in module_options:
28+
self.output_file = module_options["OUTPUT"]
29+
if "TYPE" in module_options:
30+
if module_options["TYPE"].lower() == "netbios":
31+
self.netbios_only = True
32+
elif module_options["TYPE"].lower() == "fqdn":
33+
self.fqdn_only = True
34+
35+
def on_login(self, context, connection):
36+
resp = connection.search(
37+
searchFilter="(objectCategory=computer)",
38+
attributes=["dNSHostName", "operatingSystem"]
39+
)
40+
resp_parsed = parse_result_attributes(resp)
41+
42+
answers = []
43+
context.log.debug(f"Total number of records returned: {len(resp_parsed)}")
44+
45+
for item in resp_parsed:
46+
dns_host_name = item["dNSHostName"]
47+
operating_system = item.get("operatingSystem", "Unknown OS")
48+
49+
if self.netbios_only:
50+
netbios_name = dns_host_name.split(".")[0]
51+
answer = netbios_name
52+
elif self.fqdn_only:
53+
answer = dns_host_name
54+
else:
55+
answer = f"{dns_host_name} ({operating_system})"
56+
answers.append(answer)
57+
58+
context.log.success("Found the following computers:")
59+
for answer in answers:
60+
context.log.highlight(answer)
61+
62+
if self.output_file:
63+
try:
64+
with open(self.output_file, "w") as f:
65+
f.write("\n".join(answers) + "\n")
66+
context.log.success(f"Results saved to {self.output_file}")
67+
except Exception as e:
68+
context.log.error(f"Failed to write to file {self.output_file}: {e}")

tests/e2e_commands.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M subnets
210210
netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M user-desc
211211
netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M whoami
212212
netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M pso
213+
netexec ldap TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -M dump-computers
213214
##### WINRM
214215
netexec winrm TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS # need an extra space after this command due to regex
215216
netexec winrm TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig

0 commit comments

Comments
 (0)