builder

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: 24 Imported by: 0

Documentation

Overview

Package builder constructs BloodHound-compatible objects from LDAP entries. It handles AD principals, PKI infrastructure, and their relationships.

Index

Constants

View Source
const (
	ADRightCreateChild          uint32 = 1        // 0x1
	ADRightDeleteChild          uint32 = 2        // 0x2
	ADRightListChildren         uint32 = 4        // 0x4
	ADRightSelf                 uint32 = 8        // 0x8
	ADRightReadProperty         uint32 = 16       // 0x10
	ADRightWriteProperty        uint32 = 32       // 0x20
	ADRightDeleteTree           uint32 = 64       // 0x40
	ADRightListObject           uint32 = 128      // 0x80
	ADRightExtendedRight        uint32 = 256      // 0x100
	ADRightDelete               uint32 = 65536    // 0x10000
	ADRightReadControl          uint32 = 131072   // 0x20000
	ADRightGenericExecute       uint32 = 131076   // 0x20004
	ADRightGenericWrite         uint32 = 131112   // 0x20028
	ADRightGenericRead          uint32 = 131220   // 0x20094
	ADRightWriteDacl            uint32 = 262144   // 0x40000
	ADRightWriteOwner           uint32 = 524288   // 0x80000
	ADRightGenericAll           uint32 = 983551   // 0xF01FF
	ADRightSynchronize          uint32 = 1048576  // 0x100000
	ADRightAccessSystemSecurity uint32 = 16777216 // 0x1000000
)

ActiveDirectoryRights flag constants

View Source
const (
	ShardNumStandard = 16 // Used for high-volume lookups (SIDs, DNs, hostnames)
	ShardNumSmall    = 2  // Used for lower-volume lookups (cert templates)
)

Cache shards' constants - affects memory vs contention tradeoff

View Source
const (
	OIDAnyPurpose                 = "2.5.29.37.0"
	OIDClientAuthentication       = "1.3.6.1.5.5.7.3.2"
	OIDPKINITClientAuthentication = "1.3.6.1.5.2.3.4"
	OIDSmartcardLogon             = "1.3.6.1.4.1.311.20.2.2"
	OIDCertificateRequestAgent    = "1.3.6.1.4.1.311.20.2.1"
)

Common OID constants for certificate authentication

View Source
const (
	PKIEnrollmentFlagIncludeSymmetricAlgorithms                               = 0x00000001
	PKIEnrollmentFlagPendAllRequests                                          = 0x00000002
	PKIEnrollmentFlagPublishToKRAContainer                                    = 0x00000004
	PKIEnrollmentFlagPublishToDS                                              = 0x00000008
	PKIEnrollmentFlagAutoEnrollmentCheckUserDSCertificate                     = 0x00000010
	PKIEnrollmentFlagAutoEnrollment                                           = 0x00000020
	PKIEnrollmentFlagCTFlagDomainAuthenticationNotRequired                    = 0x00000080
	PKIEnrollmentFlagPreviousApprovalValidateReenrollment                     = 0x00000040
	PKIEnrollmentFlagUserInteractionRequired                                  = 0x00000100
	PKIEnrollmentFlagAddTemplateName                                          = 0x00000200
	PKIEnrollmentFlagRemoveInvalidCertificateFromPersonalStore                = 0x00000400
	PKIEnrollmentFlagAllowEnrollOnBehalfOf                                    = 0x00000800
	PKIEnrollmentFlagAddOCSPNoCheck                                           = 0x00001000
	PKIEnrollmentFlagEnableKeyReuseOnNTTokenKeysetStorageFull                 = 0x00002000
	PKIEnrollmentFlagNoRevocationInfoInIssuedCerts                            = 0x00004000
	PKIEnrollmentFlagIncludeBasicConstraintsForEECerts                        = 0x00008000
	PKIEnrollmentFlagAllowPreviousApprovalKeyBasedRenewalValidateReenrollment = 0x00010000
	PKIEnrollmentFlagIssuancePoliciesFromRequest                              = 0x00020000
	PKIEnrollmentFlagSkipAutoRenewal                                          = 0x00040000
	PKIEnrollmentFlagNoSecurityExtension                                      = 0x00080000
)

PKIEnrollmentFlag constants

View Source
const (
	PKICertificateNameFlagEnrolleeSuppliesSubject          = 0x00000001
	PKICertificateNameFlagAddEmail                         = 0x00000002
	PKICertificateNameFlagAddObjGuid                       = 0x00000004
	PKICertificateNameFlagOldCertSuppliesSubjectAndAltName = 0x00000008
	PKICertificateNameFlagAddDirectoryPath                 = 0x00000100
	PKICertificateNameFlagEnrolleeSuppliesSubjectAltName   = 0x00010000
	PKICertificateNameFlagSubjectAltRequireDomainDNS       = 0x00400000
	PKICertificateNameFlagSubjectAltRequireSPN             = 0x00800000
	PKICertificateNameFlagSubjectAltRequireDirectoryGuid   = 0x01000000
	PKICertificateNameFlagSubjectAltRequireUPN             = 0x02000000
	PKICertificateNameFlagSubjectAltRequireEmail           = 0x04000000
	PKICertificateNameFlagSubjectAltRequireDNS             = 0x08000000
	PKICertificateNameFlagSubjectRequireDNSAsCN            = 0x10000000
	PKICertificateNameFlagSubjectRequireEmail              = 0x20000000
	PKICertificateNameFlagSubjectRequireCommonName         = 0x40000000
	PKICertificateNameFlagSubjectRequireDirectoryPath      = 0x80000000
)

PKICertificateNameFlag constants

View Source
const (
	PKICertificateAuthorityFlagNoTemplateSupport              = 0x00000001
	PKICertificateAuthorityFlagSupportsNTAuthentication       = 0x00000002
	PKICertificateAuthorityFlagCASupportsManualAuthentication = 0x00000004
	PKICertificateAuthorityFlagCAServerTypeAdvanced           = 0x00000008
)

PKICertificateAuthorityFlags constants

View Source
const (
	PKIPrivateKeyFlagUseLegacyProvider = 0x00000100
)

PKIPrivateKeyFlag constants

Variables

View Source
var (
	// AuthenticationOIDs contains OIDs that enable authentication
	AuthenticationOIDs = []string{
		OIDClientAuthentication,
		OIDPKINITClientAuthentication,
		OIDSmartcardLogon,
		OIDAnyPurpose,
	}

	// SchannelAuthenticationOIDs contains OIDs that enable Schannel authentication
	SchannelAuthenticationOIDs = []string{
		OIDClientAuthentication,
		OIDAnyPurpose,
	}
)
View Source
var ACEGuids = map[string]string{
	"AllGuid":                    "00000000-0000-0000-0000-000000000000",
	"GetChanges":                 "1131f6aa-9c07-11d1-f79f-00c04fc2dcd2",
	"GetChangesAll":              "1131f6ad-9c07-11d1-f79f-00c04fc2dcd2",
	"GetChangesInFilteredSet":    "89e95b76-444d-4c62-991a-0facbeda640c",
	"WriteMember":                "bf9679c0-0de6-11d0-a285-00aa003049e2",
	"MembershipPropertySet":      "bc0ac240-79a9-11d0-9020-00c04fc2d4cf",
	"UserForceChangePassword":    "00299570-246d-11d0-a768-00aa006e0529",
	"AllowedToAct":               "3f78c3e5-f79a-46bd-a0b8-9d18116ddc79",
	"AddKeyPrincipal":            "5b47d60f-6090-40b2-9f37-2a4de88f3063",
	"UserAccountRestrictionsSet": "4c164200-20c0-11d0-a768-00aa006e0529",
	"WriteGPLink":                "f30e3bbe-9ff0-11d1-b603-0000f80367c1",
	"WriteSPN":                   "f3a64788-5306-11d1-a9c5-0000f80367c1",
	"PKINameFlag":                "ea1dddc4-60ff-416e-8cc0-17cee534bce7",
	"PKIEnrollmentFlag":          "d15ef7d8-f226-46db-ae79-b34e560bd12c",
	"Enroll":                     "0e10c968-78fb-11d2-90d4-00c04f79dc55",
}

