bloodhound

package
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 14, 2026 License: MIT Imports: 41 Imported by: 0

Documentation

Overview

Package bloodhound provides BloodHound data processing and collection capabilities. It handles conversion of LDAP data to BloodHound format and remote data collection from Active Directory environments.

Index

Constants

View Source
const (
	// Computer availability error messages
	ErrorNonWindowsOS = "NonWindowsOS"
	ErrorNotActive    = "NotActive"
	ErrorPortNotOpen  = "PortNotOpen"

	// Default thresholds
	DefaultPasswordAgeThreshold = 60 * 24 * time.Hour // 60 days
	SMBPort                     = 445
)
View Source
const CURRENT_BH_VER = 5

CURRENT_BH_VER is the BloodHound JSON schema version this tool generates.

Variables

This section is empty.

Functions

This section is empty.

Types

type BH

type BH struct {
	FilesMap                     BHFilesMap
	Timestamp                    string
	LdapFolder                   string
	OutputFolder                 string
	ActiveFolder                 string
	Logger                       *core.Logger
	RuntimeOptions               *config.RuntimeOptions
	Resolver                     *config.CustomResolver
	RemoteWorkers                int
	DNSWorkers                   int
	RemoteComputerTimeout        time.Duration
	RemoteMethodTimeout          time.Duration
	RemoteWriteBuff              int
	RemoteComputerCollection     map[string]*RemoteCollectionResult
	RemoteEnterpriseCACollection map[string]*EnterpriseCARemoteCollectionResult
	RemoteGPOChangesCollection   map[string]*GPOLocalGroupsCollectionResult
	ConversionUpdates            chan<- core.ConversionUpdate
	RemoteCollectionUpdates      chan<- core.RemoteCollectionUpdate
	// contains filtered or unexported fields
}

BH orchestrates BloodHound data conversion and remote collection operations. It maintains state for ingestion paths, output locations, and runtime configuration.

func (*BH) GetCurrentWriter

func (bh *BH) GetCurrentWriter(kind string) (*BHFormatWriter, error)

GetCurrentWriter creates a new BloodHound format writer for the specified object kind NOTE: Not thread-safe

func (*BH) GetPaths

func (bh *BH) GetPaths(fileKey string) ([]string, error)

GetPaths retrieves the file paths for a given logical file key within the LDAP data folder.

func (*BH) Init

func (bh *BH) Init(ldapFolder string, activeFolder string, outputFolder string, customResolver *config.CustomResolver, remoteWorkers int, remoteComputerTimeout time.Duration, remoteMethodTimeout time.Duration, runtimeOptions *config.RuntimeOptions, logger *core.Logger)

Init initializes the BloodHound processor with necessary parameters

func (*BH) IsAborted

func (bh *BH) IsAborted() bool

IsAborted reports whether an abort was requested.

func (*BH) LoadRemoteResults added in v0.3.0

func (bh *BH) LoadRemoteResults(step int)

func (*BH) LoadSchemaInfo

func (bh *BH) LoadSchemaInfo(step int)

LoadSchemaInfo loads schema information from the schema file

func (*BH) PerformConversion

func (bh *BH) PerformConversion()

PerformConversion transforms LDAP data to BloodHound JSON format with progress tracking.

func (*BH) PerformRemoteCollection

func (bh *BH) PerformRemoteCollection(auth *config.CredentialMgr, noCrossDomain bool)

PerformRemoteCollection gathers data from computers and CAs using RPC and HTTP.

func (*BH) ProcessConfiguration

func (bh *BH) ProcessConfiguration(step int)

ProcessConfiguration processes configuration entries for PKI objects

func (*BH) ProcessDomain

func (bh *BH) ProcessDomain(step int)

ProcessDomain reads domain entries and creates a domain JSON file

func (*BH) ProcessObjects

func (bh *BH) ProcessObjects(fileNames []string, kind string, step int) int

func (*BH) RequestAbort

func (bh *BH) RequestAbort() bool

RequestAbort sets the abort flag if it has not been set already.

func (*BH) ResetAbortFlag

func (bh *BH) ResetAbortFlag()

ResetAbortFlag clears any pending abort request.

type BHFilesMap

type BHFilesMap struct {
	Files map[string]string
}

BHFilesMap maps logical file keys to their physical filenames for LDAP ingestion data.

