Code Monkey home page Code Monkey logo

bloodhound.py's Introduction

BloodHound.py

Python 3 compatible PyPI version License: MIT

BloodHound.py is a Python based ingestor for BloodHound, based on Impacket.

This version of BloodHound.py is only compatible with BloodHound 4.2 and 4.3. For BloodHound CE, check out the bloodhound-ce branch

Limitations

BloodHound.py currently has the following limitations:

  • Supports most, but not all BloodHound (SharpHound) features. Currently GPO local groups are not supported, all other collection methods are implemented.

Installation and usage

You can install the ingestor via pip with pip install bloodhound, or by cloning this repository and running pip install . from the project directory. BloodHound.py requires impacket, ldap3 and dnspython to function.

The installation will add a command line tool bloodhound-python to your PATH.

To use the ingestor, at a minimum you will need credentials of the domain you're logging in to. You will need to specify the -u option with a username of this domain (or username@domain for a user in a trusted domain). If you have your DNS set up properly and the AD domain is in your DNS search list, then BloodHound.py will automatically detect the domain for you. If not, you have to specify it manually with the -d option.

By default BloodHound.py will query LDAP and the individual computers of the domain to enumerate users, computers, groups, trusts, sessions and local admins. If you want to restrict collection, specify the --collectionmethod parameter, which supports the following options (similar to SharpHound):

  • Default - Performs group membership collection, domain trust collection, local admin collection, and session collection
  • Group - Performs group membership collection
  • LocalAdmin - Performs local admin collection
  • RDP - Performs Remote Desktop Users collection
  • DCOM - Performs Distributed COM Users collection
  • Container - Performs container collection (GPO/Organizational Units/Default containers)
  • PSRemote - Performs Remote Management (PS Remoting) Users collection
  • DCOnly - Runs all collection methods that can be queried from the DC only, no connection to member hosts/servers needed. This is equal to Group,Acl,Trusts,ObjectProps,Container
  • Session - Performs session collection
  • Acl - Performs ACL collection
  • Trusts - Performs domain trust enumeration
  • LoggedOn - Performs privileged Session enumeration (requires local admin on the target)
  • ObjectProps - Performs Object Properties collection for properties such as LastLogon or PwdLastSet
  • All - Runs all methods above, except LoggedOn
  • Experimental - Connects to individual hosts to enumerate services and scheduled tasks that may have stored credentials

Multiple collectionmethods should be separated by a comma, for example: -c Group,LocalAdmin

You can override some of the automatic detection options, such as the hostname of the primary Domain Controller if you want to use a different Domain Controller with -dc, or specify your own Global Catalog with -gc.

Docker usage

  1. Build container
    docker build -t bloodhound .
  2. Run container
    docker run -v ${PWD}:/bloodhound-data -it bloodhound
    After that you can run bloodhound-python inside the container, all data will be stored in the path from where you start the container.

Credits

BloodHound.py was originally written by Dirk-jan Mollema, Edwin van Vliet and Matthijs Gielen from Fox-IT (NCC Group). BloodHound.py is currently maintained by Dirk-jan Mollema from Outsider Security. The implementation and data model is based on the original tool from SpecterOps. Many thanks to everyone who contributed by testing, submitting issues and pull requests over the years.

bloodhound.py's People

Contributors

0x48756773 avatar 5il avatar adrianvollmer avatar dirkjanm avatar ejohn avatar flangvik avatar h4rm0ny avatar itm4n avatar jarilaos avatar jasper-vdhoven avatar justin-p avatar lefayjey avatar micahvandeusen avatar mubix avatar mwgielen avatar nickvourd avatar noraj avatar ntalexio2 avatar pgrimaud avatar quibbitlabs avatar richroc avatar rvazarkar avatar shutdownrepo avatar simondotsh avatar sq00ky avatar trietend avatar vruello avatar williambruneau avatar zblurx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bloodhound.py's Issues

Kali 2020 issue

Hi :)

