From 1f41c0470c1278a8775e41de06f12be92037c1a0 Mon Sep 17 00:00:00 2001 From: Vlad Grigorescu Date: Fri, 23 Jan 2015 17:22:10 -0500 Subject: [PATCH] Improve Kerberos DPD and fix a few parse errors. --- scripts/base/protocols/krb/dpd.sig | 23 +++++++- scripts/base/protocols/krb/main.bro | 13 +++-- src/analyzer/protocol/krb/krb-analyzer.pac | 66 +++++++++++----------- src/analyzer/protocol/krb/krb-protocol.pac | 47 ++++++++------- 4 files changed, 88 insertions(+), 61 deletions(-) diff --git a/scripts/base/protocols/krb/dpd.sig b/scripts/base/protocols/krb/dpd.sig index 89c07309f6..1d4986aedf 100644 --- a/scripts/base/protocols/krb/dpd.sig +++ b/scripts/base/protocols/krb/dpd.sig @@ -1,7 +1,26 @@ -signature dpd_krb_udp { +# This is the ASN.1 encoded version and message type headers + +signature dpd_krb_udp_requests { ip-proto == udp - payload /\x6c...\x30...\xa1\x03\x02\x05/ + payload /(\x6a|\x6c).{1,4}\x30.{1,4}\xa1\x03\x02\x01\x05\xa2\x03\x02\x01/ enable "krb" } +signature dpd_krb_udp_replies { + ip-proto == udp + payload /(\x6b|\x6d|\x7e).{1,4}\x30.{1,4}\xa0\x03\x02\x01\x05\xa1\x03\x02\x01/ + enable "krb" +} + +signature dpd_krb_tcp_requests { + ip-proto == tcp + payload /.{4}(\x6a|\x6c).{1,4}\x30.{1,4}\xa1\x03\x02\x01\x05\xa2\x03\x02\x01/ + enable "krb_tcp" +} + +signature dpd_krb_tcp_replies { + ip-proto == tcp + payload /.{4}(\x6b|\x6d|\x7e).{1,4}\x30.{1,4}\xa0\x03\x02\x01\x05\xa1\x03\x02\x01/ + enable "krb_tcp" +} diff --git a/scripts/base/protocols/krb/main.bro b/scripts/base/protocols/krb/main.bro index 97c210319a..22160e4053 100644 --- a/scripts/base/protocols/krb/main.bro +++ b/scripts/base/protocols/krb/main.bro @@ -77,8 +77,8 @@ const tcp_ports = { 88/tcp, 750/tcp }; event bro_init() &priority=5 { Log::create_stream(KRB::LOG, [$columns=Info, $ev=log_krb]); - Analyzer::register_for_ports(Analyzer::ANALYZER_KRB, udp_ports); - Analyzer::register_for_ports(Analyzer::ANALYZER_KRB_TCP, tcp_ports); +# Analyzer::register_for_ports(Analyzer::ANALYZER_KRB, udp_ports); +# Analyzer::register_for_ports(Analyzer::ANALYZER_KRB_TCP, tcp_ports); } event krb_error(c: connection, msg: Error_Msg) &priority=5 @@ -114,7 +114,7 @@ event krb_error(c: connection, msg: Error_Msg) &priority=5 info$result = "failed"; info$error_code = msg$error_code; - + if ( msg?$error_text ) info$error_msg = msg$error_text; else @@ -128,8 +128,11 @@ event krb_error(c: connection, msg: Error_Msg) &priority=5 event krb_error(c: connection, msg: Error_Msg) &priority=-5 { - Log::write(KRB::LOG, c$krb); - c$krb$logged = T; + if ( c?$krb ) + { + Log::write(KRB::LOG, c$krb); + c$krb$logged = T; + } } event krb_as_req(c: connection, msg: KDC_Request) &priority=5 diff --git a/src/analyzer/protocol/krb/krb-analyzer.pac b/src/analyzer/protocol/krb/krb-analyzer.pac index acf7f5e79d..2cde4e42c1 100644 --- a/src/analyzer/protocol/krb/krb-analyzer.pac +++ b/src/analyzer/protocol/krb/krb-analyzer.pac @@ -432,40 +432,40 @@ refine connection KRB_Conn += { rv->Assign(9, bytestring_to_val(${msg.args[i].args.e_text.encoding.content})); break; case 12: - if ( ${msg.error_code.data.content}[0] == 25 ) - { - VectorVal* padata = new VectorVal(internal_type("KRB::Type_Value_Vector")->AsVectorType()); + // if ( ${msg.error_code.data.content}[0] == 25 ) + // { + // VectorVal* padata = new VectorVal(internal_type("KRB::Type_Value_Vector")->AsVectorType()); - for ( uint j = 0; j < ${msg.args[i].args.e_data.padata.padata_elems}->size(); ++j) - { - switch( ${msg.args[i].args.e_data.padata.padata_elems[j].data_type} ) - { - case 1: - // will be generated as separate event - break; - case 3: - { - RecordVal * type_val = new RecordVal(BifType::Record::KRB::Type_Value); - type_val->Assign(0, new Val(${msg.args[i].args.e_data.padata.padata_elems[j].data_type}, TYPE_COUNT)); - type_val->Assign(1, bytestring_to_val(${msg.args[i].args.e_data.padata.padata_elems[j].pa_data_element.pa_pw_salt.encoding.content})); - padata->Assign(padata->Size(), type_val); - break; - } - default: - { - if ( ${msg.args[i].args.e_data.padata.padata_elems[j].pa_data_element.unknown}.length() ) - { - RecordVal * type_val = new RecordVal(BifType::Record::KRB::Type_Value); - type_val->Assign(0, new Val(${msg.args[i].args.e_data.padata.padata_elems[j].data_type}, TYPE_COUNT)); - type_val->Assign(1, bytestring_to_val(${msg.args[i].args.e_data.padata.padata_elems[j].pa_data_element.unknown})); - padata->Assign(padata->Size(), type_val); - } - break; - } - } - } - rv->Assign(10, padata); - } + // for ( uint j = 0; j < ${msg.args[i].args.e_data.padata.padata_elems}->size(); ++j) + // { + // switch( ${msg.args[i].args.e_data.padata.padata_elems[j].data_type} ) + // { + // case 1: + // // will be generated as separate event + // break; + // case 3: + // { + // RecordVal * type_val = new RecordVal(BifType::Record::KRB::Type_Value); + // type_val->Assign(0, new Val(${msg.args[i].args.e_data.padata.padata_elems[j].data_type}, TYPE_COUNT)); + // type_val->Assign(1, bytestring_to_val(${msg.args[i].args.e_data.padata.padata_elems[j].pa_data_element.pa_pw_salt.encoding.content})); + // padata->Assign(padata->Size(), type_val); + // break; + // } + // default: + // { + // if ( ${msg.args[i].args.e_data.padata.padata_elems[j].pa_data_element.unknown}.length() ) + // { + // RecordVal * type_val = new RecordVal(BifType::Record::KRB::Type_Value); + // type_val->Assign(0, new Val(${msg.args[i].args.e_data.padata.padata_elems[j].data_type}, TYPE_COUNT)); + // type_val->Assign(1, bytestring_to_val(${msg.args[i].args.e_data.padata.padata_elems[j].pa_data_element.unknown})); + // padata->Assign(padata->Size(), type_val); + // } + // break; + // } + // } + // } + // rv->Assign(10, padata); + // } break; default: break; diff --git a/src/analyzer/protocol/krb/krb-protocol.pac b/src/analyzer/protocol/krb/krb-protocol.pac index e30ee1fd91..d3c7854099 100644 --- a/src/analyzer/protocol/krb/krb-protocol.pac +++ b/src/analyzer/protocol/krb/krb-protocol.pac @@ -36,30 +36,30 @@ type KRB_PDU = record { } &byteorder=bigendian; type KRB_AS_REQ = record { - data: KRB_KDC_REQ; + data: KRB_KDC_REQ(AS_REQ); }; type KRB_TGS_REQ = record { - data: KRB_KDC_REQ; + data: KRB_KDC_REQ(TGS_REQ); }; type KRB_AS_REP = record { - data: KRB_KDC_REP; + data: KRB_KDC_REP(AS_REP); }; type KRB_TGS_REP = record { - data: KRB_KDC_REP; + data: KRB_KDC_REP(TGS_REP); }; ### KDC_REQ -type KRB_KDC_REQ = record { +type KRB_KDC_REQ(pkt_type: uint8) = record { seq_meta : ASN1EncodingMeta; pvno : SequenceElement(true); msg_type : SequenceElement(true); padata_meta: ASN1EncodingMeta; tmp1 : case has_padata of { - true -> padata : KRB_PA_Data_Sequence &length=padata_meta.length; + true -> padata : KRB_PA_Data_Sequence(pkt_type) &length=padata_meta.length; false -> n1 : empty; }; tmp2 : case has_padata of { @@ -72,16 +72,19 @@ type KRB_KDC_REQ = record { body_length: uint64 = has_padata ? meta2.length : padata_meta.length; }; -type KRB_PA_Data_Sequence = record { +type KRB_PA_Data_Sequence(pkt_type: uint8) = record { seq_meta : ASN1EncodingMeta; - padata_elems: KRB_PA_Data[]; + padata_elems: KRB_PA_Data(pkt_type)[]; }; -type KRB_PA_Data = record { +type KRB_PA_Data(pkttype: uint8) = record { seq_meta : ASN1EncodingMeta; pa_data_type : SequenceElement(true); pa_data_elem_meta : ASN1EncodingMeta; - pa_data_element : KRB_PA_Data_Element(data_type, pa_data_elem_meta.length); + have_data : case ( pkttype == 30 ) of { + true -> pa_data_placeholder: bytestring &length=pa_data_elem_meta.length; + false -> pa_data_element : KRB_PA_Data_Element(binary_to_int64(pa_data_type.data.content), pa_data_elem_meta.length); + }; } &let { data_type: int64 = binary_to_int64(pa_data_type.data.content); }; @@ -275,13 +278,13 @@ type KRB_Encrypted_Data = record { ### KDC_REP -type KRB_KDC_REP = record { +type KRB_KDC_REP(pkt_type: uint8) = record { seq_meta : ASN1EncodingMeta; pvno : SequenceElement(true); msg_type : SequenceElement(true); padata_meta : ASN1EncodingMeta; tmp1 : case has_padata of { - true -> padata : KRB_PA_Data_Sequence &length=padata_meta.length; + true -> padata : KRB_PA_Data_Sequence(pkt_type) &length=padata_meta.length; false -> n1 : empty; }; tmp2 : case has_padata of { @@ -387,17 +390,19 @@ type KRB_ERROR_Arg_Data(index: uint8, error_code: uint64) = case index of { 9 -> realm : ASN1OctetString; 10 -> sname : KRB_Principal_Name; 11 -> e_text : ASN1OctetString; - 12 -> e_data : KRB_ERROR_PA_Data(error_code); + 12 -> e_data : KRB_ERROR_E_Data(error_code); }; -type KRB_ERROR_PA_Data(error_code: uint64) = record { - have_padata1: case ( error_code == 25 ) of { - true -> meta1 : ASN1EncodingMeta; - false -> data : ASN1OctetString; - }; - have_padata2: case ( error_code == 25 ) of { - true -> padata : KRB_PA_Data_Sequence; - false -> n1 : empty; +type KRB_ERROR_E_Data(error_code: uint64) = case ( error_code == 25 ) of { + true -> padata : KRB_ERROR_PA_Data; + false -> unknown : bytestring &restofdata; +}; + +type KRB_ERROR_PA_Data = record { + meta : ASN1EncodingMeta; + have_padata : case ( meta.tag == 30 ) of { + true -> padata : KRB_PA_Data_Sequence(KRB_ERROR); + false -> unknown : bytestring &restofdata; }; };