func NewBHFilesMap

func NewBHFilesMap() BHFilesMap

NewBHFilesMap creates a new file map with standard LDAP data file names.

func (*BHFilesMap) GetPaths

func (bp *BHFilesMap) GetPaths(ldapFolder string, fileKey string) ([]string, error)

type BHFormatWriter

type BHFormatWriter struct {
	// contains filtered or unexported fields
}

BHFormatWriter writes BloodHound JSON objects with streaming and buffering.

func NewBHFormatWriter

func NewBHFormatWriter(filename, typeName string, version int, bufferSize int) (*BHFormatWriter, error)

NewBHFormatWriter creates a buffered writer for BloodHound JSON output.

func (*BHFormatWriter) Add

func (w *BHFormatWriter) Add(obj any) error

func (*BHFormatWriter) Close

func (w *BHFormatWriter) Close() error

type CAEnrollmentProcessor

type CAEnrollmentProcessor struct {
	// contains filtered or unexported fields
}

CAEnrollmentProcessor scans CA web enrollment endpoints for NTLM authentication vulnerabilities and channel binding weaknesses.

func NewCAEnrollmentProcessor

func NewCAEnrollmentProcessor(caDnsHostname, caName string, auth *config.CredentialMgr, log chan<- string) *CAEnrollmentProcessor

NewCAEnrollmentProcessor creates an enrollment scanner for the given CA.

func (*CAEnrollmentProcessor) ScanCAEnrollmentEndpoints

func (p *CAEnrollmentProcessor) ScanCAEnrollmentEndpoints(ctx context.Context) ([]builder.CAEnrollmentEndpointAPIResult, error)

ScanCAEnrollmentEndpoints probes both web enrollment and web service endpoints for NTLM vulnerabilities (ESC8) and channel binding issues.

type CertAbuseProcessor

type CertAbuseProcessor struct {
	// contains filtered or unexported fields
}

CertAbuseProcessor collects and processes certificate authority security data, including enrollment permissions and related abuse vectors.

func NewCertAbuseProcessor

func NewCertAbuseProcessor(domain string, msrpcObj *msrpc.WinregRPC, auth *config.CredentialMgr, rpcMgr *RPCManager) *CertAbuseProcessor

NewCertAbuseProcessor creates a processor for the specified domain.

func (*CertAbuseProcessor) GetCASecurity

func (cap *CertAbuseProcessor) GetCASecurity(caName string) builder.RegistryAPIResult

GetCASecurity retrieves CA security registry value from the remote machine

func (*CertAbuseProcessor) GetEnrollmentAgentRights

func (cap *CertAbuseProcessor) GetEnrollmentAgentRights(caName string) builder.RegistryAPIResult

GetEnrollmentAgentRights retrieves EnrollmentAgentRights registry value from the remote machine

func (*CertAbuseProcessor) IsRoleSeparationEnabled

func (cap *CertAbuseProcessor) IsRoleSeparationEnabled(caName string) builder.BoolRegistryAPIResult

RoleSeparationEnabled checks if role separation is enabled on the CA

func (*CertAbuseProcessor) IsUserSpecifiesSanEnabled

func (cap *CertAbuseProcessor) IsUserSpecifiesSanEnabled(caName string) builder.BoolRegistryAPIResult

IsUserSpecifiesSanEnabled checks if a requesting user can specify any SAN they want

func (*CertAbuseProcessor) ProcessEAPermissions

func (cap *CertAbuseProcessor) ProcessEAPermissions(
	ctx context.Context,
	caName string,
	computerName string,
	computerObjectId string,
	objectDomain string,
) builder.EnrollmentAgentRegistryAPIResult

ProcessEAPermissions retrieves enrollment agent restrictions from a CA

func (*CertAbuseProcessor) ProcessRegistryEnrollmentPermissions

func (cap *CertAbuseProcessor) ProcessRegistryEnrollmentPermissions(
	ctx context.Context,
	caName string,
	computerName string,
	computerObjectId string,
	objectDomain string,
) builder.AceRegistryAPIResult

ProcessRegistryEnrollmentPermissions retrieves CA security from the registry, including ownership and management rights ACEs.

type CollectionTarget

type CollectionTarget struct {
	SID                string
	DNSHostName        string
	SamName            string
	IsDC               bool
	Domain             string
	OperatingSystem    string
	PwdLastSet         int64
	LastLogonTimestamp int64
}