ACEGuids maps well-known permission GUIDs to their logical names.

View Source
var ObjectTypeRawToStrMap = map[ObjectTypeEnum]string{
	BaseObjectType:           "Base",
	UserObjectType:           "User",
	ComputerObjectType:       "Computer",
	GroupObjectType:          "Group",
	LocalGroupObjectType:     "LocalGroup",
	LocalUserObjectType:      "LocalUser",
	GPOObjectType:            "GPO",
	DomainObjectType:         "Domain",
	OUObjectType:             "OU",
	ContainerObjectType:      "Container",
	ConfigurationObjectType:  "Configuration",
	CertTemplateObjectType:   "CertTemplate",
	RootCAObjectType:         "RootCA",
	AIACAObjectType:          "AIACA",
	EnterpriseCAObjectType:   "EnterpriseCA",
	NTAuthStoreObjectType:    "NTAuthStore",
	IssuancePolicyObjectType: "IssuancePolicy",
	FSPObjectType:            "foreignsecurityprincipal",
	TrustAccountObjectType:   "trustaccount",
}
View Source
var StrToObjectTypeRawMap = map[string]ObjectTypeEnum{
	"Base":                     BaseObjectType,
	"User":                     UserObjectType,
	"Computer":                 ComputerObjectType,
	"Group":                    GroupObjectType,
	"LocalGroup":               LocalGroupObjectType,
	"LocalUser":                LocalUserObjectType,
	"GPO":                      GPOObjectType,
	"Domain":                   DomainObjectType,
	"OU":                       OUObjectType,
	"Container":                ContainerObjectType,
	"Configuration":            ConfigurationObjectType,
	"CertTemplate":             CertTemplateObjectType,
	"RootCA":                   RootCAObjectType,
	"AIACA":                    AIACAObjectType,
	"EnterpriseCA":             EnterpriseCAObjectType,
	"NTAuthStore":              NTAuthStoreObjectType,
	"IssuancePolicy":           IssuancePolicyObjectType,
	"foreignsecurityprincipal": FSPObjectType,
	"trustaccount":             TrustAccountObjectType,
}

Functions

func CalculateImplicitACLHash

func CalculateImplicitACLHash(securityDescriptor []byte) (string, error)

CalculateImplicitACLHash calculates a SHA1 hash of non-inherited ACEs combined with DACL protection status This is used to detect AdminSDHolder protection by comparing object ACL hashes

func CalculateInheritanceHash

func CalculateInheritanceHash(targetAce ace.AccessControlEntry) string

CalculateInheritanceHash calculates the inheritance hash for an ACE This function is a direct translation of the original BloodHound code

func CheckAnyACEGrantOwnerRights

func CheckAnyACEGrantOwnerRights(aces []ACE, inherited bool) bool

func ConvertEncryptionTypes

func ConvertEncryptionTypes(encryptionTypesStr string) []string

func ConvertPKIPeriod

func ConvertPKIPeriod(bytes []byte) string

ConvertPKIPeriod converts PKI period bytes to a human-readable string The bytes represent a 64-bit integer in little-endian format representing 100-nanosecond intervals

func GetInheritedAceHashes added in v0.3.0

func GetInheritedAceHashes(securityDescriptor []byte) []string

GetInheritedAceHashes calculates inheritance hashes from ACEs that will be inherited down the tree This function processes the security descriptor and returns unique inheritance hashes from ACEs that have inheritance flags set

func IgnoreSID

func IgnoreSID(s string) bool

func IsAdminSDHolderProtected

func IsAdminSDHolderProtected(securityDescriptor []byte, adminSdHolderHash, objectName string) (bool, error)

IsAdminSDHolderProtected checks if an object's ACL matches the AdminSDHolder ACL hash Returns true if the object is protected by AdminSDHolder

func IsFilteredContainer

func IsFilteredContainer(containerDN string) bool

IsFilteredContainer checks if a container DN should be filtered out.

func ParseCertTemplateApplicationPolicies

func ParseCertTemplateApplicationPolicies(applicationPolicies []string, schemaVersion int, hasUseLegacyProvider bool) []string

ParseCertTemplateApplicationPolicies parses application policies based on schema version Format: "Name`Type`Value`Name`Type`Value`..." (https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-crtd/c55ec697-be3f-4117-8316-8895e4399237) Returns the Value of Name = "msPKI-RA-Application-Policies" entries

func ResolveACETypes

func ResolveACETypes(ACEs *[]ACE, sidCache *StringCache, objectDomain string)

ResolveACETypes resolves the principal types for a list of ACEs

func ResolveHostnameInCaches

func ResolveHostnameInCaches(host string, domain string) (string, bool)

ResolveHostnameInCaches attempts to resolve a hostname to a computer SID

func ResolveSpn

func ResolveSpn(host string, domain string) (string, bool)

ResolveSpn resolves a service principal name (SPN) to a computer SID using caches This is different from SharpHound's implementation of ResolveHostToSid in which they try to issue (1) NetrWkstaGetInfo, (2) reverse DNS (if the strippedHost is an IP) and (3) NetBIOS In our current implementation we only check our existing caches, which might lead to false negatives Also, SharpHound uses the same ResolveHostToSid to map SPNs in AllowedToDelegateTo / ServicePrincipalNames and for resolving the hosting computer of an Enterprise CA, whereas we split these two use cases into ResolveSpn and ResolveHostname respectively.

Types

type ACE

type ACE struct {
	SID                                    string `json:"PrincipalSID"`
	PrincipalType                          string `json:"PrincipalType"`
	RightName                              string `json:"RightName"`
	Inherited                              bool   `json:"IsInherited"`
	InheritanceHash                        string `json:"InheritanceHash"`
	IsPermissionForOwnerRightsSid          bool   `json:"IsPermissionForOwnerRightsSid"`
	IsInheritedPermissionForOwnerRightsSid bool   `json:"IsInheritedPermissionForOwnerRightsSid"`
}

ACE represents a BloodHound-compatible access control entry.

func ParseBinaryACL

func ParseBinaryACL(entryType string, entryDomain string, hasLAPS bool, aclData []byte) ([]ACE, bool, error)

ParseBinaryACL parses an AD object's DACL into ACEs

func ParseGMSAReaders

func ParseGMSAReaders(gmsaBytes []byte, objectName string) ([]ACE, error)

