From bbf81dd0e493a6829c7b4955f6aede6b497ff125 Mon Sep 17 00:00:00 2001 From: noreply <users.noreply@github.com> Date: Wed, 15 Jan 2025 16:38:31 +0530 Subject: [PATCH 1/2] Added option to mention custom LDAP server IP --- bloodhound/__init__.py | 7 ++++++- bloodhound/ad/domain.py | 22 ++++++++++++++++------ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/bloodhound/__init__.py b/bloodhound/__init__.py index df3cb19..95c6036 100644 --- a/bloodhound/__init__.py +++ b/bloodhound/__init__.py @@ -228,6 +228,10 @@ def main(): metavar='HOST', action='store', help='Override which DC to query (hostname)') + coopts.add_argument('-dc-ip', + '--domain-ip', + action='store', + help='Override which DC/LDAP server to query (IP)') coopts.add_argument('-gc', '--global-catalog', metavar='HOST', @@ -303,7 +307,7 @@ def main(): args.auth_method = 'kerberos' auth = ADAuthentication(username=args.username, password=args.password, domain=args.domain, auth_method=args.auth_method, ldap_channel_binding=args.ldap_channel_binding) - ad = AD(auth=auth, domain=args.domain, nameserver=args.nameserver, dns_tcp=args.dns_tcp, dns_timeout=args.dns_timeout, use_ldaps=args.use_ldaps) + ad = AD(auth=auth, domain=args.domain, nameserver=args.nameserver, dns_tcp=args.dns_tcp, dns_timeout=args.dns_timeout, use_ldaps=args.use_ldaps, dc_ip=args.domain_ip) # Resolve collection methods collect = resolve_collection_methods(args.collectionmethod) if not collect: @@ -311,6 +315,7 @@ def main(): logging.debug('Resolved collection methods: %s', ', '.join(list(collect))) logging.debug('Using DNS to retrieve domain information') + print(args) ad.dns_resolve(domain=args.domain, options=args) # Override the detected DC / GC if specified diff --git a/bloodhound/ad/domain.py b/bloodhound/ad/domain.py index 46f76fb..562f119 100644 --- a/bloodhound/ad/domain.py +++ b/bloodhound/ad/domain.py @@ -61,11 +61,19 @@ def ldap_connect(self, protocol=None, resolver=False): logging.info('Connecting to LDAP server: %s' % self.hostname) logging.debug('Using protocol %s' % protocol) - # Convert the hostname to an IP, this prevents ldap3 from doing it - # which doesn't use our custom nameservers - q = self.ad.dnsresolver.query(self.hostname, tcp=self.ad.dns_tcp) - for r in q: - ip = r.address + + if (self.ad.dc_ip): + logging.info('LDAP server IP provied') + logging.info('LDAP server IP: %s' % self.ad.dc_ip) + ip = self.ad.dc_ip + else: + # Convert the hostname to an IP, this prevents ldap3 from doing it + # which doesn't use our custom nameservers + logging.info('Resolving LDAP ip from nameserver') + q = self.ad.dnsresolver.query(self.hostname, tcp=self.ad.dns_tcp) + for r in q: + ip = r.address + logging.info('LDAP server IP: %s' % ip) ldap = self.ad.auth.getLDAPConnection(hostname=self.hostname, ip=ip, baseDN=self.ad.baseDN, protocol=protocol) @@ -588,7 +596,7 @@ def get_root_domain(self): """ class AD(object): - def __init__(self, domain=None, auth=None, nameserver=None, dns_tcp=False, dns_timeout=3.0, use_ldaps=False): + def __init__(self, domain=None, auth=None, nameserver=None, dns_tcp=False, dns_timeout=3.0, use_ldaps=False,dc_ip=None): self.domain = domain # Object of type ADDomain, added later self.domain_object = None @@ -614,6 +622,8 @@ def __init__(self, domain=None, auth=None, nameserver=None, dns_tcp=False, dns_t self.dnsresolver.nameservers = [nameserver] # Resolve DNS over TCP? self.dns_tcp = dns_tcp + # ldap ip to query + self.dc_ip = dc_ip # Give it a cache to prevent duplicate lookups self.dnsresolver.cache = resolver.Cache() # Default timeout after 3 seconds if the DNS servers From a20cd4cd8c131bd79b0fed72a120acc50b5d5f28 Mon Sep 17 00:00:00 2001 From: noreply <users.noreply@github.com> Date: Wed, 15 Jan 2025 16:42:51 +0530 Subject: [PATCH 2/2] remove some debug logs --- bloodhound/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/bloodhound/__init__.py b/bloodhound/__init__.py index 95c6036..298b62d 100644 --- a/bloodhound/__init__.py +++ b/bloodhound/__init__.py @@ -315,7 +315,6 @@ def main(): logging.debug('Resolved collection methods: %s', ', '.join(list(collect))) logging.debug('Using DNS to retrieve domain information') - print(args) ad.dns_resolve(domain=args.domain, options=args) # Override the detected DC / GC if specified