From 6f65b88f1b3a94c2bb6c3e3c97f64cdb253bde7b Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Tue, 23 Jul 2024 12:38:54 +0200 Subject: [PATCH] Merge remote-tracking branch 'origin/topic/awelzel/ldap-extended-request-response-starttls' * origin/topic/awelzel/ldap-extended-request-response-starttls: ldap: Add heuristic for wrap tokens ldap: Ignore ec/rrc for sealed wrap tokens ldap: Add LDAP sample with SASL-SRP mechanism ldap: Reintroduce encryption after SASL heuristic ldap: Fix assuming GSS-SPNEGO for all bindResponses ldap: Implement extended request/response and StartTLS support (cherry picked from commit 6a6a5c3d0d60a1d4d32ba2173c035023c29fbf1d) --- scripts/base/protocols/ldap/consts.zeek | 7 + scripts/base/protocols/ldap/main.zeek | 3 + scripts/base/protocols/ldap/spicy-events.zeek | 41 +++ src/analyzer/protocol/ldap/CMakeLists.txt | 4 +- src/analyzer/protocol/ldap/ldap.evt | 15 ++ src/analyzer/protocol/ldap/ldap.spicy | 243 ++++++++++++++---- src/analyzer/protocol/ldap/ldap_zeek.spicy | 12 + .../conn.log | 11 + .../ldap.log | 13 + .../ldap_search.log | 11 + .../conn.log | 11 + .../ldap.log | 13 + .../ldap_search.log | 11 + .../conn.log | 11 + .../ldap.log | 12 + .../conn.log | 11 + .../ldap.log | 11 + .../scripts.base.protocols.ldap.starttls/out | 4 + .../ssl.log | 11 + .../conn.log | 11 + .../ldap.log | 13 + .../scripts.base.protocols.ldap.who-am-i/out | 3 + testing/btest/Traces/ldap/ldap-starttls.pcap | Bin 0 -> 6009 bytes testing/btest/Traces/ldap/ldap-who-am-i.pcap | Bin 0 -> 1248 bytes testing/btest/Traces/ldap/sasl-ntlm.pcap | Bin 0 -> 4052 bytes .../btest/Traces/ldap/sasl-scram-sha-512.pcap | Bin 0 -> 4297 bytes .../btest/Traces/ldap/sasl-srp-who-am-i.pcap | Bin 0 -> 2838 bytes .../base/protocols/ldap/sasl-ntlm.zeek | 12 + .../protocols/ldap/sasl-scram-sha-512.zeek | 12 + .../protocols/ldap/sasl-srp-who-am-i.zeek | 11 + .../scripts/base/protocols/ldap/starttls.zeek | 25 ++ .../scripts/base/protocols/ldap/who-am-i.zeek | 20 ++ 32 files changed, 506 insertions(+), 56 deletions(-) create mode 100644 src/analyzer/protocol/ldap/ldap_zeek.spicy create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/conn.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/ldap.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/ldap_search.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/conn.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/ldap.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/ldap_search.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.sasl-srp-who-am-i/conn.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.sasl-srp-who-am-i/ldap.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.starttls/conn.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.starttls/ldap.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.starttls/out create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.starttls/ssl.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/conn.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/ldap.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/out create mode 100644 testing/btest/Traces/ldap/ldap-starttls.pcap create mode 100644 testing/btest/Traces/ldap/ldap-who-am-i.pcap create mode 100644 testing/btest/Traces/ldap/sasl-ntlm.pcap create mode 100644 testing/btest/Traces/ldap/sasl-scram-sha-512.pcap create mode 100644 testing/btest/Traces/ldap/sasl-srp-who-am-i.pcap create mode 100644 testing/btest/scripts/base/protocols/ldap/sasl-ntlm.zeek create mode 100644 testing/btest/scripts/base/protocols/ldap/sasl-scram-sha-512.zeek create mode 100644 testing/btest/scripts/base/protocols/ldap/sasl-srp-who-am-i.zeek create mode 100644 testing/btest/scripts/base/protocols/ldap/starttls.zeek create mode 100644 testing/btest/scripts/base/protocols/ldap/who-am-i.zeek diff --git a/scripts/base/protocols/ldap/consts.zeek b/scripts/base/protocols/ldap/consts.zeek index bbd378c7e8..5b29fd22e4 100644 --- a/scripts/base/protocols/ldap/consts.zeek +++ b/scripts/base/protocols/ldap/consts.zeek @@ -120,4 +120,11 @@ export { "searching", [ LDAP::SearchDerefAlias_DEREF_FINDING_BASE ] = "finding", [ LDAP::SearchDerefAlias_DEREF_ALWAYS ] = "always", } &default="unknown"; + + const EXTENDED_REQUESTS = { + # StartTLS, https://datatracker.ietf.org/doc/html/rfc4511#section-4.14.1 + [ "1.3.6.1.4.1.1466.20037" ] = "StartTLS", + # whoami, https://datatracker.ietf.org/doc/html/rfc4532#section-2 + [ "1.3.6.1.4.1.4203.1.11.3" ] = "whoami", + } &default="unknown" &redef; } diff --git a/scripts/base/protocols/ldap/main.zeek b/scripts/base/protocols/ldap/main.zeek index 93c301a65a..da4a21871c 100644 --- a/scripts/base/protocols/ldap/main.zeek +++ b/scripts/base/protocols/ldap/main.zeek @@ -258,6 +258,9 @@ event LDAP::message(c: connection, } m$object = object; + + if ( opcode == LDAP::ProtocolOpcode_EXTENDED_REQUEST ) + m$object += fmt(" (%s)", EXTENDED_REQUESTS[object]); } if ( argument != "" ) { diff --git a/scripts/base/protocols/ldap/spicy-events.zeek b/scripts/base/protocols/ldap/spicy-events.zeek index fa670f3456..baa00ba548 100644 --- a/scripts/base/protocols/ldap/spicy-events.zeek +++ b/scripts/base/protocols/ldap/spicy-events.zeek @@ -98,3 +98,44 @@ global LDAP::search_result_entry: event ( message_id: int, object_name: string ); + +## Event generated for each ExtendedRequest in LDAP messages. +## +## c: The connection. +## +## message_id: The messageID element. +## +## request_name: The name of the extended request. +## +## request_value: The value of the extended request (empty if missing). +global LDAP::extended_request: event ( + c: connection, + message_id: int, + request_name: string, + request_value: string +); + +## Event generated for each ExtendedResponse in LDAP messages. +## +## c: The connection. +## +## message_id: The messageID element. +## +## result: The result code of the response. +## +## response_name: The name of the extended response (empty if missing). +## +## response_value: The value of the extended response (empty if missing). +global LDAP::extended_response: event ( + c: connection, + message_id: int, + result: LDAP::ResultCode, + response_name: string, + response_value: string +); + +## Event generated when a plaintext LDAP connection switched to TLS. +## +## c: The connection. +## +global LDAP::starttls: event(c: connection); diff --git a/src/analyzer/protocol/ldap/CMakeLists.txt b/src/analyzer/protocol/ldap/CMakeLists.txt index a687e880ff..3f69e6543d 100644 --- a/src/analyzer/protocol/ldap/CMakeLists.txt +++ b/src/analyzer/protocol/ldap/CMakeLists.txt @@ -1,5 +1,5 @@ spicy_add_analyzer( NAME LDAP PACKAGE_NAME spicy-ldap - SOURCES ldap.spicy ldap.evt asn1.spicy - MODULES LDAP ASN1) + SOURCES ldap.spicy ldap.evt asn1.spicy ldap_zeek.spicy + MODULES LDAP ASN1 LDAP_Zeek) diff --git a/src/analyzer/protocol/ldap/ldap.evt b/src/analyzer/protocol/ldap/ldap.evt index 96baef6f98..77f34fb62e 100644 --- a/src/analyzer/protocol/ldap/ldap.evt +++ b/src/analyzer/protocol/ldap/ldap.evt @@ -41,3 +41,18 @@ on LDAP::SearchRequest -> event LDAP::search_request($conn, on LDAP::SearchResultEntry -> event LDAP::search_result_entry($conn, message.messageID, self.objectName); + +on LDAP::ExtendedRequest -> event LDAP::extended_request($conn, + message.messageID, + self.requestName, + self.requestValue); + +on LDAP::ExtendedResponse -> event LDAP::extended_response($conn, + message.messageID, + message.result_.code, + self.responseName, + self.responseValue); + +# Once switched into MessageMode::TLS, we won't parse messages anymore, +# so this is raised just once. +on LDAP::Message if (ctx.messageMode == LDAP::MessageMode::TLS) -> event LDAP::starttls($conn); diff --git a/src/analyzer/protocol/ldap/ldap.spicy b/src/analyzer/protocol/ldap/ldap.spicy index 2d4f821d78..96f942d7a3 100644 --- a/src/analyzer/protocol/ldap/ldap.spicy +++ b/src/analyzer/protocol/ldap/ldap.spicy @@ -130,29 +130,104 @@ public type Result = unit { const GSSAPI_MECH_MS_KRB5 = "1.2.840.48018.1.2.2"; # Supported SASL stripping modes. -type SaslStripping = enum { - MS_KRB5 = 1, # Payload starts with a 4 byte length followed by a wrap token that may or may not be sealed. +type MessageMode = enum { + MS_KRB5 = 1, # Payload starts with a 4 byte length followed by a wrap token that may or may not be sealed. + TLS = 2, # Client/server used StartTLS, forward to SSL analyzer. + MAYBE_ENCRYPTED = 3, # Use a heuristic to determine encrypted traffic. + CLEARTEXT = 4, # Assume cleartext. + ENCRYPTED = 5, # Assume encrypted. }; type Ctx = struct { - saslStripping: SaslStripping; # Which mode of SASL stripping to use. + messageMode: MessageMode; # Message dispatching mode + saslMechanism: string; # The SASL mechanism selected by the client. + startTlsRequested: bool; # Did the client use the StartTLS extended request? }; #----------------------------------------------------------------------------- public type Messages = unit { %context = Ctx; - : SASLStrip(self.context())[]; + : MessageDispatch(self.context())[]; }; #----------------------------------------------------------------------------- -public type SASLStrip = unit(ctx: Ctx&) { - switch( ctx.saslStripping ) { - SaslStripping::Undef -> : Message(ctx); - SaslStripping::MS_KRB5 -> : SaslMsKrb5Stripper(ctx); +public type MessageDispatch = unit(ctx: Ctx&) { + switch( ctx.messageMode ) { + MessageMode::Undef -> : Message(ctx); + MessageMode::MS_KRB5 -> : SaslMsKrb5Stripper(ctx); + MessageMode::TLS -> : TlsForward; # never returns + MessageMode::MAYBE_ENCRYPTED -> : MaybeEncrypted(ctx); + MessageMode::CLEARTEXT -> : Message(ctx); + MessageMode::ENCRYPTED -> : EncryptedMessage; }; }; +#----------------------------------------------------------------------------- +type MaybeEncrypted = unit(ctx: Ctx&) { + # A plaintext LDAP message always starts with at least 3 bytes and the first + # byte is 0x30 for the sequence. A SASL encrypted message starts with a 4 byte + # length field. The heuristic here is that if the first byte is a 0x30, + # assume it's unencrypted LDAP. This should be pretty good, if it was an + # encrypted/SASL wrapped message, it would have a size between 0x30000000 and + # 0x30FFFFFF, meaning at least a size of ~768MB, which seems unlikely. + var start: iterator; + var saslLen: uint64; + var mech: bytes; + + on %init { + self.start = self.input(); + # Don't have starts_with() on string, work around that. + # https://github.com/zeek/spicy/issues/1807 + self.mech = ctx.saslMechanism.encode(spicy::Charset::UTF8); + } + + first: uint8 { + if ( $$ == 0x30 ) { + ctx.messageMode = MessageMode::CLEARTEXT; + } else { + ctx.messageMode = MessageMode::ENCRYPTED; + } + } + + # As a further heuristic, if encrypted mode was decided and the client + # requested GSSAPI or GSS-SPNEGO (or we just didn't see it) peak a bit + # into the SASL payload and check if it starts with a 0504 (WRAP_TOKEN). + # If so, switch into KRB mode assuming that's what is being used and + # have a chance seeing some more plaintext LDAP in non-sealed tokens. + rem: uint8[3] if ( ctx.messageMode == MessageMode::ENCRYPTED && (|self.mech| == 0 || self.mech.starts_with(b"GSS")) ) { + self.saslLen = (self.first << 24) + ($$[0] << 16) + ($$[1] << 8) + $$[2]; + } + + : uint16 if ( self.saslLen >= 2 ) { + if ( $$ == 0x0504 ) { + ctx.messageMode = MessageMode::MS_KRB5; + } + } + + # Rewind the input. + : void { + # Prevent MessageDispatch from recursing endlessly. + assert ctx.messageMode != MessageMode::MAYBE_ENCRYPTED; + self.set_input(self.start); + } + + # One recursion to parse with the new ctx.messageMode setting. + : MessageDispatch(ctx); +}; + +#----------------------------------------------------------------------------- +type EncryptedMessage = unit { + len: uint32; + : skip bytes &size=self.len; +}; + +#----------------------------------------------------------------------------- +type TlsForward = unit { + # Just consume everything. This is hooked in ldap_zeek.spicy + chunk: bytes &chunked &eod; +}; + type KrbWrapToken = unit { # https://datatracker.ietf.org/doc/html/rfc4121#section-4.2.6.2 @@ -174,7 +249,10 @@ type KrbWrapToken = unit { } else if ( self.rrc == 0 ) { self.trailer_ec = self.ec; } else { - throw "Unhandled rc %s and ec %s" % (self.ec, self.rrc); + if ( ! self.ctx_flags.sealed ) + # If it's sealed, we'll consume until &eod anyhow + # and ec/rrc shouldn't apply, otherwise, bail. + throw "Unhandled rc %s and ec %s" % (self.ec, self.rrc); } } @@ -223,6 +301,7 @@ public type Message = unit(ctx: Ctx&) { var arg: string = ""; var seqHeaderLen: uint64; var msgLen: uint64; + var opLen: uint64; seqHeader: ASN1::ASN1Header &requires=($$.tag.class == ASN1::ASN1Class::Universal && $$.tag.type_ == ASN1::ASN1Type::Sequence) { self.msgLen = $$.len.len; @@ -241,10 +320,11 @@ public type Message = unit(ctx: Ctx&) { protocolOp: ASN1::ASN1Header &requires=($$.tag.class == ASN1::ASN1Class::Application) { self.opcode = cast(cast($$.tag.type_)); + self.opLen = $$.len.len; } switch ( self.opcode ) { - ProtocolOpcode::BIND_REQUEST -> BIND_REQUEST: BindRequest(self); + ProtocolOpcode::BIND_REQUEST -> BIND_REQUEST: BindRequest(self, ctx); ProtocolOpcode::BIND_RESPONSE -> BIND_RESPONSE: BindResponse(self, ctx); ProtocolOpcode::UNBIND_REQUEST -> UNBIND_REQUEST: UnbindRequest(self); ProtocolOpcode::SEARCH_REQUEST -> SEARCH_REQUEST: SearchRequest(self); @@ -263,12 +343,12 @@ public type Message = unit(ctx: Ctx&) { # just commenting this out, it will stop processing LDAP Messages in this connection ProtocolOpcode::ADD_REQUEST -> ADD_REQUEST: NotImplemented(self); ProtocolOpcode::COMPARE_REQUEST -> COMPARE_REQUEST: NotImplemented(self); - ProtocolOpcode::EXTENDED_REQUEST -> EXTENDED_REQUEST: NotImplemented(self); - ProtocolOpcode::EXTENDED_RESPONSE -> EXTENDED_RESPONSE: NotImplemented(self); + ProtocolOpcode::EXTENDED_REQUEST -> EXTENDED_REQUEST: ExtendedRequest(self, ctx); + ProtocolOpcode::EXTENDED_RESPONSE -> EXTENDED_RESPONSE: ExtendedResponse(self, ctx); ProtocolOpcode::INTERMEDIATE_RESPONSE -> INTERMEDIATE_RESPONSE: NotImplemented(self); ProtocolOpcode::MOD_DN_REQUEST -> MOD_DN_REQUEST: NotImplemented(self); ProtocolOpcode::SEARCH_RESULT_REFERENCE -> SEARCH_RESULT_REFERENCE: NotImplemented(self); - } &size=self.protocolOp.len.len; + } &size=self.opLen; # Ensure some invariants hold after parsing the command. : void &requires=(self.offset() >= self.seqHeaderLen); @@ -296,7 +376,7 @@ type GSS_SPNEGO_negTokenInit = unit { }; # Peak into GSS-SPNEGO payload and ensure it is indeed GSS-SPNEGO. -type GSS_SPNEGO = unit { +type GSS_SPNEGO_Init = unit { # This is the optional octet string in SaslCredentials. credentialsHeader: ASN1::ASN1Header &requires=($$.tag.type_ == ASN1::ASN1Type::OctetString); @@ -322,12 +402,19 @@ type SaslCredentials = unit() { # Peak into GSS-SPNEGO payload if we have any. switch ( self.mechanism ) { - "GSS-SPNEGO" -> gss_spnego: GSS_SPNEGO; + "GSS-SPNEGO" -> gss_spnego: GSS_SPNEGO_Init; * -> : skip bytes &eod; }; }; -type NegTokenResp = unit { +type GSS_SPNEGO_Subsequent = unit { + token: ASN1::ASN1Header &requires=($$.tag.class == ASN1::ASN1Class::ContextSpecific); + switch ( self.token.tag.type_ ) { + ASN1::ASN1Type(1) -> negTokenResp: GSS_SPNEGO_negTokenResp; + }; +}; + +type GSS_SPNEGO_negTokenResp = unit { var accepted: bool; var supportedMech: ASN1::ASN1Message; @@ -355,34 +442,13 @@ type NegTokenResp = unit { } &parse-from=self.supportedMech.application_data; }; -type ServerSaslCreds = unit { - serverSaslCreds: ASN1::ASN1Header &requires=($$.tag.class == ASN1::ASN1Class::ContextSpecific && $$.tag.type_ == ASN1::ASN1Type(7)); - - # The PCAP missing_ldap_logs.pcapng has a1 81 b6 here for the GSS-SPNEGO response. - # - # This is context-specific ID 1, constructed, and a length of 182 as - # specified by in 4.2 of RFC4178. - # - # https://www.rfc-editor.org/rfc/rfc4178#section-4.2 - # - # TODO: This is only valid for a GSS-SPNEGO negTokenResp. - # If you want to support something else, remove the requires - # and add more to the switch below. - choice: ASN1::ASN1Header &requires=($$.tag.class == ASN1::ASN1Class::ContextSpecific); - - switch ( self.choice.tag.type_ ) { - ASN1::ASN1Type(1) -> negTokenResp: NegTokenResp; - # ... - } &size=self.choice.len.len; -}; - # TODO(fox-ds): A helper unit for requests for which no handling has been implemented. # Eventually all uses of this unit should be replaced with actual parsers so this unit can be removed. type NotImplemented = unit(inout message: Message) { : skip bytes &eod; }; -type BindRequest = unit(inout message: Message) { +type BindRequest = unit(inout message: Message, ctx: Ctx&) { version: ASN1::ASN1Message(True) &convert=$$.body.num_value; name: ASN1::ASN1Message(True) &convert=$$.body.str_value { message.obj = self.name; @@ -406,12 +472,32 @@ type BindRequest = unit(inout message: Message) { saslCreds: SaslCredentials() &parse-from=self.authData if ((self.authType == BindAuthType::BIND_AUTH_SASL) && (|self.authData| > 0)) { message.arg = self.saslCreds.mechanism; + ctx.saslMechanism = self.saslCreds.mechanism; } } &requires=(self?.authType && (self.authType != BindAuthType::Undef)); +type ServerSaslCreds = unit { + serverSaslCreds: ASN1::ASN1Header &requires=($$.tag.class == ASN1::ASN1Class::ContextSpecific && $$.tag.type_ == ASN1::ASN1Type(7)); + payload: bytes &size=self.serverSaslCreds.len.len; +}; + type BindResponse = unit(inout message: Message, ctx: Ctx&) { : Result { message.result_ = $$; + + # The SASL authentication was successful. We do not actually + # know if the following messages are encrypted or not. This may be + # mechanism and parameter specific. For example SCRAM-SHA512 or NTLM + # will continue to be cleartext, while SRP or GSS-API would be encrypted. + # + # Switch messageMode into trial mode which is explored via MessageDispatch + # and the MaybeEncrypted unit. + # + # Note, messageMode may be changed to something more specific like + # MS_KRB5 below. + if ( |ctx.saslMechanism| > 0 && $$.code == ResultCode::SUCCESS ) { + ctx.messageMode = MessageMode::MAYBE_ENCRYPTED; + } } # Try to parse serverSaslCreds if there's any input remaining. This @@ -421,14 +507,18 @@ type BindResponse = unit(inout message: Message, ctx: Ctx&) { # if the serverSaslCreds field exists or not. But, not sure we can # check if there's any bytes left at this point outside of passing # in the length and playing with offset(). - serverSaslCreds: ServerSaslCreds[] &eod { - if ( |self.serverSaslCreds| > 0 ) { - if ( self.serverSaslCreds[0]?.negTokenResp ) { - local token = self.serverSaslCreds[0].negTokenResp; - if ( token.accepted && token?.supportedMechOid ) { - if ( token.supportedMechOid == GSSAPI_MECH_MS_KRB5 ) { - ctx.saslStripping = SaslStripping::MS_KRB5; - } + serverSaslCreds: ServerSaslCreds[] &eod; + + # If the client requested GSS-SPNEGO, try to parse the server's response + # to switch message mode. + gss_spnego: GSS_SPNEGO_Subsequent &parse-from=self.serverSaslCreds[0].payload + if (ctx.saslMechanism == "GSS-SPNEGO" && |self.serverSaslCreds| > 0) { + + if ( $$?.negTokenResp ) { + local token = $$.negTokenResp; + if ( token.accepted && token?.supportedMechOid ) { + if ( token.supportedMechOid == GSSAPI_MECH_MS_KRB5 ) { + ctx.messageMode = MessageMode::MS_KRB5; } } } @@ -980,16 +1070,61 @@ type AbandonRequest = unit(inout message: Message) { #----------------------------------------------------------------------------- # Extended Operation # https://tools.ietf.org/html/rfc4511#section-4.12 +type ExtendedRequest = unit(inout message: Message, ctx: Ctx&) { + var requestValue: bytes; + header: ASN1::ASN1Header &requires=($$.tag.class == ASN1::ASN1Class::ContextSpecific); + requestName: bytes &size=self.header.len.len &convert=$$.decode(spicy::Charset::ASCII) { + message.obj = $$; + } -# TODO: implement ExtendedRequest -# type ExtendedRequest = unit(inout message: Message) { -# -# }; + # If there's more byte to parse, it's the requestValue. + : ASN1::ASN1Message(False) + &requires=($$.head.tag.class == ASN1::ASN1Class::ContextSpecific) + if ( message.opLen > self.offset() ) { -# TODO: implement ExtendedResponse -# type ExtendedResponse = unit(inout message: Message) { -# -# }; + self.requestValue = $$.application_data; + } + + on %done { + # Did the client request StartTLS? + # + # https://datatracker.ietf.org/doc/html/rfc4511#section-4.14.1 + if ( self.requestName == "1.3.6.1.4.1.1466.20037" ) + ctx.startTlsRequested = True; + } +}; + +#----------------------------------------------------------------------------- +type ExtendedResponseEntry = unit(inout r: ExtendedResponse) { + : ASN1::ASN1Message(False) &requires=($$.head.tag.class == ASN1::ASN1Class::ContextSpecific) { + if ( $$.head.tag.type_ == ASN1::ASN1Type(10) ) + r.responseName = $$.application_data; + else if ( $$.head.tag.type_ == ASN1::ASN1Type(11) ) + r.responseValue = $$.application_data; + else + throw "Unhandled extended response tag %s" % $$.head.tag; + } +}; + +#----------------------------------------------------------------------------- +type ExtendedResponse = unit(inout message: Message, ctx: Ctx&) { + var responseName: bytes; + var responseValue: bytes; + : Result { + message.result_ = $$; + } + + # Try to parse two ASN1 entries if there are bytes left in the unit. + # Both are optional and identified by context specific tagging. + : ExtendedResponseEntry(self) if ( message.opLen > self.offset() ); + : ExtendedResponseEntry(self) if ( message.opLen > self.offset() ); + + on %done { + # Client had requested StartTLS and it was successful? Switch to SSL. + if ( ctx.startTlsRequested && message.result_.code == ResultCode::SUCCESS ) + ctx.messageMode = MessageMode::TLS; + } +}; #----------------------------------------------------------------------------- # IntermediateResponse Message diff --git a/src/analyzer/protocol/ldap/ldap_zeek.spicy b/src/analyzer/protocol/ldap/ldap_zeek.spicy new file mode 100644 index 0000000000..3a6784589f --- /dev/null +++ b/src/analyzer/protocol/ldap/ldap_zeek.spicy @@ -0,0 +1,12 @@ +module LDAP_Zeek; + +import LDAP; +import zeek; + +on LDAP::TlsForward::%init { + zeek::protocol_begin("SSL"); +} + +on LDAP::TlsForward::chunk { + zeek::protocol_data_in(zeek::is_orig(), self.chunk); +} diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/conn.log b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/conn.log new file mode 100644 index 0000000000..27c56bc33b --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/conn.log @@ -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 conn +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string count string count count count count set[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 60126 127.0.1.1 389 tcp ldap_tcp 2.290081 289 1509 SF 0 ShADadFf 12 921 15 2297 - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/ldap.log b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/ldap.log new file mode 100644 index 0000000000..cd94c49d5b --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/ldap.log @@ -0,0 +1,13 @@ +### 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 127.0.0.1 60126 127.0.1.1 389 1 3 bind SASL SASL bind in progress SASL(0): successful result: - NTLM +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 60126 127.0.1.1 389 2 3 bind SASL success - - NTLM +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 60126 127.0.1.1 389 4 - unbind - - - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/ldap_search.log b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/ldap_search.log new file mode 100644 index 0000000000..3ff2f3b1a6 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-ntlm/ldap_search.log @@ -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 127.0.0.1 60126 127.0.1.1 389 3 tree never dc=example,dc=com 9 success - (objectclass=*) - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/conn.log b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/conn.log new file mode 100644 index 0000000000..5fcce64ab8 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/conn.log @@ -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 conn +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string count string count count count count set[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 59552 127.0.1.1 389 tcp ldap_tcp 2.231680 353 1772 SF 0 ShADadFf 11 933 15 2560 - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/ldap.log b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/ldap.log new file mode 100644 index 0000000000..7c3478b262 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/ldap.log @@ -0,0 +1,13 @@ +### 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 127.0.0.1 59552 127.0.1.1 389 1 3 bind SASL SASL bind in progress SASL(0): successful result: user: sasladmin@slapd.ldap property: slapAuthzDN not found in sasldb - SCRAM-SHA-512 +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 59552 127.0.1.1 389 2 3 bind SASL success - - SCRAM-SHA-512 +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 59552 127.0.1.1 389 4 - unbind - - - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/ldap_search.log b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/ldap_search.log new file mode 100644 index 0000000000..edcf38ced5 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-scram-sha-512/ldap_search.log @@ -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 127.0.0.1 59552 127.0.1.1 389 3 tree never dc=example,dc=com 9 success - (objectclass=*) - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-srp-who-am-i/conn.log b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-srp-who-am-i/conn.log new file mode 100644 index 0000000000..2638ca3cba --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-srp-who-am-i/conn.log @@ -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 conn +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string count string count count count count set[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 60648 127.0.1.1 389 tcp ldap_tcp 2.114467 548 1020 SF 0 ShADadFf 9 1024 6 1340 - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-srp-who-am-i/ldap.log b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-srp-who-am-i/ldap.log new file mode 100644 index 0000000000..facaf46bc7 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.sasl-srp-who-am-i/ldap.log @@ -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 127.0.0.1 60648 127.0.1.1 389 1 3 bind SASL SASL bind in progress SASL(0): successful result: user: zeek@ubuntu-01.example.com property: slapAuthzDN not found in sasldb - SRP +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 60648 127.0.1.1 389 2 3 bind SASL success - - SRP +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/conn.log b/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/conn.log new file mode 100644 index 0000000000..db789c02c1 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/conn.log @@ -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 conn +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string count string count count count count set[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 45936 127.0.1.1 389 tcp ldap_tcp,ssl 0.016922 683 3002 RSTO 0 ShADadFR 14 1407 14 3738 - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/ldap.log b/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/ldap.log new file mode 100644 index 0000000000..95a084dab8 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/ldap.log @@ -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 CHhAvVGS1DHFjwGM9 127.0.0.1 45936 127.0.1.1 389 1 - extended success - 1.3.6.1.4.1.1466.20037 (StartTLS) - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/out b/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/out new file mode 100644 index 0000000000..08e6ccc9f2 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/out @@ -0,0 +1,4 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +CHhAvVGS1DHFjwGM9, extended_request, 1.3.6.1.4.1.1466.20037 (StartTLS), +CHhAvVGS1DHFjwGM9, extended_response, LDAP::ResultCode_SUCCESS, , +CHhAvVGS1DHFjwGM9, LDAP::starttls diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/ssl.log b/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/ssl.log new file mode 100644 index 0000000000..19fdd43528 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.starttls/ssl.log @@ -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 ssl +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name resumed last_alert next_protocol established ssl_history cert_chain_fps client_cert_chain_fps sni_matches_cert +#types time string addr port addr port string string string string bool string string bool string vector[string] vector[string] bool +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 45936 127.0.1.1 389 TLSv13 TLS_AES_256_GCM_SHA384 secp256r1 ubuntu-01.example.com F - - T CsiI - - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/conn.log b/testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/conn.log new file mode 100644 index 0000000000..9914fbe2dc --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/conn.log @@ -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 conn +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string count string count count count count set[string] +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 48122 127.0.1.1 389 tcp ldap_tcp 0.001192 83 59 SF 0 ShADadFf 8 507 5 327 - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/ldap.log b/testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/ldap.log new file mode 100644 index 0000000000..80da834eba --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/ldap.log @@ -0,0 +1,13 @@ +### 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 127.0.0.1 48122 127.0.1.1 389 1 3 bind simple success - cn=admin,dc=example,dc=com REDACTED +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 48122 127.0.1.1 389 2 - extended success - 1.3.6.1.4.1.4203.1.11.3 (whoami) - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 48122 127.0.1.1 389 3 - unbind - - - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/out b/testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/out new file mode 100644 index 0000000000..c4dbc10489 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.who-am-i/out @@ -0,0 +1,3 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +CHhAvVGS1DHFjwGM9, extended_request, 1.3.6.1.4.1.4203.1.11.3 (whoami), +CHhAvVGS1DHFjwGM9, extended_response, LDAP::ResultCode_SUCCESS, , dn:cn=admin,dc=example,dc=com diff --git a/testing/btest/Traces/ldap/ldap-starttls.pcap b/testing/btest/Traces/ldap/ldap-starttls.pcap new file mode 100644 index 0000000000000000000000000000000000000000..0cb6035125efd4ca7094ea308e0aec2ef1f37e9f GIT binary patch literal 6009 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 DyIjjT literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/ldap/ldap-who-am-i.pcap b/testing/btest/Traces/ldap/ldap-who-am-i.pcap new file mode 100644 index 0000000000000000000000000000000000000000..75dae01d4e5c84bb150be922d14eef212fba067d GIT binary patch literal 1248 zcmaKr&ui0g7{=dknyq8(U?<`nY)nBBf0V>^Q`;3r!Gn64;8kqaBsjF~ytpzZi?FKL zZHF-sFEWcDDhL)~wmS&w#i0j_?hhEd<=jKpLw(|TbR@e z&Qq^F-cxU-M8uD;0VZ$|YG?60iQ*&^ueBxiLH&JwpSVo9D?K=m7VH*yhGaf9KalUU zf%BZ#6Hi_%xPcwsz`gyvHqrGmIgY*om_)18&SJ;c?F&qtYD>foENr`p%Ah2qnIqO= zH9Q<14Xfb@^*Lo2FDgDG#WE^pQHt7Gtf&=JoRR9uXa`d-S(wqSxGSSg(TrMZ~YZL_5YFA9_4i&|@#3 IpCPx$KS)1C6#xJL literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/ldap/sasl-ntlm.pcap b/testing/btest/Traces/ldap/sasl-ntlm.pcap new file mode 100644 index 0000000000000000000000000000000000000000..ef2fb91ab4e18be7df4fbe120116ef99178c1ce9 GIT binary patch literal 4052 zcmb7{e`phD7{}kczD;YJ^p{oZkJ_kotJB#_twXJ4ZJk&({ef+DbDMg(T+^$`UCbro zWKL6bGOC+Y9Tf$Cfj`Ek(+Q3t_=o;6VGIP(unifLfH>G6f-rTPd!F}_cz2Bf-}KFU zx#Yg@=lMR*``-2T^-CvsLP@$ke@+MoA1+lK?w_XeWF;J9H@8BvjF2UX!4}fukh*rj z1v?1GJ-o;5K0M5wz+WEcw{I;!PY6%*FH^p-=+1-p*W-CEFRuWV>vJj-g33)lpem|! zyC2?rTsyKD)K4C-_&EH}w=a~Pn}=qidRn;!l-pn??B>Rp8xxxt^BNoTNl|LL^*onH$*DR@JA1ty z)Q#^wJ>AUt0^XR#otg|sc<)*ql|diaa@Y%c>{@Au=&g#FbD&r}eb->KZ$LH|9@FidY=(nXe%R^lb?aMVM3nIp@9|K*M( zLM$`Aw#+0T*XLNSy_U?(x(trg{^%fo!MxbbjXCmrLPbU2nXHPC>uW30ivCsTvk*VW zbNt5mDI?qQBdK)9N7C`2`7_p5Q0~_Vev4$5=kP|`w091n5u?2qHfo?^{6C`(Z(DC)YvVyn63AYTCjc5`DSN0U{| zyH=ZbSHQcg=$-3W#=COx&MWi-iC@e@B6x+lG&TKFoZeGS^P*aq7W$N-6J`JmY9VDm?VC6UbpHvp$CWdU7%&2M^7A@qwB&`5z57 z^7vjvkAF(1YO&^SSxcE{^-~B4b=D{*8&Oo4*~MU=szikn%4;!CA$1sP!W>%cmvt$k zgfT$RG&*Ierbb0Yl_TzcE#i*pa3HJEh$8D4pbrB41nz0r%?(q-g_Bb-z`jkk0MDlb zl;_w29O4#YghQN%z8+Kj&0xB!%j(=*;SO($7jOM|Nn7`Dd!bCbQplp%VPBA3o`8F})6C)yermN`LN(Lv4r@W+kT(r1N^y%)@ z$yu~CDhK88fTqfwv5-%Wc*En0yz97NZMC-O6>81JYOR3gGcn}d0=y>y6uY@G-h;_$jCYxp_fUJ9_rIq$-u1}) z9$OsCBU&t+4S4Y@0B075p@ziUf%r6_VmCKNJesU##4R@BvuWbx4{gLgB>s?AgTo!7 zGyoNujd{r{Fqbiti)dk552<$n^%20uZf=ZvUvfI5UTLNN(wV0I6do^eD~B6{v4O5d z>eZ|+R`^3=I7?kL3bU+BvXW-oeljJ&bP)9mK)nl$*v*Zh-b~goRF@4^PNQD9Z$pib zAZvUtt(DZ~fD9XfjGM_z%R>^TTDhIHD6HwqR(1t0eOT(S^bIMY61NC{YJEdxdvKi! z)2*9mDRr@{-J&FEF*S-|9)d7)+^#ocm{Pax=6dyU?V+=9yZ(Fsej`k{opoSVQ1J{X zu7h0|ySbrpoHyx4#lFvM#yw3Nr{PpDa@-*dah2%Y5a*(`xD&td?qyp+{J!v-)w@Zw zAQduoG80=31IE}`YV5rhUtv#i&U!pkpGwkXS`^d* zirO-O3pO$nVTE+1QM zqi%eFT6-;{*ooC94W?L>F}D&HM<*(ZITaHz#^|*%-T=lK%+A6LV>bj}`9DG^6M6su literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/ldap/sasl-scram-sha-512.pcap b/testing/btest/Traces/ldap/sasl-scram-sha-512.pcap new file mode 100644 index 0000000000000000000000000000000000000000..70fd3d6b0d3659dec9bf9e97aa1d87ecce5a5af5 GIT binary patch literal 4297 zcmb7{4@?{P702()kMPI*OQBu*C!4i2BOL_JV8BUZ2?ORo1TX}LZB@?a!#--?S$Ajt zc-{D;wMbdIbXis9KXk34sp_ODTDP{_5@=Fsnc8Sm6Q)L6D=nKAG)3K{NmG|i-FrXV z^zP!)<%uWY;J){H-}iox0#!%F0iSANLe9-S9Q0G4dH7!|Y2Q zZf2Udtk%xL4YLf(-dbj#E-nAyQT)wi+qb6o|BYd6B=@JpmS4EG{_YT7XLEA$Q28gD zDl-f!KmI1FqB{HZt!1_H_^HLuv_O}js`*!;~y}KKnb!4AhT`hYwUW@Xfm?SsD=Xj_l8sg*Cs%Lbf zSDk548V<;^-d;a?V5Ca#AN0%Ja;G{t=57-aw)9G>^z7x^Uq@K3&|>U0Fm?{g|M-K( z6l{_DpR;T0*KeTWE040w*I*(rje+H}efBp{vF7ht6}K@TGmmU2zJ`k20((Cgz%Q^R zg=`67$RWSi-@A)@Y_CI02!g0-5)?jg6kz9-x#j*L#U`i6qTp-5e~ ziGhBlGd|f9j7NL>v?DzecJmSq<0N^n9H zbRo)X8poiEr{-AZ6+pl=1|>Od{{?k%$?W3EQE+hS!LdcjXKFO65TS#ygki2wxNd5+p z{|=BbjX}vT*?&pNr!3?bGvr?_u#nFmLG<}&$iqs)GaxEy6U}~dVQ!bXiU(6w+-GFx zqa(7Ub0x&4B%JwVOG=HaBKDA|391yw0-cYLhgua`=OtNGVdJTERXRjjS0z!y0^foH zVa91%3uNQ=UtxhYSIh;T>dzGTW4IHC1WtXbH4Cg8D_mfmq%t9eJYc%4iE{O3Mn%GLi#N#Qvop$~`~|!qTKD_wz9kueb1O zkXL#1Oq0>GZVJbh6PqAAi;2C34{DC|#T}$n7o%c4qR3)@A{G=?XBjEk<>K6rIT{)o zcGvHztAlCVHqHy06qBOj@Mgd5;vlvY662+)^L|pEMr=-Zz6OpFcH=U1W0TGP9Cl;X zX*sg9YUSy}xY^&|k?IBLNRy^y?ZWP+z#_0uOQhL+Qvvw9Yp;jp#B~hF^xe{uh`$Bs859$iHU8J z3U3XHI^!%MMYVXPHf`yHq%f+4CD|Vlqfw`w6x0SKxi-ja5pFBV4U2-J85*$NY&D2s z!A7V53{G#dWxtP3uX1;9*`@QiWv|~!Ic?ms>!3IQO~W(>9nlv1Wjdmke}0zEXL|RX zWa(WIbWY4mzb4{r9A03VE)d2v2GxH&d5jY8%0j$?FHlP_n2EVu8%tW~o7p)K-o%O@ zP~jSj@H1-V(#qUcu;MRfVMGmlXER0n+tiBxn#Xu)1*}-4iZ?f`xQYg&;x{){Og>K; UcUu@2fpL|#>rWeu_?mL{e?Fa+O8@`> literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/ldap/sasl-srp-who-am-i.pcap b/testing/btest/Traces/ldap/sasl-srp-who-am-i.pcap new file mode 100644 index 0000000000000000000000000000000000000000..9e70f2d1b063516f418723540e8cc557d484e226 GIT binary patch literal 2838 zcmb7`3pkW%8^@n_W*n9aIfP1@$tqKr8KuNhidD+tGt$Xv@Q#LId~+bP)EJ}m_1UCa zBjvnHv<@Y^Y#XtZw6T>^)aszv(2*-tzULWRtJ${e`tIwx=bCx1XMXqpxu5&}zwfoC zllcTd0`FpS5&#VTF#j@(-Q5g;JN%AvdZ+_e0KVv1v7mfPv}dtG^EXPG8zB9tWCob%{S1|x(u>Foq1Jp4 z0*HVpl+!~&^zX4$5TiayGzJsleea0=0fk?G@2(uY_bKoaA4 zlNr^lSOq&EqY^F1Fg9V*xPZo$mLvewCE#i{- zxIn}e+LJ{BoNrG?n_MLd5k(6{R&<6nzJnDN!^N#bc~RsTJ}(C63*+IxxvUsxk#M`% z#giP(6O!3HQFIuY6HOMd1l+KYJyOD3I055uP)|g5JKMM)$$rMZ6R5v;Gp&MOgU{MC ztoE9bamev>uy>(=+E$&HHI#I)R}>eX@7QUkSGJzW(E4@P+T*uKZ@l}}S8#@Y2(N4p zK5TTv(Eb#Aw#r23cxgY?`1m(8&4WK~9E(3Vm>Kv-iIz~K`{kriu%*Mfv&pG=u7#;f zq(Pj+#ms7Zvk8e|?9XKJ8g5w9vn#b~dyKxEz3rII!_-%CYkghKPJdq6nHX3sUMRXU zI8L;j=pLb++QAB5m`>^wKdji}DIi{EQjcCDnS9lx-nGb2{-UI#N&4?{+gAhK6E%lU zUm$kniXYhCF^lpE@)c#{_xZ1{fBjsiSa)8I`=kJ1gc*FB;MaMrjD~2vas2k({&N^G zW&gHqpGW6jhEI05&^Ilx(eRR?dgJ$V36dm|QSt8}$!Kt%9hq*R&%FPVu@A^r6sSj? zbdPs3HU8`wCt&*{S+~Ed-S`TjUZ&$!i{%O0HD&SFqg?{yei%5mH2`G9TnKk-eN{_K zdah49CS3T%3HyV1f%RmXEV-iHLuS%Hcqs91y+y(U`LDZQbPVkOd@rZHvwhvVg&DP@ zk9UR^-P?cfMw!mOb)NFz2c?f!?sCyft}I%>8&I_iiqtIGRPwxoo4cxKUqncXZIPz+ z?ICTa=!^?uDBOadL$u~JaH(Rkqzb?lINcsZi6q~x;+4(4^sqFb^#g#Vh z0QfyBjOEB&>ukla_hIfCtfBdl>|`dTq; z>@1^LJ3>TkHqIAt#JJ-!TiYee(7nuo_wqlxLywihmkufU67*3YL*x!^WAA;51s%d1 z5mVy{;1M)`l+yz_9d@(F8W97AKT3q|FbHjI$~*lzh)9=W`2>s*EX9sYxt$a{Fy(hr zEEO)5VZce#PTxDF^{h^FCO2wz!)5Wzvy<&^<sqsZ|*Q{OU(F>O?Qs2 z+%9ZG)#`%qbic*bNAn3!>||P96#Fxrnu~Xn8*i?wy;Ue*qO#kO8Wby&Tse0?EA?e2 zPlx{MjJ2&zhR4pQ=QFwKPWH(ywT30~Z|kZ5U;%3#LczGac#EIwiKrgDN-UbCTh#;B1*Te~5D z)QGAc_a`FN(CP%3hIKfR`!Pl5%KLOiIgHloNcPqRyk~Ip9B%{ i584`ui1SlEsnJHEQR!W^tq*Fnu2oFiol>Y&A4anR8 literal 0 HcmV?d00001 diff --git a/testing/btest/scripts/base/protocols/ldap/sasl-ntlm.zeek b/testing/btest/scripts/base/protocols/ldap/sasl-ntlm.zeek new file mode 100644 index 0000000000..0504ba7a0a --- /dev/null +++ b/testing/btest/scripts/base/protocols/ldap/sasl-ntlm.zeek @@ -0,0 +1,12 @@ +# Copyright (c) 2024 by the Zeek Project. See LICENSE for details. + +# @TEST-REQUIRES: have-spicy +# @TEST-EXEC: zeek -C -r ${TRACES}/ldap/sasl-ntlm.pcap %INPUT +# @TEST-EXEC: cat conn.log | zeek-cut -Cn local_orig local_resp > conn.log2 && mv conn.log2 conn.log +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: btest-diff ldap.log +# @TEST-EXEC: btest-diff ldap_search.log +# @TEST-EXEC: ! test -f dpd.log +# @TEST-EXEC: ! test -f analyzer.log +# +# @TEST-DOC: This broke after #3826 got merged diff --git a/testing/btest/scripts/base/protocols/ldap/sasl-scram-sha-512.zeek b/testing/btest/scripts/base/protocols/ldap/sasl-scram-sha-512.zeek new file mode 100644 index 0000000000..9db41f96bc --- /dev/null +++ b/testing/btest/scripts/base/protocols/ldap/sasl-scram-sha-512.zeek @@ -0,0 +1,12 @@ +# Copyright (c) 2024 by the Zeek Project. See LICENSE for details. + +# @TEST-REQUIRES: have-spicy +# @TEST-EXEC: zeek -C -r ${TRACES}/ldap/sasl-scram-sha-512.pcap %INPUT +# @TEST-EXEC: cat conn.log | zeek-cut -Cn local_orig local_resp > conn.log2 && mv conn.log2 conn.log +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: btest-diff ldap.log +# @TEST-EXEC: btest-diff ldap_search.log +# @TEST-EXEC: ! test -f dpd.log +# @TEST-EXEC: ! test -f analyzer.log +# +# @TEST-DOC: This broke after #3826 got merged diff --git a/testing/btest/scripts/base/protocols/ldap/sasl-srp-who-am-i.zeek b/testing/btest/scripts/base/protocols/ldap/sasl-srp-who-am-i.zeek new file mode 100644 index 0000000000..b467dbe484 --- /dev/null +++ b/testing/btest/scripts/base/protocols/ldap/sasl-srp-who-am-i.zeek @@ -0,0 +1,11 @@ +# Copyright (c) 2024 by the Zeek Project. See LICENSE for details. + +# @TEST-REQUIRES: have-spicy +# @TEST-EXEC: zeek -C -r ${TRACES}/ldap/sasl-srp-who-am-i.pcap %INPUT +# @TEST-EXEC: cat conn.log | zeek-cut -Cn local_orig local_resp > conn.log2 && mv conn.log2 conn.log +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: btest-diff ldap.log +# @TEST-EXEC: ! test -f dpd.log +# @TEST-EXEC: ! test -f analyzer.log +# +# @TEST-DOC: SASL authentication using SRP (Secure Remote Password) diff --git a/testing/btest/scripts/base/protocols/ldap/starttls.zeek b/testing/btest/scripts/base/protocols/ldap/starttls.zeek new file mode 100644 index 0000000000..df94315210 --- /dev/null +++ b/testing/btest/scripts/base/protocols/ldap/starttls.zeek @@ -0,0 +1,25 @@ +# Copyright (c) 2024 by the Zeek Project. See LICENSE for details. + +# @TEST-REQUIRES: have-spicy +# @TEST-EXEC: zeek -C -r ${TRACES}/ldap/ldap-starttls.pcap %INPUT >out +# @TEST-EXEC: cat conn.log | zeek-cut -Cn local_orig local_resp > conn.log2 && mv conn.log2 conn.log +# @TEST-EXEC: btest-diff out +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: btest-diff ldap.log +# @TEST-EXEC: btest-diff ssl.log +# @TEST-EXEC: ! test -f dpd.log +# @TEST-EXEC: ! test -f analyzer.log +# +# @TEST-DOC: LDAP supports StartTLS through extendedRequest 1.3.6.1.4.1.1466.20037 + +event LDAP::extended_request(c: connection, message_id: int, request_name: string, request_value: string) { + print c$uid, "extended_request", fmt("%s (%s)", request_name, LDAP::EXTENDED_REQUESTS[request_name]), request_value; +} + +event LDAP::extended_response(c: connection, message_id: int, result: LDAP::ResultCode, response_name: string, response_value: string) { + print c$uid, "extended_response", result, response_name, response_value; +} + +event LDAP::starttls(c: connection) { + print c$uid, "LDAP::starttls"; +} diff --git a/testing/btest/scripts/base/protocols/ldap/who-am-i.zeek b/testing/btest/scripts/base/protocols/ldap/who-am-i.zeek new file mode 100644 index 0000000000..6026add5cc --- /dev/null +++ b/testing/btest/scripts/base/protocols/ldap/who-am-i.zeek @@ -0,0 +1,20 @@ +# Copyright (c) 2024 by the Zeek Project. See LICENSE for details. + +# @TEST-REQUIRES: have-spicy +# @TEST-EXEC: zeek -C -r ${TRACES}/ldap/ldap-who-am-i.pcap %INPUT >out +# @TEST-EXEC: cat conn.log | zeek-cut -Cn local_orig local_resp > conn.log2 && mv conn.log2 conn.log +# @TEST-EXEC: btest-diff out +# @TEST-EXEC: btest-diff conn.log +# @TEST-EXEC: btest-diff ldap.log +# @TEST-EXEC: ! test -f dpd.log +# @TEST-EXEC: ! test -f analyzer.log +# +# @TEST-DOC: Testing OpenLDAP's ldapwhoami utility with simple authentication. + +event LDAP::extended_request(c: connection, message_id: int, request_name: string, request_value: string) { + print c$uid, "extended_request", fmt("%s (%s)", request_name, LDAP::EXTENDED_REQUESTS[request_name]), request_value; +} + +event LDAP::extended_response(c: connection, message_id: int, result: LDAP::ResultCode, response_name: string, response_value: string) { + print c$uid, "extended_response", result, response_name, response_value; +}