I made sure all my pacakges are up to date but i keep getting this error :(

Traceback (most recent call last):
  File "bloodhound.py", line 5, in <module>
    bloodhound.main()
  File "/root/HTB/blackfield/BloodHound.py/bloodhound/__init__.py", line 284, in main
    bloodhound.run(collect=collect,
  File "/root/HTB/blackfield/BloodHound.py/bloodhound/__init__.py", line 72, in run
    self.pdc.prefetch_info('objectprops' in collect, 'acl' in collect)
  File "/root/HTB/blackfield/BloodHound.py/bloodhound/ad/domain.py", line 394, in prefetch_info
    self.get_objecttype()
  File "/root/HTB/blackfield/BloodHound.py/bloodhound/ad/domain.py", line 224, in get_objecttype
    self.ldap_connect()
  File "/root/HTB/blackfield/BloodHound.py/bloodhound/ad/domain.py", line 68, in ldap_connect
    ldap = self.ad.auth.getLDAPConnection(hostname=ip,
  File "/root/HTB/blackfield/BloodHound.py/bloodhound/ad/authentication.py", line 78, in getLDAPConnection
    if not conn.bind():
  File "/usr/lib/python3/dist-packages/ldap3/core/connection.py", line 563, in bind
    response = self.do_ntlm_bind(controls)
  File "/usr/lib/python3/dist-packages/ldap3/core/connection.py", line 1302, in do_ntlm_bind
    request = bind_operation(self.version, 'SICILY_RESPONSE_NTLM', ntlm_client, result['server_creds'])
  File "/usr/lib/python3/dist-packages/ldap3/operation/bind.py", line 81, in bind_operation
    server_creds = name.create_authenticate_message()
  File "/usr/lib/python3/dist-packages/ldap3/utils/ntlm.py", line 379, in create_authenticate_message
    nt_challenge_response = self.compute_nt_response()
  File "/usr/lib/python3/dist-packages/ldap3/utils/ntlm.py", line 485, in compute_nt_response
    response_key_nt = self.ntowf_v2()
  File "/usr/lib/python3/dist-packages/ldap3/utils/ntlm.py", line 497, in ntowf_v2
    return hmac.new(password_digest, (self.user_name.upper() + self.user_domain).encode('utf-16-le')).digest()
  File "/usr/lib/python3.8/hmac.py", line 153, in new
    return HMAC(key, msg, digestmod)
  File "/usr/lib/python3.8/hmac.py", line 51, in __init__
    raise TypeError("Missing required parameter 'digestmod'.")
TypeError: Missing required parameter 'digestmod'.

ImportError: No module named ldap

Hello,

Tried installing it both ways (repo and with pip) but keep getting this error:

Traceback (most recent call last):
  File "/usr/local/bin/bloodhound-python", line 11, in <module>
    load_entry_point('bloodhound==0.5.0', 'console_scripts', 'bloodhound-python')()
  File "/usr/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 476, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "/usr/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 2700, in load_entry_point
    return ep.load()
  File "/usr/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 2318, in load
    return self.resolve()
  File "/usr/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 2324, in resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
  File "build/bdist.linux-x86_64/egg/bloodhound/__init__.py", line 26, in <module>
ImportError: No module named ldap

I'm sure I've install all required modules but no success thus far.

ValueError: bytes must be in range(0, 256)

When running the following I get a large error blob after it successfully connects to the LDAP server and states how many computers it has found.

Command run:

python3 bloodhound.py -u USER -p 'PASS' -c All,LoggedOn -d DOMAIN.com

Error output (redacted):

INFO: Found AD domain: DOMAIN.com
INFO: Connecting to LDAP server: DC.DOMAIN.com
INFO: Found 1 domains
INFO: Found 1 domains in the forest
INFO: Found NUMBERS computers
INFO: Connecting to LDAP server: DC.DOMAIN.com
Exception in thread Thread-4:
Traceback (most recent call last):
  File "/root/tools/BloodHound.py/bloodhound/ad/utils.py", line 345, in resolve_aces
    entry = self.addomain.sidcache.get(ace['sid'])
  File "/root/tools/BloodHound.py/bloodhound/ad/utils.py", line 438, in get
    return self._cache[entry]
KeyError: 'S-1-5-21-NUMBERS-2617'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/root/.pyenv/versions/3.8.7/lib/python3.8/threading.py", line 932, in _bootstrap_inner
    self.run()
  File "/root/.pyenv/versions/3.8.7/lib/python3.8/threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
  File "/root/.pyenv/versions/3.8.7/lib/python3.8/multiprocessing/pool.py", line 592, in _handle_results
    cache[job]._set(i, obj)
  File "/root/.pyenv/versions/3.8.7/lib/python3.8/multiprocessing/pool.py", line 776, in _set
    self._callback(self._value)
  File "/root/tools/BloodHound.py/bloodhound/enumeration/memberships.py", line 408, in process_acldata
    data['Aces'] += self.aceresolver.resolve_aces(aces)
  File "/root/tools/BloodHound.py/bloodhound/ad/utils.py", line 350, in resolve_aces
    ldapentry = self.resolver.resolve_sid(ace['sid'], use_gc)
  File "/root/tools/BloodHound.py/bloodhound/enumeration/objectresolver.py", line 132, in resolve_sid
    for entry in entries:
  File "/root/tools/BloodHound.py/bloodhound/ad/domain.py", line 156, in search
    for e in sresult:
  File "/root/.pyenv/versions/3.8.7/lib/python3.8/site-packages/ldap3/extend/standard/PagedSearch.py", line 56, in paged_search_generator
    result = connection.search(search_base,
  File "/root/.pyenv/versions/3.8.7/lib/python3.8/site-packages/ldap3/core/connection.py", line 838, in search
    request = search_operation(search_base,
  File "/root/.pyenv/versions/3.8.7/lib/python3.8/site-packages/ldap3/operation/search.py", line 371, in search_operation
    request['filter'] = compile_filter(parse_filter(search_filter, schema, auto_escape, auto_encode, validator, check_names).elements[0])  # parse the searchFilter string and compile it starting from the root node
  File "/root/.pyenv/versions/3.8.7/lib/python3.8/site-packages/ldap3/operation/search.py", line 290, in compile_filter
    matching_filter['assertionValue'] = AssertionValue(prepare_filter_for_sending(filter_node.assertion['value']))
  File "/root/.pyenv/versions/3.8.7/lib/python3.8/site-packages/ldap3/protocol/convert.py", line 205, in prepare_filter_for_sending
    return bytes(ints)
ValueError: bytes must be in range(0, 256)

This is a new one, never seen it. If I do NOT specify that I want to collect All,LoggedOn then it runs as expected

Thanks!

Improve multidomain support

Currently BloodHound.py only supports single domain data gathering.
This means that in multi-domain forests several relationships might be missed.

For multidomain support the following is required:

  • Establish a connection to the GC to query the whole forest for pincipals
  • Use the GC connection to establish which user a session belongs to based on the netbios name returned by netSessEnum
  • Establish connections to domains with a 2-way trust and map the foreignsecurityprincipals in the current domain/forest to users in the trusted forest

To do this all efficiently a SIDresolver worker should be added, which is put in between the enumeration and the write workers. This allows for resolving SIDs.
This will also involve a SID cache object (similar to the current DNS cache). If we use this cache more it will reduce the number of SID lookups made over SAMR.
Additionally the multi-domain support should rewrite the existing use of ADDomain objects so that the domains are properly mapped.

After all this is done a flag similar to SharpHound could be added to enable enumerating the entire forest.

Collection of containers

The new SharpHound collects Containers as well as GPLinks to them and ACEs on them.
This would be a nice addition to BloodHound.py!

Cheers

Return JSON results through function call

First, thanks for the tool!

Second, is there a easy place in the code to return a JSON object instead of having it write out to a file? Basically, I would like to call the bloodhound collector from my own code and get a JSON object. Something like this

def mytest():
results = bloodhound(params)
print results # JSON result here

Looks like the file is being created in outputworker.py and a couple others so I figured I can create JSON objects there, redirect it to a function and return the result?

I believe I can accomplish this but if you had any tips while I look over the code that would be great!

Thanks

dependency incompatibility

$ pip install .
...
Collecting MarkupSafe>=0.23 (from Jinja2>=2.10.1->flask>=1.0->impacket>=0.9.17->bloodhound==1.0.3)
  Downloading https://files.pythonhosted.org/packages/4b/20/f6d7648c81cb84815d0be935d5c74cd1cc0239e43eadb1a61062d34b6543/MarkupSafe-1.1.1-cp38-cp38-manylinux1_x86_64.whl
Collecting pycparser (from cffi!=1.11.3,>=1.8->cryptography>=2.8->pyOpenSSL>=0.13.1->impacket>=0.9.17->bloodhound==1.0.3)
  Downloading https://files.pythonhosted.org/packages/ae/e7/d9c3a176ca4b02024debf82342dab36efadfc5776f9c8db077e8f6e71821/pycparser-2.20-py2.py3-none-any.whl (112kB)
     |████████████████████████████████| 112kB 45.6MB/s 
ERROR: impacket 0.9.20 has requirement ldap3==2.5.1, but you'll have ldap3 2.7 which is incompatible.
Installing collected packages: bloodhound, pycryptodomex, pycparser, cffi, six, cryptography, pyOpenSSL, MarkupSafe, Jinja2, Werkzeug, click, itsdangerous
  Found existing installation: bloodhound 1.0.3
    Uninstalling bloodhound-1.0.3:
      Successfully uninstalled bloodhound-1.0.3
  Running setup.py install for bloodhound ... done
Successfully installed Jinja2-2.11.1 MarkupSafe-1.1.1 Werkzeug-1.0.0 bloodhound-1.0.3 cffi-1.14.0 click-7.1.1 cryptography-2.8 itsdangerous-1.1.0 pyOpenSSL-19.1.0 pycparser-2.20 pycryptodomex-3.9.7 six-1.14.0
Traceback (most recent call last):
  File "/tmp/BloodHound.py/venv/bin/pip", line 10, in <module>
    sys.exit(main())
  File "/tmp/BloodHound.py/venv/lib/python3.8/site-packages/pip/_internal/__init__.py", line 77, in main
    return command.main(cmd_args)
  File "/tmp/BloodHound.py/venv/lib/python3.8/site-packages/pip/_internal/cli/base_command.py", line 234, in main
    session = self._build_session(
  File "/tmp/BloodHound.py/venv/lib/python3.8/site-packages/pip/_internal/cli/base_command.py", line 101, in _build_session
    session = PipSession(
  File "/tmp/BloodHound.py/venv/lib/python3.8/site-packages/pip/_internal/download.py", line 559, in __init__
    self.headers["User-Agent"] = user_agent()
  File "/tmp/BloodHound.py/venv/lib/python3.8/site-packages/pip/_internal/download.py", line 170, in user_agent
    setuptools_version = get_installed_version("setuptools")
  File "/tmp/BloodHound.py/venv/lib/python3.8/site-packages/pip/_internal/utils/misc.py", line 1044, in get_installed_version
    working_set = pkg_resources.WorkingSet()
  File "/tmp/BloodHound.py/venv/lib/python3.8/site-packages/pip/_vendor/pkg_resources/__init__.py", line 567, in __init__
    self.add_entry(entry)
  File "/tmp/BloodHound.py/venv/lib/python3.8/site-packages/pip/_vendor/pkg_resources/__init__.py", line 623, in add_entry
    for dist in find_distributions(entry, True):
  File "/tmp/BloodHound.py/venv/lib/python3.8/site-packages/pip/_vendor/pkg_resources/__init__.py", line 1974, in find_eggs_in_zip
    if metadata.has_metadata('PKG-INFO'):
  File "/tmp/BloodHound.py/venv/lib/python3.8/site-packages/pip/_vendor/pkg_resources/__init__.py", line 1414, in has_metadata
    return self._has(path)
  File "/tmp/BloodHound.py/venv/lib/python3.8/site-packages/pip/_vendor/pkg_resources/__init__.py", line 1845, in _has
    return zip_path in self.zipinfo or zip_path in self._index()
  File "/tmp/BloodHound.py/venv/lib/python3.8/site-packages/pip/_vendor/pkg_resources/__init__.py", line 1722, in zipinfo
    return self._zip_manifests.load(self.loader.archive)
  File "/tmp/BloodHound.py/venv/lib/python3.8/site-packages/pip/_vendor/pkg_resources/__init__.py", line 1679, in load
    mtime = os.stat(path).st_mtime
FileNotFoundError: [Errno 2] No such file or directory: '/tmp/BloodHound.py/venv/lib/python3.8/site-packages/bloodhound-1.0.3-py3.8.egg'

git version efc8b57

Python 3.8.2

AttributeError

I installed bloodhound-python, using (the now obsolete) Python 2.7. It seems to work fast and with a nice low memory footprint, but during the group retrieval it crashes (possibly confidential information redacted):

$ uname -a
FreeBSD xxxxxxxx 12.1-RELEASE-p1 FreeBSD 12.1-RELEASE-p1 r356271 GENERIC amd64
$ bloodhound-python -u xxxxxxxx -p xxxxxxxx -d xxxxxxxx -gc gc._msdcs.xxxxxxxx
INFO: Found AD domain: xxxxxxxx
INFO: Connecting to LDAP server: xxxxxxxx
INFO: Found 1 domains
INFO: Found 2 domains in the forest
INFO: Found 100000 computers
INFO: Found 100000 users
INFO: Connecting to LDAP server: xxxxxxxx
INFO: Connecting to GC LDAP server: gc._msdcs.xxxxxxxx
INFO: Found 100000 groups
Traceback (most recent call last):
File "/usr/local/bin/bloodhound-python", line 8, in
sys.exit(main())
File "/usr/local/lib/python2.7/site-packages/bloodhound/init.py", line 286, in main
disable_pooling=args.disable_pooling)
File "/usr/local/lib/python2.7/site-packages/bloodhound/init.py", line 85, in run
trusts_enum.dump_domain(collect)
File "/usr/local/lib/python2.7/site-packages/bloodhound/enumeration/domains.py", line 119, in dump_domain
_, aces = parse_binary_acl(domain, 'domain', ADUtils.get_entry_property(domain_object, 'nTSecurityDescriptor'), self
.addc.objecttype_guid_map)
AttributeError: 'ADDC' object has no attribute 'objecttype_guid_map'

leaving me with a users.json and groups.json, but an empty domains.json. Is this a know problem? Or maybe the domain I used it on has something unusual in it?

Python3 support

Could you please support python3 as python2 is EOL in a few months?

impacket is not officially python3 compatible but an active python3.6 branch is available for testing, see fortra/impacket#61 (comment)

Python Error - "cannot import name cstruct"

When I first attempted to run it the error was related to dissect. I installed it using pip install dissect.

Now I am receiving the error "ImportError: cannot import name cstruct" Below is the error output

Traceback (most recent call last):
File "./bloodhound.py", line 3, in
import bloodhound
File "/opt/BloodHound.py/bloodhound/init.py", line 28, in
from bloodhound.enumeration.computers import ComputerEnumerator
File "/opt/BloodHound.py/bloodhound/enumeration/computers.py", line 30, in
from bloodhound.enumeration.memberships import MembershipEnumerator
File "/opt/BloodHound.py/bloodhound/enumeration/memberships.py", line 33, in
from bloodhound.enumeration.acls import AclEnumerator, parse_binary_acl
File "/opt/BloodHound.py/bloodhound/enumeration/acls.py", line 31, in
from dissect import cstruct
ImportError: cannot import name cstruct

Please help :(

membership_write_worker - corrupt data during an exception

I found out today that https://github.com/fox-it/BloodHound.py/blob/fd793b94d6e3a4238c5451ab76915bce59ae5ed0/bloodhound/enumeration/outputworker.py#L59 will write part of the user object to membership_out before throwing a TypeError. The partial object corrupts the whole JSON file.

Better to buffer to a string first before writing to the file?

--- a/bloodhound/enumeration/outputworker.py
+++ b/bloodhound/enumeration/outputworker.py
@@ -103,7 +103,8 @@ class OutputWorker(object):
             if num_members != 0:
                 membership_out.write(',')
             try:
-                json.dump(data, membership_out, indent=indent_level)
+                encoded_member = json.dumps(data, indent=indent_level)
+                membership_out.write(encoded_member)
             except TypeError:
                 logging.error('Data error {0}, could not convert data to json'.format(repr(data)))
                 membership_out.write('{}')

It looks like that pattern is used a few times in outputworker.py

Won't import

I installed bloodhound.py by using pip3 install bloodhound. Then I run bloodhound-python to generate a zip file. While uploading to bloodhound it won't import the files. (Stuck on Upload progress 0% for each file). Friend ran it from his Kali and I can import his zip file.

Updated every package in kali and reinstalled bloodhound and python-bloodhound. But not able to import the zip it generates. Any idea on what is causing the problem? I know you wont have much to go on, but maybe you know something.

Issue Running the script in Kali

Hello,

When I try to run the script i get the following issue below:

bloodhound-python

Traceback (most recent call last):
File "/usr/local/bin/bloodhound-python", line 11, in
load_entry_point('bloodhound==0.4.0', 'console_scripts', 'bloodhound-python')()
File "/usr/lib/python3/dist-packages/pkg_resources/init.py", line 476, in load_entry_point
return get_distribution(dist).load_entry_point(group, name)
File "/usr/lib/python3/dist-packages/pkg_resources/init.py", line 2700, in load_entry_point
return ep.load()
File "/usr/lib/python3/dist-packages/pkg_resources/init.py", line 2318, in load
return self.resolve()
File "/usr/lib/python3/dist-packages/pkg_resources/init.py", line 2324, in resolve
module = import(self.module_name, fromlist=['name'], level=0)
File "/usr/local/lib/python3.6/dist-packages/bloodhound/init.py", line 26, in
from impacket.ldap import ldapasn1
File "/usr/local/lib/python3.6/dist-packages/impacket/ldap/ldapasn1.py", line 578
def init(self, criticality=None, flags=0x00000007L, **kwargs):
^
SyntaxError: invalid syntax

Cross forest authentication support.

When attempting to authenticate across forest trusts, I'm getting the following output:

INFO: Found AD domain: acme.com
INFO: Connecting to LDAP server: acme.com
Traceback (most recent call last):
  File "./bloodhound.py", line 5, in <module>
    bloodhound.main()
  File "/root/james/BloodHound.py/bloodhound/__init__.py", line 286, in main
    disable_pooling=args.disable_pooling)
  File "/root/james/BloodHound.py/bloodhound/__init__.py", line 72, in run
    self.pdc.prefetch_info('objectprops' in collect, 'acl' in collect)
  File "/root/james/BloodHound.py/bloodhound/ad/domain.py", line 387, in prefetch_info
    self.get_objecttype()
  File "/root/james/BloodHound.py/bloodhound/ad/domain.py", line 216, in get_objecttype
    self.ldap_connect()
  File "/root/james/BloodHound.py/bloodhound/ad/domain.py", line 69, in ldap_connect
    baseDN=self.ad.baseDN, protocol=protocol)
  File "/root/james/BloodHound.py/bloodhound/ad/authentication.py", line 78, in getLDAPConnection
    if not conn.bind():
  File "/usr/lib/python2.7/dist-packages/ldap3/core/connection.py", line 570, in bind
    raise LDAPUnknownAuthenticationMethodError(self.last_error)
ldap3.core.exceptions.LDAPUnknownAuthenticationMethodError: NTLM needs domain\username and a password

I did note a previous issue where it's stated that this is not fully implemented:

#8

Is this still the case, or is there a way to get this working?

connects but throws an error NoneType object has no attribute 'sid'

I have tried specifying multiple user accounts but its still the same. Anyways I am passing with --hashes option! i have tried specifinyg password also and its same.

INFO: Found 0 domains
INFO: Found 1 domains in the forest
INFO: Found 0 computers
INFO: Found 0 users
Traceback (most recent call last):
  File "bloodhound.py", line 5, in <module>
    bloodhound.main()
  File "/home/xx/BloodHound.py/bloodhound/__init__.py", line 286, in main
    disable_pooling=args.disable_pooling)
  File "/home/xx/BloodHound.py/bloodhound/__init__.py", line 75, in run
    membership_enum.enumerate_memberships()
  File "/home/xx/BloodHound.py/bloodhound/enumeration/memberships.py", line 489, in enumerate_memberships
    self.enumerate_groups()
  File "/home/xx/BloodHound.py/bloodhound/enumeration/memberships.py", line 312, in enumerate_groups
    self.write_default_groups()
  File "/home/xx/BloodHound.py/bloodhound/enumeration/memberships.py", line 438, in write_default_groups
    domainsid = self.addomain.domain_object.sid
AttributeError: 'NoneType' object has no attribute 'sid'

Session Loop

Question: Is session loop on the road map similar to SharpHound? If not, would be a cool feature for the backlog.

I may or may not be placing this in the right place...

In bloodhound/enumeration/computers.py, around line 80..:

    logging.info('Starting computer enumeration with %d workers', num_workers)
    if len(computers) / num_workers > 500:
        logging.info('The workload seems to be rather large. Consider increasing the number of w....
    for _ in range(0, num_workers):
        ## Try to create session loop
        t_end = time.time() + 10 * 1
        while time.time() < t_end:
            print "[>] starting enumeration"
            t = threading.Thread(target=self.work, args=(q,result_q))
            t.daemon = True
            t.start()
            print "[+] done, waiting 3 seconds"
            time.sleep(3) ## Wait for 3 seconds
        print "------ [c] done with entire loop!"

Ive tried placing it in the work() function and deeper levels but it will loop over each computer for 10 seconds whereas I believe the Session Loop is supposed to loop over all the computers and then have a wait period, and then do it again.

I suppose I could just run the program with only Session Collection and put that in a loop...

LDAPNoSuchObjectResult Exception

Ran this tool with the following format:

root@box:/opt/BloodHound.py# bloodhound-python -u user -p pass -d domain -ns 192.168.1.100

After the recent update, this crash results:

INFO: Found AD domain: somedomain.com
INFO: Connecting to LDAP server: somedc.somedomain.com
INFO: Found 1 domains
INFO: Found 1 domains in the forest
INFO: Found 1384 computers
INFO: Found 973 groups
WARNING: Warning: Unknown primarygroupid 512
INFO: Connecting to GC LDAP server: somedc.somedomain.com
Traceback (most recent call last):
File "/usr/local/bin/bloodhound-python", line 11, in
load_entry_point('bloodhound==0.4.0', 'console_scripts', 'bloodhound-python')()
File "build/bdist.linux-x86_64/egg/bloodhound/init.py", line 194, in main
File "build/bdist.linux-x86_64/egg/bloodhound/init.py", line 68, in run
File "build/bdist.linux-x86_64/egg/bloodhound/enumeration/memberships.py", line 96, in enumerate_memberships
File "build/bdist.linux-x86_64/egg/bloodhound/enumeration/memberships.py", line 54, in write_membership
File "build/bdist.linux-x86_64/egg/bloodhound/enumeration/objectresolver.py", line 51, in resolve_group
File "build/bdist.linux-x86_64/egg/bloodhound/ad/domain.py", line 124, in ldap_get_single
File "/usr/local/lib/python2.7/dist-packages/ldap3/extend/init.py", line 125, in paged_search
paged_criticality)
File "/usr/local/lib/python2.7/dist-packages/ldap3/extend/standard/PagedSearch.py", line 121, in paged_search_accumulator
paged_criticality):
File "/usr/local/lib/python2.7/dist-packages/ldap3/extend/standard/PagedSearch.py", line 84, in paged_search_generator
raise LDAPOperationResult(result=result['result'], description=result['description'], dn=result['dn'], message=result['message'], response_type=result['type'])
ldap3.core.exceptions.LDAPNoSuchObjectResult: LDAPNoSuchObjectResult - 32 - noSuchObject - OU=Enterprise Admins,DC=somedomain,DC=com - 0000208D: NameErr: DSID-0315270B, problem 2001 (NO_OBJECT), data 0, best match of:
'OU=Enterprise Admins,DC=somedomain,DC=com'

  • searchResDone - None

Running v0.3.2 (May release) of this tool works fine.

Crash argument

Hey, great concept for a tool, going to be excellent doing this from kali with an ntlm hash.

However when i run it, it crashes due to one of the arguments being null? I can't see where the nonetype would be coming from.

# bloodhound-python -u admin -p password -d target.domain.com
INFO: Found AD domain: target.domain.com
INFO: Connecting to LDAP server: xxxxx-targetdc52.target.domain.com
INFO: Found 1 domains
Traceback (most recent call last):
  File "/usr/local/bin/bloodhound-python", line 11, in <module>
    sys.exit(main())
  File "/usr/local/lib/python2.7/dist-packages/bloodhound/__init__.py", line 172, in main
    bloodhound.run(skip_groups=args.skip_groups, skip_computers=args.skip_computers)
  File "/usr/local/lib/python2.7/dist-packages/bloodhound/__init__.py", line 63, in run
    self.dc.fetch_all()
  File "/usr/local/lib/python2.7/dist-packages/bloodhound/ad/domain.py", line 613, in fetch_all
    self.get_computers()
  File "/usr/local/lib/python2.7/dist-packages/bloodhound/ad/domain.py", line 461, in get_computers
    for entry in entries:
  File "/usr/local/lib/python2.7/dist-packages/bloodhound/ad/domain.py", line 368, in search
    for e in result:
  File "/usr/local/lib/python2.7/dist-packages/ldap3/extend/standard/PagedSearch.py", line 63, in paged_search_generator
    None if cookie is True else cookie)
  File "/usr/local/lib/python2.7/dist-packages/ldap3/core/connection.py", line 762, in search
    self.server.schema if self.server else None)
  File "/usr/local/lib/python2.7/dist-packages/ldap3/operation/search.py", line 370, in search_operation
    request['filter'] = compile_filter(parse_filter(search_filter, schema, auto_escape, auto_encode).elements[0])  # parse the searchFilter string and compile it starting from the root node
  File "/usr/local/lib/python2.7/dist-packages/ldap3/operation/search.py", line 230, in compile_filter
    boolean_filter[pos] = compile_filter(element)
  File "/usr/local/lib/python2.7/dist-packages/ldap3/operation/search.py", line 242, in compile_filter
    boolean_filter['innerNotFilter'] = compile_filter(filter_node.elements[0])
  File "/usr/local/lib/python2.7/dist-packages/ldap3/operation/search.py", line 267, in compile_filter
    matching_filter['dnAttributes'] = DnAttributes(filter_node.assertion['dnAttributes'])
  File "/usr/local/lib/python2.7/dist-packages/pyasn1/type/univ.py", line 103, in __init__
    base.AbstractSimpleAsn1Item.__init__(self, value, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/pyasn1/type/base.py", line 240, in __init__
    value = self.prettyIn(value)
  File "/usr/local/lib/python2.7/dist-packages/pyasn1/type/univ.py", line 254, in prettyIn
    return int(value)
TypeError: int() argument must be a string or a number, not 'NoneType'

Python 3

Is there any other guide on getting this to work with Python3 other than "To use it with python 3.x, use the latest impacket from GitHub."?

Syntax Error after installing with pip

Steps to reproduce:
Ubuntu 16.04

Python 2.7.15
pip installed, ldap3,dnspython,impacket all installed via pip

pip install bloodhound

Executing gives the following stacktrace:

Traceback (most recent call last):
  File "/usr/local/bin/bloodhound-python", line 11, in <module>
    load_entry_point('bloodhound==0.5.1', 'console_scripts', 'bloodhound-python')()
  File "/usr/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 480, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "/usr/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 2693, in load_entry_point
    return ep.load()
  File "/usr/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 2324, in load
    return self.resolve()
  File "/usr/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 2330, in resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
  File "build/bdist.linux-x86_64/egg/bloodhound/__init__.py", line 26, in <module>
  File "build/bdist.linux-x86_64/egg/bloodhound/ad/domain.py", line 28, in <module>
  File "/usr/local/lib/python2.7/dist-packages/dns/resolver.py", line 35, in <module>
    import dns.message
  File "/usr/local/lib/python2.7/dist-packages/dns/message.py", line 191
    print('id %d' % self.id, file=s)
                                 ^
SyntaxError: invalid syntax

ImportError: No module named parse

Traceback (most recent call last):
  File "/usr/local/bin/bloodhound-python", line 11, in <module>
    load_entry_point('bloodhound==1.0.4', 'console_scripts', 'bloodhound-python')()
  File "/usr/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 489, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "/usr/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 2852, in load_entry_point
    return ep.load()
  File "/usr/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 2443, in load
    return self.resolve()
  File "/usr/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 2449, in resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
  File "build/bdist.linux-x86_64/egg/bloodhound/__init__.py", line 26, in <module>
  File "build/bdist.linux-x86_64/egg/bloodhound/ad/domain.py", line 29, in <module>
  File "build/bdist.linux-x86_64/egg/dns/resolver.py", line 19, in <module>
ImportError: No module named parse

I am sure i've install parse successfully.

Python 3.8 compatibility

Hello ^^
I recently 'pip3 install bloodhound' and cloned, in Python 3.8, and I got this error message: 'TypeError: Missing required parameter 'digestmod'.'

Googling it I found this:
https://github.com/SecureAuthCorp/impacket/pull/711#issue-346729192

Maybe you need to add 'digestmod=hashlib.md5'?

Thank you in advanced for your time. :)

Complete error message:
Traceback (most recent call last):
File "bloodhound.py", line 5, in
bloodhound.main()
File "/home/kali/HacktheBoox/Pathfinder/bloodhound/bloodhound/init.py", line 284, in main
bloodhound.run(collect=collect,
File "/home/kali/HacktheBoox/Pathfinder/bloodhound/bloodhound/init.py", line 72, in run
self.pdc.prefetch_info('objectprops' in collect, 'acl' in collect)
File "/home/kali/HacktheBoox/Pathfinder/bloodhound/bloodhound/ad/domain.py", line 394, in prefetch_info
self.get_objecttype()
File "/home/kali/HacktheBoox/Pathfinder/bloodhound/bloodhound/ad/domain.py", line 224, in get_objecttype
self.ldap_connect()
File "/home/kali/HacktheBoox/Pathfinder/bloodhound/bloodhound/ad/domain.py", line 68, in ldap_connect
ldap = self.ad.auth.getLDAPConnection(hostname=ip,
File "/home/kali/HacktheBoox/Pathfinder/bloodhound/bloodhound/ad/authentication.py", line 78, in getLDAPConnection
if not conn.bind():
File "/usr/lib/python3/dist-packages/ldap3/core/connection.py", line 563, in bind
response = self.do_ntlm_bind(controls)
File "/usr/lib/python3/dist-packages/ldap3/core/connection.py", line 1302, in do_ntlm_bind
request = bind_operation(self.version, 'SICILY_RESPONSE_NTLM', ntlm_client, result['server_creds'])
File "/usr/lib/python3/dist-packages/ldap3/operation/bind.py", line 81, in bind_operation
server_creds = name.create_authenticate_message()
File "/usr/lib/python3/dist-packages/ldap3/utils/ntlm.py", line 379, in create_authenticate_message
nt_challenge_response = self.compute_nt_response()
File "/usr/lib/python3/dist-packages/ldap3/utils/ntlm.py", line 485, in compute_nt_response
response_key_nt = self.ntowf_v2()
File "/usr/lib/python3/dist-packages/ldap3/utils/ntlm.py", line 497, in ntowf_v2
return hmac.new(password_digest, (self.user_name.upper() + self.user_domain).encode('utf-16-le')).digest()
File "/usr/lib/python3.8/hmac.py", line 153, in new
return HMAC(key, msg, digestmod)
File "/usr/lib/python3.8/hmac.py", line 51, in init
raise TypeError("Missing required parameter 'digestmod'.")
TypeError: Missing required parameter 'digestmod'.

Python Ingestor errors

Hello,
I got the below error when i sused this syntax:
bloodhound-python -u vic -p password1 -ns 192.168.1.10 -d bank.local -dc dc1.bank.local -gc dc1.bank.local

INFO: Found AD domain: bank.local
INFO: Connecting to LDAP server: dc1.bank.local
INFO: Found 1 domains
INFO: Found 1 domains in the forest
INFO: Found 107 computers
Traceback (most recent call last):
  File "/usr/local/bin/bloodhound-python", line 11, in <module>
    load_entry_point('bloodhound==1.0.2', 'console_scripts', 'bloodhound-python')()
  File "build/bdist.linux-x86_64/egg/bloodhound/__init__.py", line 286, in main
  File "build/bdist.linux-x86_64/egg/bloodhound/__init__.py", line 75, in run
  File "build/bdist.linux-x86_64/egg/bloodhound/enumeration/memberships.py", line 487, in enumerate_memberships
  File "build/bdist.linux-x86_64/egg/bloodhound/enumeration/memberships.py", line 144, in enumerate_users
  File "build/bdist.linux-x86_64/egg/bloodhound/ad/domain.py", line 313, in get_users
TypeError: argument of type 'NoneType' is not iterable

bloodhound.py won't run whatever i do (upgrade issue?)

Hi,

At first, I've had some dns issues, which I've resolved.

Furthermore I've did an upgrade to the following.

pip install --upgrade domain-connect-dyndns pip install ldap3 pyasn1 --upgrade
But it may seem, that there is an issue in regards to impacket ldap3?
I'm not sure what to make of this.

Would you be so kind to help me out? I'm not really experienced with this tool.
I've also used python & python3. Output stay's the same.

I'm on kali 2020.1 and performed a git clone repo of yours. After that chmod 755 setup.py and pip install .

root@localhost:/opt/BloodHound.py# python3 bloodhound.py -c all -d EGOTISTICAL-BANK.LOCAL -gc EGOTISTICAL-BANK.LOCAL -dc SAUNA.EGOTISTICAL-BANK.LOCAL -u '' -p '' INFO: Connecting to LDAP server: SAUNA.EGOTISTICAL-BANK.LOCAL Traceback (most recent call last): File "bloodhound.py", line 5, in <module> bloodhound.main() File "/opt/BloodHound.py/bloodhound/__init__.py", line 286, in main disable_pooling=args.disable_pooling) File "/opt/BloodHound.py/bloodhound/__init__.py", line 72, in run self.pdc.prefetch_info('objectprops' in collect, 'acl' in collect) File "/opt/BloodHound.py/bloodhound/ad/domain.py", line 394, in prefetch_info self.get_objecttype() File "/opt/BloodHound.py/bloodhound/ad/domain.py", line 224, in get_objecttype self.ldap_connect() File "/opt/BloodHound.py/bloodhound/ad/domain.py", line 64, in ldap_connect q = self.ad.dnsresolver.query(self.hostname, tcp=self.ad.dns_tcp) File "/usr/lib/python3/dist-packages/dns/resolver.py", line 1002, in query raise NXDOMAIN(qnames=qnames_to_try, responses=nxdomain_responses) dns.resolver.NXDOMAIN: None of DNS query names exist: SAUNA.EGOTISTICAL-BANK.LOCAL., SAUNA.EGOTISTICAL-BANK.LOCAL.

root@localhost:/opt/BloodHound.py# ping SAUNA.EGOTISTICAL-BANK.LOCAL PING SAUNA.EGOTISTICAL-BANK.LOCAL (10.10.10.175) 56(84) bytes of data. 64 bytes from sauna.htb (10.10.10.175): icmp_seq=1 ttl=127 time=21.1 ms 64 bytes from sauna.htb (10.10.10.175): icmp_seq=2 ttl=127 time=23.6 ms

Format Timestamp error

Hi, when invoking bloodhound, I get the following error which appears to occur when converting timestamps gathered from the DC. Wondering if anyone else is experiencing similar issues..

[2019-06-29 18:20:19,687: ERROR/ForkPoolWorker-2] Task app.tasks.bloodhound_job[c0ff7df6-67a7-4ce3-9885-21caef11f661] raised unexpected: TypeError("unsupported operand type(s) for -: 'str' and 'datetime.datetime'",)
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/celery/app/trace.py", line 382, in trace_task
    R = retval = fun(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/celery/app/trace.py", line 641, in __protected_call__
    return self.run(*args, **kwargs)
  File "/home/app/tasks.py", line 40, in bloodhound_job
    disable_pooling=True,domain=domain,campaign_id=campaign_id)
  File "/home/app/bhcollector/bloodhound/__init__.py", line 73, in run
    self.pdc.prefetch_info('objectprops' in collect, 'acl' in collect)
  File "/home/app/bhcollector/bloodhound/ad/domain.py", line 327, in prefetch_info
    self.get_domains(acl=acls)
  File "/home/app/bhcollector/bloodhound/ad/domain.py", line 204, in get_domains
    for entry in entries:
  File "/home/app/bhcollector/bloodhound/ad/domain.py", line 134, in search
    for e in sresult:
  File "/usr/local/lib/python2.7/dist-packages/ldap3/extend/standard/PagedSearch.py", line 64, in paged_search_generator
    None if cookie is True else cookie)
  File "/usr/local/lib/python2.7/dist-packages/ldap3/core/connection.py", line 788, in search
    response = self.post_send_search(self.send('searchRequest', request, controls))
  File "/usr/local/lib/python2.7/dist-packages/ldap3/strategy/sync.py", line 139, in post_send_search
    responses, result = self.get_response(message_id)
  File "/usr/local/lib/python2.7/dist-packages/ldap3/strategy/base.py", line 325, in get_response
    responses = self._get_response(message_id)
  File "/usr/local/lib/python2.7/dist-packages/ldap3/strategy/sync.py", line 165, in _get_response
    dict_response = self.decode_response_fast(ldap_resp)
  File "/usr/local/lib/python2.7/dist-packages/ldap3/strategy/base.py", line 509, in decode_response_fast
    result = search_result_entry_response_to_dict_fast(ldap_message['payload'], self.connection.server.schema, self.connection.server.custom_formatter, self.connection.check_names)
  File "/usr/local/lib/python2.7/dist-packages/ldap3/operation/search.py", line 568, in search_result_entry_response_to_dict_fast
    entry_dict['attributes'] = checked_attributes_to_dict_fast(response[1][3], schema, custom_formatter)  # attributes
  File "/usr/local/lib/python2.7/dist-packages/ldap3/operation/search.py", line 453, in checked_attributes_to_dict_fast
    checked_attributes[name] = format_attribute_values(schema, name, decode_raw_vals_fast(attribute[3][1][3]) or [], custom_formatter)
  File "/usr/local/lib/python2.7/dist-packages/ldap3/protocol/formatters/standard.py", line 213, in format_attribute_values
    formatted_values = [formatter(raw_value) for raw_value in values]  # executes formatter
  File "/usr/local/lib/python2.7/dist-packages/ldap3/protocol/formatters/formatters.py", line 340, in format_ad_timedelta
    return format_ad_timestamp(raw_value * -1) - format_ad_timestamp(0)
TypeError: unsupported operand type(s) for -: 'str' and 'datetime.datetime'

The error appears to be happening with this function in /usr/local/lib/python2.7/dist-packages/ldap3/protocol/formatters/formatters.py

def format_ad_timedelta(raw_value):
    """  
    Convert a negative filetime value to a timedelta.
    """
    # Active Directory stores attributes like "minPwdAge" as a negative
    # "filetime" timestamp, which is the number of 100-nanosecond intervals that
    # have elapsed since the 0 hour on January 1, 1601. By making the number
    # positive, we can reuse format_ad_timestamp to get a datetime object.
    # Afterwards, we can subtract a datetime representing 0 hour on January 1,
    # 1601 from the returned datetime to get the timedelta.
    return format_ad_timestamp(raw_value * -1) - format_ad_timestamp(0)

This is the value that is passed into raw_value -18000000000 when an error occurs.

I would prefer not to wrap this in a try/except. Thank you for any help!

Investigate memory usage (caching vs memory optimization)

In large networks the memory usage can grow quite fast, creating trouble on drop devices such as raspberry Pis.
There are several caches in the code, which could probably be optimized.

Some things to look at:

  • Which cache grows fastest on larger networks
  • Can stuff be removed from the cache once it's likely no longer useful
  • Can the amount of detail in the cache be reduced
  • Are objects GC'd properly when not cached.

Missings ACEs

When working on a lab I noticed bloodhound-python is missing ACEs.
To compare, I used bloodhound ingestor from the official bloodhound repository. The 2 dumps were performed at the same time.

import json
with open("computers.json") as f:
     wrong = json.load(f)

with open("20210307143122_computers.json") as f:
     correct = json.load(f)

wrong['computers'][1]['Properties']['name']
'TEST.SUB.CORP.LOCAL'

correct['computers'][1]['Properties']['name']
'TEST.SUB.CORP.LOCAL'

len(wrong['computers'][1]['Aces'])
7
len(correct['computers'][1]['Aces'])
9

In this specific case, bloodhound is missing a critical ACE for domain user with Extended Rights :

        {
          "PrincipalSID": "S-1-5-21-1559563558-6653093943-1360247436-1103",
          "PrincipalType": "User",
          "RightName": "ExtendedRight",
          "AceType": "All",
          "IsInherited": false
        }

When running bloodhound-python I got no particular error except SID resolution (global catalog server not found) and nothing related to this user.

GPO based collection method

I saw under the limitations - https://github.com/fox-it/BloodHound.py#limitations - that GPO based collection methods are not supported. What are the blockers preventing these methods from being implemented? Just trying to get an idea of whether or not its worth forking the repo and implementing the solutions for the GPO based collection. My team and I are looking for ways to automate the BloodHound process and this seems to be the best solution so far though the limitations mentioned are serious blockers on our end.

KeyError: (0,12) crash

Any way I can help to debug this?

$ python bloodhound.py -d mydomain -v -u myuser -p mypass
[...]
INFO: Connecting to LDAP server: mydc.domain.com
DEBUG: Authenticating to LDAP server
INFO: Found 1 domains
Traceback (most recent call last):
File "bloodhound.py", line 5, in
bloodhound.main()
File "/Users/hubert/BloodHound.py/bloodhound/init.py", line 182, in main
bloodhound.run(skip_groups=args.skip_groups, skip_computers=args.skip_computers, skip_trusts=args.skip_trusts, num_workers=args.workers)
File "/Users/hubert/BloodHound.py/bloodhound/init.py", line 63, in run
self.dc.fetch_all()
File "/Users/hubert/BloodHound.py/bloodhound/ad/domain.py", line 619, in fetch_all
self.get_computers()
File "/Users/hubert/BloodHound.py/bloodhound/ad/domain.py", line 467, in get_computers
for entry in entries:
File "/Users/hubert/BloodHound.py/bloodhound/ad/domain.py", line 374, in search
for e in result:
File "/usr/local/lib/python2.7/site-packages/ldap3/extend/standard/PagedSearch.py", line 64, in paged_search_generator
None if cookie is True else cookie)
File "/usr/local/lib/python2.7/site-packages/ldap3/core/connection.py", line 775, in search
response = self.post_send_search(self.send('searchRequest', request, controls))
File "/usr/local/lib/python2.7/site-packages/ldap3/strategy/sync.py", line 142, in post_send_search
responses, result = self.get_response(message_id)
File "/usr/local/lib/python2.7/site-packages/ldap3/strategy/base.py", line 331, in get_response
responses = self._get_response(message_id)
File "/usr/local/lib/python2.7/site-packages/ldap3/strategy/sync.py", line 167, in _get_response
ldap_resp = decode_message_fast(response)
File "/usr/local/lib/python2.7/site-packages/ldap3/utils/asn1.py", line 104, in decode_message_fast
decoded = decode_sequence(message, ber_value_offset, ber_len + ber_value_offset, LDAP_MESSAGE_CONTEXT)
File "/usr/local/lib/python2.7/site-packages/ldap3/utils/asn1.py", line 124, in decode_sequence
value = ber_decoder(message, start, start + ber_len, context_decoders) # call value decode function
File "/usr/local/lib/python2.7/site-packages/ldap3/utils/asn1.py", line 124, in decode_sequence
value = ber_decoder(message, start, start + ber_len, context_decoders) # call value decode function
File "/usr/local/lib/python2.7/site-packages/ldap3/utils/asn1.py", line 124, in decode_sequence
value = ber_decoder(message, start, start + ber_len, context_decoders) # call value decode function
File "/usr/local/lib/python2.7/site-packages/ldap3/utils/asn1.py", line 120, in decode_sequence
ber_decoder = DECODERS[(ber_class, octet & 0b00011111)] if ber_class < 2 else None
KeyError: (0, 12)

several compilations give stacktraces.

Bloodhound-python: traces on a Rasperry Pi 3 1Gb mem running Kali GNU/Linux Rolling \n \l

On default collections only LocalAdmin and Session are working other collections from default give
stack traces.

DEBUG: Authentication: username/password
DEBUG: Resolved collection methods: localadmin, session, group, trusts
DEBUG: Using DNS to retrieve domain information
DEBUG: Querying domain controller information from DNS
DEBUG: Using domain hint:
INFO: Found AD domain:
DEBUG: Found primary DC:
DEBUG: Found Global Catalog server:
DEBUG: Found Global Catalog server:
DEBUG: Found Global Catalog server:
DEBUG: Found Global Catalog server:
DEBUG: Using LDAP server:
DEBUG: Using base DN:
INFO: Connecting to LDAP server:
DEBUG: Authenticating to LDAP server
INFO: Found 1 domains
INFO: Found 1 domains in the forest
INFO: Found 1577 computers
DEBUG: Writing users to file: users.json
Traceback (most recent call last):
File "/home/user/.local/bin/bloodhound-python", line 10, in
sys.exit(main())
File "/home/user/.local/lib/python2.7/site-packages/bloodhound/init.py", line 286, in main
disable_pooling=args.disable_pooling)
File "/home/user/.local/lib/python2.7/site-packages/bloodhound/init.py", line 75, in run
membership_enum.enumerate_memberships()
File "/home/user/.local/lib/python2.7/site-packages/bloodhound/enumeration/memberships.py", line 486, in enumerate_memberships
self.enumerate_users()
File "/home/user/.local/lib/python2.7/site-packages/bloodhound/enumeration/memberships.py", line 204, in enumerate_users
self.parse_gmsa(user, entry)
File "/home/user/.local/lib/python2.7/site-packages/bloodhound/enumeration/memberships.py", line 392, in parse_gmsa
_, aces = parse_binary_acl(user, 'user', ADUtils.get_entry_property(entry, 'msDS-GroupMSAMembership', raw=True), self.addc.objecttype_guid_map)
AttributeError: 'ADDC' object has no attribute ‘objecttype_guid_map’

