From 5afde3f0e56d17e706274fa6e0f67f7060fb80e8 Mon Sep 17 00:00:00 2001 From: "John E. Rollinson" Date: Sun, 17 Sep 2017 14:59:41 -0400 Subject: [PATCH 1/6] Changes proposed in #104 --- src/analyzer/protocol/gssapi/gssapi-analyzer.pac | 10 +++++----- src/analyzer/protocol/gssapi/gssapi-protocol.pac | 6 ++++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/analyzer/protocol/gssapi/gssapi-analyzer.pac b/src/analyzer/protocol/gssapi/gssapi-analyzer.pac index 64e8dd5e50..4290c7bbef 100644 --- a/src/analyzer/protocol/gssapi/gssapi-analyzer.pac +++ b/src/analyzer/protocol/gssapi/gssapi-analyzer.pac @@ -28,8 +28,8 @@ refine connection GSSAPI_Conn += { function forward_blob(val: GSSAPI_NEG_TOKEN_MECH_TOKEN, is_orig: bool): bool %{ - if ( ${val.mech_token}.length() >= 7 && - memcmp("NTLMSSP", ${val.mech_token}.begin(), 7) == 0 ) + if ( val->oid()->meta()->length() >= 7 && + memcmp("NTLMSSP", val->oid()->content().begin(), 7) == 0 ) { // ntlmssp if ( ! ntlm ) @@ -38,9 +38,9 @@ refine connection GSSAPI_Conn += { if ( ntlm ) ntlm->DeliverStream(${val.mech_token}.length(), ${val.mech_token}.begin(), is_orig); } - else if ( ${val.mech_token}.length() == 9 && - (memcmp("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02", ${val.mech_token}.begin(), ${val.mech_token}.length()) == 0 || - memcmp("\x2a\x86\x48\x82\xf7\x12\x01\x02\x02", ${val.mech_token}.begin(), ${val.mech_token}.length()) == 0 ) ) + else if ( val->oid()->meta()->length() == 9 && + (memcmp("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02", val->oid()->content().begin(), val->oid()->meta()->length()) == 0 || + memcmp("\x2a\x86\x48\x82\xf7\x12\x01\x02\x02", val->oid()->content().begin(), val->oid()->meta()->length()) == 0 ) ) { // krb5 && ms-krb5 if ( ! krb5 ) diff --git a/src/analyzer/protocol/gssapi/gssapi-protocol.pac b/src/analyzer/protocol/gssapi/gssapi-protocol.pac index abd58d7a4d..224ee1c886 100644 --- a/src/analyzer/protocol/gssapi/gssapi-protocol.pac +++ b/src/analyzer/protocol/gssapi/gssapi-protocol.pac @@ -50,7 +50,9 @@ type GSSAPI_NEG_TOKEN_RESP_Arg = record { }; type GSSAPI_NEG_TOKEN_MECH_TOKEN(is_orig: bool) = record { - meta : ASN1EncodingMeta; - mech_token : bytestring &length=meta.length; + meta : ASN1EncodingMeta; + mech_token_meta : ASN1EncodingMeta; + oid : ASN1Encoding; + mech_token : bytestring &restofdata; }; From 9ad93a507704c24c91879f863f34d0fac64c9526 Mon Sep 17 00:00:00 2001 From: "John E. Rollinson" Date: Sun, 17 Sep 2017 16:13:10 -0400 Subject: [PATCH 2/6] Initial btest structure --- testing/btest/Traces/krb/smb_gssapi.trace | Bin 0 -> 2859 bytes .../scripts/base/protocols/krb/smb_gssapi.test | 10 ++++++++++ 2 files changed, 10 insertions(+) create mode 100755 testing/btest/Traces/krb/smb_gssapi.trace create mode 100644 testing/btest/scripts/base/protocols/krb/smb_gssapi.test diff --git a/testing/btest/Traces/krb/smb_gssapi.trace b/testing/btest/Traces/krb/smb_gssapi.trace new file mode 100755 index 0000000000000000000000000000000000000000..140ce3a914c549bc97ebe2fc6e60e36f4dc8a275 GIT binary patch literal 2859 zcmc&#c|4Ts7k}QFcLrmvY-JlNKM`J|kRl_lCB{z4ZV+NHxt6jGEy`XhlI*lx+*Bfa zLMU$GC)8EarY?n)V($Bn&vkFQpWnZ~cRuHxGtW8a`<(N9&pfB^&b53TfWhAn3?TFe zuT+fT)CoSIi|UvF-~u2$ASe^3D$WfI0YLbr^*}5!&5tCm_ktwOy&3L;>Lq(igfZVB z9GmUL1ONvUu0s%v`vHxE0|Y!KI1hJ+zP^>9}iyZknaC=#^VAgD>> zM>KQ^VDdw53jAbFZb2(@6G0K{EQQ!?XUD%QY((QR`2pouepw79_2s{!h@&WDoUkKo z8*}{-Ocl53;H)ga*oz$11K=!ok!gmu4i?tC$(Gg@M%GkwvYHA4aAs7RIhDpy9ee}n zj4&qIn-M~GV1)SlgfK#bm}GSoHFwm{Tup_t2SF%*g-}$~0FGu$HZvz9Dr%Hv!UoYD zFlWK>^i(oGhK~1L;q7}=N^30V@9_YIn5s6Afh(N&Q=^)$l)*@m= z9>t@^thvTwbs%F>gWyL~{(KCn5FcxYSPtrn=Rz^G$? z2#n8h_yspB_N3;wc8iT~K7N&69pKO1k&>*m$AUrHJ~Bj#L~>eBu7ML}5SU z->c`dr>ADRN7CLjZ1IUSZ6Ut@mJmIDEWXr)I+a!?PI*(KO%}|Zu_*aAJfjTC&YZ~l z_(yfcKWKgT@ zV%R!ZKX;Aa(LNcc_O_BPr^z758@pDtDSJeeFzU7e_(TU?i+Z@^nT^Lb$4`d1z=TvyyQ?qWoA z&^AJc{|(|E&6uK$FmwL&vc$8?gV^*q;i@iG{KIK?0P6UW;*J>d}Mn|^V zk&9BUmLB=?kv-QmqB-Fn#&pjHeinrt=}Ez|S;42*d={&%m*n=OqJF?37aq1&lM}oo~r;{VX%r<7zmy<{3$M zaD&o>tMD(;irK7Prt)~lU5IsH3_aylPNPppS@HCcqeZ>oi@P6sOos>$T5EM6u4(Ra z9i7uPV|T;FYLEIyKMWnkDfh^B)43u-NBVYBqs=_@TNyeT>6NNZC%o<((lw+k?wT&X zE-64!(j%rf39DN#kLtTAh@%HvVPEmyf4)34e zbX@9U=36`aW{=+=Fyx%XlDLW^OhhlFjvLNBEz4fWn)_^;rqDQZ<(ZyHM*q8;7qs(QS3h>|0$z@6kT~3>P(3B6z*2M{zZo;uRxWY z&~^9gUdrvZ*~ZBtUcp(Zn1g1)9s%VC#@sX?8fF`5xAfS54)M$Q5MVVNG;6D(t+X+w z`ekm_B}en2yoqE-%6Of_nZa!;jZs)`hApKpF|n8j;L0u48%#hx_UhJC^L3= z|HP5Gvp)8<^QE#ze;vDKfh$FE4M^PWrGI{06&zRjTCme_ad)(B>UxFd)Q_j_@zntv z?Mu34thSvK9eAc4_@rN0iqh~%R3n^Nalz@<)Q(BUc;}W=NK|K&wnTVUSkjzyf!WS{ z_1)xGiQ27}M`AYB$yJTZzyWKc=)C8fSvW z>D3Ov7X&U(xHIVOh{?*E9~|dj&l&st-{1UKtvNTpINRB|763Y6fH1&B?^p^z&<_RG zY=9RC0Y9U=c%m8^SORxc^XK?rei|H40G9IjH-xP~1*may!sgSLc0SMv0gkMk!%$r! zXAaxyd_RXPTqJw1Uc=^aUke5Vr7h2=b6m#(kTkp8)2k3zvoRg;LS9fl z3*tgp5Izr2f*uYlqJCbj)@>_>SJ829X zKGLukR1*E`RlXYSE7^tgp+de!@(+vO^ Q0}Eh>_J#>+H9`^o1Xu Date: Sun, 17 Sep 2017 21:25:59 +0000 Subject: [PATCH 3/6] Added and verified correct test results --- .../scripts.base.protocols.krb.smb_gssapi/kerberos.log | 10 ++++++++++ .../btest/scripts/base/protocols/krb/smb_gssapi.test | 5 +++-- 2 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 testing/btest/Baseline/scripts.base.protocols.krb.smb_gssapi/kerberos.log diff --git a/testing/btest/Baseline/scripts.base.protocols.krb.smb_gssapi/kerberos.log b/testing/btest/Baseline/scripts.base.protocols.krb.smb_gssapi/kerberos.log new file mode 100644 index 0000000000..d55cd5281a --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.krb.smb_gssapi/kerberos.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path kerberos +#open 2017-09-17-21-25-06 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p request_type client service success error_msg from till cipher forwardable renewable client_cert_subject client_cert_fuid server_cert_subject server_cert_fuid +#types time string addr port addr port string string string bool string time time string bool bool string string string string +1165958411.822000 CHhAvVGS1DHFjwGM9 10.24.64.228 1227 10.24.8.44 445 - - - - - - - - - - - - - - +#close 2017-09-17-21-25-06 diff --git a/testing/btest/scripts/base/protocols/krb/smb_gssapi.test b/testing/btest/scripts/base/protocols/krb/smb_gssapi.test index 5cc223657b..f4995cd2f6 100644 --- a/testing/btest/scripts/base/protocols/krb/smb_gssapi.test +++ b/testing/btest/scripts/base/protocols/krb/smb_gssapi.test @@ -3,8 +3,9 @@ # SMB authentication event and therfore relies on the SMB # analyzer as well. -# @TEST-EXEC: bro -b -r $TRACES/krb/smb_gssapi.trace %INPUT +# @TEST-EXEC: bro -b -C -r $TRACES/krb/smb_gssapi.trace %INPUT # @TEST-EXEC: btest-diff kerberos.log +# @TEST-EXEC: btest-diff-rst scripts.base.protocols.krb @load base/protocols/krb -@load base/protocols/smb +@load policy/protocols/smb From 57bfbc02b111f8e6474e7b622cb39073c0ecbb35 Mon Sep 17 00:00:00 2001 From: Justin Oursler Date: Wed, 11 Oct 2017 13:42:54 -0400 Subject: [PATCH 4/6] modified GSSAPI analyzer to parse NTLM and KRB tokens --- .../protocol/gssapi/gssapi-analyzer.pac | 76 +++++++++++++------ .../protocol/gssapi/gssapi-protocol.pac | 7 +- 2 files changed, 56 insertions(+), 27 deletions(-) diff --git a/src/analyzer/protocol/gssapi/gssapi-analyzer.pac b/src/analyzer/protocol/gssapi/gssapi-analyzer.pac index 4290c7bbef..e30756197d 100644 --- a/src/analyzer/protocol/gssapi/gssapi-analyzer.pac +++ b/src/analyzer/protocol/gssapi/gssapi-analyzer.pac @@ -28,31 +28,63 @@ refine connection GSSAPI_Conn += { function forward_blob(val: GSSAPI_NEG_TOKEN_MECH_TOKEN, is_orig: bool): bool %{ - if ( val->oid()->meta()->length() >= 7 && - memcmp("NTLMSSP", val->oid()->content().begin(), 7) == 0 ) - { - // ntlmssp - if ( ! ntlm ) - ntlm = analyzer_mgr->InstantiateAnalyzer("NTLM", bro_analyzer()->Conn()); + if ( ${val.token}.length() >= 7 && + memcmp("NTLMSSP", ${val.token}.begin(), 7) == 0 ) + { + // ntlmssp + if ( ! ntlm ) + ntlm = analyzer_mgr->InstantiateAnalyzer("NTLM", bro_analyzer()->Conn()); - if ( ntlm ) - ntlm->DeliverStream(${val.mech_token}.length(), ${val.mech_token}.begin(), is_orig); - } - else if ( val->oid()->meta()->length() == 9 && - (memcmp("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02", val->oid()->content().begin(), val->oid()->meta()->length()) == 0 || - memcmp("\x2a\x86\x48\x82\xf7\x12\x01\x02\x02", val->oid()->content().begin(), val->oid()->meta()->length()) == 0 ) ) - { - // krb5 && ms-krb5 - if ( ! krb5 ) - krb5 = analyzer_mgr->InstantiateAnalyzer("KRB", bro_analyzer()->Conn()); + if ( ntlm ) + ntlm->DeliverStream(${val.token}.length(), + ${val.token}.begin(), is_orig); + } - // 0x0100 is a special marker - if ( krb5 && memcmp("\x01\x00", ${val.mech_token}.begin(), 2) == 0 ) - { - krb5->DeliverPacket(${val.mech_token}.length()-2, ${val.mech_token}.begin()+2, is_orig, 0, 0, 0); - } - } + else if ( 0x60 == *(${val.token}.begin()) ) + { + // probably KRB + + const unsigned char *p = ${val.token}.begin(); + int len_to_send = ${val.token}.length(); + p++; + len_to_send--; + + int shift = 1; + if ( ((*p) & 0x80) > 0 ) + { + shift += (*p) & 0x7f; + } + + p += shift; // eating an ASN.1 meta + len_to_send -= shift; + + // should now be pointing at OID + if ( (*p) == 0x06 ) + { + p++; + len_to_send--; + len_to_send -= (*p) + 1; + p += (*p) + 1; // eating the OID. assuming short form on + // OID len + + // should now be pointing at the type of KRB + // 0x0100 or 0x0200 + // krb5 && ms-krb5 + if ( ! krb5 ) + krb5 = analyzer_mgr->InstantiateAnalyzer("KRB", bro_analyzer()->Conn()); + + if ( krb5 && ( + memcmp("\x01\x00", p, 2) == 0 || // KRB5 AP REQ + memcmp("\x02\x00", p, 2) == 0 ) // KRB5 AP REP + ) + { + krb5->DeliverPacket(len_to_send-2, + p+2, + is_orig, 0, 0, 0); + } + } + } return true; %} diff --git a/src/analyzer/protocol/gssapi/gssapi-protocol.pac b/src/analyzer/protocol/gssapi/gssapi-protocol.pac index 224ee1c886..8038e52b25 100644 --- a/src/analyzer/protocol/gssapi/gssapi-protocol.pac +++ b/src/analyzer/protocol/gssapi/gssapi-protocol.pac @@ -50,9 +50,6 @@ type GSSAPI_NEG_TOKEN_RESP_Arg = record { }; type GSSAPI_NEG_TOKEN_MECH_TOKEN(is_orig: bool) = record { - meta : ASN1EncodingMeta; - mech_token_meta : ASN1EncodingMeta; - oid : ASN1Encoding; - mech_token : bytestring &restofdata; + meta : ASN1EncodingMeta; + token : bytestring &length=meta.length; }; - From 3d2ec29d04a86c0f41c06e39de3286646345798f Mon Sep 17 00:00:00 2001 From: Justin Oursler Date: Wed, 11 Oct 2017 14:18:58 -0400 Subject: [PATCH 5/6] removed check on kerberos request or response type. allow the kerberos analyzer to handle what it can, gssapi shouldn't check this --- src/analyzer/protocol/gssapi/gssapi-analyzer.pac | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/analyzer/protocol/gssapi/gssapi-analyzer.pac b/src/analyzer/protocol/gssapi/gssapi-analyzer.pac index e30756197d..28516bd9a3 100644 --- a/src/analyzer/protocol/gssapi/gssapi-analyzer.pac +++ b/src/analyzer/protocol/gssapi/gssapi-analyzer.pac @@ -74,10 +74,8 @@ refine connection GSSAPI_Conn += { if ( ! krb5 ) krb5 = analyzer_mgr->InstantiateAnalyzer("KRB", bro_analyzer()->Conn()); - if ( krb5 && ( - memcmp("\x01\x00", p, 2) == 0 || // KRB5 AP REQ - memcmp("\x02\x00", p, 2) == 0 ) // KRB5 AP REP - ) + if ( krb5 ) // accepting all KRB types (REQ, REP, etc) + { krb5->DeliverPacket(len_to_send-2, p+2, From 313195276206a384ffdb93731532e688f0cfa2a8 Mon Sep 17 00:00:00 2001 From: Seth Hall Date: Tue, 3 Apr 2018 01:56:34 -0400 Subject: [PATCH 6/6] Cleaned up and moved parsing to binpac. Too much parsing was being done in C++ so I moved more of it into binpac. Also, fixed up a bunch of the whitespace (the new code was indented with spaces). --- .../protocol/gssapi/gssapi-analyzer.pac | 73 ++++++------------- .../protocol/gssapi/gssapi-protocol.pac | 21 +++++- 2 files changed, 41 insertions(+), 53 deletions(-) diff --git a/src/analyzer/protocol/gssapi/gssapi-analyzer.pac b/src/analyzer/protocol/gssapi/gssapi-analyzer.pac index 28516bd9a3..3478e66c93 100644 --- a/src/analyzer/protocol/gssapi/gssapi-analyzer.pac +++ b/src/analyzer/protocol/gssapi/gssapi-analyzer.pac @@ -28,61 +28,32 @@ refine connection GSSAPI_Conn += { function forward_blob(val: GSSAPI_NEG_TOKEN_MECH_TOKEN, is_orig: bool): bool %{ - if ( ${val.token}.length() >= 7 && - memcmp("NTLMSSP", ${val.token}.begin(), 7) == 0 ) - { - // ntlmssp - if ( ! ntlm ) - ntlm = analyzer_mgr->InstantiateAnalyzer("NTLM", bro_analyzer()->Conn()); + if ( ${val.has_ntlm} && + ${val.ntlm}.length() >= 7 && + memcmp("NTLMSSP", ${val.ntlm}.begin(), 7) == 0 ) + { + // ntlmssp + if ( ! ntlm ) + ntlm = analyzer_mgr->InstantiateAnalyzer("NTLM", bro_analyzer()->Conn()); - if ( ntlm ) - ntlm->DeliverStream(${val.token}.length(), - ${val.token}.begin(), is_orig); - } + if ( ntlm ) + ntlm->DeliverStream(${val.ntlm}.length(), + ${val.ntlm}.begin(), is_orig); + } + else if ( ${val.has_krb} ) + { + if ( ! krb5 ) + krb5 = analyzer_mgr->InstantiateAnalyzer("KRB", bro_analyzer()->Conn()); - else if ( 0x60 == *(${val.token}.begin()) ) - { - // probably KRB + if ( krb5 ) // accepting all KRB types (REQ, REP, etc) + { + krb5->DeliverPacket(${val.krb.blob}.length(), + ${val.krb.blob}.begin(), + is_orig, 0, 0, 0); + } + } - const unsigned char *p = ${val.token}.begin(); - int len_to_send = ${val.token}.length(); - p++; - len_to_send--; - - int shift = 1; - if ( ((*p) & 0x80) > 0 ) - { - shift += (*p) & 0x7f; - } - - p += shift; // eating an ASN.1 meta - len_to_send -= shift; - - // should now be pointing at OID - if ( (*p) == 0x06 ) - { - p++; - len_to_send--; - len_to_send -= (*p) + 1; - p += (*p) + 1; // eating the OID. assuming short form on - // OID len - - // should now be pointing at the type of KRB - // 0x0100 or 0x0200 - // krb5 && ms-krb5 - if ( ! krb5 ) - krb5 = analyzer_mgr->InstantiateAnalyzer("KRB", bro_analyzer()->Conn()); - - if ( krb5 ) // accepting all KRB types (REQ, REP, etc) - - { - krb5->DeliverPacket(len_to_send-2, - p+2, - is_orig, 0, 0, 0); - } - } - } return true; %} diff --git a/src/analyzer/protocol/gssapi/gssapi-protocol.pac b/src/analyzer/protocol/gssapi/gssapi-protocol.pac index 8038e52b25..48e360d295 100644 --- a/src/analyzer/protocol/gssapi/gssapi-protocol.pac +++ b/src/analyzer/protocol/gssapi/gssapi-protocol.pac @@ -50,6 +50,23 @@ type GSSAPI_NEG_TOKEN_RESP_Arg = record { }; type GSSAPI_NEG_TOKEN_MECH_TOKEN(is_orig: bool) = record { - meta : ASN1EncodingMeta; - token : bytestring &length=meta.length; + meta : ASN1EncodingMeta; + token : bytestring &length=meta.length; +} &let { + ntlm = token &if($context.connection.is_first_byte(token, 0x43)); + krb : KRB_BLOB withinput token &if($context.connection.is_first_byte(token, 0x60)) &restofdata; +}; + +type KRB_BLOB = record { + meta : ASN1EncodingMeta; + oid : ASN1OctetString; + token_id : uint16 &byteorder=littleendian; + blob : bytestring &restofdata; +}; + +refine connection GSSAPI_Conn += { + function is_first_byte(token: bytestring, byte: uint8): bool + %{ + return token[0] == byte; + %} };