mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
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 6a6a5c3d0d
)
This commit is contained in:
parent
cfe47f40a4
commit
6f65b88f1b
32 changed files with 506 additions and 56 deletions
|
@ -120,4 +120,11 @@ export {
|
||||||
"searching", [ LDAP::SearchDerefAlias_DEREF_FINDING_BASE ] =
|
"searching", [ LDAP::SearchDerefAlias_DEREF_FINDING_BASE ] =
|
||||||
"finding", [ LDAP::SearchDerefAlias_DEREF_ALWAYS ] = "always", }
|
"finding", [ LDAP::SearchDerefAlias_DEREF_ALWAYS ] = "always", }
|
||||||
&default="unknown";
|
&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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -258,6 +258,9 @@ event LDAP::message(c: connection,
|
||||||
}
|
}
|
||||||
|
|
||||||
m$object = object;
|
m$object = object;
|
||||||
|
|
||||||
|
if ( opcode == LDAP::ProtocolOpcode_EXTENDED_REQUEST )
|
||||||
|
m$object += fmt(" (%s)", EXTENDED_REQUESTS[object]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( argument != "" ) {
|
if ( argument != "" ) {
|
||||||
|
|
|
@ -98,3 +98,44 @@ global LDAP::search_result_entry: event (
|
||||||
message_id: int,
|
message_id: int,
|
||||||
object_name: string
|
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);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
spicy_add_analyzer(
|
spicy_add_analyzer(
|
||||||
NAME LDAP
|
NAME LDAP
|
||||||
PACKAGE_NAME spicy-ldap
|
PACKAGE_NAME spicy-ldap
|
||||||
SOURCES ldap.spicy ldap.evt asn1.spicy
|
SOURCES ldap.spicy ldap.evt asn1.spicy ldap_zeek.spicy
|
||||||
MODULES LDAP ASN1)
|
MODULES LDAP ASN1 LDAP_Zeek)
|
||||||
|
|
|
@ -41,3 +41,18 @@ on LDAP::SearchRequest -> event LDAP::search_request($conn,
|
||||||
on LDAP::SearchResultEntry -> event LDAP::search_result_entry($conn,
|
on LDAP::SearchResultEntry -> event LDAP::search_result_entry($conn,
|
||||||
message.messageID,
|
message.messageID,
|
||||||
self.objectName);
|
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);
|
||||||
|
|
|
@ -130,29 +130,104 @@ public type Result = unit {
|
||||||
const GSSAPI_MECH_MS_KRB5 = "1.2.840.48018.1.2.2";
|
const GSSAPI_MECH_MS_KRB5 = "1.2.840.48018.1.2.2";
|
||||||
|
|
||||||
# Supported SASL stripping modes.
|
# Supported SASL stripping modes.
|
||||||
type SaslStripping = enum {
|
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.
|
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 {
|
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 {
|
public type Messages = unit {
|
||||||
%context = Ctx;
|
%context = Ctx;
|
||||||
: SASLStrip(self.context())[];
|
: MessageDispatch(self.context())[];
|
||||||
};
|
};
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
public type SASLStrip = unit(ctx: Ctx&) {
|
public type MessageDispatch = unit(ctx: Ctx&) {
|
||||||
switch( ctx.saslStripping ) {
|
switch( ctx.messageMode ) {
|
||||||
SaslStripping::Undef -> : Message(ctx);
|
MessageMode::Undef -> : Message(ctx);
|
||||||
SaslStripping::MS_KRB5 -> : SaslMsKrb5Stripper(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<stream>;
|
||||||
|
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 {
|
type KrbWrapToken = unit {
|
||||||
# https://datatracker.ietf.org/doc/html/rfc4121#section-4.2.6.2
|
# https://datatracker.ietf.org/doc/html/rfc4121#section-4.2.6.2
|
||||||
|
|
||||||
|
@ -174,7 +249,10 @@ type KrbWrapToken = unit {
|
||||||
} else if ( self.rrc == 0 ) {
|
} else if ( self.rrc == 0 ) {
|
||||||
self.trailer_ec = self.ec;
|
self.trailer_ec = self.ec;
|
||||||
} else {
|
} 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 arg: string = "";
|
||||||
var seqHeaderLen: uint64;
|
var seqHeaderLen: uint64;
|
||||||
var msgLen: uint64;
|
var msgLen: uint64;
|
||||||
|
var opLen: uint64;
|
||||||
|
|
||||||
seqHeader: ASN1::ASN1Header &requires=($$.tag.class == ASN1::ASN1Class::Universal && $$.tag.type_ == ASN1::ASN1Type::Sequence) {
|
seqHeader: ASN1::ASN1Header &requires=($$.tag.class == ASN1::ASN1Class::Universal && $$.tag.type_ == ASN1::ASN1Type::Sequence) {
|
||||||
self.msgLen = $$.len.len;
|
self.msgLen = $$.len.len;
|
||||||
|
@ -241,10 +320,11 @@ public type Message = unit(ctx: Ctx&) {
|
||||||
|
|
||||||
protocolOp: ASN1::ASN1Header &requires=($$.tag.class == ASN1::ASN1Class::Application) {
|
protocolOp: ASN1::ASN1Header &requires=($$.tag.class == ASN1::ASN1Class::Application) {
|
||||||
self.opcode = cast<ProtocolOpcode>(cast<uint8>($$.tag.type_));
|
self.opcode = cast<ProtocolOpcode>(cast<uint8>($$.tag.type_));
|
||||||
|
self.opLen = $$.len.len;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ( self.opcode ) {
|
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::BIND_RESPONSE -> BIND_RESPONSE: BindResponse(self, ctx);
|
||||||
ProtocolOpcode::UNBIND_REQUEST -> UNBIND_REQUEST: UnbindRequest(self);
|
ProtocolOpcode::UNBIND_REQUEST -> UNBIND_REQUEST: UnbindRequest(self);
|
||||||
ProtocolOpcode::SEARCH_REQUEST -> SEARCH_REQUEST: SearchRequest(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
|
# just commenting this out, it will stop processing LDAP Messages in this connection
|
||||||
ProtocolOpcode::ADD_REQUEST -> ADD_REQUEST: NotImplemented(self);
|
ProtocolOpcode::ADD_REQUEST -> ADD_REQUEST: NotImplemented(self);
|
||||||
ProtocolOpcode::COMPARE_REQUEST -> COMPARE_REQUEST: NotImplemented(self);
|
ProtocolOpcode::COMPARE_REQUEST -> COMPARE_REQUEST: NotImplemented(self);
|
||||||
ProtocolOpcode::EXTENDED_REQUEST -> EXTENDED_REQUEST: NotImplemented(self);
|
ProtocolOpcode::EXTENDED_REQUEST -> EXTENDED_REQUEST: ExtendedRequest(self, ctx);
|
||||||
ProtocolOpcode::EXTENDED_RESPONSE -> EXTENDED_RESPONSE: NotImplemented(self);
|
ProtocolOpcode::EXTENDED_RESPONSE -> EXTENDED_RESPONSE: ExtendedResponse(self, ctx);
|
||||||
ProtocolOpcode::INTERMEDIATE_RESPONSE -> INTERMEDIATE_RESPONSE: NotImplemented(self);
|
ProtocolOpcode::INTERMEDIATE_RESPONSE -> INTERMEDIATE_RESPONSE: NotImplemented(self);
|
||||||
ProtocolOpcode::MOD_DN_REQUEST -> MOD_DN_REQUEST: NotImplemented(self);
|
ProtocolOpcode::MOD_DN_REQUEST -> MOD_DN_REQUEST: NotImplemented(self);
|
||||||
ProtocolOpcode::SEARCH_RESULT_REFERENCE -> SEARCH_RESULT_REFERENCE: 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.
|
# Ensure some invariants hold after parsing the command.
|
||||||
: void &requires=(self.offset() >= self.seqHeaderLen);
|
: 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.
|
# 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.
|
# This is the optional octet string in SaslCredentials.
|
||||||
credentialsHeader: ASN1::ASN1Header &requires=($$.tag.type_ == ASN1::ASN1Type::OctetString);
|
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.
|
# Peak into GSS-SPNEGO payload if we have any.
|
||||||
switch ( self.mechanism ) {
|
switch ( self.mechanism ) {
|
||||||
"GSS-SPNEGO" -> gss_spnego: GSS_SPNEGO;
|
"GSS-SPNEGO" -> gss_spnego: GSS_SPNEGO_Init;
|
||||||
* -> : skip bytes &eod;
|
* -> : 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 accepted: bool;
|
||||||
var supportedMech: ASN1::ASN1Message;
|
var supportedMech: ASN1::ASN1Message;
|
||||||
|
|
||||||
|
@ -355,34 +442,13 @@ type NegTokenResp = unit {
|
||||||
} &parse-from=self.supportedMech.application_data;
|
} &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.
|
# 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.
|
# Eventually all uses of this unit should be replaced with actual parsers so this unit can be removed.
|
||||||
type NotImplemented = unit(inout message: Message) {
|
type NotImplemented = unit(inout message: Message) {
|
||||||
: skip bytes &eod;
|
: 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;
|
version: ASN1::ASN1Message(True) &convert=$$.body.num_value;
|
||||||
name: ASN1::ASN1Message(True) &convert=$$.body.str_value {
|
name: ASN1::ASN1Message(True) &convert=$$.body.str_value {
|
||||||
message.obj = self.name;
|
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) &&
|
saslCreds: SaslCredentials() &parse-from=self.authData if ((self.authType == BindAuthType::BIND_AUTH_SASL) &&
|
||||||
(|self.authData| > 0)) {
|
(|self.authData| > 0)) {
|
||||||
message.arg = self.saslCreds.mechanism;
|
message.arg = self.saslCreds.mechanism;
|
||||||
|
ctx.saslMechanism = self.saslCreds.mechanism;
|
||||||
}
|
}
|
||||||
} &requires=(self?.authType && (self.authType != BindAuthType::Undef));
|
} &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&) {
|
type BindResponse = unit(inout message: Message, ctx: Ctx&) {
|
||||||
: Result {
|
: Result {
|
||||||
message.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
|
# 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
|
# 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
|
# check if there's any bytes left at this point outside of passing
|
||||||
# in the length and playing with offset().
|
# in the length and playing with offset().
|
||||||
serverSaslCreds: ServerSaslCreds[] &eod {
|
serverSaslCreds: ServerSaslCreds[] &eod;
|
||||||
if ( |self.serverSaslCreds| > 0 ) {
|
|
||||||
if ( self.serverSaslCreds[0]?.negTokenResp ) {
|
# If the client requested GSS-SPNEGO, try to parse the server's response
|
||||||
local token = self.serverSaslCreds[0].negTokenResp;
|
# to switch message mode.
|
||||||
if ( token.accepted && token?.supportedMechOid ) {
|
gss_spnego: GSS_SPNEGO_Subsequent &parse-from=self.serverSaslCreds[0].payload
|
||||||
if ( token.supportedMechOid == GSSAPI_MECH_MS_KRB5 ) {
|
if (ctx.saslMechanism == "GSS-SPNEGO" && |self.serverSaslCreds| > 0) {
|
||||||
ctx.saslStripping = SaslStripping::MS_KRB5;
|
|
||||||
}
|
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
|
# Extended Operation
|
||||||
# https://tools.ietf.org/html/rfc4511#section-4.12
|
# 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
|
# If there's more byte to parse, it's the requestValue.
|
||||||
# type ExtendedRequest = unit(inout message: Message) {
|
: ASN1::ASN1Message(False)
|
||||||
#
|
&requires=($$.head.tag.class == ASN1::ASN1Class::ContextSpecific)
|
||||||
# };
|
if ( message.opLen > self.offset() ) {
|
||||||
|
|
||||||
# TODO: implement ExtendedResponse
|
self.requestValue = $$.application_data;
|
||||||
# type ExtendedResponse = unit(inout message: Message) {
|
}
|
||||||
#
|
|
||||||
# };
|
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
|
# IntermediateResponse Message
|
||||||
|
|
12
src/analyzer/protocol/ldap/ldap_zeek.spicy
Normal file
12
src/analyzer/protocol/ldap/ldap_zeek.spicy
Normal file
|
@ -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);
|
||||||
|
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
BIN
testing/btest/Traces/ldap/ldap-starttls.pcap
Normal file
BIN
testing/btest/Traces/ldap/ldap-starttls.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/ldap/ldap-who-am-i.pcap
Normal file
BIN
testing/btest/Traces/ldap/ldap-who-am-i.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/ldap/sasl-ntlm.pcap
Normal file
BIN
testing/btest/Traces/ldap/sasl-ntlm.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/ldap/sasl-scram-sha-512.pcap
Normal file
BIN
testing/btest/Traces/ldap/sasl-scram-sha-512.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/ldap/sasl-srp-who-am-i.pcap
Normal file
BIN
testing/btest/Traces/ldap/sasl-srp-who-am-i.pcap
Normal file
Binary file not shown.
12
testing/btest/scripts/base/protocols/ldap/sasl-ntlm.zeek
Normal file
12
testing/btest/scripts/base/protocols/ldap/sasl-ntlm.zeek
Normal file
|
@ -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
|
|
@ -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
|
|
@ -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)
|
25
testing/btest/scripts/base/protocols/ldap/starttls.zeek
Normal file
25
testing/btest/scripts/base/protocols/ldap/starttls.zeek
Normal file
|
@ -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";
|
||||||
|
}
|
20
testing/btest/scripts/base/protocols/ldap/who-am-i.zeek
Normal file
20
testing/btest/scripts/base/protocols/ldap/who-am-i.zeek
Normal file
|
@ -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;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue