BloodHound.py
BloodHound.py copied to clipboard
Fix to solve DNS resolution fail when different DNs sufix
trafficstars
I faced some issue when using a BloodHound in a environment with a different DNS sufix.
Error sample 1
bloodhound-python -c All -ns 192.168.30.230 -d alunos.sec4us.local -u 'aluno.0' -p '...'
INFO: Found AD domain: alunos.sec4us.local
Traceback (most recent call last):
File "/usr/local/bin/bloodhound-python", line 8, in <module>
sys.exit(main())
^^^^^^
File "/usr/local/lib/python3.11/dist-packages/bloodhound/__init__.py", line 308, in main
ad.dns_resolve(domain=args.domain, options=args)
File "/usr/local/lib/python3.11/dist-packages/bloodhound/ad/domain.py", line 720, in dns_resolve
q = self.dnsresolver.query(query.replace('pdc','gc'), 'SRV', tcp=self.dns_tcp)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/dns/resolver.py", line 1262, in query
return self.resolve(
^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/dns/resolver.py", line 1204, in resolve
timeout = self._compute_timeout(start, lifetime, resolution.errors)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/dns/resolver.py", line 988, in _compute_timeout
raise LifetimeTimeout(timeout=duration, errors=errors)
dns.resolver.LifetimeTimeout: The resolution lifetime expired after 3.103 seconds: Server 192.168.30.230 UDP port 53 answered The DNS operation timed out.
Error sample 2
bloodhound-python -c All -ns 192.168.30.230 -d alunos.sec4us.local -u 'aluno.0' -p '...' --disable-autogc --dns-timeout 50
INFO: Found AD domain: alunos.sec4us.local
Traceback (most recent call last):
File "/usr/local/bin/bloodhound-python", line 8, in <module>
sys.exit(main())
^^^^^^
File "/usr/local/lib/python3.11/dist-packages/bloodhound/__init__.py", line 308, in main
ad.dns_resolve(domain=args.domain, options=args)
File "/usr/local/lib/python3.11/dist-packages/bloodhound/ad/domain.py", line 720, in dns_resolve
q = self.dnsresolver.query(query.replace('pdc','gc'), 'SRV', tcp=self.dns_tcp)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/dns/resolver.py", line 1262, in query
return self.resolve(
^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/dns/resolver.py", line 1201, in resolve
(nameserver, port, tcp, backoff) = resolution.next_nameserver()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/dns/resolver.py", line 704, in next_nameserver
raise NoNameservers(request=self.request, errors=self.errors)
dns.resolver.NoNameservers: All nameservers failed to answer the query _ldap._tcp.gc._msdcs.alunos.sec4us.local.labpentestbrasil.com.br. IN SRV: Server 192.168.30.230 UDP port 53 answered SERVFAIL
This second error show me what is the issue
Looking at my DNS config
ccat /etc/resolv.conf
───────┬────────────────────────────────
│ File: /etc/resolv.conf
───────┼────────────────────────────────
1 │ # Generated by NetworkManager
2 │ search labpentestbrasil.com.br
3 │ nameserver 192.168.30.1
───────┴────────────────────────────────
Solution PoC
To test i just put the "." at the end of the domain
bloodhound-python -c All -ns 192.168.30.230 -d alunos.sec4us.local. -u 'aluno.0' -p '...'
INFO: Found AD domain: alunos.sec4us.local
WARNING: Could not find a global catalog server, assuming the primary DC has this role
If this gives errors, either specify a hostname with -gc or disable gc resolution with --disable-autogc
INFO: Getting TGT for user
WARNING: Failed to get Kerberos TGT. Falling back to NTLM authentication. Error: [Errno Connection error (dc02.alunos.sec4us.local:88)] [Errno 113] No route to host
INFO: Connecting to LDAP server: dc02.alunos.sec4us.local
INFO: Found 1 domains
INFO: Found 2 domains in the forest
INFO: Found 5 computers
INFO: Connecting to LDAP server: dc02.alunos.sec4us.local
INFO: Connecting to GC LDAP server: dc02.alunos.sec4us.local
INFO: Found 132 users
INFO: Found 75 groups
INFO: Found 2 gpos
INFO: Found 16 ous
INFO: Found 19 containers
INFO: Found 1 trusts
...
Solution
Add the following code to force "." at the end
args.domain = f'{args.domain.rstrip(" .")}.'
Final test
ccat /usr/local/lib/python3.11/dist-packages/bloodhound/__init__.py -l 285:310
─────┬──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ File: /usr/local/lib/python3.11/dist-packages/bloodhound/__init__.py
─────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
... │
285 │ elif args.hashes is not None and args.username is not None:
286 │ logging.debug('Authentication: NT hash')
287 │ lm, nt = args.hashes.split(":")
288 │ auth = ADAuthentication(lm_hash=lm, nt_hash=nt, username=args.username, domain=args.domain, auth_method=args.auth_method)
289 │ elif args.aesKey is not None and args.username is not None:
290 │ logging.debug('Authentication: Kerberos AES')
291 │ auth = ADAuthentication(username=args.username, domain=args.domain, aeskey=args.aesKey, auth_method=args.auth_method)
292 │ else:
293 │ if not args.kerberos:
294 │ parser.print_help()
295 │ sys.exit(1)
296 │ else:
297 │ auth = ADAuthentication(username=args.username, password=args.password, domain=args.domain, auth_method=args.auth_method)
298 │
299 │ # Put "." at the end to prevent DNS resolution error
300 │ args.domain = f'{args.domain.rstrip(" .")}.'
301 │
302 │ 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)
303 │
304 │ # Resolve collection methods
305 │ collect = resolve_collection_methods(args.collectionmethod)
306 │ if not collect:
307 │ return
308 │ logging.debug('Resolved collection methods: %s', ', '.join(list(collect)))
309 │
310 │ logging.debug('Using DNS to retrieve domain information')
... │
─────┴──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
bloodhound-python -c All -ns 192.168.30.230 -d alunos.sec4us.local -u 'aluno.0' -p '...'
INFO: Found AD domain: alunos.sec4us.local
WARNING: Could not find a global catalog server, assuming the primary DC has this role
If this gives errors, either specify a hostname with -gc or disable gc resolution with --disable-autogc
INFO: Getting TGT for user
WARNING: Failed to get Kerberos TGT. Falling back to NTLM authentication. Error: [Errno Connection error (dc02.alunos.sec4us.local:88)] [Errno 113] No route to host
INFO: Connecting to LDAP server: dc02.alunos.sec4us.local
INFO: Found 1 domains
INFO: Found 2 domains in the forest
INFO: Found 5 computers
INFO: Connecting to LDAP server: dc02.alunos.sec4us.local
INFO: Connecting to GC LDAP server: dc02.alunos.sec4us.local
INFO: Found 132 users
INFO: Found 75 groups
INFO: Found 2 gpos
INFO: Found 16 ous
INFO: Found 19 containers
INFO: Found 1 trusts
+1
Thanks for debugging this, I've resolved this in a slightly different way but it should be resolved now