CollectionTarget identifies a computer for remote data collection.

type ConversionUpdate

type ConversionUpdate = core.ConversionUpdate

type Dialer added in v0.3.0

type Dialer interface {
	DialContext(context.Context, string, string) (net.Conn, error)
}

checkPortOpen attempts to connect to a port

type EnterpriseCACollectionTarget

type EnterpriseCACollectionTarget struct {
	GUID        string
	DN          string
	DNSHostName string
	CAName      string
	Domain      string
}

EnterpriseCACollectionTarget identifies a CA for remote data collection.

type EnterpriseCARemoteCollectionResult

type EnterpriseCARemoteCollectionResult struct {
	GUID                    string
	DN                      string
	CARegistryData          builder.CARegistryData
	HttpEnrollmentEndpoints []builder.CAEnrollmentEndpointAPIResult
	HostingComputer         string
}

EnterpriseCARemoteCollectionResult holds data collected remotely from a CA.

type GPLink struct {
	DN     string
	Status string // "0" = unenforced, "2" = enforced, "1" = disabled
}

GPLink represents a single GPO link with its status

type GPOLocalGroupsCollectionResult added in v0.3.0

type GPOLocalGroupsCollectionResult struct {
	DN                string
	ObjectType        string
	GPOChanges        builder.GPOChanges
	AffectedComputers []builder.TypedPrincipal
}

GPOLocalGroupsCollectionResult represents the GPO changes for a single OU or Domain

type GroupAction added in v0.3.0

type GroupAction struct {
	Action     GroupActionOperation
	Target     GroupActionTarget
	TargetSID  string
	TargetType string // User, Group, Computer, etc.
	TargetRID  LocalGroupRids
}

GroupAction represents an action from a GPO

func (*GroupAction) GetTargetPrincipal added in v0.3.0

func (ga *GroupAction) GetTargetPrincipal() builder.TypedPrincipal

Tobuilder.TypedPrincipal converts a GroupAction to a builder.TypedPrincipal

type GroupActionOperation added in v0.3.0

type GroupActionOperation int

GroupActionOperation represents the type of operation to perform

const (
	GroupActionAdd GroupActionOperation = iota
	GroupActionDelete
	GroupActionDeleteUsers
	GroupActionDeleteGroups
)

type GroupActionTarget added in v0.3.0

type GroupActionTarget int

GroupActionTarget represents the target type for a group action

const (
	GroupActionTargetRestrictedMemberOf GroupActionTarget = iota
	GroupActionTargetRestrictedMember
	GroupActionTargetLocalGroup
)

type GroupResults added in v0.3.0

type GroupResults struct {
	LocalGroups        []builder.TypedPrincipal
	RestrictedMember   []builder.TypedPrincipal
	RestrictedMemberOf []builder.TypedPrincipal
}

GroupResults stores membership for each group type

type GroupXML added in v0.3.0

type GroupXML struct {
	Disabled   string        `xml:"disabled,attr"`
	Properties PropertiesXML `xml:"Properties"`
}

type GroupsXML added in v0.3.0

type GroupsXML struct {
	XMLName xml.Name   `xml:"Groups"`
	Groups  []GroupXML `xml:"Group"`
}

XML structure definitions for Groups.xml parsing

type LocalGroupRids added in v0.3.0

type LocalGroupRids int

LocalGroupRids represents the RIDs of built-in local groups

const (
	LocalGroupNone               LocalGroupRids = 0
	LocalGroupAdministrators     LocalGroupRids = 544
	LocalGroupRemoteDesktopUsers LocalGroupRids = 555
	LocalGroupDcomUsers          LocalGroupRids = 562
	LocalGroupPSRemote           LocalGroupRids = 580
)

type MemberXML added in v0.3.0

type MemberXML struct {
	Action string `xml:"action,attr"`
	Name   string `xml:"name,attr"`
	SID    string `xml:"sid,attr"`
}

type MembersXML added in v0.3.0

type MembersXML struct {
	Members []MemberXML `xml:"Member"`
}

type OUTreeNode added in v0.3.0

type OUTreeNode struct {
	DN        string
	Computers []builder.TypedPrincipal // Computers directly in this OU
	Children  map[string]*OUTreeNode   // Child OUs (keyed by their full DN)
}