Other not default collection errors:

For example ACL or DCOnly give stack traces.

Traceback (most recent call last):
File "/home/user/.local/bin/bloodhound-python", line 10, in
sys.exit(main())
File "/home/user/.local/lib/python2.7/site-packages/bloodhound/init.py", line 286, in main
disable_pooling=args.disable_pooling)
File "/home/user/.local/lib/python2.7/site-packages/bloodhound/init.py", line 72, in run
self.pdc.prefetch_info('objectprops' in collect, 'acl' in collect)
File "/home/user/.local/lib/python2.7/site-packages/bloodhound/ad/domain.py", line 385, in prefetch_info
self.get_computers(include_properties=props, acl=acls)
File "/home/user/.local/lib/python2.7/site-packages/bloodhound/ad/domain.py", line 352, in get_computers
for entry in entries:
File "/home/user/.local/lib/python2.7/site-packages/bloodhound/ad/domain.py", line 150, in search
for e in sresult:
File "/home/user/.local/lib/python2.7/site-packages/ldap3/extend/standard/PagedSearch.py", line 64, in paged_search_generator
None if cookie is True else cookie)
File "/home/user/.local/lib/python2.7/site-packages/ldap3/core/connection.py", line 765, in search
raise LDAPAttributeError('invalid attribute type ' + attribute_name_to_check)
ldap3.core.exceptions.LDAPAttributeError: invalid attribute type ms-mcs-admpwdexpirationtime