ParseGMSAReaders parses GMSA (Group Managed Service Account) readers from the msDS-GroupMSAMembership attribute

func (*ACE) ResolvePrincipal

func (r *ACE) ResolvePrincipal(sidCache *StringCache, objectDomain string)

type ACEForHashing

type ACEForHashing struct {
	AccessControlType   string // "Allow" or "Deny"
	IdentityReference   string // SID string
	Rights              string // Numeric rights value
	ObjectType          string // GUID string (empty if not object-specific)
	InheritedObjectType string // GUID string (empty if not inherited-object-specific)
	InheritanceFlags    string // Numeric inheritance flags
}

ACEForHashing represents an ACE structure optimized for consistent hashing and sorting

func (ACEForHashing) String

func (a ACEForHashing) String() string

String returns the semicolon-separated representation of the ACE for hashing

type AIACA

type AIACA struct {
	BaseADObject
	Properties AIACAProperties `json:"Properties"`
}

func BuildAIACAFromEntry

func BuildAIACAFromEntry(entry *gildap.LDAPEntry) (*AIACA, bool)

BuildAIACAFromEntry constructs an AIACA object from an LDAP entry.

type AIACAProperties

type AIACAProperties struct {
	BaseProperties
	Name                      string   `json:"name"`
	CrossCertificatePair      []byte   `json:"crosscertificatepair"`
	HasCrossCertificatePair   bool     `json:"hascrosscertificatepair"`
	CertThumbprint            string   `json:"certthumbprint"`
	CertName                  string   `json:"certname"`
	CertChain                 []string `json:"certchain"`
	HasBasicConstraints       bool     `json:"hasbasicconstraints"`
	BasicConstraintPathLength int      `json:"basicconstraintpathlength"`
}

type APIResult

type APIResult struct {
	Collected     bool    `json:"Collected"`
	FailureReason *string `json:"FailureReason"`
}

Active collection types

type AceRegistryAPIResult

type AceRegistryAPIResult struct {
	APIResult
	Data []ACE `json:"Data"`
}

type BaseADObject

type BaseADObject struct {
	ObjectIdentifier string          `json:"ObjectIdentifier"`
	Aces             []ACE           `json:"Aces"`
	IsDeleted        bool            `json:"IsDeleted"`
	IsACLProtected   bool            `json:"IsACLProtected"`
	ContainedBy      *TypedPrincipal `json:"ContainedBy"`
}

BaseADObject contains fields shared across most AD principals. Embedded in User, Group, Computer, OU, Domain, Container, and GPO. JSON marshaling promotes these fields to the outer struct.

func (*BaseADObject) FromEntry

func (bo *BaseADObject) FromEntry(entry *gildap.LDAPEntry, entryType string)

type BaseProperties

type BaseProperties struct {
	Domain                              string `json:"domain"`
	DistinguishedName                   string `json:"distinguishedname,omitempty"`
	DomainSID                           string `json:"domainsid,omitempty"`
	Description                         string `json:"description,omitempty"`
	WhenCreated                         int64  `json:"whencreated,omitempty"`
	DoesAnyAceGrantOwnerRights          bool   `json:"doesanyacegrantownerrights"`
	DoesAnyInheritedAceGrantOwnerRights bool   `json:"doesanyinheritedacegrantownerrights"`
}

BaseProperties holds common metadata for AD objects.

func (*BaseProperties) FromEntry

func (bp *BaseProperties) FromEntry(entry *gildap.LDAPEntry)

FromEntry populates common properties from an LDAP entry.

func (*BaseProperties) SetOwnerRightsFlags

func (bp *BaseProperties) SetOwnerRightsFlags(aces []ACE)

type BoolRegistryAPIResult

type BoolRegistryAPIResult struct {
	APIResult
	Value bool
}

type CAEnrollmentEndpoint

type CAEnrollmentEndpoint struct {
	Url                    string                         `json:"Url"`
	Type                   CAEnrollmentEndpointType       `json:"CAEnrollmentEndpointType"`
	Status                 CAEnrollmentEndpointScanResult `json:"CAEnrollmentEndpointScanResult"`
	ADCSWebEnrollmentHTTP  bool                           `json:"ADCSWebEnrollmentHTTP"`
	ADCSWebEnrollmentHTTPS bool                           `json:"ADCSWebEnrollmentHTTPS"`
	ADCSWebEnrollmentEPA   bool                           `json:"ADCSWebEnrollmentEPA"`
}

type CAEnrollmentEndpointAPIResult

type CAEnrollmentEndpointAPIResult struct {
	APIResult
	Result CAEnrollmentEndpoint `json:"Result"`
}

type CAEnrollmentEndpointScanResult

type CAEnrollmentEndpointScanResult int

CAEnrollmentEndpointScanResult represents the scan result status

const (
	// Endpoint is vulnerable due to using HTTP (not HTTPS) with NTLM auth (ESC8)
	CAScanVulnerableNtlmHttpEndpoint CAEnrollmentEndpointScanResult = iota
	// Endpoint is vulnerable due to using HTTP (not HTTPS) with Kerberos auth
	CAScanVulnerableKerberosHttpEndpoint
	// Endpoint is vulnerable due to not requiring channel binding for the HTTPS endpoint (ESC8)
	CAScanVulnerableNtlmHttpsNoChannelBinding
	// Endpoint is not vulnerable due to not existing
	CAScanNotVulnerablePortInaccessible
	// The server did not return an NTLM challenge (e.g., when Negotiate:Kerberos is enabled)
	CAScanNotVulnerableNoNtlmChallenge
	// 404 NotFound when accessing the endpoint
	CAScanNotVulnerablePathNotFound
	// Returned if the IIS is configured to require SSL (so no HTTP possible)
	CAScanNotVulnerablePathForbidden
	// 500 Server Error when visiting URL and error reveals ExtendedProtectionPolicy is misconfigured.
	// Occurs when IIS's EPA settings differ from site's web.config's ExtendedProtectionPolicy setting.
	CAScanNotVulnerableEpaMisconfigured
	// Endpoint is not vulnerable due requiring ChannelBinding or only supporting Kerberos authentication (or both)
	CAScanNotVulnerableNtlmChannelBindingRequired
	// ?
	CAScanError
)

type CAEnrollmentEndpointType

type CAEnrollmentEndpointType int

CAEnrollmentEndpointType represents the type of enrollment endpoint

const (
	// The Certificate Authority Web Enrollment server role, an ASP web application
	CATypeWebEnrollmentApplication CAEnrollmentEndpointType = iota
	// The Certificate Enrollment Web Service (CES) server role, a SOAP-based web service
	CATypeEnrollmentWebService
	// The Network Device Enrollment Service (NDES), which uses the SCEP protocol to obtain certificates.
	CATypeEnrollmentNDES
	// ICertPassage Remote Protocol (MS-ICPR), an RPC protcol
	CATypeEnrollmentRPC
	// The Windows Client Certificate Enrollment Protocol (MS-WCCE), a set of DCOM interfaces for certificate enrollment
	CATypeEnrollmentDCOM
)

type CARegistryData

type CARegistryData struct {
	CASecurity                  AceRegistryAPIResult             `json:"CASecurity"`
	EnrollmentAgentRestrictions EnrollmentAgentRegistryAPIResult `json:"EnrollmentAgentRestrictions"`
	IsUserSpecifiesSanEnabled   BoolRegistryAPIResult            `json:"IsUserSpecifiesSanEnabled"`
	IsRoleSeparationEnabled     BoolRegistryAPIResult            `json:"IsRoleSeparationEnabled"`
}

type CertTemplate

type CertTemplate struct {
	BaseADObject
	Properties CertTemplateProperties `json:"Properties"`
}

func BuildCertTemplateFromEntry

func BuildCertTemplateFromEntry(entry *gildap.LDAPEntry) (*CertTemplate, bool)

BuildCertTemplateFromEntry converts an LDAP entry into a CertTemplate structure. BuildCertTemplateFromEntry constructs a CertTemplate object from an LDAP entry.

type CertTemplateProperties

type CertTemplateProperties struct {
	BaseProperties
	Name                          string   `json:"name"`
	ValidityPeriod                string   `json:"validityperiod"`
	RenewalPeriod                 string   `json:"renewalperiod"`
	SchemaVersion                 uint32   `json:"schemaversion"`
	DisplayName                   string   `json:"displayname"`
	OID                           string   `json:"oid"`
	EnrollmentFlag                string   `json:"enrollmentflag"`
	RequiresManagerApproval       bool     `json:"requiresmanagerapproval"`
	NoSecurityExtension           bool     `json:"nosecurityextension"`
	CertificateNameFlag           string   `json:"certificatenameflag"`
	EnrolleeSuppliesSubject       bool     `json:"enrolleesuppliessubject"`
	SubjectAltRequireUPN          bool     `json:"subjectaltrequireupn"`
	SubjectAltRequireDNS          bool     `json:"subjectaltrequiredns"`
	SubjectAltRequireDomainDNS    bool     `json:"subjectaltrequiredomaindns"`
	SubjectAltRequireEmail        bool     `json:"subjectaltrequireemail"`
	SubjectAltRequireSPN          bool     `json:"subjectaltrequirespn"`
	SubjectRequireEmail           bool     `json:"subjectrequireemail"`
	EKUs                          []string `json:"ekus"`
	CertificateApplicationPolicy  []string `json:"certificateapplicationpolicy"`
	CertificatePolicy             []string `json:"certificatepolicy"`
	AuthorizedSignatures          int64    `json:"authorizedsignatures"`
	ApplicationPolicies           []string `json:"applicationpolicies"`
	IssuancePolicies              []string `json:"issuancepolicies"`
	EffectiveEKUs                 []string `json:"effectiveekus"`
	AuthenticationEnabled         bool     `json:"authenticationenabled"`
	SchannelAuthenticationEnabled bool     `json:"schannelauthenticationenabled"`
}

type CertificateInfo

type CertificateInfo struct {
	Thumbprint                string
	Name                      string
	Chain                     []string
	HasBasicConstraints       bool
	BasicConstraintPathLength int
}

CertificateInfo holds parsed certificate information

type Computer

type Computer struct {
	BaseADObject
	DomainSID               string                      `json:"DomainSID"`
	AllowedToAct            []TypedPrincipal            `json:"AllowedToAct"`
	AllowedToDelegate       []TypedPrincipal            `json:"AllowedToDelegate"`
	UnconstrainedDelegation bool                        `json:"UnconstrainedDelegation"`
	PrimaryGroupSID         string                      `json:"PrimaryGroupSID"`
	LocalGroups             []LocalGroupAPIResult       `json:"LocalGroups"`
	Sessions                SessionAPIResult            `json:"Sessions"`
	PrivilegedSessions      SessionAPIResult            `json:"PrivilegedSessions"`
	RegistrySessions        SessionAPIResult            `json:"RegistrySessions"`
	Properties              ComputerProperties          `json:"Properties"`
	HasSIDHistory           []TypedPrincipal            `json:"HasSIDHistory"`
	Status                  *ComputerStatus             `json:"Status"`
	UserRights              []UserRightsAPIResult       `json:"UserRights"`
	DumpSMSAPassword        []TypedPrincipal            `json:"DumpSMSAPassword"`
	DCRegistryData          DCRegistryData              `json:"DCRegistryData"`
	NTLMRegistryData        NTLMRegistryData            `json:"NTLMRegistryData"`
	IsWebClientRunning      IsWebClientRunningAPIResult `json:"IsWebClientRunning"`
	IsDC                    bool                        `json:"IsDC"`
	SMBInfo                 *SMBInfoAPIResult           `json:"SMBInfo"`
}

func BuildComputerFromEntry

func BuildComputerFromEntry(entry *gildap.LDAPEntry) (*Computer, bool)

BuildComputerFromEntry constructs a Computer object from an LDAP entry.

type ComputerProperties

type ComputerProperties struct {
	BaseProperties
	Name                     string   `json:"name"`
	SAMAccountName           string   `json:"samaccountname"`
	HasLAPS                  bool     `json:"haslaps"`
	IsACLProtected           bool     `json:"isaclprotected"`
	AdminSDHolderProtected   bool     `json:"adminsdholderprotected"`
	Enabled                  bool     `json:"enabled"`
	UnconstrainedDelegation  bool     `json:"unconstraineddelegation"`
	TrustedToAuth            bool     `json:"trustedtoauth"`
	IsDC                     bool     `json:"isdc"`
	IsReadOnlyDC             bool     `json:"isreadonlydc"`
	EncryptedTextPwdAllowed  bool     `json:"encryptedtextpwdallowed"`
	UseDesKeyOnly            bool     `json:"usedeskeyonly"`
	LogonScriptEnabled       bool     `json:"logonscriptenabled"`
	LockedOut                bool     `json:"lockedout"`
	PasswordExpired          bool     `json:"passwordexpired"`
	SupportedEncryptionTypes []string `json:"supportedencryptiontypes"`
	AdminCount               bool     `json:"admincount"`
	LastLogon                int64    `json:"lastlogon"`
	LastLogonTimestamp       int64    `json:"lastlogontimestamp"`
	PwdLastSet               int64    `json:"pwdlastset"`
	ServicePrincipalNames    []string `json:"serviceprincipalnames"`
	Email                    string   `json:"email"`
	UserAccountControl       int64    `json:"useraccountcontrol"`
	OperatingSystem          string   `json:"operatingsystem"`
	SIDHistory               []string `json:"sidhistory"`
	ObjectGUID               string   `json:"objectguid"`
	AllowedToDelegate        []string `json:"allowedtodelegate,omitempty"`
	LdapAvailable            *bool    `json:"ldapavailable,omitempty"`
	LdapsAvailable           *bool    `json:"ldapsavailable,omitempty"`
	LdapSigning              *bool    `json:"ldapsigning,omitempty"`
	LdapsEpa                 *bool    `json:"ldapsepa,omitempty"`
}

type ComputerStatus

type ComputerStatus struct {
	Connectable bool   `json:"Connectable"`
	Error       string `json:"Error"`
}

type Container

type Container struct {
	BaseADObject
	Properties        ContainerProperties `json:"Properties"`
	ChildObjects      []TypedPrincipal    `json:"ChildObjects"`
	InheritanceHashes []string            `json:"InheritanceHashes"`
}

Container represents an Active Directory container (e.g., CN=Users, CN=Computers).

func BuildContainerFromEntry

func BuildContainerFromEntry(entry *gildap.LDAPEntry) (*Container, bool)

BuildContainerFromEntry constructs a Container object from an LDAP entry.

type ContainerProperties

type ContainerProperties struct {
	BaseProperties
	Name           string `json:"name"`
	HighValue      bool   `json:"highvalue"`
	IsACLProtected bool   `json:"isaclprotected"`
}

ContainerProperties holds AD metadata for the container.

type DCRegistryData

type DCRegistryData struct {
	CertificateMappingMethods            *IntRegistryAPIResult
	StrongCertificateBindingEnforcement  *IntRegistryAPIResult
	VulnerableNetlogonSecurityDescriptor *StrRegistryAPIResult
}

type Domain

type Domain struct {
	BaseADObject
	Properties           DomainProperties `json:"Properties"`
	Trusts               []DomainTrust    `json:"Trusts"`
	Links                []GPLinkRef      `json:"Links"`
	ChildObjects         []TypedPrincipal `json:"ChildObjects"`
	GPOChanges           GPOChanges       `json:"GPOChanges"`
	InheritanceHashes    []string         `json:"InheritanceHashes"`
	ForestRootIdentifier string           `json:"ForestRootIdentifier,omitempty"`
}

Domain represents an Active Directory domain.

func BuildDomainFromEntry

func BuildDomainFromEntry(domainEntry *gildap.LDAPEntry, trustEntries []gildap.LDAPEntry) *Domain

BuildDomainFromEntry constructs a Domain object from LDAP entries.

type DomainProperties

type DomainProperties struct {
	BaseProperties
	Name            string `json:"name"`
	FunctionalLevel string `json:"functionallevel"`
	HighValue       bool   `json:"highvalue"` // Not present in sample (?)
	IsACLProtected  bool   `json:"isaclprotected"`
	Collected       bool   `json:"collected"`
}

DomainProperties holds metadata about the domain.

type DomainTrust

type DomainTrust struct {
	Name                 string `json:"TargetDomainName"`
	TrustDirection       string `json:"TrustDirection"`
	TrustType            string `json:"TrustType"`
	SecurityID           string `json:"TargetDomainSid"`
	SidFilteringEnabled  bool   `json:"SidFilteringEnabled"`
	IsTransitive         bool   `json:"IsTransitive"`
	TGTDelegationEnabled bool   `json:"TGTDelegationEnabled"`
}

DomainTrust represents a trust ACLship between domains.

type EnrollmentAgentRegistryAPIResult

type EnrollmentAgentRegistryAPIResult struct {
	APIResult
	Restrictions []EnrollmentAgentRestriction `json:"Restrictions"`
}

type EnrollmentAgentRestriction

type EnrollmentAgentRestriction struct {
	AccessType   string           `json:"AccessType"`
	Agent        TypedPrincipal   `json:"Agent"`
	Targets      []TypedPrincipal `json:"Targets"`
	Template     *TypedPrincipal  `json:"Template"`
	AllTemplates bool             `json:"AllTemplates"`
}

type EnterpriseCA

type EnterpriseCA struct {
	BaseADObject
	Properties              EnterpriseCAProperties          `json:"Properties"`
	HostingComputer         string                          `json:"HostingComputer"`
	CARegistryData          CARegistryData                  `json:"CARegistryData"`
	EnabledCertTemplates    []TypedPrincipal                `json:"EnabledCertTemplates"`
	HttpEnrollmentEndpoints []CAEnrollmentEndpointAPIResult `json:"HttpEnrollmentEndpoints"`
}

func BuildEnterpriseCAFromEntry

func BuildEnterpriseCAFromEntry(entry *gildap.LDAPEntry) (*EnterpriseCA, bool)

BuildEnterpriseCAFromEntry constructs an EnterpriseCA object from an LDAP entry.

type EnterpriseCAProperties

type EnterpriseCAProperties struct {
	BaseProperties
	Name                                 string   `json:"name"`
	CAName                               string   `json:"caname"`
	DNSHostname                          string   `json:"dnshostname"`
	Flags                                string   `json:"flags"`
	CertThumbprint                       string   `json:"certthumbprint"`
	CertName                             string   `json:"certname"`
	CertChain                            []string `json:"certchain"`
	HasBasicConstraints                  bool     `json:"hasbasicconstraints"`
	BasicConstraintPathLength            int      `json:"basicconstraintpathlength"`
	CASecurityCollected                  bool     `json:"casecuritycollected"`
	EnrollmentAgentRestrictionsCollected bool     `json:"enrollmentagentrestrictionscollected"`
	IsUserSpecifiesSanEnabledCollected   bool     `json:"isuserspecifiessanenabledcollected"`
	RoleSeparationEnabledCollected       bool     `json:"roleseparationenabledcollected"`
	UnresolvedPublishedTemplates         []string `json:"unresolvedpublishedtemplates"`
}

type Entry

type Entry struct {
	ObjectIdentifier string
	ObjectTypeRaw    ObjectTypeEnum
}

Entry represents a cached typed principal with its object identifier and type.

func (*Entry) FromTypedPrincipal

func (e *Entry) FromTypedPrincipal(r *TypedPrincipal)

func (*Entry) ToTypedPrincipal

func (e *Entry) ToTypedPrincipal() TypedPrincipal
type GPLink struct {
	DN     string
	Option int
}

type GPLinkEntry added in v0.3.0

type GPLinkEntry struct {
	GPLink     string
	ObjectType string // "domain" or "ou"
}

GPLinkEntry stores gPLink and object type for domains/OUs

type GPLinkRef

type GPLinkRef struct {
	GUID       string
	IsEnforced bool
}

type GPO

type GPO struct {
	BaseADObject
	Properties GPOProperties `json:"Properties"`
}

GPO represents a Group Policy Object in AD.

func BuildGPOFromEntry

func BuildGPOFromEntry(entry *gildap.LDAPEntry) (*GPO, bool)

BuildGPOFromEntry constructs a GPO object from an LDAP entry.

type GPOCache

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

GPOCache maintains GPO entries indexed by DN

func NewGPOCache

func NewGPOCache() *GPOCache

NewGPOCache creates a new GPO cache

func (*GPOCache) Clear added in v0.2.0

func (c *GPOCache) Clear()

Clear removes all entries from the cache

func (*GPOCache) Get

func (c *GPOCache) Get(dn string) (*GPOCacheEntry, bool)

Get retrieves a GPO entry by DN (case-insensitive)

func (*GPOCache) Set

func (c *GPOCache) Set(dn string, entry *GPOCacheEntry)

Set stores a GPO entry by its DN (case-insensitive)

type GPOCacheEntry

type GPOCacheEntry struct {
	Name    string
	GUID    string
	GPOPath string
	Flags   string
}

GPOCacheEntry stores GPO attributes needed for local group processing

type GPOChanges

type GPOChanges struct {
	AffectedComputers  []TypedPrincipal `json:"AffectedComputers"`
	DcomUsers          []TypedPrincipal `json:"DcomUsers"`
	LocalAdmins        []TypedPrincipal `json:"LocalAdmins"`
	PSRemoteUsers      []TypedPrincipal `json:"PSRemoteUsers"`
	RemoteDesktopUsers []TypedPrincipal `json:"RemoteDesktopUsers"`
}

GPOChanges represents GPO-related deltas linked to an OU or domain. (theoretically Sites too, but those are not used in BloodHound)

func (*GPOChanges) IsEmpty added in v0.3.0

func (gc *GPOChanges) IsEmpty() bool

IsEmpty checks if there are any GPO changes recorded.

type GPOProperties

type GPOProperties struct {
	BaseProperties
	Name           string `json:"name"`
	IsACLProtected bool   `json:"isaclprotected"`
	GPCPath        string `json:"gpcpath"`
	HighValue      bool   `json:"highvalue"`
}

GPOProperties contains descriptive and identifying metadata for a GPO.

type Group

type Group struct {
	BaseADObject
	HasSIDHistory []TypedPrincipal `json:"HasSIDHistory"`
	Properties    GroupProperties  `json:"Properties"`
	Members       []TypedPrincipal `json:"Members"`
}

Group represents an Active Directory group object.

func BuildGroupFromEntry

func BuildGroupFromEntry(entry *gildap.LDAPEntry) (*Group, bool)

BuildGroupFromEntry constructs a Group object from an LDAP entry.

type GroupProperties

type GroupProperties struct {
	BaseProperties
	Name                   string   `json:"name"`
	SAMAccountName         string   `json:"samaccountname"` // Optional?
	IsACLProtected         bool     `json:"isaclprotected"`
	AdminCount             bool     `json:"admincount"` // Optional?
	HighValue              bool     `json:"highvalue"`
	SIDHistory             []string `json:"sidhistory"`
	AdminSDHolderProtected bool     `json:"adminsdholderprotected"`
}

GroupProperties holds the AD group attributes.

type IntRegistryAPIResult

type IntRegistryAPIResult struct {
	APIResult
	Value int
}

type IsChannelBindingRequiredAPIResult

type IsChannelBindingRequiredAPIResult struct {
	APIResult
	Result *bool
}

type IsSigningRequiredAPIResult

type IsSigningRequiredAPIResult struct {
	APIResult
	Result *bool
}

type IsWebClientRunningAPIResult

type IsWebClientRunningAPIResult struct {
	APIResult
	Result *bool
}

type IssuancePolicy

type IssuancePolicy struct {
	BaseADObject
	Properties IssuancePolicyProperties `json:"Properties"`
	GroupLink  TypedPrincipal           `json:"GroupLink"`
}

func BuildIssuancePolicyFromEntry

func BuildIssuancePolicyFromEntry(entry *gildap.LDAPEntry) (*IssuancePolicy, bool)

BuildIssuancePolicyFromEntry constructs an IssuancePolicy object from an LDAP entry.

type IssuancePolicyProperties

type IssuancePolicyProperties struct {
	BaseProperties
	Name            string `json:"name"`
	DisplayName     string `json:"displayname"`
	CertTemplateOID string `json:"certtemplateoid"`
	OIDGroupLink    string `json:"oidgrouplink,omitempty"`
}

type LdapServicesResult

type LdapServicesResult struct {
	HasLdap                  bool                              `json:"HasLdap"`
	HasLdaps                 bool                              `json:"HasLdaps"`
	IsSigningRequired        IsSigningRequiredAPIResult        `json:"IsSigningRequired"`
	IsChannelBindingRequired IsChannelBindingRequiredAPIResult `json:"IsChannelBindingRequired"`
}

type LocalGroupAPIResult

type LocalGroupAPIResult struct {
	APIResult
	ObjectIdentifier string           `json:"ObjectIdentifier"`
	Name             string           `json:"Name"`
	Results          []TypedPrincipal `json:"Results"`
	LocalNames       []NamedPrincipal `json:"LocalNames"`
}

type NTAuthStore

type NTAuthStore struct {
	BaseADObject
	DomainSID  string                `json:"DomainSID"`
	Properties NTAuthStoreProperties `json:"Properties"`
}

func BuildNTAuthStoreFromEntry

func BuildNTAuthStoreFromEntry(entry *gildap.LDAPEntry) (*NTAuthStore, bool)

BuildNTAuthStoreFromEntry constructs an NTAuthStore object from an LDAP entry.

type NTAuthStoreProperties

type NTAuthStoreProperties struct {
	BaseProperties
	Name            string   `json:"name"`
	CertThumbprints []string `json:"certthumbprints"`
}

type NTLMRegistryData

type NTLMRegistryData struct {
	APIResult
	Result NTLMRegistryValues
}

type NTLMRegistryValues

type NTLMRegistryValues struct {
	RestrictSendingNtlmTraffic   *uint32  `json:"RestrictSendingNtlmTraffic"`
	RestrictReceivingNtlmTraffic *uint32  `json:"RestrictReceivingNtlmTraffic"`
	NtlmMinServerSec             *uint32  `json:"NtlmMinServerSec"`
	NtlmMinClientSec             *uint32  `json:"NtlmMinClientSec"`
	LmCompatibilityLevel         *uint32  `json:"LmCompatibilityLevel"`
	UseMachineId                 *uint32  `json:"UseMachineId"`
	RequireSecuritySignature     *uint32  `json:"RequireSecuritySignature"`
	EnableSecuritySignature      *uint32  `json:"EnableSecuritySignature"`
	ClientAllowedNTLMServers     []string `json:"ClientAllowedNTLMServers"`
}

type NTLMSession

type NTLMSession struct {
	TimeCreatedUtc string `json:"TimeCreatedUtc"`
	Id             string `json:"Id"`
	AccountSid     string `json:"AccountSid"`
	AccountName    string `json:"AccountName"`
	AccountDomain  string `json:"AccountDomain"`
	SourceHost     string `json:"SourceHost"`
	SourceIp       string `json:"SourceIp"`
	SourcePort     string `json:"SourcePort"`
	PackageName    string `json:"PackageName"`
}

type NTLMSessionAPIResult

type NTLMSessionAPIResult struct {
	APIResult
	Sessions           []NTLMSession
	CollectionDuration time.Duration
}

type NamedPrincipal

type NamedPrincipal struct {
	ObjectIdentifier string `json:"ObjectIdentifier"`
	PrincipalName    string `json:"PrincipalName"`
}

type OUProperties

type OUProperties struct {
	BaseProperties
	Name              string `json:"name"`
	IsACLProtected    bool   `json:"isaclprotected"`
	BlocksInheritance bool   `json:"blocksinheritance"`
	HighValue         bool   `json:"highvalue"`
}

OUProperties contains the OU-specific metadata.

type ObjectTypeEnum

type ObjectTypeEnum uint8

TODO: Improve usage of these labels

const (
	BaseObjectType ObjectTypeEnum = iota
	UserObjectType
	ComputerObjectType
	GroupObjectType
	LocalGroupObjectType
	LocalUserObjectType
	GPOObjectType
	DomainObjectType
	OUObjectType
	ContainerObjectType
	ConfigurationObjectType
	CertTemplateObjectType
	RootCAObjectType
	AIACAObjectType
	EnterpriseCAObjectType
	NTAuthStoreObjectType
	IssuancePolicyObjectType
	FSPObjectType
	TrustAccountObjectType
)

type OrganizationalUnit

type OrganizationalUnit struct {
	BaseADObject
	Properties        OUProperties     `json:"Properties"`
	Links             []GPLinkRef      `json:"Links"`
	ChildObjects      []TypedPrincipal `json:"ChildObjects"`
	GPOChanges        GPOChanges       `json:"GPOChanges"`
	InheritanceHashes []string         `json:"InheritanceHashes"`
}

OrganizationalUnit represents an AD OU with nested properties and linked GPOs.

func BuildOUFromEntry

func BuildOUFromEntry(entry *gildap.LDAPEntry) (*OrganizationalUnit, bool)

BuildOUFromEntry constructs an OrganizationalUnit object from an LDAP entry.

type ParentChildCache

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

ParentChildCache maintains parent-child relationships in AD containers using sharded concurrent maps for scalability.

func NewParentChildCache

func NewParentChildCache(numShards int) *ParentChildCache

NewParentChildCache creates a sharded cache for parent-child relationships. The number of shards is rounded up to the next power of 2.

func (*ParentChildCache) AddChild

func (c *ParentChildCache) AddChild(parentDN string, child *Entry)

AddChild adds a child object to the specified parent DN.

func (*ParentChildCache) Clear added in v0.2.0

func (c *ParentChildCache) Clear()

Clear removes all entries from the cache

func (*ParentChildCache) Delete

func (c *ParentChildCache) Delete(parentDN string)

Delete removes all children for a parent DN.

func (*ParentChildCache) GetChildren

func (c *ParentChildCache) GetChildren(parentDN string) ([]Entry, bool)

GetChildren retrieves all direct children for a parent DN.

func (*ParentChildCache) HasChildren

func (c *ParentChildCache) HasChildren(parentDN string) bool

HasChildren checks if a parent DN has any children without returning them.

func (*ParentChildCache) SetChildren

func (c *ParentChildCache) SetChildren(parentDN string, children []Entry)

SetChildren sets all children for a parent DN (replaces existing).

func (*ParentChildCache) Size

func (c *ParentChildCache) Size() int

Size returns the approximate number of parent entries.

func (*ParentChildCache) TotalChildren

func (c *ParentChildCache) TotalChildren() int

TotalChildren returns the approximate total number of child objects across all parents.

type RegistryAPIResult

type RegistryAPIResult struct {
	APIResult
	Value []byte
}

Registry-related types

type RootCA

type RootCA struct {
	BaseADObject
	DomainSID  string           `json:"DomainSID"`
	Properties RootCAProperties `json:"Properties"`
}

func BuildRootCAFromEntry

func BuildRootCAFromEntry(entry *gildap.LDAPEntry) (*RootCA, bool)

BuildRootCAFromEntry constructs a RootCA object from an LDAP entry.

type RootCAProperties

type RootCAProperties struct {
	BaseProperties
	Name                      string   `json:"name"`
	CertThumbprint            string   `json:"certthumbprint"`
	CertName                  string   `json:"certname"`
	CertChain                 []string `json:"certchain"`
	HasBasicConstraints       bool     `json:"hasbasicconstraints"`
	BasicConstraintPathLength int      `json:"basicconstraintpathlength"`
}

type SMBInfo added in v0.2.0

type SMBInfo struct {
	SigningEnabled bool `json:"SigningEnabled"`
}

type SMBInfoAPIResult

type SMBInfoAPIResult struct {
	APIResult
	Result SMBInfo
}

type SPNPrivilege

type SPNPrivilege struct {
	ComputerSID string `json:"ComputerSID"`
	Port        int    `json:"Port"`
	Service     string `json:"Service"`
}

User is the top-level object representing an AD user.

type Session

type Session struct {
	ComputerSID string `json:"ComputerSID"`
	UserSID     string `json:"UserSID"`
}

type SessionAPIResult

type SessionAPIResult struct {
	APIResult
	Results []Session `json:"Results"`
}

type SimpleCache

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

SimpleCache is a simple thread-safe cache for key<->value mappings.

func NewSimpleCache

func NewSimpleCache() *SimpleCache

NewSimpleCache creates a new cache.

func (*SimpleCache) Clear added in v0.2.0

func (c *SimpleCache) Clear()

Clear removes all entries from the cache

func (*SimpleCache) Get

func (c *SimpleCache) Get(key string) (string, bool)

Get retrieves a value by key. Returns (value, true) if found.

func (*SimpleCache) Set

func (c *SimpleCache) Set(key string, sid string)

Set stores or updates a key.

type State

type State struct {
	DomainControllers map[string][]TypedPrincipal // Domain SID → DCs in that domain

	AttrGUIDMap            sync.Map             // Schema attribute name → GUID mappings
	DomainSIDCache         *SimpleCache         // Domain name → SID
	SIDDomainCache         *SimpleCache         // SID → domain name
	NetBIOSDomainCache     *SimpleCache         // NetBIOS name → DNS domain name
	MemberCache            *StringCache         // DN → Entry
	SIDCache               *StringCache         // SID → Entry
	HostDnsCache           *StringCache         // domain+hostname → Computer Entry
	SamCache               *StringCache         // domain+sAMAccountName → Entry
	MachineSIDCache        *StringCache         // Object SID → Entry with MachineSID
	ChildCache             *ParentChildCache    // Parent DN → Child Entries
	AdminSDHolderHashCache sync.Map             // Domain → AdminSDHolder ACL hash
	CertTemplateCache      *StringCache         // domain+template CN/OID → Cert Template Entry
	GPOCache               *GPOCache            // DN → GPO metadata (for GPO local group processing)
	WellKnown              *WellKnownSIDTracker // Seen well-known SIDs (S-1-5-32-*, etc)
	CacheWaitGroup         sync.WaitGroup       // Waitgroup for cache loading
	EmptySDCount           int                  // # of entries with empty security descriptors
	// contains filtered or unexported fields
}

State maintains global caches and mappings during BloodHound data construction. This is a singleton accessed via BState().

func BState

func BState() *State

BState returns the singleton State instance.

func (*State) CacheEntries

func (st *State) CacheEntries(reader *reader.MPReader, identifier string, logger *core.Logger, shouldAbort func() bool, progressCallback func(processed, total int)) error

CacheEntries reads LDAP entries from a msgpack file and populates multiple caches for efficient lookups during remote collection / conversion steps. Different entry types are cached in different ways based on the identifier (domains, users, computers, etc).

func (*State) Clear

func (st *State) Clear()

Clear clears all cached data and resets the state

func (*State) GetCachedComputerDNMap added in v0.3.0

func (st *State) GetCachedComputerDNMap() map[string]map[string]string

GetCachedComputerDNMap returns computer SID map stored for GPO collection, keyed by domain then DN

func (st *State) GetCachedGPLinks() map[string]GPLinkEntry

GetCachedGPLinks returns gPLink entries stored for GPO collection (domains and OUs), keyed by DN

func (*State) GetForestRoot

func (st *State) GetForestRoot(domain string) string

func (*State) Init

func (st *State) Init(forestMapPath string)

Init prepares the state for a new operation. This is called at the start of each remote collection and conversion operations.

func (*State) IsCacheLoaded

func (st *State) IsCacheLoaded(fileName string) bool

IsCacheLoaded checks if a msgpack file has already been loaded into caches. This prevents re-processing the same file multiple times.

func (*State) MarkCacheLoaded

func (st *State) MarkCacheLoaded(fileName string)

MarkCacheLoaded records that a msgpack file has been processed.

type StrRegistryAPIResult

type StrRegistryAPIResult struct {
	APIResult
	Value string
}

type StringCache

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

StringCache is a concurrent sharded map keyed by xxhash64 of arbitrary strings. Sharding avoids a global lock and improves write performance.

func NewCache

func NewCache(numShards int) *StringCache

NewCache creates a new cache with N shards. Use a power of two (e.g. 16, 32, 64) for best performance.

func (*StringCache) Clear added in v0.2.0

func (c *StringCache) Clear()

Clear removes all entries from the cache

func (*StringCache) Delete

func (c *StringCache) Delete(dn string)

Delete removes an entry by a key if present.

func (*StringCache) Get

func (c *StringCache) Get(key string) (Entry, bool)

Get retrieves an entry by a key. Returns (Entry, true) if found.

func (*StringCache) Set

func (c *StringCache) Set(key string, e *Entry)

Set stores or updates an entry keyed by a key.

func (*StringCache) Size

func (c *StringCache) Size() int

Size returns the approximate number of entries.

type TypedPrincipal

type TypedPrincipal struct {
	ObjectIdentifier string `json:"ObjectIdentifier"`
	ObjectType       string `json:"ObjectType"`
}

General types

func ResolveAccountName added in v0.3.0

func ResolveAccountName(account, domainName string) (TypedPrincipal, bool)

ResolveAccountName resolves an account name (sAMAccountName or DOMAIN\sAMAccountName) to a typed principal. It checks the SamCache and also tries appending $ for computer accounts. Returns the typed principal and true if found, or an empty principal and false if not found.

func ResolveSID

func ResolveSID(sid string, domainName string) TypedPrincipal

ResolveSID resolves a SID to a typed principal, checking well-known SIDs first.

func ResolveSIDFromCache

func ResolveSIDFromCache(sid string) (TypedPrincipal, bool)

ResolveSIDFromCache looks up a SID in the cache and returns the typed principal.

type User

type User struct {
	BaseADObject
	Properties              UserProperties   `json:"Properties"`
	AllowedToDelegate       []TypedPrincipal `json:"AllowedToDelegate"`
	UnconstrainedDelegation bool             `json:"UnconstrainedDelegation"`
	PrimaryGroupSID         string           `json:"PrimaryGroupSID"`
	HasSIDHistory           []TypedPrincipal `json:"HasSIDHistory"`
	SPNTargets              []SPNPrivilege   `json:"SPNTargets"`
	DomainSID               string           `json:"DomainSID"`
}

func BuildUserFromEntry

func BuildUserFromEntry(entry *gildap.LDAPEntry) (*User, bool)

BuildUserFromEntry constructs a User object from an LDAP entry.

type UserProperties

type UserProperties struct {
	BaseProperties
	Name                    string   `json:"name"`
	SAMAccountName          string   `json:"samaccountname"`
	IsACLProtected          bool     `json:"isaclprotected"`
	Sensitive               bool     `json:"sensitive"`
	DontReqPreauth          bool     `json:"dontreqpreauth"`
	PasswordNotReqd         bool     `json:"passwordnotreqd"`
	UnconstrainedDelegation bool     `json:"unconstraineddelegation"`
	PwdNeverExpires         bool     `json:"pwdneverexpires"`
	Enabled                 bool     `json:"enabled"`
	TrustedToAuth           bool     `json:"trustedtoauth"`
	LastLogon               int64    `json:"lastlogon"`
	LastLogonTimestamp      int64    `json:"lastlogontimestamp"`
	PwdLastSet              int64    `json:"pwdlastset"`
	ServicePrincipalNames   []string `json:"serviceprincipalnames"`
	HasSPN                  bool     `json:"hasspn"`
	DisplayName             string   `json:"displayname"`
	Email                   string   `json:"email"`           // Nullable
	Title                   string   `json:"title"`           // Nullable
	HomeDirectory           string   `json:"homedirectory"`   // Nullable
	UserPassword            string   `json:"userpassword"`    // Nullable
	UnixPassword            string   `json:"unixpassword"`    // Nullable
	UnicodePassword         string   `json:"unicodepassword"` // Nullable
	SFUPassword             string   `json:"sfupassword"`     // Nullable
	LogonScript             string   `json:"logonscript"`     // Nullable
	AllowedToDelegate       []string `json:"allowedtodelegate,omitempty"`
	AdminCount              bool     `json:"admincount"`
	SIDHistory              []string `json:"sidhistory"`
	AdminSDHolderProtected  bool     `json:"adminsdholderprotected"`
}

UserProperties holds various extracted attributes.

type UserRightsAPIResult

type UserRightsAPIResult struct {
	APIResult
	Privilege  string
	Results    []TypedPrincipal
	LocalNames []NamedPrincipal
}

type UserRightsAssignmentAPIResult

type UserRightsAssignmentAPIResult struct {
	APIResult
	Privilege  string
	Results    []TypedPrincipal
	LocalNames []NamedPrincipal
}

type WellKnownGroup

type WellKnownGroup struct {
	BaseADObject
	Properties WellKnownProperties `json:"Properties"`
	Members    []TypedPrincipal    `json:"Members"`
}

func BuildWellKnownGroup

func BuildWellKnownGroup(sid, name string, domainName string, domainSID string) WellKnownGroup

BuildWellKnownGroup creates a well-known group object for BloodHound

type WellKnownProperties

type WellKnownProperties struct {
	BaseProperties
	Name string `json:"name"`
}

type WellKnownSIDTracker

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

WellKnownSIDTracker tracks well-known SIDs and which ones have been seen

func NewWellKnownSIDTracker

func NewWellKnownSIDTracker() *WellKnownSIDTracker

NewWellKnownSIDTracker creates a new tracker with the well-known SIDs

func (*WellKnownSIDTracker) Get

func (w *WellKnownSIDTracker) Get(sid string) (gildap.WksDesc, bool)

Get retrieves a well-known SID and marks it as seen

func (*WellKnownSIDTracker) GetAll

func (w *WellKnownSIDTracker) GetAll() map[string]gildap.WksDesc

GetAll returns all well-known SIDs (for iteration purposes, does not mark as seen)

func (*WellKnownSIDTracker) GetSeen

func (w *WellKnownSIDTracker) GetSeen() map[string]gildap.WksDesc

GetSeen returns only the well-known SIDs that have been marked as seen

func (*WellKnownSIDTracker) IsSeenWellKnownPrincipal

func (w *WellKnownSIDTracker) IsSeenWellKnownPrincipal(sid string) bool

IsSeenWellKnownPrincipal checks if a SID has been marked as seen

type WellKnownUser

type WellKnownUser struct {
	BaseADObject
	Properties WellKnownProperties `json:"Properties"`
}

func BuildWellKnownUser

func BuildWellKnownUser(sid, name string, domainName string, domainSID string) WellKnownUser

BuildWellKnownUser creates a well-known user object for BloodHound

Jump to

Keyboard shortcuts

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