Exemple #1
0
def group(self, domain):
    """
    Generate statistics for Active Directory groups, such as average group membership.
    """
    print(
        green("[+] Group Module Selected: Crunching group membership data..."))
    neo4j_driver = setup_database_conn()
    domain_metrics = domains.DomainData(neo4j_driver)
    group_metrics = groups.GroupMetrics(neo4j_driver)
    users_metrics = users.UserMetrics(neo4j_driver)

    if domain:
        all_domains = [domain]
    else:
        all_domains = domain_metrics.get_all_domains()

    for domain in all_domains:
        # We may get a 'None' domain if the label is missing in BloodHound
        if domain:
            print(green("[*] Domain: %s" % domain))

            avg_membership_nonrecur = group_metrics.get_avg_group_membership(
                domain)
            avg_membership_recur = group_metrics.get_avg_group_membership(
                domain, True)
            admin_groups = group_metrics.find_admin_groups(domain)
            local_admin = group_metrics.find_local_admin_groups(domain)
            foreign_groups = group_metrics.find_foreign_group_membership(
                domain)

            print(
                green("L.. Average group membership:\t\t\t%s" %
                      avg_membership_nonrecur))
            print(
                green("L.. Average recursive group membership:\t\t%s" %
                      avg_membership_recur))
            print(
                green("L.. Nested groups increased membership by:\t%s" %
                      float(avg_membership_recur - avg_membership_nonrecur)))
            print(green("L.. Admin groups:"))
            for group in admin_groups:
                print(yellow("\t%s" % group))
            print(green("L.. Non-Admin groups with Local Admin:"))
            for group in local_admin:
                print(yellow("\t%s" % group))
            print(green("L.. Groups with foregin group membership:"))
            for group, foreign_group in foreign_groups.items():
                print(yellow("\t%s -> %s" % (group, foreign_group)))
Exemple #2
0
def domain(self, domain):
    """
    Generate information and statistics for domains in the dataset.
    """
    print(
        green("[+] Domain Module Selected: Crunching domain-related data..."))
    neo4j_driver = setup_database_conn()
    domain_metrics = domains.DomainData(neo4j_driver)
    group_metrics = groups.GroupMetrics(neo4j_driver)
    users_metrics = users.UserMetrics(neo4j_driver)

    if domain:
        all_domains = [domain]
    else:
        all_domains = domain_metrics.get_all_domains()

    for domain in all_domains:
        # We may get a 'None' domain if the label is missing in BloodHound
        if domain:
            print(green("\n[+] Domain: %s" % domain))

            operating_systems = domain_metrics.get_operating_systems(domain)
            gpo_list = domain_metrics.get_all_gpos(domain)
            da_sessions = domain_metrics.get_systems_with_da(domain)

            print(green("L.. Number of GPOs:\t%s" % len(gpo_list)))
            print(
                green(
                    "L.. Systems that are not Domain Controllers with Domain Admin sessions:"
                ))
            if da_sessions:
                for session in da_sessions:
                    print(yellow("\t%s" % session))
            else:
                print(yellow("\tNone! :D"))
            print(green("L.. Operating Systems seen in domain:"))
            for op_sys, count in operating_systems.items():
                print(yellow("\t%s\t%s" % (count, op_sys)))
