diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index 018378661e..431e172d6e 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -3009,6 +3009,14 @@ export { validate : bool; }; + ## AP Options. See :rfc:`4120` + type KRB::AP_Options: record { + ## Indicates that user-to-user-authentication is in use + use_session_key : bool; + ## Mutual authentication is required + mutual_required : bool; + }; + ## Used in a few places in the Kerberos analyzer for elements ## that have a type and a string value. type KRB::Type_Value: record { diff --git a/src/analyzer/protocol/krb/events.bif b/src/analyzer/protocol/krb/events.bif index 6655f616b8..052863cbb7 100644 --- a/src/analyzer/protocol/krb/events.bif +++ b/src/analyzer/protocol/krb/events.bif @@ -30,6 +30,43 @@ event krb_as_rep%(c: connection, msg: KRB::KDC_Reply%); ## msg: A Kerberos KDC reply message data structure. event krb_tgs_rep%(c: connection, msg: KRB::KDC_Reply%); +## A Kerberos 5 ``Authentication Header (AP) Request`` as defined +## in :rfc:`4120`. +## +## c: The connection over which this Kerberos message was sent. +## +## msg: A Kerberos KDC request message data structure. +event krb_ap_req%(c: connection, ticket: KRB::Ticket, opts: KRB::AP_Options%); + +## A Kerberos 5 ``Authentication Header (AP) Reply`` as defined +## in :rfc:`4120`. This is used if mutual authentication is desired. +## All of the interesting information in here is encrypted, so the event +## doesn't have much useful data, but it's available in case it's important +## to know that this message was sent. +## +## c: The connection over which this Kerberos message was sent. +## +## msg: A Kerberos KDC request message data structure. +event krb_ap_rep%(c: connection%); + +## A Kerberos 5 ``Private Message`` as defined +## in :rfc:`4120`. This is an encrypted message, so the event +## doesn't have much useful data, but it's available in case it's important +## to know that this message was sent. +## +## c: The connection over which this Kerberos message was sent. +## +## msg: A Kerberos KDC request message data structure. +event krb_priv%(c: connection%); + +## A Kerberos 5 ``Credential Message`` as defined +## in :rfc:`4120`. +## +## c: The connection over which this Kerberos message was sent. +## +## msg: A Kerberos KDC request message data structure. +event krb_cred%(c: connection, tickets: KRB::Ticket_Vector%); + ## A Kerberos 5 ``ERROR_MSG`` as defined in :rfc:`4120`. ## ## c: The connection over which this Kerberos message was sent. diff --git a/src/analyzer/protocol/krb/krb-analyzer.pac b/src/analyzer/protocol/krb/krb-analyzer.pac index 1ce046d7ce..07e034e075 100644 --- a/src/analyzer/protocol/krb/krb-analyzer.pac +++ b/src/analyzer/protocol/krb/krb-analyzer.pac @@ -208,14 +208,7 @@ refine connection KRB_Conn += { rv->Assign(3, bytestring_to_val(${msg.client_realm.encoding.content})); rv->Assign(4, GetStringFromPrincipalName(${msg.client_name})); - RecordVal* ticket = new RecordVal(BifType::Record::KRB::Ticket); - - ticket->Assign(0, asn1_integer_to_val(${msg.ticket.tkt_vno.data}, TYPE_COUNT)); - ticket->Assign(1, bytestring_to_val(${msg.ticket.realm.data.content})); - ticket->Assign(2, GetStringFromPrincipalName(${msg.ticket.sname})); - ticket->Assign(3, asn1_integer_to_val(${msg.ticket.enc_part.etype.data}, TYPE_COUNT)); - - rv->Assign(5, ticket); + rv->Assign(5, proc_ticket(${msg.ticket})); if ( ( binary_to_int64(${msg.msg_type.data.content}) == 11 ) ) BifEvent::generate_krb_as_rep(bro_analyzer(), bro_analyzer()->Conn(), rv); @@ -243,14 +236,25 @@ refine connection KRB_Conn += { function proc_krb_ap_req(msg: KRB_AP_REQ): bool %{ bro_analyzer()->ProtocolConfirmation(); - // Not implemented + if ( krb_ap_req ) + { + RecordVal* rv = new RecordVal(BifType::Record::KRB::AP_Options); + rv->Assign(0, new Val(${msg.ap_options.use_session_key}, TYPE_BOOL)); + rv->Assign(1, new Val(${msg.ap_options.mutual_required}, TYPE_BOOL)); + + BifEvent::generate_krb_ap_req(bro_analyzer(), bro_analyzer()->Conn(), + proc_ticket(${msg.ticket}), rv); + } return true; %} function proc_krb_ap_rep(msg: KRB_AP_REP): bool %{ bro_analyzer()->ProtocolConfirmation(); - // Not implemented + if ( krb_ap_rep ) + { + BifEvent::generate_krb_ap_rep(bro_analyzer(), bro_analyzer()->Conn()); + } return true; %} @@ -264,14 +268,20 @@ refine connection KRB_Conn += { function proc_krb_priv_msg(msg: KRB_PRIV_MSG): bool %{ bro_analyzer()->ProtocolConfirmation(); - // Not implemented + if ( krb_priv ) + { + BifEvent::generate_krb_priv(bro_analyzer(), bro_analyzer()->Conn()); + } return true; %} function proc_krb_cred_msg(msg: KRB_CRED_MSG): bool %{ bro_analyzer()->ProtocolConfirmation(); - // Not implemented + if ( krb_cred ) + { + BifEvent::generate_krb_cred(bro_analyzer(), bro_analyzer()->Conn(), proc_tickets(${msg.tickets})); + } return true; %} } diff --git a/src/analyzer/protocol/krb/krb-protocol.pac b/src/analyzer/protocol/krb/krb-protocol.pac index b64f9a72f6..8896e52f0f 100644 --- a/src/analyzer/protocol/krb/krb-protocol.pac +++ b/src/analyzer/protocol/krb/krb-protocol.pac @@ -215,7 +215,7 @@ type KRB_SAFE_Arg = record { type KRB_SAFE_Arg_Data(index: uint8) = case index of { 0 -> user_data : ASN1OctetString; 1 -> timestamp : KRB_Time; - 2 -> usec : ASN1Integer; + 2 -> usec : ASN1Integer; 3 -> seq_number : ASN1Integer; 4 -> sender_addr: KRB_Host_Address; 5 -> recp_addr : KRB_Host_Address; diff --git a/src/analyzer/protocol/krb/krb-types.pac b/src/analyzer/protocol/krb/krb-types.pac index a5ac4a17be..8306d9a6f0 100644 --- a/src/analyzer/protocol/krb/krb-types.pac +++ b/src/analyzer/protocol/krb/krb-types.pac @@ -5,7 +5,9 @@ Val* GetStringFromPrincipalName(const KRB_Principal_Name* pname); VectorVal* proc_cipher_list(const Array* list); VectorVal* proc_host_address_list(const KRB_Host_Addresses* list); + VectorVal* proc_tickets(const KRB_Ticket_Sequence* list); +RecordVal* proc_ticket(const KRB_Ticket* ticket); %} %code{ @@ -71,17 +73,23 @@ VectorVal* proc_tickets(const KRB_Ticket_Sequence* list) for ( uint i = 0; i < list->tickets()->size(); ++i ) { KRB_Ticket* element = (*list->tickets())[i]; - RecordVal* ticket = new RecordVal(BifType::Record::KRB::Ticket); - - ticket->Assign(0, asn1_integer_to_val(element->tkt_vno()->data(), TYPE_COUNT)); - ticket->Assign(1, bytestring_to_val(element->realm()->data()->content())); - ticket->Assign(2, GetStringFromPrincipalName(element->sname())); - ticket->Assign(3, asn1_integer_to_val(element->enc_part()->etype()->data(), TYPE_COUNT)); - tickets->Assign(tickets->Size(), ticket); + tickets->Assign(tickets->Size(), proc_ticket(element)); } return tickets; } + +RecordVal* proc_ticket(const KRB_Ticket* ticket) +{ + RecordVal* rv = new RecordVal(BifType::Record::KRB::Ticket); + + rv->Assign(0, asn1_integer_to_val(ticket->tkt_vno()->data(), TYPE_COUNT)); + rv->Assign(1, bytestring_to_val(ticket->realm()->data()->content())); + rv->Assign(2, GetStringFromPrincipalName(ticket->sname())); + rv->Assign(3, asn1_integer_to_val(ticket->enc_part()->etype()->data(), TYPE_COUNT)); + + return rv; +} %} type KRB_Principal_Name = record { diff --git a/src/analyzer/protocol/krb/types.bif b/src/analyzer/protocol/krb/types.bif index 5464d03510..54ac492b00 100644 --- a/src/analyzer/protocol/krb/types.bif +++ b/src/analyzer/protocol/krb/types.bif @@ -3,8 +3,10 @@ module KRB; type Error_Msg: record; type KDC_Options: record; +type AP_Options: record; type Type_Value: record; type Ticket: record; +type Ticket_Vector: vector; type Host_Address: record; type KDC_Request: record;