Merge remote-tracking branch 'origin/topic/awelzel/4275-ldap-gss-spnego-auth-miss'

* origin/topic/awelzel/4275-ldap-gss-spnego-auth-miss:
  ldap: Clean up from code review
  ldap: Add Sicily Authentication constants
  ldap: Only switch into MS_KRB5 mode if responseToken exists
This commit is contained in:
Arne Welzel 2025-04-16 09:34:09 +02:00
commit a2a535d0c9
13 changed files with 123 additions and 18 deletions

View file

@ -1,3 +1,11 @@
7.2.0-dev.541 | 2025-04-16 09:34:09 +0200
* ldap: Clean up from code review (Arne Welzel, Corelight)
* ldap: Add Sicily Authentication constants (Arne Welzel, Corelight)
* GH-4275: ldap: Only switch into MS_KRB5 mode if responseToken exists (Arne Welzel, Corelight)
7.2.0-dev.536 | 2025-04-15 18:31:28 +0200
* IXWebSocket: Bump to latest upstream master (Arne Welzel, Corelight)

View file

@ -1 +1 @@
7.2.0-dev.536
7.2.0-dev.541

View file

@ -26,6 +26,8 @@ export {
const BIND_SIMPLE = "bind simple";
const BIND_SASL = "bind SASL";
const BIND_SICILY_NEGOTIATE = "sicily_negotiate";
const BIND_SICILY_RESPONSE= "sicily_response";
const RESULT_CODES = { [ LDAP::ResultCode_SUCCESS ] = "success", [
LDAP::ResultCode_OPERATIONS_ERROR ] = "operations error", [

View file

@ -376,13 +376,23 @@ event LDAP::bind_request(c: connection,
if ( m?$opcode )
Reporter::conn_weird("LDAP_bind_opcode_already_set", c, m$opcode, "LDAP");
if (authType == LDAP::BindAuthType_BIND_AUTH_SIMPLE) {
switch ( authType ) {
case LDAP::BindAuthType_BIND_AUTH_SIMPLE:
m$opcode = BIND_SIMPLE;
} else if (authType == LDAP::BindAuthType_BIND_AUTH_SASL) {
break;
case LDAP::BindAuthType_BIND_AUTH_SASL:
m$opcode = BIND_SASL;
} else {
break;
case LDAP::BindAuthType_SICILY_NEGOTIATE:
m$opcode = BIND_SICILY_NEGOTIATE;
break;
case LDAP::BindAuthType_SICILY_RESPONSE:
m$opcode = BIND_SICILY_RESPONSE;
break;
default:
Reporter::conn_weird("LDAP_unknown_auth_type", c, cat(authType), "LDAP");
m$opcode = cat(authType);
break;
}
}

View file

@ -365,6 +365,12 @@ public type Message = unit(ctx: Ctx&) {
public type BindAuthType = enum {
BIND_AUTH_SIMPLE = 0,
BIND_AUTH_SASL = 3,
# https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/8b9dbfb2-5b6a-497a-a533-7e709cb9a982
# 5.1.1.1.3 Sicily Authentication
SICILY_PACKAGE_DISCOVERY = 9,
SICILY_NEGOTIATE = 10,
SICILY_RESPONSE = 11,
};
type GSS_SPNEGO_negTokenInit = unit {
@ -410,6 +416,13 @@ type SaslCredentials = unit() {
};
};
type SicilyMessage = unit() {
# Just ensure the signature matches. We could do more,
# but it'd be better to forward to an NTLM analyzer.
signature: skip b"NTLMSSP";
var signature_decoded: string = "NTLMSSP";
};
type GSS_SPNEGO_Subsequent = unit {
switch {
-> spnegoChoiceByte: uint8(0xa1);
@ -423,6 +436,7 @@ type GSS_SPNEGO_Subsequent = unit {
type GSS_SPNEGO_negTokenResp = unit {
var accepted: bool;
var supportedMech: ASN1::ASN1Message;
var responseToken: optional<bytes>;
# Parse the contained Sequence.
seq: ASN1::ASN1Message(True) {
@ -433,7 +447,7 @@ type GSS_SPNEGO_negTokenResp = unit {
} else if ( msg.application_id == 1 ) {
self.supportedMech = msg;
} else if ( msg.application_id == 2 ) {
# ignore responseToken
self.responseToken = msg.application_data;
} else if ( msg.application_id == 3 ) {
# ignore mechListMec
} else {
@ -468,18 +482,30 @@ type BindRequest = unit(inout message: Message, ctx: Ctx&) {
self.authType = cast<BindAuthType>(cast<uint8>($$.application_id));
self.authData = $$.application_data;
}
if ((self.authType == BindAuthType::BIND_AUTH_SIMPLE) && (|self.authData| > 0)) {
}
if ( |self.authData| > 0 ) {
switch ( self.authType ) {
BindAuthType::BIND_AUTH_SIMPLE ->
: void {
self.simpleCreds = self.authData.decode();
if (|self.simpleCreds| > 0) {
message.arg = self.simpleCreds;
}
}
}
saslCreds: SaslCredentials() &parse-from=self.authData if ((self.authType == BindAuthType::BIND_AUTH_SASL) &&
(|self.authData| > 0)) {
BindAuthType::BIND_AUTH_SASL ->
saslCreds: SaslCredentials {
message.arg = self.saslCreds.mechanism;
ctx.saslMechanism = self.saslCreds.mechanism;
}
BindAuthType::SICILY_NEGOTIATE, BindAuthType::SICILY_RESPONSE ->
sicilyMessage: SicilyMessage {
message.arg = self.sicilyMessage.signature_decoded;
}
* -> : void;
} &parse-from=self.authData;
};
} &requires=(self?.authType && (self.authType != BindAuthType::Undef));
type ServerSaslCreds = unit {
@ -523,7 +549,7 @@ type BindResponse = unit(inout message: Message, ctx: Ctx&) {
if ( $$?.negTokenResp ) {
local token = $$.negTokenResp;
if ( token.accepted && token?.supportedMechOid ) {
if ( token.supportedMechOid == GSSAPI_MECH_MS_KRB5 ) {
if ( token.supportedMechOid == GSSAPI_MECH_MS_KRB5 && token.responseToken ) {
ctx.messageMode = MessageMode::MS_KRB5;
}
}

View file

@ -0,0 +1,11 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path ldap
#open XXXX-XX-XX-XX-XX-XX
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p message_id version opcode result diagnostic_message object argument
#types time string addr port addr port int int string string string string string
XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 192.168.226.131 54544 192.168.226.136 389 1440128865 3 bind SASL success - User1 GSS-SPNEGO
#close XXXX-XX-XX-XX-XX-XX

View file

@ -0,0 +1,11 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path ldap_search
#open XXXX-XX-XX-XX-XX-XX
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p message_id scope deref_aliases base_object result_count result diagnostic_message filter attributes
#types time string addr port addr port int string string string count string string string vector[string]
XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 192.168.226.131 54544 192.168.226.136 389 1319382063 tree never dc=ADHACKING,dc=LOCAL 3 success - (&(&(sAMAccountName=*)(mail=*))(!(UserAccountControl:1.2.840.113556.1.4.803:=2))) -
#close XXXX-XX-XX-XX-XX-XX

View file

@ -0,0 +1,12 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path ldap
#open XXXX-XX-XX-XX-XX-XX
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p message_id version opcode result diagnostic_message object argument
#types time string addr port addr port int int string string string string string
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.226.131 37618 192.168.226.136 389 173945320 3 sicily_negotiate success - User1 NTLMSSP
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.226.131 37618 192.168.226.136 389 1489001992 3 sicily_response success - User1 NTLMSSP
#close XXXX-XX-XX-XX-XX-XX

View file

@ -0,0 +1,11 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path ldap_search
#open XXXX-XX-XX-XX-XX-XX
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p message_id scope deref_aliases base_object result_count result diagnostic_message filter attributes
#types time string addr port addr port int string string string count string string string vector[string]
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.226.131 37618 192.168.226.136 389 1673297393 tree never dc=ADHACKING,dc=LOCAL 3 success - (&(&(sAMAccountName=*)(mail=*))(!(UserAccountControl:1.2.840.113556.1.4.803:=2))) -
#close XXXX-XX-XX-XX-XX-XX

View file

@ -50,3 +50,6 @@ Trace Index/Sources:
Provided by Eldon Koyle Corelight for testing.
- cdp-v1.pcap
From the Wireshark library of captures at https://wiki.wireshark.org/samplecaptures.
- ldap/adduser1.pcap ldap/adduser1-ntlm.pcap
Provided by Mohan-Dhawan on #4275
https://github.com/zeek/zeek/issues/4275

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,11 @@
# @TEST-REQUIRES: have-spicy
# @TEST-EXEC: zeek -C -r ${TRACES}/ldap/aduser1.pcap %INPUT
# @TEST-EXEC: mkdir krb && mv *.log krb
# @TEST-EXEC: zeek -C -r ${TRACES}/ldap/aduser1-ntlm.pcap %INPUT
# @TEST-EXEC: mkdir ntlm && mv *.log ntlm
# @TEST-EXEC: btest-diff krb/ldap.log
# @TEST-EXEC: btest-diff krb/ldap_search.log
# @TEST-EXEC: btest-diff ntlm/ldap.log
# @TEST-EXEC: btest-diff ntlm/ldap_search.log
#
# @TEST-DOC: Check two traces using different authentication mechanisms, but the same search request.