ldap: Handle integrity-only KRB wrap tokens

Mostly staring at the PCAPs and opened a few RFCs. For now, only if the
MS_KRB5 OID is used and accepted in a bind response, start stripping
KRB5 wrap tokens for both, client and server traffic.

Would probably be nice to forward the GSS-API data to the analyzer...

Closes zeek/spicy-ldap#29.
This commit is contained in:
Arne Welzel 2024-07-11 20:09:55 +02:00
parent 9ba7c2ddaf
commit 31122f335f
11 changed files with 310 additions and 12 deletions

View file

@ -126,9 +126,22 @@ public type Result = unit {
# https://tools.ietf.org/html/rfc4511#section-4.1.10 # https://tools.ietf.org/html/rfc4511#section-4.1.10
}; };
# 1.2.840.48018.1.2.2 (MS KRB5 - Microsoft Kerberos 5)
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 Ctx = struct {
saslStripping: SaslStripping; # Which mode of SASL stripping to use.
};
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
public type Messages = unit { public type Messages = unit {
: MessageWrapper[]; %context = Ctx;
: SASLStrip(self.context())[];
}; };
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
@ -149,7 +162,76 @@ type SASLLayer = unit {
}; };
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
public type MessageWrapper = unit { public type SASLStrip = unit(ctx: Ctx&) {
switch( ctx.saslStripping ) {
SaslStripping::Undef -> :MessageWrapper(ctx);
SaslStripping::MS_KRB5 -> : SaslMsKrb5Stripper(ctx);
};
};
type KrbWrapToken = unit {
# https://datatracker.ietf.org/doc/html/rfc4121#section-4.2.6.2
# Number of bytes to expect *after* the payload.
var trailer_ec: uint64;
var header_ec: uint64;
ctx_flags: bitfield(8) {
send_by_acceptor: 0;
sealed: 1;
acceptor_subkey: 2;
};
filler: skip b"\xff";
ec: uint16; # extra count
rrc: uint16 { # right rotation count
# Handle rrc == ec or rrc == 0.
if ( self.rrc == self.ec ) {
self.header_ec = self.ec;
} else if ( self.rrc == 0 ) {
self.trailer_ec = self.ec;
} else {
throw "Unhandled rc %s and ec %s" % (self.ec, self.rrc);
}
}
snd_seq: uint64;
header_e: skip bytes &size=self.header_ec;
};
#-----------------------------------------------------------------------------
type SaslMsKrb5Stripper = unit(ctx: Ctx&) {
# This is based on Wireshark output and example traffic we have. There's always
# a 4 byte length field followed by the krb5_tok_id field in messages after
# MS_KRB5 was selected. I haven't read enough specs to understand if it's
# just this one case that works, or others could use the same stripping.
var switch_size: uint64;
len: uint32;
krb5_tok_id: uint16;
switch ( self.krb5_tok_id ) {
0x0504 -> krb_wrap_token: KrbWrapToken;
* -> : void;
};
: skip bytes &size=0 {
self.switch_size = self.len - (self.offset() - 4);
if ( self?.krb_wrap_token )
self.switch_size -= self.krb_wrap_token.trailer_ec;
}
switch ( self?.krb_wrap_token && ! self.krb_wrap_token.ctx_flags.sealed ) {
True -> : Message(ctx)[] &eod;
* -> : skip bytes &eod;
} &size=self.switch_size;
# Consume the wrap token trailer, if any.
trailer_e: skip bytes &size=self.krb_wrap_token.trailer_ec if (self?.krb_wrap_token);
};
#-----------------------------------------------------------------------------
public type MessageWrapper = unit(ctx: Ctx&) {
# A wrapper around 'Message'. First, we try to parse a Message unit. # A wrapper around 'Message'. First, we try to parse a Message unit.
# There are two possible outcomes: # There are two possible outcomes:
# (1) Success -> We consumed all bytes and successfully parsed a Message unit # (1) Success -> We consumed all bytes and successfully parsed a Message unit
@ -159,10 +241,10 @@ public type MessageWrapper = unit {
# This success variable is different, because this keeps track of the status for the MessageWrapper object # This success variable is different, because this keeps track of the status for the MessageWrapper object
var success: bool = False; var success: bool = False;
var message: Message; var message: optional<Message>;
# Here, we try to parse the message... # Here, we try to parse the message...
: Message &try { : Message(ctx) &try {
# ... and only if the Message unit successfully parsed, we can set # ... and only if the Message unit successfully parsed, we can set
# the status of this MessageWrapper's success to 'True' # the status of this MessageWrapper's success to 'True'
@ -205,7 +287,7 @@ public type MessageWrapper = unit {
# Also, we could try to do this recursively or try a few iterations, but for now I would suggest # Also, we could try to do this recursively or try a few iterations, but for now I would suggest
# to try this extra parsing once to get the best cost/benefit tradeoff. # to try this extra parsing once to get the best cost/benefit tradeoff.
: Message &try &parse-from=self.remainder if ( self.success == False && self.sasl_success == True ) { : Message(ctx) &try &parse-from=self.remainder if ( self.success == False && self.sasl_success == True ) {
if ( $$.success == True ) { if ( $$.success == True ) {
self.success = True; self.success = True;
self.message = $$; self.message = $$;
@ -218,7 +300,7 @@ public type MessageWrapper = unit {
} &convert=self.message; } &convert=self.message;
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
public type Message = unit { public type Message = unit(ctx: Ctx&) {
var messageID: int64; var messageID: int64;
var opcode: ProtocolOpcode = ProtocolOpcode::Undef; var opcode: ProtocolOpcode = ProtocolOpcode::Undef;
var applicationBytes: bytes; var applicationBytes: bytes;
@ -244,7 +326,7 @@ public type Message = unit {
switch ( self.opcode ) { switch ( self.opcode ) {
ProtocolOpcode::BIND_REQUEST -> BIND_REQUEST: BindRequest(self); ProtocolOpcode::BIND_REQUEST -> BIND_REQUEST: BindRequest(self);
ProtocolOpcode::BIND_RESPONSE -> BIND_RESPONSE: BindResponse(self); 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);
ProtocolOpcode::SEARCH_RESULT_ENTRY -> SEARCH_RESULT_ENTRY: SearchResultEntry(self); ProtocolOpcode::SEARCH_RESULT_ENTRY -> SEARCH_RESULT_ENTRY: SearchResultEntry(self);
@ -288,9 +370,93 @@ public type BindAuthType = enum {
BIND_AUTH_SASL = 3, BIND_AUTH_SASL = 3,
}; };
type GSS_SPNEGO_negTokenInit = unit {
oidHeader: ASN1::ASN1Header &requires=($$.tag.class == ASN1::ASN1Class::Universal && $$.tag.type_ == ASN1::ASN1Type::ObjectIdentifier);
oid: ASN1::ASN1ObjectIdentifier(self.oidHeader.len.len) &requires=(self.oid.oidstring == "1.3.6.1.5.5.2");
# TODO: Parse the rest of negTokenInit.
: skip bytes &eod;
};
# Peak into GSS-SPNEGO payload and ensure it is indeed GSS-SPNEGO.
type GSS_SPNEGO = unit {
# This is the optional octet string in SaslCredentials.
credentialsHeader: ASN1::ASN1Header &requires=($$.tag.type_ == ASN1::ASN1Type::OctetString);
# Now we either have the initial message as specified in RFC2743 or
# a continuation from RFC4178
#
# 60 -> APPLICATION [0] https://datatracker.ietf.org/doc/html/rfc2743#page-81)
# a1 -> CHOICE [1] https://www.rfc-editor.org/rfc/rfc4178#section-4.2
#
gssapiHeader: ASN1::ASN1Header &requires=(
$$.tag.class == ASN1::ASN1Class::Application && $$.tag.type_ == ASN1::ASN1Type(0)
|| $$.tag.class == ASN1::ASN1Class::ContextSpecific && $$.tag.type_ == ASN1::ASN1Type(1)
);
switch ( self.gssapiHeader.tag.type_ ) {
ASN1::ASN1Type(0) -> initial: GSS_SPNEGO_negTokenInit;
* -> : skip bytes &eod;
} &size=self.gssapiHeader.len.len;
};
type SaslCredentials = unit() { type SaslCredentials = unit() {
mechanism: ASN1::ASN1Message(True) &convert=$$.body.str_value; mechanism: ASN1::ASN1Message(False) &convert=$$.body.str_value;
# TODO: if we want to parse the (optional) credentials string
# Peak into GSS-SPNEGO payload if we have any.
switch ( self.mechanism ) {
"GSS-SPNEGO" -> gss_spnego: GSS_SPNEGO;
* -> : skip bytes &eod;
};
};
type NegTokenResp = unit {
var accepted: bool;
var supportedMech: ASN1::ASN1Message;
# Parse the contained Sequence.
seq: ASN1::ASN1Message(True) {
for ( msg in $$.body.seq.submessages ) {
# https://www.rfc-editor.org/rfc/rfc4178#section-4.2.2
if ( msg.application_id == 0 ) {
self.accepted = msg.application_data == b"\x0a\x01\x00";
} else if ( msg.application_id == 1 ) {
self.supportedMech = msg;
} else if ( msg.application_id == 2 ) {
# ignore responseToken
} else if ( msg.application_id == 3 ) {
# ignore mechListMec
} else {
throw "unhandled NegTokenResp id %s" % msg.application_id;
}
}
}
switch ( self?.supportedMech ) {
True -> supportedMechOid: ASN1::ASN1Message(False) &convert=$$.body.str_value;
* -> : void;
} &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.
@ -324,14 +490,32 @@ type BindRequest = unit(inout message: Message) {
(|self.authData| > 0)) { (|self.authData| > 0)) {
message.arg = self.saslCreds.mechanism; message.arg = self.saslCreds.mechanism;
} }
} &requires=((self?.authType) && (self.authType != BindAuthType::Undef)); } &requires=(self?.authType && (self.authType != BindAuthType::Undef));
type BindResponse = unit(inout message: Message) { type BindResponse = unit(inout message: Message, ctx: Ctx&) {
: Result { : Result {
message.result_ = $$; message.result_ = $$;
} }
# TODO: if we want to parse SASL credentials returned # Try to parse serverSaslCreds if there's any input remaining. This
# unit is parsed with &size, so &eod here works.
#
# Technically we should be able to tell from the ASN.1 structure
# 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;
}
}
}
}
}
}; };
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------

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 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 192.168.10.138 63815 192.168.10.186 389 tcp ldap_tcp 0.033404 3046 90400 RSTR 0 ShADdar 14 1733 68 93132 -
#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.10.138 63815 192.168.10.186 389 3 3 bind SASL success - - GSS-SPNEGO
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.10.138 63815 192.168.10.186 389 9 - unbind - - - -
#close XXXX-XX-XX-XX-XX-XX

View file

@ -0,0 +1,14 @@
### 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.10.138 63815 192.168.10.186 389 1 base never - 1 success - (objectclass=*) -
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.10.138 63815 192.168.10.186 389 4 base never - 1 success - (objectClass=*) -
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.10.138 63815 192.168.10.186 389 6 single never CN=Schema,CN=Configuration,DC=matrix,DC=local 424 success - (&(!(isdefunct=TRUE))(|(|(|(|(|(attributeSyntax=2.5.5.17)(attributeSyntax=2.5.5.10))(attributeSyntax=2.5.5.15))(attributeSyntax=2.5.5.1))(attributeSyntax=2.5.5.7))(attributeSyntax=2.5.5.14))) -
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.10.138 63815 192.168.10.186 389 8 tree never DC=matrix,DC=local 1 success - (samaccountname=krbtgt) -
#close XXXX-XX-XX-XX-XX-XX

View file

@ -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 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 10.199.2.121 59327 10.199.2.111 389 tcp ldap_tcp 63.273503 3963 400107 OTH 0 Dd 12 2595 282 411387 -
XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 10.199.2.121 59355 10.199.2.111 389 tcp ldap_tcp 0.007979 2630 3327 OTH 0 Dd 6 990 6 3567 -
XXXXXXXXXX.XXXXXX C4J4Th3PJpwUYZZ6gc 10.199.2.121 59356 10.199.2.111 389 tcp ldap_tcp 0.001925 2183 3436 OTH 0 Dd 4 463 5 3636 -
#close XXXX-XX-XX-XX-XX-XX

View file

@ -0,0 +1,15 @@
### 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 10.199.2.121 59327 10.199.2.111 389 3 3 bind SASL success - - GSS-SPNEGO
XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 10.199.2.121 59355 10.199.2.111 389 3 3 bind SASL success - - GSS-SPNEGO
XXXXXXXXXX.XXXXXX C4J4Th3PJpwUYZZ6gc 10.199.2.121 59356 10.199.2.111 389 9 3 bind SASL success - - GSS-SPNEGO
XXXXXXXXXX.XXXXXX C4J4Th3PJpwUYZZ6gc 10.199.2.121 59356 10.199.2.111 389 12 - unbind - - - -
XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 10.199.2.121 59355 10.199.2.111 389 13 - unbind - - - -
#close XXXX-XX-XX-XX-XX-XX

View file

@ -0,0 +1,27 @@
### 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 10.199.2.121 59327 10.199.2.111 389 1 base never - 1 success - (objectclass=*) -
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.199.2.121 59327 10.199.2.111 389 4 base never - 1 success - (objectClass=*) -
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.199.2.121 59327 10.199.2.111 389 5 base never CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,DC=DMC,DC=local 1 success - (objectClass=*) -
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.199.2.121 59327 10.199.2.111 389 6 base never - 1 success - (objectClass=*) -
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.199.2.121 59327 10.199.2.111 389 7 tree never CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,DC=DMC,DC=local 2 success - (objectCategory=pKIEnrollmentService) -
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.199.2.121 59327 10.199.2.111 389 8 base never - 1 success - (objectClass=*) -
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.199.2.121 59327 10.199.2.111 389 9 base never CN=Schema,CN=Configuration,DC=DMC,DC=local 1 success - (objectClass=dMD) -
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.199.2.121 59327 10.199.2.111 389 10 base never CN=Schema,CN=Configuration,DC=DMC,DC=local 1 success - (objectClass=dMD) -
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.199.2.121 59327 10.199.2.111 389 11 base never CN=Aggregate,CN=Schema,CN=Configuration,DC=DMC,DC=local 1 success - (objectClass=*) -
XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 10.199.2.121 59355 10.199.2.111 389 1 base never - 1 success - (objectclass=*) -
XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 10.199.2.121 59355 10.199.2.111 389 4 base never CN=WS01,CN=Computers,DC=DMC,DC=local 1 success - (objectclass=*) -
XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 10.199.2.121 59355 10.199.2.111 389 5 base never CN=WS01,CN=Computers,DC=DMC,DC=local 1 success - (objectclass=*) -
XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 10.199.2.121 59355 10.199.2.111 389 6 base never CN=WS01,CN=Computers,DC=DMC,DC=local 1 success - (objectclass=*) -
XXXXXXXXXX.XXXXXX C4J4Th3PJpwUYZZ6gc 10.199.2.121 59356 10.199.2.111 389 10 base never - 1 success - (ObjectClass=*) -
XXXXXXXXXX.XXXXXX C4J4Th3PJpwUYZZ6gc 10.199.2.121 59356 10.199.2.111 389 11 base never CN=62a0ff2e-97b9-4513-943f-0d221bd30080,CN=Device Registration Configuration,CN=services,CN=Configuration,DC=DMC,DC=local 0 no such object 0000208D: NameErr: DSID-0310028B, problem 2001 (NO_OBJECT), data 0, best match of:??'CN=Services,CN=Configuration,DC=DMC,DC=local'?? (ObjectClass=*) -
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.199.2.121 59327 10.199.2.111 389 12 base never CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=DMC,DC=local 1 success - (objectClass=*) -
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.199.2.121 59327 10.199.2.111 389 13 tree never CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=DMC,DC=local 38 success - (objectclass=pKICertificateTemplate) -
#close XXXX-XX-XX-XX-XX-XX

Binary file not shown.

View file

@ -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/missing_krbtgt_ldap_request.pcapng %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-DOC: Test LDAP analyzer with GSS-API integrity traffic where we can still peak into LDAP wrapped into WRAP tokens.

View file

@ -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/missing_ldap_logs.pcapng %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-DOC: Test LDAP analyzer with GSS-API integrity traffic where we can still peak into LDAP wrapped into WRAP tokens.