diff --git a/bloodhound/__init__.py b/bloodhound/__init__.py index df3cb19..298b62d 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: 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