OUTreeNode represents a node in the OU hierarchy tree

func NewOUTreeNode added in v0.3.0

func NewOUTreeNode(dn string) *OUTreeNode

NewOUTreeNode creates a new OU tree node

func (*OUTreeNode) GetAllComputersInSubtree added in v0.3.0

func (node *OUTreeNode) GetAllComputersInSubtree() []builder.TypedPrincipal

GetAllComputersInSubtree returns all computers in this OU and all child OUs (iterative)

type PropertiesXML added in v0.3.0

type PropertiesXML struct {
	Action          string     `xml:"action,attr"`
	GroupSID        string     `xml:"groupSid,attr"`
	GroupName       string     `xml:"groupName,attr"`
	DeleteAllUsers  string     `xml:"deleteAllUsers,attr"`
	DeleteAllGroups string     `xml:"deleteAllGroups,attr"`
	Members         MembersXML `xml:"Members"`
}

type RPCManager added in v0.3.0

type RPCManager struct {
	// contains filtered or unexported fields
}

RPCManager manages RPC client creation, reuse, and timing measurement

func NewRPCManager added in v0.3.0

func NewRPCManager(targetHost string, auth *config.CredentialMgr) *RPCManager

NewRPCManager creates a new RPC manager

func (*RPCManager) Close added in v0.3.0

func (rm *RPCManager) Close()

Close closes all cached RPC clients

func (*RPCManager) GetMethodTimes added in v0.3.0

func (rm *RPCManager) GetMethodTimes() map[string]time.Duration

GetMethodTimes returns the collected method timing data

func (*RPCManager) GetOrCreateLsadRPC added in v0.3.0

func (rm *RPCManager) GetOrCreateLsadRPC(ctx context.Context) (*msrpc.LsadRPC, error)

GetOrCreateLsadRPC gets or creates an LsadRPC client and tracks the creation time

func (*RPCManager) GetOrCreateLsatRPC added in v0.3.0

func (rm *RPCManager) GetOrCreateLsatRPC(ctx context.Context) (*msrpc.LsatRPC, error)

GetOrCreateLsatRPC gets or creates an LsatRPC client and tracks the creation time

func (*RPCManager) GetOrCreateSamrRPC added in v0.3.0

func (rm *RPCManager) GetOrCreateSamrRPC(ctx context.Context) (*msrpc.SamrRPC, error)

GetOrCreateSamrRPC gets or creates a SamrRPC client and tracks the creation time

func (*RPCManager) GetOrCreateSrvsvcRPC added in v0.3.0

func (rm *RPCManager) GetOrCreateSrvsvcRPC(ctx context.Context) (*msrpc.SrvsvcRPC, error)

GetOrCreateSrvsvcRPC gets or creates a SrvsvcRPC client and tracks the creation time

func (*RPCManager) GetOrCreateWinregRPC added in v0.3.0

func (rm *RPCManager) GetOrCreateWinregRPC(ctx context.Context) (*msrpc.WinregRPC, error)

GetOrCreateWinregRPC gets or creates a WinregRPC client and tracks the creation time

func (*RPCManager) GetOrCreateWkssvcRPC added in v0.3.0

func (rm *RPCManager) GetOrCreateWkssvcRPC(ctx context.Context) (*msrpc.WkssvcRPC, error)

GetOrCreateWkssvcRPC gets or creates a WkssvcRPC client and tracks the creation time

func (*RPCManager) GetTargetHost added in v0.3.0

func (rm *RPCManager) GetTargetHost() string

GetTargetHost returns the target hostname

type RemoteCollectionResult

type RemoteCollectionResult struct {
	SID                   string
	LocalGroups           []builder.LocalGroupAPIResult
	Sessions              builder.SessionAPIResult
	PrivilegedSessions    builder.SessionAPIResult
	RegistrySessions      builder.SessionAPIResult
	DCRegistryData        builder.DCRegistryData
	NTLMRegistryData      builder.NTLMRegistryData
	UserRights            []builder.UserRightsAPIResult
	IsWebClientRunning    builder.IsWebClientRunningAPIResult
	LdapServices          builder.LdapServicesResult
	SMBInfo               *builder.SMBInfoAPIResult
	Status                *builder.ComputerStatus
	AttemptedMethodsCount int `msgpack:"-"` // Not serialized (only used for progress tracking)
}

