From 02e3d302277a01fa3cdd4eb9ae51a2408145c9c4 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Fri, 26 Jul 2024 12:31:53 +0200 Subject: [PATCH] ldap: Recognize SASL+SPNEGO+NTLMSSP The ctu-sme-11-win7ad-1-ldap-tcp-50041.pcap file was harvested from the CTU-SME-11 (Experiment-VM-Microsoft-Windows7AD-1) dataset at https://zenodo.org/records/7958259 (DOI 10.5281/zenodo.7958258). Closes #3853 --- src/analyzer/protocol/ldap/ldap.spicy | 34 ++++++++++-------- .../conn.log | 12 +++++++ .../ldap.log | 14 ++++++++ testing/btest/Traces/README | 3 ++ .../ctu-sme-11-win7ad-1-ldap-tcp-50041.pcap | Bin 0 -> 2084 bytes .../base/protocols/ldap/spnego-ntlmssp.zeek | 15 ++++++++ 6 files changed, 64 insertions(+), 14 deletions(-) create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.spnego-ntlmssp/conn.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ldap.spnego-ntlmssp/ldap.log create mode 100644 testing/btest/Traces/ldap/ctu-sme-11-win7ad-1-ldap-tcp-50041.pcap create mode 100644 testing/btest/scripts/base/protocols/ldap/spnego-ntlmssp.zeek diff --git a/src/analyzer/protocol/ldap/ldap.spicy b/src/analyzer/protocol/ldap/ldap.spicy index 96f942d7a3..52ab0e6160 100644 --- a/src/analyzer/protocol/ldap/ldap.spicy +++ b/src/analyzer/protocol/ldap/ldap.spicy @@ -375,26 +375,29 @@ type GSS_SPNEGO_negTokenInit = unit { : skip bytes &eod; }; -# Peak into GSS-SPNEGO payload and ensure it is indeed GSS-SPNEGO. +# Peak into GSS-SPNEGO payload and ensure it is indeed GSS-SPNEGO, +# or GSS-SPNEGO with a NTMLSSP payload that starts with NTLMSSP. type GSS_SPNEGO_Init = 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 + # a continuation from RFC4178, or a "NTMLSSP" signature. # - # 60 -> APPLICATION [0] https://datatracker.ietf.org/doc/html/rfc2743#page-81) + # 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 + # "NTMLSSP" https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/907f519d-6217-45b1-b421-dca10fc8af0d # - 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 { + -> spnegoInitByte: uint8(0x60); + -> spnegoChoiceByte: uint8(0xa1); + -> ntlmSignature: skip b"NTLMSSP"; # Unsupported, should forward to child analyzer! + }; - switch ( self.gssapiHeader.tag.type_ ) { - ASN1::ASN1Type(0) -> initial: GSS_SPNEGO_negTokenInit; - * -> : skip bytes &eod; - } &size=self.gssapiHeader.len.len; + spnegoLen: skip ASN1::LengthType if (self?.spnegoInitByte || self?.spnegoChoiceByte); + + # Peak into the SPNEGO_negTokenInit + spnegoInitial: skip GSS_SPNEGO_negTokenInit if (self?.spnegoInitByte); }; type SaslCredentials = unit() { @@ -408,10 +411,13 @@ type SaslCredentials = 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; + switch { + -> spnegoChoiceByte: uint8(0xa1); + -> ntmlSignature: skip b"NTLMSSP"; # Unsupported, should forward to NTLM! }; + + spnegoChoiceLen: skip ASN1::LengthType if (self?.spnegoChoiceByte); + negTokenResp: GSS_SPNEGO_negTokenResp if (self?.spnegoChoiceByte); }; type GSS_SPNEGO_negTokenResp = unit { diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.spnego-ntlmssp/conn.log b/testing/btest/Baseline/scripts.base.protocols.ldap.spnego-ntlmssp/conn.log new file mode 100644 index 0000000000..84a495d3fb --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.spnego-ntlmssp/conn.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 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.1.105 50041 192.168.1.108 389 tcp ldap_tcp 0.004745 93 283 RSTR 0 ShADdFar 5 305 4 455 - +XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 192.168.1.107 50041 192.168.1.108 389 tcp ldap_tcp 0.005883 93 283 RSTR 0 ShADdFar 5 305 4 455 - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ldap.spnego-ntlmssp/ldap.log b/testing/btest/Baseline/scripts.base.protocols.ldap.spnego-ntlmssp/ldap.log new file mode 100644 index 0000000000..07355e0e78 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ldap.spnego-ntlmssp/ldap.log @@ -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 +#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.1.105 50041 192.168.1.108 389 160 3 bind SASL SASL bind in progress - - GSS-SPNEGO +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 192.168.1.105 50041 192.168.1.108 389 161 - unbind - - - - +XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 192.168.1.107 50041 192.168.1.108 389 427 3 bind SASL SASL bind in progress - - GSS-SPNEGO +XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 192.168.1.107 50041 192.168.1.108 389 428 - unbind - - - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Traces/README b/testing/btest/Traces/README index bc5a304436..43942584f2 100644 --- a/testing/btest/Traces/README +++ b/testing/btest/Traces/README @@ -18,3 +18,6 @@ Trace Index/Sources: - one `\x30` byte in the ciphertext changed to `\x00` - ldap/issue-32.pcapng: Provided by GH user martinvanhensbergen, +- ldap/ctu-sme-11-win7ad-1-ldap-tcp-50041.pcap: Harvested from CTU-SME-11 + (Experiment-VM-Microsoft-Windows7AD-1) dataset, filtering on tcp port 389 and port 50041. + https://zenodo.org/records/7958259 (DOI 10.5281/zenodo.7958258). diff --git a/testing/btest/Traces/ldap/ctu-sme-11-win7ad-1-ldap-tcp-50041.pcap b/testing/btest/Traces/ldap/ctu-sme-11-win7ad-1-ldap-tcp-50041.pcap new file mode 100644 index 0000000000000000000000000000000000000000..dd2b34ce4add5cef82f592fb7a64421f6153fcf4 GIT binary patch literal 2084 zcmds%Uq}>D6voe;9rurtyDOOzY#36mq9U=16hW@3P@8V84+*wv24-tS=F39rwrC;= zAwBqq3N@2*?ZFTUdZ`ww$AU6ae9-Elf7l1)xifcWc7F5Cch3D@ zgzpYYAjA451H+SG+?U!GI|C=qX&52xnIQ-F=lhn8Pz2zxHSdFfzGC}>TdW>OL)g#S z)1OaYB2qv~0d^Tcl4B;APG@9HmWcQyT_AFn!X=`shlm*lq7jv~hyC8FMGI290tqQF zzA2LUIfFqSzL7?RM!T(rYs}PW>_V#5ZDC-UQ@*s)!Jq>PG$JT|TPsnHPDiCAGq`pU zAg2uqP))M}iRomxLDM`rw#4Jf^0-TjO3Gw=X}Rl=$K&QE_XLge_zz*zvvC_< zFq2*5xeN|tHE5{Tt9G$MS1-x3f794yMZ0F*DC=vzB8w%GtQyq9;$m663^H^C8K^=e zd|Lwk^6{7$?3_Q{oZOc7F@CSAY7!>l0G{Y|fgN}-d!QVSKmqQ{z=cOANceQ*RR+mX zu4ci0C`1KY@m>=&LJjWEAg2b7LpIJDp$>H55biecyULTb4Y0KT&CwY|qo zSYu5Jc>70`6p-hLa`rw_d_wZsD_mw2u%mSrA_QZM$urViJGYRK5 z?8kSU7#4}6CQif@7+zBP@s&ss3J-Sg3Q>|mV&P{NQin!ksjG(<70Q(+L5r61i&I9U LQZNN>eggOn=p^s( literal 0 HcmV?d00001 diff --git a/testing/btest/scripts/base/protocols/ldap/spnego-ntlmssp.zeek b/testing/btest/scripts/base/protocols/ldap/spnego-ntlmssp.zeek new file mode 100644 index 0000000000..e936332b47 --- /dev/null +++ b/testing/btest/scripts/base/protocols/ldap/spnego-ntlmssp.zeek @@ -0,0 +1,15 @@ +# Copyright (c) 2024 by the Zeek Project. See LICENSE for details. +# +# The ctu-sme-11-win7ad-1-ldap-tcp-50041.pcap file was harvested +# from the CTU-SME-11 (Experiment-VM-Microsoft-Windows7AD-1) dataset +# at https://zenodo.org/records/7958259 (DOI 10.5281/zenodo.7958258). + +# @TEST-REQUIRES: have-spicy +# @TEST-EXEC: zeek -C -r ${TRACES}/ldap/ctu-sme-11-win7ad-1-ldap-tcp-50041.pcap +# @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 bindRequest with SPNEGO NTLMSSP.