Exemple #3
0
Fichier : fox.py Projet : l0ss/Fox
def fox(domain, pass_age):
    """
    Welcome to Fox! Before using Fox, start your Neo4j project containing your
    BloodHound data. Please review the README for details for the modules and queries.\n
    Let's crunch some BloodHound data!
    """
    click.clear()
    print(green("""
  █████▒▒█████  ▒██   ██▒
▓██   ▒▒██▒  ██▒▒▒ █ █ ▒░
▒████ ░▒██░  ██▒░░  █   ░
░▓█▒  ░▒██   ██░ ░ █ █ ▒ 
░▒█░   ░ ████▓▒░▒██▒ ▒██▒
 ▒ ░   ░ ▒░▒░▒░ ▒▒ ░ ░▓ ░
 ░       ░ ▒ ▒░ ░░   ░▒ ░
 ░ ░   ░ ░ ░ ▒   ░    ░  
           ░ ░   ░    ░  
\t\t  v.0.2
    """))

    # Setup the DB connection and metrics objects
    neo4j_driver = helpers.setup_database_conn()
    domain_metrics = domains.DomainData(neo4j_driver)
    group_metrics = groups.GroupMetrics(neo4j_driver)
    users_metrics = users.UserMetrics(neo4j_driver)
    all_domains = helpers.prepare_domains_list(domain_metrics, domain)
    # A few variables we need for tracking some numbers across domains
    super_total_users = 0
    super_total_enabled_users = 0
    super_total_computers = 0
    
    for domain in all_domains:
        # We may get a 'None' domain if the label is missing in BloodHound
        if domain:
            # Neo4j will expect domain names to match what it has in the database, so must be all uppercase
            domain = domain.upper()
            print(green("\n[+] Domain: %s" % domain))

            # Collect session info
            print(green("[+] Collecting session data..."))
            da_sessions = domain_metrics.get_systems_with_da(domain)
            
            # Calculations for group membership
            print(green("[+] Collecting group membership information..."))
            avg_membership_nonrecur = group_metrics.get_avg_group_membership(domain)
            avg_membership_recur = group_metrics.get_avg_group_membership(domain, True)
            dadmins, eadmins, admins = group_metrics.get_admin_groups(domain)
            admin_groups = group_metrics.find_admin_groups(domain)
            local_admin = group_metrics.find_local_admin_groups(domain)
            rdp_users = group_metrics.find_remote_desktop_users(domain)
            foreign_groups = group_metrics.find_foreign_group_membership(domain)
            
            # Collect user object info
            print(green("[+] Collecting user and computer object information..."))
            total_users = users_metrics.get_total_users(domain)
            total_enabled_users = users_metrics.get_total_users(domain, True)
            total_computers = users_metrics.get_total_computers(domain)
            unc_deleg_computers = users_metrics.find_unconstrained_delegation(domain)
            
            # Calculations for user objects
            super_total_users += total_users
            super_total_enabled_users += total_enabled_users
            super_total_computers = super_total_computers + total_computers
            
            # Path to DA calculations
            print(green("[+] Calculating paths to Domain Admin and averages -- this can take \
some time..."))
            total_paths = domain_metrics.get_all_da_paths(domain)
            #avg_path = domain_metrics.avg_path_length(domain)
            try:
                percentage_users_path_to_da = 100.0 * (total_paths/total_users)
            except:
                percentage_users_path_to_da = 0
            try:
                percentage_comps_path_to_da = 100.0 * (total_paths/total_computers)
            except:
                percentage_comps_path_to_da = 0

            # Other statistics and data
            print(green("[+] Querying some additional interesting data... nearly done..."))
            gpo_list = domain_metrics.get_all_gpos(domain)
            operating_systems = domain_metrics.get_operating_systems(domain)
            old_passwords = users_metrics.find_old_pwdlastset(domain, pass_age)
            special_users = users_metrics.find_special_users(domain)
            da_spn = users_metrics.find_da_spn(domain)
            foreign_groups = users_metrics.find_foreign_group_membership(domain)
            blocker_ous = domain_metrics.find_blocked_inheritance(domain)

            # Review the data to see if we can detect any missing labels/data and try to name
            # CollectionMethod types that are missing from the database
            warning_count = 0
            print(yellow("\n[!] WARNINGS for %s:" % domain))
            if len(gpo_list) == 0:
                warning_count += 1
                print(yellow("[*] There are zero GPOs for this domain!"))
                print(yellow("L.. Missing CollectionMethod: GPO"))
            if total_enabled_users == 0:
                warning_count += 1
                print(yellow("[*] There are no user objects with the Enabled attribute!"))
                print(yellow("L.. Missing CollectionMethod: ObjectProps"))
            if not operating_systems:
                warning_count += 1
                print(yellow("[*] There are no computer objects with the operating system attribute!"))
                print(yellow("L.. Missing CollectionMethod: ObjectProps"))
            if not avg_membership_nonrecur:
                warning_count += 1
                print(red("[X] Cannot pull group membership data!"))
                print(red("L.. Data for this domain is too incomplete and will be skipped."))
                continue
            if warning_count == 0:
                print(green("\tNone! BloodHound data looks good!\n"))

            # Report domain-related data
            if len(gpo_list) > 0:
                print(green("Number of GPOs:\t%s" % len(gpo_list)))
            if blocker_ous:
                print(green("OUs blocking inheritance:"))
                for ou in blocker_ous:
                    print(yellow("\t%s" % ou))
            if operating_systems:
                print(green("Operating Systems seen in domain:"))
                for key, value in operating_systems.items():
                    print(yellow("\t%s\t%s" % (value, key)))
            print(green("Domain Admins tied to SPNs:"))
            if len(da_spn):
                for account in da_spn:
                    print(yellow("\t%s" % account))
            else:
                print(green("\tNone! :D"))

            # Report session data
            print(green("Systems that are not Domain Controllers with Domain Admin sessions:"))
            if da_sessions:
                for session in da_sessions:
                    print(yellow("\t%s" % session))
            else:
                print(green("\tNone! :D"))

            # Report group-related data
            print(green("Average group membership:\t\t\t%s" % avg_membership_nonrecur))
            print(green("Average recursive group membership:\t\t%s" % avg_membership_recur))
            print(green("Nested groups increased membership by:\t\t%s"
                         % float(avg_membership_recur-avg_membership_nonrecur)))
            print(green("Domain Admins:"))
            for user in dadmins:
                print(yellow("\t%s" % user))
            print(green("Enterprise Admins:"))
            for user in eadmins:
                print(yellow("\t%s" % user))
            print(green("Administrators:"))
            for user in admins:
                print(yellow("\t%s" % user))
            print(green("Other ADMIN groups:"))
            for group in admin_groups:
                print(yellow("\t%s" % group))
            print(green("Non-Admin groups with Local Admin:"))
            if local_admin:
                for group in local_admin:
                    print(yellow("\t%s" % group))
            else:
                print(green("\tNone! :D"))
            print(green("REMOTE DESKTOP USERS members:"))
            for member in rdp_users:
                if "DOMAIN USERS" in member:
                    print(red("\t--> %s" % member))
                else:
                    print(yellow("\t%s" % member))
            if foreign_groups:
                print(green("Groups with foregin group membership:"))
                for group,foreign_group in foreign_groups.items():
                    print(yellow("\t%s -> %s" % (group, foreign_group)))

            # Report user statistics
            print(green("Total users:\t\t\t\t\t%s" % total_users))
            print(green("Total enabled users:\t\t\t\t%s (%s disabled)"
                         % (total_enabled_users, total_users-total_enabled_users)))
            print(green("Users with passwords older than %s months:\t%s"
                         % (pass_age, len(old_passwords))))
            print(green("Total computers:\t\t\t\t%s" % total_computers))
            print(green("Potentially privileged accounts:"))
            for account in special_users:
                print(yellow("\t%s" % account))
            print(green("Users with foregin group membership:"))
            if foreign_groups:
                for account,group in foreign_groups.items():
                    print(yellow("\t%s -> %s" % (account, group)))
            else:
                print(green("\tNone!"))

            # Report on computer objects
            print(green("Computers with Unconstrained Delegation:"))
            if unc_deleg_computers:
                for computer in unc_deleg_computers:
                    print(yellow("\t%s" % computer))
            else:
                print(green("\tNone! :D"))

            # Report on paths
            print(green("Total paths:\t\t\t\t\t%s" % total_paths))
            #print(green("Average path length:\t\t\t\t%s" % avg_path))
            print(green("Users with path to a Domain Admin:\t\t%s %%"
                         % percentage_users_path_to_da))
            print(green("Machines with path to Domain Admin:\t\t%s %%"
                         % percentage_comps_path_to_da))

    # Report totals across domains
    print(green("\n[+] Totals for all domains in dataset:"))
    print(green("Total users across domains:\t\t\t%s" % super_total_users))
    print(green("Total enabled users across domains:\t\t%s" % super_total_enabled_users))
    print(green("Total computers across domains:\t\t\t%s" % super_total_computers))
