From 8c9a3d37dd7e08d8b08f8e9ed1508fadedec39fd Mon Sep 17 00:00:00 2001 From: p0dalirius Date: Wed, 24 Nov 2021 20:33:14 +0100 Subject: [PATCH] Added LDAP module to list AD sites and subnets --- cme/modules/subnets.py | 103 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 cme/modules/subnets.py diff --git a/cme/modules/subnets.py b/cme/modules/subnets.py new file mode 100644 index 00000000..c0a57b47 --- /dev/null +++ b/cme/modules/subnets.py @@ -0,0 +1,103 @@ +from impacket.ldap import ldapasn1 as ldapasn1_impacket + +def searchResEntry_to_dict(results): + data = {} + for attr in results['attributes']: + key = str(attr['type']) + value = str(attr['vals'][0]) + data[key] = value + return data + +class CMEModule: + ''' + Retrieves the different Sites and Subnets of an Active Directory + + Authors: + Podalirius: @podalirius_ + ''' + + def options(self, context, module_options): + """ + showservers Toggle printing of servers (default: true) + """ + + self.showservers = True + + if module_options and 'SHOWSERVERS' in module_options: + if module_options['SHOWSERVERS'].lower() == "true" or module_options['SHOWSERVERS'] == "1": + self.showservers = True + elif module_options['SHOWSERVERS'].lower() == "false" or module_options['SHOWSERVERS'] == "0": + self.showservers = False + else: + print("Could not parse showservers option.") + + name = 'subnets' + description = 'Retrieves the different Sites and Subnets of an Active Directory' + supported_protocols = ['ldap'] + opsec_safe = True + multiple_hosts = False + + def on_login(self, context, connection): + dn = ','.join(["DC=%s" % part for part in context.domain.split('.')]) + + context.log.info('Getting the Sites and Subnets from domain') + + list_sites = connection.ldapConnection.search( + searchBase="CN=Configuration,%s" % dn, + searchFilter='(objectClass=site)', + attributes=['distinguishedName', 'name', 'description'], + sizeLimit=999 + ) + for site in list_sites: + if isinstance(site, ldapasn1_impacket.SearchResultEntry) is not True: + continue + site = searchResEntry_to_dict(site) + site_dn = site['distinguishedName'] + site_name = site['name'] + site_description = "" + if "description" in site.keys(): + site_description = site['description'] + # Getting subnets of this site + list_subnets = connection.ldapConnection.search( + searchBase="CN=Sites,CN=Configuration,%s" % dn, + searchFilter='(siteObject=%s)' % site_dn, + attributes=['distinguishedName', 'name'], + sizeLimit=999 + ) + if len([subnet for subnet in list_subnets if isinstance(subnet, ldapasn1_impacket.SearchResultEntry)]) == 0: + context.log.highlight("Site \"%s\"" % site_name) + else: + for subnet in list_subnets: + if isinstance(subnet, ldapasn1_impacket.SearchResultEntry) is not True: + continue + subnet = searchResEntry_to_dict(subnet) + subnet_dn = subnet['distinguishedName'] + subnet_name = subnet['name'] + + if self.showservers: + # Getting machines in these subnets + list_servers = connection.ldapConnection.search( + searchBase=site_dn, + searchFilter='(objectClass=server)', + attributes=['cn'], + sizeLimit=999 + ) + if len([server for server in list_servers if isinstance(server, ldapasn1_impacket.SearchResultEntry)]) == 0: + if len(site_description) != 0: + context.log.highlight("Site \"%s\" (Subnet:%s) (description:\"%s\")" % (site_name, subnet_name, site_description)) + else: + context.log.highlight("Site \"%s\" (Subnet:%s)" % (site_name, subnet_name)) + else: + for server in list_servers: + if isinstance(server, ldapasn1_impacket.SearchResultEntry) is not True: + continue + server = searchResEntry_to_dict(server)['cn'] + if len(site_description) != 0: + context.log.highlight("Site \"%s\" (Subnet:%s) (description:\"%s\") (Server:%s)" % (site_name, subnet_name, site_description, server)) + else: + context.log.highlight("Site \"%s\" (Subnet:%s) (Server:%s)" % (site_name, subnet_name, server)) + else: + if len(site_description) != 0: + context.log.highlight("Site \"%s\" (Subnet:%s) (description:\"%s\")" % (site_name, subnet_name, site_description)) + else: + context.log.highlight("Site \"%s\" (Subnet:%s)" % (site_name, subnet_name))