Also the computers.json is not parsed by bloodhound 3.0 on macOS Catalina 10.15.3 and Neo4j 3.5.14
dev-console error:

Uncaught (in promise) TypeError: Cannot read property 'flatMap' of undefined
at ov (bundle.js:116)
at a (bundle.js:116)
at Object.Xy [as computers] (bundle.js:116)
at bundle.js:116
at c (bundle.js:27)
at Generator._invoke (bundle.js:27)
at Generator.E.forEach.e. [as next] (bundle.js:27)
at gv (bundle.js:116)
at a (bundle.js:116)
at bundle.js:116
at new Promise ()
at t. (bundle.js:116)
at t. (bundle.js:116)
at t. (bundle.js:116)
at c (bundle.js:27)
at Generator._invoke (bundle.js:27)

Bloodhound-python does not work when LDAP signing is required

Bloodhound-python does not work when LDAP signing is required. Errors with debug mode can be found below.

I have verified that my installation of BloodHound.py works on a machine where LDAP signing is not enabled.

Let me know if there is anything you'd like me to clarify.

# bloodhound-python -u "validUser" --hashes "aad3b435b51404eeaad3b435b51404ee:validHash" -d corp.local -dc dc.corp.local -gc dc.corp.local -v
DEBUG: Authentication: NTLM hashes
DEBUG: Resolved collection methods: localadmin, session, group, trusts
DEBUG: Using DNS to retrieve domain information
DEBUG: Querying domain controller information from DNS
DEBUG: Using domain hint: corp.local
INFO: Found AD domain: corp.local
DEBUG: Found primary DC: dc.corp.local
DEBUG: Using LDAP server: dc.corp.local
DEBUG: Using base DN: DC=dc,DC=corp,DC=local
INFO: Connecting to LDAP server: dc.corp.local
DEBUG: Authenticating to LDAP server
WARNING: LDAP Authentication is refused because LDAP signing is enabled. Trying to connect over LDAPS instead...
DEBUG: Authenticating to LDAP server
Traceback (most recent call last):
  File "/usr/local/bin/bloodhound-python", line 11, in <module>
    load_entry_point('bloodhound==1.0.4', 'console_scripts', 'bloodhound-python')()
  File "build/bdist.linux-x86_64/egg/bloodhound/__init__.py", line 286, in main
  File "build/bdist.linux-x86_64/egg/bloodhound/__init__.py", line 72, in run
  File "build/bdist.linux-x86_64/egg/bloodhound/ad/domain.py", line 394, in prefetch_info
  File "build/bdist.linux-x86_64/egg/bloodhound/ad/domain.py", line 224, in get_objecttype
  File "build/bdist.linux-x86_64/egg/bloodhound/ad/domain.py", line 69, in ldap_connect
  File "build/bdist.linux-x86_64/egg/bloodhound/ad/authentication.py", line 83, in getLDAPConnection
  File "build/bdist.linux-x86_64/egg/bloodhound/ad/authentication.py", line 78, in getLDAPConnection
  File "/usr/local/lib/python2.7/dist-packages/ldap3/core/connection.py", line 524, in bind
    self.open(read_server_info=False)
  File "/usr/local/lib/python2.7/dist-packages/ldap3/strategy/sync.py", line 56, in open
    BaseStrategy.open(self, reset_usage, read_server_info)
  File "/usr/local/lib/python2.7/dist-packages/ldap3/strategy/base.py", line 147, in open
    raise LDAPSocketOpenError('unable to open socket', exception_history)
