mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
GSSAPI analyzer now forwards authentication blobs more correctly (and other fixes).
Previously, the GSSAPI analyzer blindly forwarded authentication blobs to the NTLM analyzer (which it instantiated too early). Now it waits to instantiate sub analyzers until a blob of a particular type has been seen. It also makes the distinction between krb and ntlm and forwards to the correct analyzer. This required some fixes to the KRB analyzer because KRB over GSSAPI looks slightly different than raw KRB. The KRB analyzer also now includes support for the PA_ENCTYPE_INFO2 pre-auth data type.
This commit is contained in:
parent
4a3dfe69b1
commit
cbde25f1b8
5 changed files with 69 additions and 11 deletions
|
@ -2,10 +2,12 @@
|
|||
refine connection GSSAPI_Conn += {
|
||||
%member{
|
||||
analyzer::Analyzer *ntlm;
|
||||
analyzer::Analyzer *krb5;
|
||||
%}
|
||||
|
||||
%init{
|
||||
ntlm = analyzer_mgr->InstantiateAnalyzer("NTLM", bro_analyzer->Conn());
|
||||
ntlm=0;
|
||||
krb5=0;
|
||||
%}
|
||||
|
||||
%cleanup{
|
||||
|
@ -13,13 +15,44 @@ refine connection GSSAPI_Conn += {
|
|||
{
|
||||
ntlm->Done();
|
||||
delete ntlm;
|
||||
ntlm=0;
|
||||
}
|
||||
|
||||
if ( krb5 )
|
||||
{
|
||||
krb5->Done();
|
||||
delete krb5;
|
||||
krb5=0;
|
||||
}
|
||||
%}
|
||||
|
||||
function forward_ntlm(data: bytestring, is_orig: bool): bool
|
||||
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 )
|
||||
{
|
||||
// ntlmssp
|
||||
if ( ! ntlm )
|
||||
ntlm = analyzer_mgr->InstantiateAnalyzer("NTLM", bro_analyzer()->Conn());
|
||||
|
||||
if ( ntlm )
|
||||
ntlm->DeliverStream(${data}.length(), ${data}.begin(), is_orig);
|
||||
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 ) )
|
||||
{
|
||||
// krb5 && ms-krb5
|
||||
if ( ! krb5 )
|
||||
krb5 = analyzer_mgr->InstantiateAnalyzer("KRB", bro_analyzer()->Conn());
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
%}
|
||||
|
||||
|
@ -37,7 +70,7 @@ refine connection GSSAPI_Conn += {
|
|||
}
|
||||
|
||||
refine typeattr GSSAPI_NEG_TOKEN_MECH_TOKEN += &let {
|
||||
fwd: bool = $context.connection.forward_ntlm(mech_token, is_orig);
|
||||
fwd: bool = $context.connection.forward_blob(this, is_orig);
|
||||
};
|
||||
|
||||
refine typeattr GSSAPI_NEG_TOKEN_RESP_Arg += &let {
|
||||
|
|
|
@ -53,3 +53,4 @@ type GSSAPI_NEG_TOKEN_MECH_TOKEN(is_orig: bool) = record {
|
|||
meta : ASN1EncodingMeta;
|
||||
mech_token : bytestring &length=meta.length;
|
||||
};
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ enum KRBPADataTypes {
|
|||
PA_PW_SALT = 3,
|
||||
PA_PW_AS_REQ = 16,
|
||||
PA_PW_AS_REP = 17,
|
||||
PA_ENCTYPE_INFO2 = 19,
|
||||
};
|
||||
|
||||
# Defined in RFC 4120
|
||||
|
|
|
@ -41,6 +41,14 @@ VectorVal* proc_padata(const KRB_PA_Data_Sequence* data, const BroAnalyzer bro_a
|
|||
vv->Assign(vv->Size(), type_val);
|
||||
break;
|
||||
}
|
||||
case PA_ENCTYPE_INFO2:
|
||||
{
|
||||
RecordVal * type_val = new RecordVal(BifType::Record::KRB::Type_Value);
|
||||
type_val->Assign(0, new Val(element->data_type(), TYPE_COUNT));
|
||||
type_val->Assign(1, bytestring_to_val(element->pa_data_element()->pf_enctype_info2()->salt()));
|
||||
vv->Assign(vv->Size(), type_val);
|
||||
break;
|
||||
}
|
||||
case PA_PW_AS_REQ:
|
||||
{
|
||||
const bytestring& cert = element->pa_data_element()->pa_pk_as_req()->cert();
|
||||
|
@ -91,11 +99,11 @@ VectorVal* proc_padata(const KRB_PA_Data_Sequence* data, const BroAnalyzer bro_a
|
|||
}
|
||||
default:
|
||||
{
|
||||
if ( ! is_error && element->pa_data_element()->unknown().length() )
|
||||
if ( ! is_error && element->pa_data_element()->unknown()->meta()->length() > 0 )
|
||||
{
|
||||
RecordVal * type_val = new RecordVal(BifType::Record::KRB::Type_Value);
|
||||
type_val->Assign(0, new Val(element->data_type(), TYPE_COUNT));
|
||||
type_val->Assign(1, bytestring_to_val(element->pa_data_element()->unknown()));
|
||||
type_val->Assign(1, bytestring_to_val(element->pa_data_element()->unknown()->content()));
|
||||
vv->Assign(vv->Size(), type_val);
|
||||
}
|
||||
break;
|
||||
|
@ -165,13 +173,21 @@ type KRB_PA_Data(is_orig: bool, pkt_type: uint8) = record {
|
|||
|
||||
# Each pre-auth element
|
||||
type KRB_PA_Data_Element(is_orig: bool, type: int64, length: uint64) = case type of {
|
||||
PA_TGS_REQ -> pa_tgs_req : KRB_AP_REQ(is_orig);
|
||||
PA_TGS_REQ -> pa_tgs_req : KRB_PA_AP_REQ_wrapper(is_orig);
|
||||
PA_PW_SALT -> pa_pw_salt : ASN1OctetString;
|
||||
PA_PW_AS_REQ -> pa_pk_as_req : KRB_PA_PK_AS_Req &length=length;
|
||||
PA_PW_AS_REP -> pa_pk_as_rep : KRB_PA_PK_AS_Rep &length=length;
|
||||
default -> unknown : bytestring &length=length;
|
||||
PA_ENCTYPE_INFO2 -> pf_enctype_info2 : KRB_PA_ENCTYPE_INFO2 &length=length;
|
||||
default -> unknown : ASN1Encoding &length=length;
|
||||
};
|
||||
|
||||
type KRB_PA_AP_REQ_wrapper(is_orig: bool) = record {
|
||||
# Not sure what these two field are, but they need to be
|
||||
# here for pre-auth ap-req messages.
|
||||
some_meta1 : ASN1EncodingMeta;
|
||||
some_meta2 : ASN1EncodingMeta;
|
||||
req : KRB_AP_REQ(is_orig);
|
||||
};
|
||||
|
||||
# The PKINIT certificate structure for a request
|
||||
type KRB_PA_PK_AS_Req = record {
|
||||
|
@ -210,3 +226,12 @@ type KRB_PA_PK_AS_Rep = record {
|
|||
: bytestring &restofdata &transient;
|
||||
};
|
||||
|
||||
type KRB_PA_ENCTYPE_INFO2 = record {
|
||||
some_meta1 : ASN1EncodingMeta;
|
||||
some_meta2 : ASN1EncodingMeta;
|
||||
seq_meta1 : ASN1EncodingMeta;
|
||||
etype : ASN1Encoding;
|
||||
seq_meta2 : ASN1EncodingMeta;
|
||||
string_meta : ASN1EncodingMeta;
|
||||
salt : bytestring &length=string_meta.length;
|
||||
};
|
|
@ -126,8 +126,6 @@ type KRB_KDC_REP(is_orig: bool, pkt_type: uint8) = record {
|
|||
### AP_REQ
|
||||
|
||||
type KRB_AP_REQ(is_orig: bool) = record {
|
||||
string_meta : ASN1EncodingMeta;
|
||||
app_meta : ASN1EncodingMeta;
|
||||
seq_meta : ASN1EncodingMeta;
|
||||
pvno : SequenceElement(true);
|
||||
msg_type : SequenceElement(true);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue