@@ -19,7 +19,7 @@ import (
1919)
2020
2121var (
22- version = "0.3.1 "
22+ version = "0.3.2 "
2323)
2424
2525// Application entry point
@@ -84,20 +84,24 @@ func main() {
8484 }
8585
8686 logger .Log0 ("🔍 [blue]Custom DNS resolver[-]: \" " + customDNS + "\" " )
87+ } else {
88+ logger .Log0 ("🔍 [blue]Using system DNS resolver: consider specifying a DNS server explicitly.[-]" )
8789 }
8890
8991 logger .Log0 ("⭕ [blue]LDAP scheme[-]: " + cfg .LdapAuthOptions .Scheme )
9092
91- // Check if we have authentication credentials
92- disableIngest := false
93- if cfg .ChosenAuthIngest == "" {
94- disableIngest = true
95- logger .Log0 ("🫠 [red]No authentication credentials detected for ingestion. Ingestion will be disabled for this session.[-]" )
96- }
97-
98- disableRemote := cfg .ChosenAuthIngest == "" && cfg .ChosenAuthRemote == ""
99- if disableRemote {
100- logger .Log0 ("🫠 [red]No authentication credentials detected for remote collection. Remote collection will be disabled for this session.[-]" )
93+ // Log LDAP obfuscation settings
94+ if cfg .LdapxFilter != "" || cfg .LdapxAttrs != "" || cfg .LdapxBaseDN != "" {
95+ logger .Log0 ("🎭 [blue]LDAP obfuscation (ldapx) enabled:[-]" )
96+ if cfg .LdapxFilter != "" {
97+ logger .Log0 (" [blue]Filter chain[-]: %s" , cfg .LdapxFilter )
98+ }
99+ if cfg .LdapxAttrs != "" {
100+ logger .Log0 (" [blue]Attrs chain[-]: %s" , cfg .LdapxAttrs )
101+ }
102+ if cfg .LdapxBaseDN != "" {
103+ logger .Log0 (" [blue]BaseDN chain[-]: %s" , cfg .LdapxBaseDN )
104+ }
101105 }
102106
103107 bhInst := & bloodhound.BH {}
@@ -112,21 +116,98 @@ func main() {
112116 if cfg .ChosenAuthIngest == "" {
113117 logger .Log0 ("🔗 [blue]Auth method (ingestion)[-]: None" )
114118 } else {
119+ // Auto-enable SimpleBind for anonymous authentication
120+ if cfg .ChosenAuthIngest == "Anonymous" {
121+ cfg .LdapAuthOptions .SimpleBind = true
122+ }
123+
115124 authMethodIngestStr := cfg .ChosenAuthIngest
116- if cfg .IngestAuth .Kerberos () {
117- authMethodIngestStr += " [blue](over Kerberos)[-]"
125+
126+ // For ingestion, SimpleBind takes precedence over all methods
127+ if cfg .LdapAuthOptions .SimpleBind {
128+ authMethodIngestStr += " [blue](SimpleBind)[-]"
129+ } else if cfg .IngestAuth .Kerberos () {
130+ // Certificate with Kerberos uses PKINIT
131+ // other credential types (password, NTHash, CCacche, AES Key) used with -k
132+ // should just be labeled "Kerberos"
133+ if cfg .ChosenAuthIngest == "CertPFX" || cfg .ChosenAuthIngest == "CertPEM" {
134+ authMethodIngestStr += " [blue](PKINIT/Kerberos)[-]"
135+ } else {
136+ authMethodIngestStr += " [blue](Kerberos)[-]"
137+ }
138+ } else if cfg .ChosenAuthIngest == "CertPFX" || cfg .ChosenAuthIngest == "CertPEM" {
139+ // Certificate without Kerberos can be said to use SChannel
140+ authMethodIngestStr += " [blue](SChannel)[-]"
141+ } else {
142+ // Otherwise, Password/NTHash uses NTLM
143+ authMethodIngestStr += " [blue](NTLM)[-]"
118144 }
119145
120146 logger .Log0 ("🔗 [blue]Auth method (ingestion)[-]: " + authMethodIngestStr )
121147 }
122148
123- if cfg .RuntimeOptions .GetRecurseTrusts () {
124- ingestNoCrossDomain := ! slices .Contains ([]string {"Password" , "NTHash" , "Anonymous" }, cfg .ChosenAuthIngest ) || cfg .IngestAuth .Kerberos ()
125- if ingestNoCrossDomain {
126- // Kerberos cross-realm auth should be feasible to implement,
127- // but I don't know how yet :)
128- logger .Log0 ("🫠 [yellow]RecurseTrusts disabled (not supported for this auth method)[-]" )
129- cfg .RuntimeOptions .SetRecurseTrusts (false )
149+ if cfg .ChosenAuthRemote == "Anonymous" {
150+ // Temporarily disabled until I can decide
151+ cfg .ChosenAuthRemote = ""
152+ }
153+
154+ if cfg .ChosenAuthRemote == "" {
155+ logger .Log0 ("🔗 [blue]Auth method (remote collection)[-]: None" )
156+ } else {
157+ authMethodRemoteStr := cfg .ChosenAuthRemote
158+ if cfg .ChosenAuthRemote == "CertPFX" || cfg .ChosenAuthRemote == "CertPEM" {
159+ // Certificates for remote collection always use PKINIT
160+ authMethodRemoteStr += " [blue](PKINIT/Kerberos)[-]"
161+ } else if cfg .RemoteAuth .Kerberos () {
162+ // Kerberos Ticket / AESKey
163+ authMethodRemoteStr += " [blue](Kerberos)[-]"
164+ } else {
165+ // Password / NTHash uses NTLM
166+ authMethodRemoteStr += " [blue](NTLM)[-]"
167+ }
168+
169+ logger .Log0 ("🔗 [blue]Auth method (remote collection)[-]: " + authMethodRemoteStr )
170+ }
171+
172+ // Check if we have proper authentication credentials
173+ // to determine whether to disable methods
174+ disableIngest := false
175+ if cfg .ChosenAuthIngest == "" {
176+ disableIngest = true
177+ logger .Log0 ("🫠 [red]No authentication credentials detected for ingestion. Ingestion will be disabled for this session.[-]" )
178+ }
179+
180+ disableRemote := cfg .ChosenAuthRemote == ""
181+ if disableRemote {
182+ logger .Log0 ("🫠 [red]No authentication credentials detected for remote collection. Remote collection will be disabled for this session.[-]" )
183+ }
184+
185+ // Check if we should disable recurse_trusts and search_forest
186+ // when using an auth method that doesn't support cross-domain authentication
187+ ingestNoCrossDomain := ! slices .Contains ([]string {"Password" , "NTHash" , "Anonymous" }, cfg .ChosenAuthIngest ) || cfg .IngestAuth .Kerberos () || (cfg .LdapAuthOptions .SimpleBind && cfg .ChosenAuthIngest != "Anonymous" )
188+
189+ if cfg .RuntimeOptions .GetRecurseTrusts () && ingestNoCrossDomain {
190+ logger .Log0 ("🫠 [yellow]RecurseTrusts disabled (not supported for this auth method)[-]" )
191+ cfg .RuntimeOptions .SetRecurseTrusts (false )
192+ }
193+
194+ if cfg .RuntimeOptions .GetSearchForest () && ingestNoCrossDomain {
195+ logger .Log0 ("🫠 [yellow]SearchForest disabled (not supported for this auth method)[-]" )
196+ cfg .RuntimeOptions .SetSearchForest (false )
197+ }
198+
199+ initialDomainRemote := strings .ToUpper (cfg .RemoteAuth .Creds ().Domain )
200+ remoteNoCrossDomain := initialDomainRemote != "." && (! slices .Contains ([]string {"Password" , "NTHash" }, cfg .ChosenAuthRemote ) || cfg .RemoteAuth .Kerberos ())
201+ if remoteNoCrossDomain {
202+ logger .Log0 ("🫠 [yellow]Remote collection methods will be limited to domain '" + initialDomainRemote + "' (cross-domain authentication not supported for this auth method)[-]" )
203+ }
204+
205+ // Temporary restriction until a better solution is implemented
206+ // TODO: Allow for NTHash too?
207+ if cfg .RuntimeOptions .IsMethodEnabled ("certservices" ) {
208+ if cfg .ChosenAuthRemote != "Password" {
209+ logger .Log0 ("🫠 [yellow]CertServices disabled (not supported for this auth method)[-]" )
210+ cfg .RuntimeOptions .DisableMethod ("certservices" )
130211 }
131212 }
132213
@@ -146,42 +227,19 @@ func main() {
146227 searchForest : cfg .RuntimeOptions .GetSearchForest (),
147228 ldapsToLdapFallback : cfg .RuntimeOptions .GetLdapsToLdapFallback (),
148229 appendForestDomains : cfg .RuntimeOptions .GetAppendForestDomains (),
230+ ldapxFilter : cfg .LdapxFilter ,
231+ ldapxAttrs : cfg .LdapxAttrs ,
232+ ldapxBaseDN : cfg .LdapxBaseDN ,
149233 }
150234
151235 conversionMgr := newConversionManager (bhInst , uiApp , logger )
152236
153- if cfg .ChosenAuthRemote == "" {
154- logger .Log0 ("🔗 [blue]Auth method (remote collection)[-]: None" )
155- } else {
156- authMethodRemoteStr := cfg .ChosenAuthRemote
157- if cfg .RemoteAuth .Kerberos () {
158- authMethodRemoteStr += " [blue](over Kerberos)[-]"
159- }
160-
161- logger .Log0 ("🔗 [blue]Auth method (remote collection)[-]: " + authMethodRemoteStr )
162- }
163-
164- initialDomainRemote := strings .ToUpper (cfg .RemoteAuth .Creds ().Domain )
165- remoteNoCrossDomain := initialDomainRemote != "." && (! slices .Contains ([]string {"Password" , "NTHash" , "Anonymous" }, cfg .ChosenAuthRemote ) || cfg .RemoteAuth .Kerberos ())
166- if remoteNoCrossDomain {
167- logger .Log0 ("🫠 [yellow]Remote collection methods will be limited to domain '" + initialDomainRemote + "' (cross-domain authentication not supported for this auth method)[-]" )
168- }
169-
170237 remoteMgr := newRemoteCollectionManager (
171238 bhInst ,
172239 uiApp ,
173240 logger ,
174241 )
175242
176- // Temporary restriction until a better solution is implemented
177- // TODO: Allow for NTHash too?
178- if cfg .RuntimeOptions .IsMethodEnabled ("certservices" ) {
179- if cfg .ChosenAuthRemote != "Password" {
180- logger .Log0 ("🫠 [yellow]CertServices disabled (not supported for this auth method)[-]" )
181- cfg .RuntimeOptions .DisableMethod ("certservices" )
182- }
183- }
184-
185243 var initialDomain , initialBaseDN , initialDC string
186244 if ! disableIngest {
187245 initialDomain = strings .ToUpper (cfg .IngestAuth .Creds ().Domain )
@@ -194,7 +252,11 @@ func main() {
194252 logger .Log0 ("🔗 [blue]Inferred BaseDN[-]: \" %s\" " , initialBaseDN )
195253
196254 initialDC = cfg .DomainController
197- logger .Log0 ("🔗 [blue]Initial DC[-]: \" %s\" " , initialDC )
255+ if initialDC == "" {
256+ logger .Log0 ("🔗 [blue]Initial DC[-]: (auto-discovered)" )
257+ } else {
258+ logger .Log0 ("🔗 [blue]Initial DC[-]: \" %s\" " , initialDC )
259+ }
198260 }
199261 }
200262 logger .Log0 ("-" )
0 commit comments