RemoteCollectionResult holds all data collected remotely from a computer.

func (*RemoteCollectionResult) CountAttemptedMethods added in v0.3.0

func (rcr *RemoteCollectionResult) CountAttemptedMethods() int

CountAttemptedMethods returns the number of collection methods that were attempted (ran, whether successful or not)

func (*RemoteCollectionResult) GetTotalMethods added in v0.3.0

func (rcr *RemoteCollectionResult) GetTotalMethods(runtimeOptions *config.RuntimeOptions, isDC bool) int

GetTotalMethods returns the total number of collection methods enabled for this target

func (*RemoteCollectionResult) StoreInComputer

func (rcr *RemoteCollectionResult) StoreInComputer(computer *builder.Computer)

Small helper as computer results include many fields to update

type RemoteCollectionUpdate

type RemoteCollectionUpdate = core.RemoteCollectionUpdate

type RemoteCollector

type RemoteCollector struct {
	RuntimeOptions      *config.RuntimeOptions
	RemoteMethodTimeout time.Duration
	// contains filtered or unexported fields
}

RemoteCollector executes remote data collection from AD computers and CAs.

func NewRemoteCollector

func NewRemoteCollector(
	authenticator *config.CredentialMgr,
	runtimeOptions *config.RuntimeOptions,
	methodTimeout time.Duration,
	noCrossDomain bool,
	logger *core.Logger,
) *RemoteCollector

NewRemoteCollector creates a collector with the given credentials and options.

func (*RemoteCollector) CollectRemoteComputer

func (rc *RemoteCollector) CollectRemoteComputer(ctx context.Context, target CollectionTarget, result *RemoteCollectionResult, mu *sync.Mutex)

func (*RemoteCollector) CollectRemoteComputerWithContext added in v0.2.0

func (rc *RemoteCollector) CollectRemoteComputerWithContext(ctx context.Context, target CollectionTarget) (RemoteCollectionResult, bool)

CollectRemoteComputerWithContext wraps CollectRemoteComputer with hard timeout enforcement. Returns the result and a boolean indicating if the collection completed successfully (true = success, false = aborted). On timeout, returns partial results collected before the timeout.

func (*RemoteCollector) CollectRemoteEnterpriseCA

func (rc *RemoteCollector) CollectRemoteEnterpriseCA(ctx context.Context, target EnterpriseCACollectionTarget, result *EnterpriseCARemoteCollectionResult, mu *sync.Mutex)

func (*RemoteCollector) CollectRemoteEnterpriseCAWithContext added in v0.2.0

func (rc *RemoteCollector) CollectRemoteEnterpriseCAWithContext(ctx context.Context, target EnterpriseCACollectionTarget) (EnterpriseCARemoteCollectionResult, bool)

CollectRemoteEnterpriseCAWithContext wraps CollectRemoteEnterpriseCA with hard timeout enforcement. Returns the result and a boolean indicating if the collection completed successfully (true = success, false = aborted). On timeout, returns partial results collected before the timeout.

func (*RemoteCollector) ProcessGPOTemplateFile added in v0.3.0

func (rc *RemoteCollector) ProcessGPOTemplateFile(basePath, gpoDomain string, reader *smb.FileReader) ([]GroupAction, error)

ProcessGPOTemplateFile parses a GPO GptTmpl.inf file for group membership changes from the "Restricted Groups" security setting

func (*RemoteCollector) ProcessGPPGroupsFile added in v0.3.0

func (rc *RemoteCollector) ProcessGPPGroupsFile(basePath, gpoDomain string, reader *smb.FileReader) ([]GroupAction, error)

ProcessGPPGroupsFile parses a GPO Groups.xml file for group membership changes

func (*RemoteCollector) ReadGPOLocalGroupsForTarget added in v0.3.0

func (rc *RemoteCollector) ReadGPOLocalGroupsForTarget(targetDn string, gpLink string, smbReader *smb.FileReader) (*builder.GPOChanges, error)

ReadGPOLocalGroupsForTarget processes GPO links for local group changes using DN and gPLink directly

Directories

Path Synopsis
Package builder constructs BloodHound-compatible objects from LDAP entries.
Package builder constructs BloodHound-compatible objects from LDAP entries.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL