1
+ #!/usr/bin/env python3
2
+ #
3
+ # Author:
4
+ # Tamas Jos (@skelsec)
5
+ #
6
+
7
+ import asyncio
8
+ import traceback
9
+ import logging
10
+ import csv
11
+ import shlex
12
+ import datetime
13
+
14
+ from msldap .external .aiocmd .aiocmd import aiocmd
15
+ from msldap .external .asciitree .asciitree import LeftAligned
16
+ from tqdm import tqdm
17
+
18
+ from msldap import logger
19
+ from asysocks import logger as sockslogger
20
+ from msldap .client import MSLDAPClient
21
+ from msldap .commons .url import MSLDAPURLDecoder
22
+ from msldap .ldap_objects import MSADUser , MSADMachine , MSADUser_TSV_ATTRS
23
+
24
+ from winacl .dtyp .security_descriptor import SECURITY_DESCRIPTOR
25
+
26
+
27
+ class MSLDAPCompDomainList :
28
+ def __init__ (self , ldap_url ):
29
+ self .conn_url = ldap_url
30
+ self .connection = None
31
+ self .adinfo = None
32
+ self .ldapinfo = None
33
+ self .domain_name = None
34
+
35
+ async def login (self ):
36
+ """Performs connection and login"""
37
+ try :
38
+ logger .debug (self .conn_url .get_credential ())
39
+ logger .debug (self .conn_url .get_target ())
40
+
41
+
42
+ self .connection = self .conn_url .get_client ()
43
+ _ , err = await self .connection .connect ()
44
+ if err is not None :
45
+ raise err
46
+
47
+ return True , None
48
+ except Exception as e :
49
+ return False , e
50
+
51
+ async def do_adinfo (self , show = True ):
52
+ """Prints detailed Active Driectory info"""
53
+ try :
54
+ if self .adinfo is None :
55
+ self .adinfo = self .connection ._ldapinfo
56
+ self .domain_name = self .adinfo .distinguishedName .replace ('DC' ,'' ).replace ('=' ,'' ).replace (',' ,'.' )
57
+ if show is True :
58
+ print (self .adinfo )
59
+
60
+ return True , None
61
+ except Exception as e :
62
+ return False , e
63
+
64
+ async def run (self ):
65
+ try :
66
+ _ , err = await self .login ()
67
+ if err is not None :
68
+ raise err
69
+ _ , err = await self .do_adinfo (False )
70
+ if err is not None :
71
+ raise err
72
+ #machine_filename = '%s_computers_%s.txt' % (self.domain_name, datetime.datetime.now().strftime("%Y%m%d-%H%M%S"))
73
+
74
+ async for machine , err in self .connection .get_all_machines (attrs = ['sAMAccountName' , 'dNSHostName' ]):
75
+ if err is not None :
76
+ raise err
77
+
78
+ dns = machine .dNSHostName
79
+ if dns is None :
80
+ dns = '%s.%s' % (machine .sAMAccountName [:- 1 ], self .domain_name )
81
+
82
+ print (str (dns ))
83
+ except :
84
+ traceback .print_exc ()
85
+
86
+
87
+ def main ():
88
+ import argparse
89
+ parser = argparse .ArgumentParser (description = 'MS LDAP library' )
90
+ parser .add_argument ('-v' , '--verbose' , action = 'count' , default = 0 , help = 'Verbosity, can be stacked' )
91
+ parser .add_argument ('-n' , '--no-interactive' , action = 'store_true' )
92
+ parser .add_argument ('url' , help = 'Connection string in URL format.' )
93
+
94
+ args = parser .parse_args ()
95
+
96
+
97
+ ###### VERBOSITY
98
+ if args .verbose == 0 :
99
+ logging .basicConfig (level = logging .INFO )
100
+ else :
101
+ sockslogger .setLevel (logging .DEBUG )
102
+ logger .setLevel (logging .DEBUG )
103
+ logging .basicConfig (level = logging .DEBUG )
104
+
105
+ ldap_url = MSLDAPURLDecoder (args .url )
106
+ compdomlist = MSLDAPCompDomainList (ldap_url )
107
+
108
+
109
+ asyncio .run (compdomlist .run ())
110
+
111
+ if __name__ == '__main__' :
112
+ main ()
0 commit comments