Exemple #4
0
def user(self, domain, pass_age):
    """
    Generate information and statistics for Active Directory user objects.
    """
    print(
        green("[+] User Module Selected: Crunching group membership data..."))
    neo4j_driver = setup_database_conn()
    domain_metrics = domains.DomainData(neo4j_driver)
    group_metrics = groups.GroupMetrics(neo4j_driver)
    users_metrics = users.UserMetrics(neo4j_driver)
    super_total_users = 0
    super_total_enabled_users = 0
    super_total_computers = 0

    if domain:
        all_domains = [domain]
    else:
        all_domains = domain_metrics.get_all_domains()

    for domain in all_domains:
        # We may get a 'None' domain if the label is missing in BloodHound
        if domain:
            print(green("\n[+] Domain: %s" % domain))
            # Calculations for totals of user objects
            total_users = users_metrics.get_total_users(domain)
            total_enabled_users = users_metrics.get_total_users(domain, True)
            total_computers = users_metrics.get_total_computers(domain)
            super_total_users = super_total_users + total_users
            super_total_enabled_users = super_total_enabled_users + total_enabled_users
            super_total_computers = super_total_computers + total_computers
            # Path to DA calculations
            total_paths = domain_metrics.get_all_da_paths(domain)
            avg_path = domain_metrics.avg_path_length(domain)
            percentage_users_path_to_da = 100.0 * (total_paths / total_users)
            percentage_comps_path_to_da = 100.0 * (total_paths /
                                                   total_computers)
            # Other statistics and data
            old_passwords = users_metrics.find_old_pwdlastset(domain, pass_age)
            special_users = users_metrics.find_special_users(domain)
            da_spn = users_metrics.find_da_spn(domain)
            foreign_groups = users_metrics.find_foreign_group_membership(
                domain)

            print(green("L.. Total users:\t\t\t\t%s" % total_users))
            print(
                green(
                    "L.. Total enabled users:\t\t\t%s (%s disabled)" %
                    (total_enabled_users, total_users - total_enabled_users)))
            print(green("L.. Total computers:\t\t\t\t%s" % total_computers))
            print(green("L.. Total paths:\t\t\t\t%s" % total_paths))
            print(green("L.. Average path length:\t\t\t%s" % avg_path))
            print(
                green("L.. Users with path to a Domain Admin:\t\t%s%%" %
                      percentage_users_path_to_da))
            print(
                green("L.. Machines with path to Domain Admin:\t\t%s%%" %
                      percentage_comps_path_to_da))
            print(
                green("L.. Users with passwords older than %s months:\t%s" %
                      (pass_age, len(old_passwords))))
            print(green("L.. Domain Admins tied to SPNs:"))
            for account in da_spn:
                print(yellow("\t%s" % account))
            print(green("L.. Potentially privileged accounts:"))
            for account in special_users:
                print(yellow("\t%s" % account))
            print(green("L.. Users with foregin group membership:"))
            for account, group in foreign_groups.items():
                print(yellow("\t%s -> %s" % (account, group)))

    print(
        green("\n[*] Total users across domains:\t\t\t%s" % super_total_users))
    print(
        green("[*] Total enabled users across domains:\t\t%s" %
              super_total_enabled_users))
    print(
        green("[*] Total computers across domains:\t\t%s" %
              super_total_computers))