ldap3.core.exceptions.LDAPSocketOpenError: ('unable to open socket', [(LDAPSocketOpenError('socket ssl wrapping error: [SSL: UNSUPPORTED_PROTOCOL] unsupported protocol (_ssl.c:727)',), ('10.10.10.10', 636))])```

Strategy for multithreading

Hello there,

This tool looks promising but unfortunately it will only be usable on real domains only if it is fast enough, that is to say multithreaded.
Bloodhound devs went from PowerShell to C# for the ingestor (only) to allow fast data collection.

Do you already know what will be your strategy for multithreading ?
There are several possibilities with Python but it depends a lot on the version (and you depend on impacket 2.7 code):

  • 2+ asyncore builtin module is known to have some bugs/limitations
  • 2.7+ twisted is renowned
  • 3.2+ concurrent.futures is great, maybe the unofficial 2+ backport does the job ?
  • 3.6+ asyncio is shiny but 3.6+ only...

Cheers.

AttributeError: 'module' object has no attribute 'SimplePagedResultsControl'

# bloodhound-python -u USERNAME -p PASSWORD INFO: Found AD domain: domain.local INFO: Connecting to LDAP server: domain.local Traceback (most recent call last): File "/usr/local/bin/bloodhound-python", line 11, in <module> load_entry_point('bloodhound==0.1.0', 'console_scripts', 'bloodhound-python')() File "build/bdist.linux-x86_64/egg/bloodhound/__init__.py", line 176, in main File "build/bdist.linux-x86_64/egg/bloodhound/__init__.py", line 62, in run File "build/bdist.linux-x86_64/egg/bloodhound/ad.py", line 978, in fetch_all File "build/bdist.linux-x86_64/egg/bloodhound/ad.py", line 918, in get_rootobject File "build/bdist.linux-x86_64/egg/bloodhound/ad.py", line 767, in search AttributeError: 'module' object has no attribute 'SimplePagedResultsControl'

KeyError: 'objectSid'

Issue

bloodhound.py exits with "KeyError: 'objectSid'

Steps to reproduce

  • Executed setup.py install
  • Executed bloodhound.py with flags: -u, -p, -d, -v

Output

DEBUG: Authentication: username/password
DEBUG: Using DNS to retrieve domain information
DEBUG: Querying domain controller information from DNS
DEBUG: Using domain hint: <redacted>
INFO: Found AD domain: <redacted>
DEBUG: Found primary DC: <redacted>
DEBUG: Using LDAP server: <redacted>
DEBUG: Using base DN: DC=<redacted>,DC=<redacted>
INFO: Connecting to LDAP server: <redacted>
DEBUG: Connecting to <redacted>, port 389, SSL False
DEBUG: Authenticating to LDAP server
DEBUG: Found 1 domains
DEBUG: Found 10489 computers
DEBUG: Found 6733 groups
Traceback (most recent call last):
  File "./bloodhound.py", line 5, in <module>
    bloodhound.main()
  File "/tools/BloodHound.py-master/bloodhound/__init__.py", line 176, in main
    bloodhound.run(skip_groups=args.skip_groups, skip_computers=args.skip_computers)
  File "/tools/BloodHound.py-master/bloodhound/__init__.py", line 62, in run
    self.dc.fetch_all()
  File "/tools/BloodHound.py-master/bloodhound/ad.py", line 979, in fetch_all
    self.get_groups()
  File "/tools/BloodHound.py-master/bloodhound/ad.py", line 840, in get_groups
    gid = int(ADUtils.formatSid(entry['objectSid']).split('-')[-1])
KeyError: 'objectSid'

DNS Timeout Issue

First off, you guys are awesome and I love using this. This has helped me out alot when I get funky issues with SharpHound.

Recently on an OP I was completely remote and didn't have a system on site, but didn't have the ability to run SharpHound. I was using socks proxy to conduct my 3rd party toolset. Enter BloodHound.py.

I was able to get everything setup, but notice I wasn't getting dns resolution. After RTFM, I see that I can flip --dcp-tcp, which worked great, but kept getting a time out issue. I ended up modifying the domain.py and setting the timeout to 30 seconds, which allowed enough time for the resolve to happen and get back an answer.

Would it be possible to add a switch to the DNS timeout, in case I need to do this from the command line?

bloodhound py puts "." and ".localdomain" at the end of domain controller ip instead of using the domain name i specified

./bloodhound.py -c all -d htb.local -dc 10.10.10.161 -u #### -p #####
WARNING: Could not find a global catalog server. Please specify one with -gc
INFO: Connecting to LDAP server: 10.10.10.161
Traceback (most recent call last):
File "./bloodhound.py", line 5, in
bloodhound.main()
File "/root/htb/forest/BloodHound.py/bloodhound/init.py", line 265, in main
disable_pooling=args.disable_pooling)
File "/root/htb/forest/BloodHound.py/bloodhound/init.py", line 68, in run
self.pdc.prefetch_info('objectprops' in collect, 'acl' in collect)
File "/root/htb/forest/BloodHound.py/bloodhound/ad/domain.py", line 329, in prefetch_info
self.get_domains(acl=acls)
File "/root/htb/forest/BloodHound.py/bloodhound/ad/domain.py", line 203, in get_domains
for entry in entries:
File "/root/htb/forest/BloodHound.py/bloodhound/ad/domain.py", line 105, in search
self.ldap_connect()
File "/root/htb/forest/BloodHound.py/bloodhound/ad/domain.py", line 60, in ldap_connect
q = self.ad.dnsresolver.query(self.hostname, tcp=self.ad.dns_tcp)
File "/usr/lib/python2.7/dist-packages/dns/resolver.py", line 1002, in query
raise NXDOMAIN(qnames=qnames_to_try, responses=nxdomain_responses)
dns.resolver.NXDOMAIN: None of DNS query names exist: 10.10.10.161., 10.10.10.161.localdomain.

if i put a / at the end of the domain name it does consider but then it just times out after 3 seconds. all the prerequisites are fully updated and this persists on both python 2 and 3

LDAPSocketReceiveError (timeout config to 70sec)

Someone facing this issue?

My command was
bloodhound-python -u --hashes <>:<> -c all -d DOMAIN.COM --dns-tcp --dns-timeout 70 -ns DC.DOMAIN.COM -v

(I check the user and NTLM with Impact and its work great)

DEBUG: Authenticating to LDAP server

Traceback (most recent call last):
  File "c:\python27\lib\runpy.py", line 174, in _run_module_as_main
    "__main__", fname, loader, pkg_name)
  File "c:\python27\lib\runpy.py", line 72, in _run_code
    exec code in run_globals
  File "C:\Python27\Scripts\bloodhound-python.exe\__main__.py", line 7, in <module>
  File "c:\python27\lib\site-packages\bloodhound\__init__.py", line 300, in main
    timestamp=timestamp)
  File "c:\python27\lib\site-packages\bloodhound\__init__.py", line 73, in run
    self.pdc.prefetch_info('objectprops' in collect, 'acl' in collect)
  File "c:\python27\lib\site-packages\bloodhound\ad\domain.py", line 393, in prefetch_info
    self.get_objecttype()
  File "c:\python27\lib\site-packages\bloodhound\ad\domain.py", line 223, in get_objecttype
    self.ldap_connect()
  File "c:\python27\lib\site-packages\bloodhound\ad\domain.py", line 69, in ldap_connect
    baseDN=self.ad.baseDN, protocol=protocol)
  File "c:\python27\lib\site-packages\bloodhound\ad\authentication.py", line 78, in getLDAPConnection
    if not conn.bind():
  File "c:\python27\lib\site-packages\ldap3\core\connection.py", line 671, in bind
    self.refresh_server_info()
  File "c:\python27\lib\site-packages\ldap3\core\connection.py", line 1427, in refresh_server_info
    self.server.get_info_from_server(self)
  File "c:\python27\lib\site-packages\ldap3\core\server.py", line 525, in get_info_from_server
    self._get_schema_info(connection)
  File "c:\python27\lib\site-packages\ldap3\core\server.py", line 489, in _get_schema_info
    get_operational_attributes=True
  File "c:\python27\lib\site-packages\ldap3\core\connection.py", line 853, in search
    response = self.post_send_search(self.send('searchRequest', request, controls))
  File "c:\python27\lib\site-packages\ldap3\strategy\sync.py", line 178, in post_send_search
    responses, result = self.get_response(message_id)
  File "c:\python27\lib\site-packages\ldap3\strategy\base.py", line 355, in get_response
    responses = self._get_response(message_id, timeout)
  File "c:\python27\lib\site-packages\ldap3\strategy\sync.py", line 196, in _get_response
    responses = self.receiving()
  File "c:\python27\lib\site-packages\ldap3\strategy\sync.py", line 99, in receiving
    raise communication_exception_factory(LDAPSocketReceiveError, type(e)(str(e)))(self.connection.last_error)
ldap3.core.exceptions.LDAPSocketReceiveError: error receiving data: timed out

Key Error in get_membership (v0.7.0)

I got this error (some infos redacted):

INFO: Found 64291 users
WARNING: Could not resolve SID: S-1-5-21-XXXXXXXXXXXXXXXXX-44658
...
Traceback (most recent call last):
  File "/home/avollmer/.local/lib/python3.7/site-packages/bloodhound/enumeration/memberships.py", line 57, in get_membership
    resolved_entry = self.addomain.users[member]
KeyError: 'CN=RTCComponentUniversalServices,CN=Users,DC=root,DC=XXXXXX,DC=de'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/avollmer/.local/lib/python3.7/site-packages/bloodhound/enumeration/memberships.py", line 61, in get_membership
    resolved_entry = self.addomain.groups[member]
KeyError: 'CN=RTCComponentUniversalServices,CN=Users,DC=root,DC=XXXXX,DC=de'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/avollmer/.local/lib/python3.7/site-packages/bloodhound/enumeration/memberships.py", line 65, in get_membership
    entry = self.addomain.computers[member]
KeyError: 'CN=RTCComponentUniversalServices,CN=Users,DC=root,DC=XXXXX,DC=de'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/ldap3/strategy/base.py", line 823, in sending
    self.connection.socket.sendall(encoded_message)
ConnectionResetError: [Errno 104] Connection reset by peer

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/avollmer/.local/bin/bloodhound-python", line 10, in <module>
    sys.exit(main())
  File "/home/avollmer/.local/lib/python3.7/site-packages/bloodhound/__init__.py", line 265, in main
    disable_pooling=args.disable_pooling)
  File "/home/avollmer/.local/lib/python3.7/site-packages/bloodhound/__init__.py", line 71, in run
    membership_enum.enumerate_memberships()
  File "/home/avollmer/.local/lib/python3.7/site-packages/bloodhound/enumeration/memberships.py", line 294, in enumerate_memberships
    self.enumerate_groups()
  File "/home/avollmer/.local/lib/python3.7/site-packages/bloodhound/enumeration/memberships.py", line 255, in enumerate_groups
    resolved_member = self.get_membership(member)
  File "/home/avollmer/.local/lib/python3.7/site-packages/bloodhound/enumeration/memberships.py", line 70, in get_membership
    qobject = self.addomain.objectresolver.resolve_distinguishedname(member, use_gc=use_gc)
  File "/home/avollmer/.local/lib/python3.7/site-packages/bloodhound/enumeration/objectresolver.py", line 58, in resolve_distinguishedname
    distinguishedname = self.addc.ldap_get_single(distinguishedname, use_gc=use_gc, use_resolver=True)
  File "/home/avollmer/.local/lib/python3.7/site-packages/bloodhound/ad/domain.py", line 163, in ldap_get_single
    generator=False)
  File "/usr/lib/python3/dist-packages/ldap3/extend/__init__.py", line 125, in paged_search
    paged_criticality)
  File "/usr/lib/python3/dist-packages/ldap3/extend/standard/PagedSearch.py", line 121, in paged_search_accumulator
    paged_criticality):
  File "/usr/lib/python3/dist-packages/ldap3/extend/standard/PagedSearch.py", line 64, in paged_search_generator
    None if cookie is True else cookie)
  File "/usr/lib/python3/dist-packages/ldap3/core/connection.py", line 782, in search
    response = self.post_send_search(self.send('searchRequest', request, controls))
  File "/usr/lib/python3/dist-packages/ldap3/strategy/base.py", line 299, in send
    self.sending(ldap_message)
  File "/usr/lib/python3/dist-packages/ldap3/strategy/base.py", line 834, in sending
    raise communication_exception_factory(LDAPSocketSendError, type(e)(str(e)))(self.connection.last_error)
ldap3.core.exceptions.LDAPSocketSendError: socket sending error[Errno 104] Connection reset by peer

This appears to have fixed it, but I'm not sure if this is a proper solution:

--- /home/avollmer/.local/lib/python3.7/site-packages/bloodhound/enumeration/memberships.py	2020-04-06 16:36:59.196000000 +0200
+++ memberships.py	2020-04-06 17:25:08.540000000 +0200
@@ -252,10 +252,7 @@
                 group['Properties']['description'] = ADUtils.get_entry_property(entry, 'description')
 
             for member in entry['attributes']['member']:
-                try:
-                    resolved_member = self.get_membership(member)
-                except KeyError:
-                    resolved_member = None
+                resolved_member = self.get_membership(member)
                 if resolved_member:
                     group['Members'].append(resolved_member)

Rust and Cryptography module

As mentioned here, many-musl release build on PyPI wheel to support alpine is still on the way. In the meanwhile should I disable Rust build? This breaks on the current docker build.

Bloodhound fails to import groups.json

Using the Bloodhound 4.0.2 I get the following error when importing groups.json:
"File created from incompatible collector"

users.json, computers.json and domains.json imports fine. Anyone knows what might be the problem?

TypeError: cannot convert 'NoneType' object to bytes

I'm trying to test out the script, but I get a stack trace and am at a bit of a dead end. Am I missing something here or is this just a bug?

./bloodhound.py -u username -dc HOSTNAME -ns 127.0.0.1
Password: 
WARNING: Could not find a global catalog server. Please specify one with -gc
INFO: Connecting to LDAP server: HOSTNAME
Traceback (most recent call last):
  File "./bloodhound.py", line 5, in <module>
    bloodhound.main()
  File "/home/aaron/BloodHound.py/bloodhound/__init__.py", line 275, in main
    disable_pooling=args.disable_pooling)
  File "/home/aaron/BloodHound.py/bloodhound/__init__.py", line 68, in run
    self.pdc.prefetch_info('objectprops' in collect, 'acl' in collect)
  File "/home/aaron/BloodHound.py/bloodhound/ad/domain.py", line 329, in prefetch_info
    self.get_domains(acl=acls)
  File "/home/aaron/BloodHound.py/bloodhound/ad/domain.py", line 203, in get_domains
    for entry in entries:
  File "/home/aaron/BloodHound.py/bloodhound/ad/domain.py", line 133, in search
    for e in sresult:
  File "/home/aaron/.local/lib/python3.7/site-packages/ldap3/extend/standard/PagedSearch.py", line 64, in paged_search_generator
    None if cookie is True else cookie)
  File "/home/aaron/.local/lib/python3.7/site-packages/ldap3/core/connection.py", line 779, in search
    check_names=self.check_names)
  File "/home/aaron/.local/lib/python3.7/site-packages/ldap3/operation/search.py", line 347, in search_operation
    request['baseObject'] = LDAPDN(search_base)
  File "/usr/lib/python3.7/site-packages/pyasn1/type/univ.py", line 829, in __init__
    base.SimpleAsn1Type.__init__(self, value, **kwargs)
  File "/usr/lib/python3.7/site-packages/pyasn1/type/base.py", line 267, in __init__
    value = self.prettyIn(value)
  File "/usr/lib/python3.7/site-packages/pyasn1/type/univ.py", line 904, in prettyIn
    return bytes(value)
TypeError: cannot convert 'NoneType' object to bytes

collecting sessions for a longer time

Hello.
Bloodhound.py collect sessions quick. Instead, it is more efficient to collect sessions for a longer time, but also only from specified targets (DC).

netview.py corp/user -target dc01.corp.local > sessions.txt
netview.py corp/user -target dc02.corp.local >> sessions.txt
netview.py corp/user -target dc03.corp.local >> sessions.txt

After a few hours I collect thousand sessions. But bloodhound.py collects far less.
I implemented import netview.py results to computers.json, but it seems to me a bit ugly.
May be it need to implement some addition option for bloodhound.py for long time collecting sessions only for specified hosts?

AttributeError: 'NoneType' object has no attribute 'sid'

When running bloodhound.py I got the following error:

INFO: Found 0 domains
INFO: Found 1 domains in the forest
INFO: Found 0 computers
INFO: Found 0 users
Traceback (most recent call last):
  File "/usr/local/bin/bloodhound-python", line 10, in <module>
    sys.exit(main())
  File "/home/pwnie/.local/lib/python2.7/site-packages/bloodhound/__init__.py", line 286, in main
    disable_pooling=args.disable_pooling)
  File "/home/pwnie/.local/lib/python2.7/site-packages/bloodhound/__init__.py", line 75, in run
    membership_enum.enumerate_memberships()
  File "/home/pwnie/.local/lib/python2.7/site-packages/bloodhound/enumeration/memberships.py", line 488, in enumerate_memberships
    self.enumerate_groups()
  File "/home/pwnie/.local/lib/python2.7/site-packages/bloodhound/enumeration/memberships.py", line 311, in enumerate_groups
    self.write_default_groups()
  File "/home/pwnie/.local/lib/python2.7/site-packages/bloodhound/enumeration/memberships.py", line 437, in write_default_groups
    domainsid = self.addomain.domain_object.sid
AttributeError: 'NoneType' object has no attribute 'sid'

I verified with crackmapexe that the credentials were valid and they are working.

Got this issue with cloning from github and via pip install. Any idea why this is happening?

Dies with "KeyError: 'distinguishedname'"

I'm trying to extract info from the domain, but it dies part way through (leaving corrupt users and groups files) with the above error.

DEBUG: Querying resolver LDAP for DN CN=Server Application Service Accounts,OU=Admin Roles,OU=Corp Resources,DC=example,DC=com
Traceback (most recent call last):
  File "/usr/local/bin/bloodhound-python", line 11, in <module>
    sys.exit(main())
  File "/usr/local/lib/python2.7/dist-packages/bloodhound/__init__.py", line 258, in main
    num_workers=args.workers)
  File "/usr/local/lib/python2.7/dist-packages/bloodhound/__init__.py", line 70, in run
    membership_enum.enumerate_memberships()
  File "/usr/local/lib/python2.7/dist-packages/bloodhound/enumeration/memberships.py", line 214, in enumerate_memberships
    self.enumerate_groups()
  File "/usr/local/lib/python2.7/dist-packages/bloodhound/enumeration/memberships.py", line 197, in enumerate_groups
    resolved_member = self.get_membership(member)
  File "/usr/local/lib/python2.7/dist-packages/bloodhound/enumeration/memberships.py", line 63, in get_membership
    resolved_entry = ADUtils.resolve_ad_entry(qobject)
  File "/usr/local/lib/python2.7/dist-packages/bloodhound/ad/utils.py", line 180, in resolve_ad_entry
    if entry['attributes']['distinguishedName']:
  File "/usr/local/lib/python2.7/dist-packages/ldap3/utils/ciDict.py", line 68, in __getitem__
    return self._store[self._case_insensitive_keymap[self._ci_key(key)]]
KeyError: 'distinguishedname'

Any suggestions?

Running BloodHound.py

I get this error message when trying to run BloodHound.py on my virtual network:

C:\Users\alice\Downloads\BloodHound.py-master\BloodHound.py-master>bloodhound-python
Traceback (most recent call last):
File "c:\users\alice\appdata\local\programs\python\python37\lib\runpy.py", line 193, in run_module_as_main
"main", mod_spec)
File "c:\users\alice\appdata\local\programs\python\python37\lib\runpy.py", line 85, in run_code
exec(code, run_globals)
File "C:\Users\alice\AppData\Local\Programs\Python\Python37\Scripts\bloodhound-python.exe_main
.py", line 5, in
File "c:\users\alice\appdata\local\programs\python\python37\lib\site-packages\bloodhound_init
.py", line 26, in
from bloodhound.ad.domain import AD, ADDC
File "c:\users\alice\appdata\local\programs\python\python37\lib\site-packages\bloodhound\ad\domain.py", line 33, in
from bloodhound.ad.computer import ADComputer
File "c:\users\alice\appdata\local\programs\python\python37\lib\site-packages\bloodhound\ad\computer.py", line 27, in
from impacket.dcerpc.v5 import transport, samr, srvs, lsat, lsad, nrpc, wkst
File "c:\users\alice\appdata\local\programs\python\python37\lib\site-packages\impacket\dcerpc\v5\transport.py", line 141
raise RuntimeError, 'virtual function'
^
SyntaxError: invalid syntax

Error: ObjectProps => "could not convert data to json"

I've got an issue with BloodHound.py.
When reading the ObjectProps, I get an convert / writing error.

python3 bloodhound.py -u <user> -p <pass> -d <domain>  -ns <DNS> -dc <DC> -c ObjectProps -v

DEBUG: Writing users to file: 20210727111744_users.json
ERROR: Data error {'AllowedToDelegate': [], 'ObjectIdentifier': 'S-1-5-21-xxxxxxxxx-yyyyyyyyy-zzzzzzzzz-5329', 'PrimaryGroupSid': 'S-1-5-21-xxxxxxxxx-yyyyyyyyy-zzzzzzzzz-513', 'Properties': {'name': '<USER>@DOMAIN.LOCAL', 'domain': 'DOMAIN.LOCAL', 'objectid': 'S-1-5-21-xxxxxxxxx-yyyyyyyyy-zzzzzzzzz-5329', 'distinguishedname': 'CN=User Name,OU=Users,DC=Domain,DC=Local', 'highvalue': False, 'unconstraineddelegation': False, 'passwordnotreqd': False, 'enabled': True, 'lastlogon': 1620219195, 'lastlogontimestamp': 1619446043, 'pwdlastset': 1620219195, 'dontreqpreauth': False, 'pwdneverexpires': True, 'sensitive': False, 'serviceprincipalnames': [], 'hasspn': False, 'displayname': 'User' Name, 'email': '[email protected]', 'title': None, 'homedirectory': None, 'description': 'For Testing', 'userpassword': b'{SHA}<base64_hash>', 'admincount': False, 'sidhistory': []}, 'Aces': [], 'SPNTargets': [], 'HasSIDHistory': []}, could not convert data to json

The Domain Controller is Windows Server 2016 in Polish.

Can't connect with LDAP Signing / Channel Binding enabled

Since I've enabled LDAP Signing on our Domain Controllers I'm no longer able to run bloodhound.py

python3 bloodhound.py -u [email protected] -d domain.local -c all -v
Password:
DEBUG: Resolved collection methods: acl, group, session, localadmin, psremote, rdp, dcom, objectprops, trusts
DEBUG: Using DNS to retrieve domain information
DEBUG: Querying domain controller information from DNS
DEBUG: Using domain hint: domain.local
INFO: Found AD domain: domain.local
DEBUG: Found primary DC: dc01.domain.local
DEBUG: Found Global Catalog server: dc01.domain.local
DEBUG: Using LDAP server: dc01.domain.local
DEBUG: Using base DN: DC=domain,DC=local
INFO: Connecting to LDAP server: dc01.domain.local
DEBUG: Authenticating to LDAP server
WARNING: LDAP Authentication is refused because LDAP signing is enabled. Trying to connect over LDAPS instead...
DEBUG: Authenticating to LDAP server
ERROR: Failure to authenticate with LDAP! Error 80090346: LdapErr: DSID-0C09069E, comment: AcceptSecurityContext error, data 80090346, v2580
Traceback (most recent call last):
File "/root/Documents/tools/BloodHound.py/bloodhound.py", line 5, in
bloodhound.main()
File "/root/Documents/tools/BloodHound.py/bloodhound/init.py", line 284, in main
bloodhound.run(collect=collect,
File "/root/Documents/tools/BloodHound.py/bloodhound/init.py", line 72, in run
self.pdc.prefetch_info('objectprops' in collect, 'acl' in collect)
File "/root/Documents/tools/BloodHound.py/bloodhound/ad/domain.py", line 394, in prefetch_info
self.get_objecttype()
File "/root/Documents/tools/BloodHound.py/bloodhound/ad/domain.py", line 226, in get_objecttype
sresult = self.ldap.extend.standard.paged_search(self.ldap.server.info.other['schemaNamingContext'][0],
AttributeError: 'NoneType' object has no attribute 'extend'

Does anyone else have this issue too?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.