mirror of
https://github.com/zeek/zeek.git
synced 2025-10-11 02:58:20 +00:00
Kerberos analyzer updates:
- Split up the (quite length) krb-protocol.pac into krb-protocol, krb-defs, krb-types and krb-padata - Add some supporting types to get rid of awkward and difficult to read case true/false statements - Clean up the conversion code in krb-analyzer.pac
This commit is contained in:
parent
1f41c0470c
commit
2d11fafd5e
6 changed files with 565 additions and 591 deletions
|
@ -4,8 +4,8 @@
|
||||||
|
|
||||||
|
|
||||||
%header{
|
%header{
|
||||||
Val* GetTimeFromAsn1(const KRB_Time* atime);
|
Val* GetTimeFromAsn1(const KRB_Time* atime, int64 usecs);
|
||||||
Val* GetTimeFromAsn1(StringVal* atime);
|
Val* GetTimeFromAsn1(StringVal* atime, int64 usecs);
|
||||||
|
|
||||||
Val* GetStringFromPrincipalName(const KRB_Principal_Name* pname);
|
Val* GetStringFromPrincipalName(const KRB_Principal_Name* pname);
|
||||||
|
|
||||||
|
@ -13,15 +13,24 @@ Val* asn1_integer_to_val(const ASN1Encoding* i, TypeTag t);
|
||||||
Val* asn1_integer_to_val(const ASN1Integer* i, TypeTag t);
|
Val* asn1_integer_to_val(const ASN1Integer* i, TypeTag t);
|
||||||
|
|
||||||
RecordVal* proc_krb_kdc_options(const KRB_KDC_Options* opts);
|
RecordVal* proc_krb_kdc_options(const KRB_KDC_Options* opts);
|
||||||
|
RecordVal* proc_krb_kdc_req_arguments(KRB_KDC_REQ* msg, const BroAnalyzer bro_analyzer);
|
||||||
|
|
||||||
|
VectorVal* proc_padata(const KRB_PA_Data_Sequence* data, const BroAnalyzer bro_analyzer, bool is_error);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
bool proc_error_arguments(RecordVal* rv, const std::vector<KRB_ERROR_Arg*>* args, int64 error_code);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%code{
|
%code{
|
||||||
Val* GetTimeFromAsn1(const KRB_Time* atime)
|
Val* GetTimeFromAsn1(const KRB_Time* atime, int64 usecs)
|
||||||
{
|
{
|
||||||
return GetTimeFromAsn1(bytestring_to_val(atime->time()));
|
return GetTimeFromAsn1(bytestring_to_val(atime->time()), usecs);
|
||||||
}
|
}
|
||||||
|
|
||||||
Val* GetTimeFromAsn1(StringVal* atime)
|
Val* GetTimeFromAsn1(StringVal* atime, int64 usecs)
|
||||||
{
|
{
|
||||||
time_t lResult = 0;
|
time_t lResult = 0;
|
||||||
|
|
||||||
|
@ -57,7 +66,7 @@ Val* GetTimeFromAsn1(StringVal* atime)
|
||||||
if ( !lResult )
|
if ( !lResult )
|
||||||
lResult = 0;
|
lResult = 0;
|
||||||
|
|
||||||
return new Val(double(lResult), TYPE_TIME);
|
return new Val(double(lResult + (usecs/100000)), TYPE_TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
Val* GetStringFromPrincipalName(const KRB_Principal_Name* pname)
|
Val* GetStringFromPrincipalName(const KRB_Principal_Name* pname)
|
||||||
|
@ -101,6 +110,294 @@ RecordVal* proc_krb_kdc_options(const KRB_KDC_Options* opts)
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VectorVal* proc_padata(const KRB_PA_Data_Sequence* data, const BroAnalyzer bro_analyzer, bool is_error)
|
||||||
|
{
|
||||||
|
VectorVal* vv = new VectorVal(internal_type("KRB::Type_Value_Vector")->AsVectorType());
|
||||||
|
for ( uint i = 0; i < data->padata_elems()->size(); ++i)
|
||||||
|
{
|
||||||
|
KRB_PA_Data* element = (*data->padata_elems())[i];
|
||||||
|
int64 data_type = element->data_type();
|
||||||
|
|
||||||
|
if ( is_error && ( data_type == 16 || data_type == 17 ) )
|
||||||
|
data_type = 0;
|
||||||
|
|
||||||
|
switch( data_type )
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
// will be generated as separate event
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
// encrypted timestamp is unreadable
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
{
|
||||||
|
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()->pa_pw_salt()->encoding()->content()));
|
||||||
|
vv->Assign(vv->Size(), type_val);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 16:
|
||||||
|
{
|
||||||
|
const bytestring& cert = element->pa_data_element()->pa_pk_as_req()->cert();
|
||||||
|
|
||||||
|
ODesc common;
|
||||||
|
common.AddRaw("Analyzer::ANALYZER_KRB");
|
||||||
|
common.Add(bro_analyzer->Conn()->StartTime());
|
||||||
|
common.AddRaw("T", 1);
|
||||||
|
bro_analyzer->Conn()->IDString(&common);
|
||||||
|
|
||||||
|
ODesc file_handle;
|
||||||
|
file_handle.Add(common.Description());
|
||||||
|
file_handle.Add(0);
|
||||||
|
|
||||||
|
string file_id = file_mgr->HashHandle(file_handle.Description());
|
||||||
|
|
||||||
|
file_mgr->DataIn(reinterpret_cast<const u_char*>(cert.data()),
|
||||||
|
cert.length(), bro_analyzer->GetAnalyzerTag(),
|
||||||
|
bro_analyzer->Conn(), true, file_id);
|
||||||
|
file_mgr->EndOfFile(file_id);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 17:
|
||||||
|
{
|
||||||
|
const bytestring& cert = element->pa_data_element()->pa_pk_as_rep()->cert();
|
||||||
|
|
||||||
|
ODesc common;
|
||||||
|
common.AddRaw("Analyzer::ANALYZER_KRB");
|
||||||
|
common.Add(bro_analyzer->Conn()->StartTime());
|
||||||
|
common.AddRaw("F", 1);
|
||||||
|
bro_analyzer->Conn()->IDString(&common);
|
||||||
|
|
||||||
|
ODesc file_handle;
|
||||||
|
file_handle.Add(common.Description());
|
||||||
|
file_handle.Add(1);
|
||||||
|
|
||||||
|
string file_id = file_mgr->HashHandle(file_handle.Description());
|
||||||
|
|
||||||
|
file_mgr->DataIn(reinterpret_cast<const u_char*>(cert.data()),
|
||||||
|
cert.length(), bro_analyzer->GetAnalyzerTag(),
|
||||||
|
bro_analyzer->Conn(), false, file_id);
|
||||||
|
file_mgr->EndOfFile(file_id);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
if ( ! is_error && element->pa_data_element()->unknown().length() )
|
||||||
|
{
|
||||||
|
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()));
|
||||||
|
vv->Assign(vv->Size(), type_val);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return vv;
|
||||||
|
}
|
||||||
|
|
||||||
|
VectorVal* proc_cipher_list(const Array* list)
|
||||||
|
{
|
||||||
|
VectorVal* ciphers = new VectorVal(internal_type("index_vec")->AsVectorType());
|
||||||
|
for ( uint i = 0; i < list->data()->size(); ++i )
|
||||||
|
ciphers->Assign(ciphers->Size(), asn1_integer_to_val((*list->data())[i], TYPE_COUNT));
|
||||||
|
return ciphers;
|
||||||
|
}
|
||||||
|
|
||||||
|
VectorVal* proc_host_address_list(const KRB_Host_Addresses* list)
|
||||||
|
{
|
||||||
|
VectorVal* addrs = new VectorVal(internal_type("KRB::Host_Address_Vector")->AsVectorType());
|
||||||
|
|
||||||
|
for ( uint i = 0; i < list->addresses()->size(); ++i )
|
||||||
|
{
|
||||||
|
RecordVal* addr = new RecordVal(BifType::Record::KRB::Host_Address);
|
||||||
|
KRB_Host_Address* element = (*list->addresses())[i];
|
||||||
|
|
||||||
|
switch ( binary_to_int64(element->addr_type()->encoding()->content()) )
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
addr->Assign(0, new AddrVal(IPAddr(IPv4,
|
||||||
|
(const uint32_t*) c_str(element->address()->data()->content()),
|
||||||
|
IPAddr::Network)));
|
||||||
|
break;
|
||||||
|
case 24:
|
||||||
|
addr->Assign(0, new AddrVal(IPAddr(IPv6,
|
||||||
|
(const uint32_t*) c_str(element->address()->data()->content()),
|
||||||
|
IPAddr::Network)));
|
||||||
|
break;
|
||||||
|
case 20:
|
||||||
|
addr->Assign(1, bytestring_to_val(element->address()->data()->content()));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
RecordVal* unk = new RecordVal(BifType::Record::KRB::Type_Value);
|
||||||
|
unk->Assign(0, asn1_integer_to_val(element->addr_type(), TYPE_COUNT));
|
||||||
|
unk->Assign(1, bytestring_to_val(element->address()->data()->content()));
|
||||||
|
addr->Assign(2, unk);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
addrs->Assign(addrs->Size(), addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return addrs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VectorVal* proc_tickets(const KRB_Ticket_Sequence* list)
|
||||||
|
{
|
||||||
|
VectorVal* tickets = new VectorVal(internal_type("KRB::Ticket_Vector")->AsVectorType());
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tickets;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool proc_error_arguments(RecordVal* rv, const std::vector<KRB_ERROR_Arg*>* args, int64 error_code )
|
||||||
|
{
|
||||||
|
uint ctime_i = 0, ctime_usecs_i = 0, stime_i = 0, stime_usecs_i = 0;
|
||||||
|
int64 ctime_usecs = 0, stime_usecs = 0;
|
||||||
|
|
||||||
|
// We need to do a pass first, to see if we have microseconds for the timestamp values, which are optional
|
||||||
|
|
||||||
|
for ( uint i = 0; i < args->size(); i++ )
|
||||||
|
{
|
||||||
|
switch ( (*args)[i]->seq_meta()->index() )
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
ctime_i = i;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
ctime_usecs_i = i;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
stime_i = i;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
stime_usecs_i = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ctime_usecs_i ) ctime_usecs = binary_to_int64((*args)[ctime_usecs_i]->args()->cusec()->encoding()->content());
|
||||||
|
if ( ctime_i ) rv->Assign(2, GetTimeFromAsn1((*args)[ctime_i]->args()->ctime(), ctime_usecs));
|
||||||
|
|
||||||
|
if ( stime_usecs_i ) stime_usecs = binary_to_int64((*args)[stime_usecs_i]->args()->susec()->encoding()->content());
|
||||||
|
if ( stime_i ) rv->Assign(3, GetTimeFromAsn1((*args)[stime_i]->args()->stime(), stime_usecs));
|
||||||
|
|
||||||
|
for ( uint i = 0; i < args->size(); i++ )
|
||||||
|
{
|
||||||
|
switch ( (*args)[i]->seq_meta()->index() )
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
rv->Assign(0, asn1_integer_to_val((*args)[i]->args()->pvno(), TYPE_COUNT));
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
rv->Assign(1, asn1_integer_to_val((*args)[i]->args()->msg_type(), TYPE_COUNT));
|
||||||
|
break;
|
||||||
|
// ctime/stime handled above
|
||||||
|
case 7:
|
||||||
|
rv->Assign(5, bytestring_to_val((*args)[i]->args()->crealm()->encoding()->content()));
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
rv->Assign(6, GetStringFromPrincipalName((*args)[i]->args()->cname()));
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
rv->Assign(7, bytestring_to_val((*args)[i]->args()->realm()->encoding()->content()));
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
rv->Assign(8, GetStringFromPrincipalName((*args)[i]->args()->sname()));
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
rv->Assign(9, bytestring_to_val((*args)[i]->args()->e_text()->encoding()->content()));
|
||||||
|
break;
|
||||||
|
case 12:
|
||||||
|
if ( error_code == 25 )
|
||||||
|
rv->Assign(10, proc_padata((*args)[i]->args()->e_data()->padata(), NULL, true));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
RecordVal* proc_krb_kdc_req_arguments(KRB_KDC_REQ* msg, const BroAnalyzer bro_analyzer)
|
||||||
|
{
|
||||||
|
RecordVal* rv = new RecordVal(BifType::Record::KRB::KDC_Request);
|
||||||
|
|
||||||
|
rv->Assign(0, asn1_integer_to_val(msg->pvno()->data(), TYPE_COUNT));
|
||||||
|
rv->Assign(1, asn1_integer_to_val(msg->msg_type()->data(), TYPE_COUNT));
|
||||||
|
|
||||||
|
if ( msg->padata()->has_padata() )
|
||||||
|
rv->Assign(2, proc_padata(msg->padata()->padata()->padata(), bro_analyzer, false));
|
||||||
|
|
||||||
|
for ( uint i = 0; i < msg->body_args()->size(); ++i )
|
||||||
|
{
|
||||||
|
KRB_REQ_Arg* element = (*msg->body_args())[i];
|
||||||
|
switch ( element->seq_meta()->index() )
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
rv->Assign(3, proc_krb_kdc_options(element->data()->options()));
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
rv->Assign(4, GetStringFromPrincipalName(element->data()->principal()));
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
rv->Assign(5, bytestring_to_val(element->data()->realm()->encoding()->content()));
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
rv->Assign(6, GetStringFromPrincipalName(element->data()->sname()));
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
rv->Assign(7, GetTimeFromAsn1(element->data()->from(), 0));
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
rv->Assign(8, GetTimeFromAsn1(element->data()->till(), 0));
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
rv->Assign(9, GetTimeFromAsn1(element->data()->rtime(), 0));
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
rv->Assign(10, asn1_integer_to_val(element->data()->nonce(), TYPE_COUNT));
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
if ( element->data()->etype()->data()->size() )
|
||||||
|
rv->Assign(11, proc_cipher_list(element->data()->etype()));
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
if ( element->data()->addrs()->addresses()->size() )
|
||||||
|
rv->Assign(12, proc_host_address_list(element->data()->addrs()));
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
// TODO
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
if ( element->data()->addl_tkts()->tickets()->size() )
|
||||||
|
rv->Assign(13, proc_tickets(element->data()->addl_tkts()));
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
refine connection KRB_Conn += {
|
refine connection KRB_Conn += {
|
||||||
|
@ -112,168 +409,9 @@ refine connection KRB_Conn += {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ( ( binary_to_int64(${msg.msg_type.data.content}) == 12 ) && ! krb_tgs_req )
|
if ( ( binary_to_int64(${msg.msg_type.data.content}) == 12 ) && ! krb_tgs_req )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
||||||
RecordVal* rv = new RecordVal(BifType::Record::KRB::KDC_Request);
|
|
||||||
|
|
||||||
rv->Assign(0, asn1_integer_to_val(${msg.pvno.data}, TYPE_COUNT));
|
RecordVal* rv = proc_krb_kdc_req_arguments(${msg}, bro_analyzer());
|
||||||
rv->Assign(1, asn1_integer_to_val(${msg.msg_type.data}, TYPE_COUNT));
|
|
||||||
|
|
||||||
if ( ${msg.has_padata} )
|
|
||||||
{
|
|
||||||
VectorVal* padata = new VectorVal(internal_type("KRB::Type_Value_Vector")->AsVectorType());
|
|
||||||
|
|
||||||
for ( uint i = 0; i < ${msg.padata.padata_elems}->size(); ++i)
|
|
||||||
{
|
|
||||||
switch( ${msg.padata.padata_elems[i].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.padata.padata_elems[i].data_type}, TYPE_COUNT));
|
|
||||||
type_val->Assign(1, bytestring_to_val(${msg.padata.padata_elems[i].pa_data_element.pa_pw_salt.encoding.content}));
|
|
||||||
padata->Assign(padata->Size(), type_val);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 16:
|
|
||||||
{
|
|
||||||
const bytestring& cert = ${msg.padata.padata_elems[i].pa_data_element.pa_pk_as_req.cert};
|
|
||||||
|
|
||||||
ODesc common;
|
|
||||||
common.AddRaw("Analyzer::ANALYZER_KRB");
|
|
||||||
common.Add(bro_analyzer()->Conn()->StartTime());
|
|
||||||
common.AddRaw("T", 1);
|
|
||||||
bro_analyzer()->Conn()->IDString(&common);
|
|
||||||
|
|
||||||
ODesc file_handle;
|
|
||||||
file_handle.Add(common.Description());
|
|
||||||
file_handle.Add(0);
|
|
||||||
|
|
||||||
string file_id = file_mgr->HashHandle(file_handle.Description());
|
|
||||||
|
|
||||||
file_mgr->DataIn(reinterpret_cast<const u_char*>(cert.data()),
|
|
||||||
cert.length(), bro_analyzer()->GetAnalyzerTag(),
|
|
||||||
bro_analyzer()->Conn(), true, file_id);
|
|
||||||
file_mgr->EndOfFile(file_id);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
if ( ${msg.padata.padata_elems[i].pa_data_element.unknown}.length() )
|
|
||||||
{
|
|
||||||
RecordVal * type_val = new RecordVal(BifType::Record::KRB::Type_Value);
|
|
||||||
type_val->Assign(0, new Val(${msg.padata.padata_elems[i].data_type}, TYPE_COUNT));
|
|
||||||
type_val->Assign(1, bytestring_to_val(${msg.padata.padata_elems[i].pa_data_element.unknown}));
|
|
||||||
padata->Assign(padata->Size(), type_val);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rv->Assign(2, padata);
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( uint i = 0; i < ${msg.body.args}->size(); ++i )
|
|
||||||
{
|
|
||||||
switch ( ${msg.body.args[i].seq_meta.index} )
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
rv->Assign(3, proc_krb_kdc_options(${msg.body.args[i].data.options}));
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
rv->Assign(4, GetStringFromPrincipalName(${msg.body.args[i].data.principal}));
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
rv->Assign(5, bytestring_to_val(${msg.body.args[i].data.realm.encoding.content}));
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
rv->Assign(6, GetStringFromPrincipalName(${msg.body.args[i].data.sname}));
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
rv->Assign(7, GetTimeFromAsn1(${msg.body.args[i].data.from}));
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
rv->Assign(8, GetTimeFromAsn1(${msg.body.args[i].data.till}));
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
rv->Assign(9, GetTimeFromAsn1(${msg.body.args[i].data.rtime}));
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
rv->Assign(10, asn1_integer_to_val(${msg.body.args[i].data.nonce}, TYPE_COUNT));
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
if ( ${msg.body.args[i].data.etype.data}->size() )
|
|
||||||
{
|
|
||||||
VectorVal* ciphers = new VectorVal(internal_type("index_vec")->AsVectorType());
|
|
||||||
|
|
||||||
for ( uint j = 0; j < ${msg.body.args[i].data.etype.data}->size(); ++j )
|
|
||||||
ciphers->Assign(ciphers->Size(), asn1_integer_to_val(${msg.body.args[i].data.etype.data[j]}, TYPE_COUNT));
|
|
||||||
|
|
||||||
rv->Assign(11, ciphers);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 9:
|
|
||||||
if ( ${msg.body.args[i].data.addrs.addresses}->size() )
|
|
||||||
{
|
|
||||||
VectorVal* addrs = new VectorVal(internal_type("KRB::Host_Address_Vector")->AsVectorType());
|
|
||||||
|
|
||||||
for ( uint j = 0; j < ${msg.body.args[i].data.addrs.addresses}->size(); ++j )
|
|
||||||
{
|
|
||||||
RecordVal* addr = new RecordVal(BifType::Record::KRB::Host_Address);
|
|
||||||
switch ( binary_to_int64(${msg.body.args[i].data.addrs.addresses[j].addr_type.encoding.content}) )
|
|
||||||
{
|
|
||||||
case 2:
|
|
||||||
addr->Assign(0, new AddrVal(IPAddr(IPv4, (const uint32_t*) c_str(${msg.body.args[i].data.addrs.addresses[j].address.data.content}), IPAddr::Network)));
|
|
||||||
break;
|
|
||||||
case 24:
|
|
||||||
addr->Assign(0, new AddrVal(IPAddr(IPv6, (const uint32_t*) c_str(${msg.body.args[i].data.addrs.addresses[j].address.data.content}), IPAddr::Network)));
|
|
||||||
break;
|
|
||||||
case 20:
|
|
||||||
addr->Assign(1, bytestring_to_val(${msg.body.args[i].data.addrs.addresses[j].address.data.content}));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
RecordVal* unk = new RecordVal(BifType::Record::KRB::Type_Value);
|
|
||||||
unk->Assign(0, asn1_integer_to_val(${msg.body.args[i].data.addrs.addresses[j].addr_type}, TYPE_COUNT));
|
|
||||||
unk->Assign(1, bytestring_to_val(${msg.body.args[i].data.addrs.addresses[j].address.data.content}));
|
|
||||||
addr->Assign(2, unk);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
addrs->Assign(addrs->Size(), addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
rv->Assign(12, addrs);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 10:
|
|
||||||
// TODO
|
|
||||||
break;
|
|
||||||
case 11:
|
|
||||||
if ( ${msg.body.args[i].data.addl_tkts.tickets}->size() )
|
|
||||||
{
|
|
||||||
VectorVal* tickets = new VectorVal(internal_type("KRB::Ticket_Vector")->AsVectorType());
|
|
||||||
|
|
||||||
for ( uint j = 0; j < ${msg.body.args[i].data.addl_tkts.tickets}->size(); ++j )
|
|
||||||
{
|
|
||||||
RecordVal* ticket = new RecordVal(BifType::Record::KRB::Ticket);
|
|
||||||
|
|
||||||
ticket->Assign(0, asn1_integer_to_val(${msg.body.args[i].data.addl_tkts.tickets[j].tkt_vno.data}, TYPE_COUNT));
|
|
||||||
ticket->Assign(1, bytestring_to_val(${msg.body.args[i].data.addl_tkts.tickets[j].realm.data.content}));
|
|
||||||
ticket->Assign(2, GetStringFromPrincipalName(${msg.body.args[i].data.addl_tkts.tickets[j].sname}));
|
|
||||||
ticket->Assign(3, asn1_integer_to_val(${msg.body.args[i].data.addl_tkts.tickets[j].enc_part.etype.data}, TYPE_COUNT));
|
|
||||||
tickets->Assign(tickets->Size(), ticket);
|
|
||||||
}
|
|
||||||
rv->Assign(13, tickets);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ( binary_to_int64(${msg.msg_type.data.content}) == 10 ) )
|
if ( ( binary_to_int64(${msg.msg_type.data.content}) == 10 ) )
|
||||||
BifEvent::generate_krb_as_req(bro_analyzer(), bro_analyzer()->Conn(), rv);
|
BifEvent::generate_krb_as_req(bro_analyzer(), bro_analyzer()->Conn(), rv);
|
||||||
|
@ -300,63 +438,8 @@ refine connection KRB_Conn += {
|
||||||
rv->Assign(0, asn1_integer_to_val(${msg.pvno.data}, TYPE_COUNT));
|
rv->Assign(0, asn1_integer_to_val(${msg.pvno.data}, TYPE_COUNT));
|
||||||
rv->Assign(1, asn1_integer_to_val(${msg.msg_type.data}, TYPE_COUNT));
|
rv->Assign(1, asn1_integer_to_val(${msg.msg_type.data}, TYPE_COUNT));
|
||||||
|
|
||||||
if ( ${msg.has_padata} )
|
if ( ${msg.padata.has_padata} )
|
||||||
{
|
rv->Assign(2, proc_padata(${msg.padata.padata.padata}, bro_analyzer(), false));
|
||||||
VectorVal* padata = new VectorVal(internal_type("KRB::Type_Value_Vector")->AsVectorType());
|
|
||||||
|
|
||||||
for ( uint i = 0; i < ${msg.padata.padata_elems}->size(); ++i)
|
|
||||||
{
|
|
||||||
switch( ${msg.padata.padata_elems[i].data_type} )
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
// will be generated as separate event
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
// encrypted timestamp is unreadable
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
{
|
|
||||||
RecordVal * type_val = new RecordVal(BifType::Record::KRB::Type_Value);
|
|
||||||
type_val->Assign(0, new Val(${msg.padata.padata_elems[i].data_type}, TYPE_COUNT));
|
|
||||||
type_val->Assign(1, bytestring_to_val(${msg.padata.padata_elems[i].pa_data_element.pa_pw_salt.encoding.content}));
|
|
||||||
padata->Assign(padata->Size(), type_val);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 17:
|
|
||||||
{
|
|
||||||
const bytestring& cert = ${msg.padata.padata_elems[i].pa_data_element.pa_pk_as_rep.cert};
|
|
||||||
|
|
||||||
ODesc common;
|
|
||||||
common.AddRaw("Analyzer::ANALYZER_KRB");
|
|
||||||
common.Add(bro_analyzer()->Conn()->StartTime());
|
|
||||||
common.AddRaw("F", 1);
|
|
||||||
bro_analyzer()->Conn()->IDString(&common);
|
|
||||||
|
|
||||||
ODesc file_handle;
|
|
||||||
file_handle.Add(common.Description());
|
|
||||||
file_handle.Add(1);
|
|
||||||
|
|
||||||
string file_id = file_mgr->HashHandle(file_handle.Description());
|
|
||||||
|
|
||||||
file_mgr->DataIn(reinterpret_cast<const u_char*>(cert.data()),
|
|
||||||
cert.length(), bro_analyzer()->GetAnalyzerTag(),
|
|
||||||
bro_analyzer()->Conn(), false, file_id);
|
|
||||||
file_mgr->EndOfFile(file_id);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
RecordVal * type_val = new RecordVal(BifType::Record::KRB::Type_Value);
|
|
||||||
type_val->Assign(0, new Val(${msg.padata.padata_elems[i].data_type}, TYPE_COUNT));
|
|
||||||
type_val->Assign(1, bytestring_to_val(${msg.padata.padata_elems[i].pa_data_element.unknown}));
|
|
||||||
padata->Assign(padata->Size(), type_val);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rv->Assign(2, padata);
|
|
||||||
}
|
|
||||||
|
|
||||||
rv->Assign(3, bytestring_to_val(${msg.client_realm.encoding.content}));
|
rv->Assign(3, bytestring_to_val(${msg.client_realm.encoding.content}));
|
||||||
rv->Assign(4, GetStringFromPrincipalName(${msg.client_name}));
|
rv->Assign(4, GetStringFromPrincipalName(${msg.client_name}));
|
||||||
|
@ -399,79 +482,10 @@ refine connection KRB_Conn += {
|
||||||
if ( krb_error )
|
if ( krb_error )
|
||||||
{
|
{
|
||||||
RecordVal* rv = new RecordVal(BifType::Record::KRB::Error_Msg);
|
RecordVal* rv = new RecordVal(BifType::Record::KRB::Error_Msg);
|
||||||
rv->Assign(0, asn1_integer_to_val(${msg.pvno.data}, TYPE_COUNT));
|
proc_error_arguments(rv, ${msg.args1}, 0);
|
||||||
rv->Assign(1, asn1_integer_to_val(${msg.msg_type.data}, TYPE_COUNT));
|
rv->Assign(4, asn1_integer_to_val(${msg.error_code}, TYPE_COUNT));
|
||||||
if ( ${msg.has_ctime} )
|
proc_error_arguments(rv, ${msg.args2}, binary_to_int64(${msg.error_code.encoding.content}));
|
||||||
rv->Assign(2, GetTimeFromAsn1(bytestring_to_val(${msg.ctime})));
|
BifEvent::generate_krb_error(bro_analyzer(), bro_analyzer()->Conn(), rv);
|
||||||
|
|
||||||
// TODO: if ( ${msg.has_cusec} )
|
|
||||||
|
|
||||||
rv->Assign(3, GetTimeFromAsn1(bytestring_to_val(${msg.stime})));
|
|
||||||
// TODO: ${msg.susec}
|
|
||||||
|
|
||||||
|
|
||||||
rv->Assign(4, asn1_integer_to_val(${msg.error_code.data}, TYPE_COUNT));
|
|
||||||
|
|
||||||
for ( uint i = 0; i < ${msg.args}->size(); i++ )
|
|
||||||
{
|
|
||||||
switch ( ${msg.args[i].seq_meta.index} )
|
|
||||||
{
|
|
||||||
case 7:
|
|
||||||
rv->Assign(5, bytestring_to_val(${msg.args[i].args.crealm.encoding.content}));
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
rv->Assign(6, GetStringFromPrincipalName(${msg.args[i].args.cname}));
|
|
||||||
break;
|
|
||||||
case 9:
|
|
||||||
rv->Assign(7, bytestring_to_val(${msg.args[i].args.realm.encoding.content}));
|
|
||||||
break;
|
|
||||||
case 10:
|
|
||||||
rv->Assign(8, GetStringFromPrincipalName(${msg.args[i].args.sname}));
|
|
||||||
break;
|
|
||||||
case 11:
|
|
||||||
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());
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BifEvent::generate_krb_error(bro_analyzer(), bro_analyzer()->Conn(), rv);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
%}
|
%}
|
||||||
|
@ -505,7 +519,13 @@ refine connection KRB_Conn += {
|
||||||
|
|
||||||
function debug_asn1_encoding_meta(msg: ASN1EncodingMeta): bool
|
function debug_asn1_encoding_meta(msg: ASN1EncodingMeta): bool
|
||||||
%{
|
%{
|
||||||
printf("ASN1 Element tag=%x, length=%d\n", ${msg.tag}, ${msg.length});
|
printf("DeBuG ASN1 Element tag=%x, length=%d\n", ${msg.tag}, ${msg.length});
|
||||||
|
return true;
|
||||||
|
%}
|
||||||
|
|
||||||
|
function debug_krb_error_arg(msg: KRB_ERROR_Arg): bool
|
||||||
|
%{
|
||||||
|
printf("DeBuG KRB Error index=%d\n", ${msg.seq_meta.index});
|
||||||
return true;
|
return true;
|
||||||
%}
|
%}
|
||||||
}
|
}
|
||||||
|
@ -555,7 +575,10 @@ refine typeattr KRB_CRED_MSG += &let {
|
||||||
# proc: bool = $context.connection.debug_req_arg(this);
|
# proc: bool = $context.connection.debug_req_arg(this);
|
||||||
#};
|
#};
|
||||||
|
|
||||||
#refine typeattr ASN1EncodingMeta += &let {
|
refine typeattr ASN1EncodingMeta += &let {
|
||||||
# proc: bool = $context.connection.debug_asn1_encoding_meta(this);
|
proc: bool = $context.connection.debug_asn1_encoding_meta(this);
|
||||||
#};
|
};
|
||||||
|
|
||||||
|
refine typeattr KRB_ERROR_Arg += &let {
|
||||||
|
proc: bool = $context.connection.debug_krb_error_arg(this);
|
||||||
|
};
|
|
@ -14,6 +14,13 @@ type ASN1EncodingMeta = record {
|
||||||
index: uint8 = tag - 160;
|
index: uint8 = tag - 160;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type ASN1OptionalEncodingMeta(is_present: bool, previous_metadata: ASN1EncodingMeta) = case is_present of {
|
||||||
|
true -> data: ASN1EncodingMeta;
|
||||||
|
false -> none: empty;
|
||||||
|
} &let {
|
||||||
|
length: uint64 = is_present ? data.length : previous_metadata.length;
|
||||||
|
};
|
||||||
|
|
||||||
type ASN1Integer = record {
|
type ASN1Integer = record {
|
||||||
encoding: ASN1Encoding;
|
encoding: ASN1Encoding;
|
||||||
};
|
};
|
||||||
|
|
13
src/analyzer/protocol/krb/krb-defs.pac
Normal file
13
src/analyzer/protocol/krb/krb-defs.pac
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
enum KRBMessageTypes {
|
||||||
|
AS_REQ = 10,
|
||||||
|
AS_REP = 11,
|
||||||
|
TGS_REQ = 12,
|
||||||
|
TGS_REP = 13,
|
||||||
|
AP_REQ = 14,
|
||||||
|
AP_REP = 15,
|
||||||
|
KRB_SAFE = 20,
|
||||||
|
KRB_PRIV = 21,
|
||||||
|
KRB_CRED = 22,
|
||||||
|
KRB_ERROR = 30,
|
||||||
|
};
|
||||||
|
|
76
src/analyzer/protocol/krb/krb-padata.pac
Normal file
76
src/analyzer/protocol/krb/krb-padata.pac
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
# Kerberos pre-authentication data is a significant piece of the complexity,
|
||||||
|
# so we're splitting this off
|
||||||
|
|
||||||
|
type KRB_PA_Data_Optional(pkt_type: uint8, desired_index: uint8) = record {
|
||||||
|
first_meta : ASN1EncodingMeta;
|
||||||
|
padata : KRB_PA_Data_Field(has_padata, pkt_type, first_meta.length);
|
||||||
|
next_meta : ASN1OptionalEncodingMeta(has_padata, first_meta);
|
||||||
|
} &let {
|
||||||
|
has_padata : bool = first_meta.index == desired_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
type KRB_PA_Data_Field(is_present: bool, pkt_type: uint8, length: uint64) = case is_present of {
|
||||||
|
true -> padata: KRB_PA_Data_Sequence(pkt_type) &length=length;
|
||||||
|
false -> none: empty;
|
||||||
|
};
|
||||||
|
|
||||||
|
type KRB_PA_Data_Sequence(pkt_type: uint8) = record {
|
||||||
|
seq_meta : ASN1EncodingMeta;
|
||||||
|
padata_elems: KRB_PA_Data(pkt_type)[];
|
||||||
|
};
|
||||||
|
|
||||||
|
type KRB_PA_Data(pkt_type: uint8) = record {
|
||||||
|
seq_meta : ASN1EncodingMeta;
|
||||||
|
pa_data_type : SequenceElement(true);
|
||||||
|
pa_data_elem_meta : ASN1EncodingMeta;
|
||||||
|
have_data : case pkt_type of {
|
||||||
|
KRB_ERROR -> pa_data_placeholder: bytestring &length=pa_data_elem_meta.length;
|
||||||
|
default -> pa_data_element : KRB_PA_Data_Element(data_type, pa_data_elem_meta.length);
|
||||||
|
} &requires(data_type);
|
||||||
|
} &let {
|
||||||
|
data_type: int64 = binary_to_int64(pa_data_type.data.content);
|
||||||
|
};
|
||||||
|
|
||||||
|
type KRB_PA_Data_Element(type: int64, length: uint64) = case type of {
|
||||||
|
1 -> pa_tgs_req : KRB_AP_REQ;
|
||||||
|
3 -> pa_pw_salt : ASN1OctetString;
|
||||||
|
16 -> pa_pk_as_req : KRB_PA_PK_AS_Req &length=length;
|
||||||
|
17 -> pa_pk_as_rep : KRB_PA_PK_AS_Rep &length=length;
|
||||||
|
default -> unknown : bytestring &length=length;
|
||||||
|
};
|
||||||
|
|
||||||
|
type KRB_PA_PK_AS_Req = record {
|
||||||
|
string_meta : ASN1EncodingMeta;
|
||||||
|
seq_meta1 : ASN1EncodingMeta;
|
||||||
|
elem_0_meta1: ASN1EncodingMeta;
|
||||||
|
seq_meta2 : ASN1EncodingMeta;
|
||||||
|
oid : ASN1Encoding;
|
||||||
|
elem_0_meta2: ASN1EncodingMeta;
|
||||||
|
seq_meta3 : ASN1EncodingMeta;
|
||||||
|
version : ASN1Encoding;
|
||||||
|
digest_algs : ASN1Encoding;
|
||||||
|
signed_data : ASN1Encoding;
|
||||||
|
cert_meta : ASN1EncodingMeta;
|
||||||
|
cert : bytestring &length=cert_meta.length;
|
||||||
|
# Ignore everything else
|
||||||
|
: bytestring &restofdata &transient;
|
||||||
|
};
|
||||||
|
|
||||||
|
type KRB_PA_PK_AS_Rep = record {
|
||||||
|
string_meta : ASN1EncodingMeta;
|
||||||
|
elem_0_meta1: ASN1EncodingMeta;
|
||||||
|
seq_meta1 : ASN1EncodingMeta;
|
||||||
|
elem_0_meta2: ASN1EncodingMeta;
|
||||||
|
seq_meta2 : ASN1EncodingMeta;
|
||||||
|
oid : ASN1Encoding;
|
||||||
|
elem_0_meta3: ASN1EncodingMeta;
|
||||||
|
seq_meta3 : ASN1EncodingMeta;
|
||||||
|
version : ASN1Encoding;
|
||||||
|
digest_algs : ASN1Encoding;
|
||||||
|
signed_data : ASN1Encoding;
|
||||||
|
cert_meta : ASN1EncodingMeta;
|
||||||
|
cert : bytestring &length=cert_meta.length;
|
||||||
|
# Ignore everything else
|
||||||
|
: bytestring &restofdata &transient;
|
||||||
|
};
|
||||||
|
|
|
@ -1,20 +1,18 @@
|
||||||
|
# ASN1 parsing
|
||||||
%include krb-asn1.pac
|
%include krb-asn1.pac
|
||||||
|
|
||||||
enum KRBMessageTypes {
|
# Constants
|
||||||
AS_REQ = 10,
|
%include krb-defs.pac
|
||||||
AS_REP = 11,
|
|
||||||
TGS_REQ = 12,
|
|
||||||
TGS_REP = 13,
|
|
||||||
AP_REQ = 14,
|
|
||||||
AP_REP = 15,
|
|
||||||
KRB_SAFE = 20,
|
|
||||||
KRB_PRIV = 21,
|
|
||||||
KRB_CRED = 22,
|
|
||||||
KRB_ERROR = 30,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
# Basic types
|
||||||
|
%include krb-types.pac
|
||||||
|
|
||||||
|
# Preauth data parsing
|
||||||
|
%include krb-padata.pac
|
||||||
|
|
||||||
|
# KRB over TCP is the same as over UDP, but prefixed with a uint32 denoting the size
|
||||||
type KRB_PDU_TCP = record {
|
type KRB_PDU_TCP = record {
|
||||||
size: uint32;
|
size : uint32;
|
||||||
pdu : KRB_PDU;
|
pdu : KRB_PDU;
|
||||||
} &length=size+4 &byteorder=bigendian;
|
} &length=size+4 &byteorder=bigendian;
|
||||||
|
|
||||||
|
@ -31,7 +29,6 @@ type KRB_PDU = record {
|
||||||
KRB_PRIV -> krb_priv : KRB_PRIV_MSG;
|
KRB_PRIV -> krb_priv : KRB_PRIV_MSG;
|
||||||
KRB_CRED -> krb_cred : KRB_CRED_MSG;
|
KRB_CRED -> krb_cred : KRB_CRED_MSG;
|
||||||
KRB_ERROR -> krb_error: KRB_ERROR_MSG;
|
KRB_ERROR -> krb_error: KRB_ERROR_MSG;
|
||||||
default -> unknown : bytestring &restofdata;
|
|
||||||
};
|
};
|
||||||
} &byteorder=bigendian;
|
} &byteorder=bigendian;
|
||||||
|
|
||||||
|
@ -51,131 +48,33 @@ type KRB_TGS_REP = record {
|
||||||
data: KRB_KDC_REP(TGS_REP);
|
data: KRB_KDC_REP(TGS_REP);
|
||||||
};
|
};
|
||||||
|
|
||||||
### KDC_REQ
|
### A Kerberos ticket-granting-service or authentication-service request
|
||||||
|
|
||||||
type KRB_KDC_REQ(pkt_type: uint8) = record {
|
type KRB_KDC_REQ(pkt_type: uint8) = record {
|
||||||
seq_meta : ASN1EncodingMeta;
|
seq_meta : ASN1EncodingMeta;
|
||||||
pvno : SequenceElement(true);
|
pvno : SequenceElement(true);
|
||||||
msg_type : SequenceElement(true);
|
msg_type : SequenceElement(true);
|
||||||
padata_meta: ASN1EncodingMeta;
|
padata : KRB_PA_Data_Optional(pkt_type, 3);
|
||||||
tmp1 : case has_padata of {
|
body_meta : ASN1EncodingMeta;
|
||||||
true -> padata : KRB_PA_Data_Sequence(pkt_type) &length=padata_meta.length;
|
body_args : KRB_REQ_Arg[];
|
||||||
false -> n1 : empty;
|
|
||||||
};
|
|
||||||
tmp2 : case has_padata of {
|
|
||||||
true -> meta2 : ASN1EncodingMeta;
|
|
||||||
false -> n2 : empty;
|
|
||||||
};
|
|
||||||
body : KRB_REQ_Body &length=body_length;
|
|
||||||
} &let {
|
|
||||||
has_padata : bool = padata_meta.index == 3;
|
|
||||||
body_length: uint64 = has_padata ? meta2.length : padata_meta.length;
|
|
||||||
};
|
|
||||||
|
|
||||||
type KRB_PA_Data_Sequence(pkt_type: uint8) = record {
|
|
||||||
seq_meta : ASN1EncodingMeta;
|
|
||||||
padata_elems: KRB_PA_Data(pkt_type)[];
|
|
||||||
};
|
|
||||||
|
|
||||||
type KRB_PA_Data(pkttype: uint8) = record {
|
|
||||||
seq_meta : ASN1EncodingMeta;
|
|
||||||
pa_data_type : SequenceElement(true);
|
|
||||||
pa_data_elem_meta : ASN1EncodingMeta;
|
|
||||||
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);
|
|
||||||
};
|
|
||||||
|
|
||||||
type KRB_PA_Data_Element(type: int64, length: uint64) = case type of {
|
|
||||||
1 -> pa_tgs_req : KRB_AP_REQ;
|
|
||||||
3 -> pa_pw_salt : ASN1OctetString;
|
|
||||||
16 -> pa_pk_as_req : KRB_PA_PK_AS_Req &length=length;
|
|
||||||
17 -> pa_pk_as_rep : KRB_PA_PK_AS_Rep &length=length;
|
|
||||||
default -> unknown : bytestring &length=length;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Octet string metadata
|
|
||||||
# -- Sequence metadata
|
|
||||||
# ---- [0] metadata
|
|
||||||
# ------ Sequence metadata
|
|
||||||
# -------- OID
|
|
||||||
# ---------- [0] metadata
|
|
||||||
# ------------ Sequence metadata
|
|
||||||
# -------------- version
|
|
||||||
# -------------- digestAlgorithms
|
|
||||||
# -------------- signedData
|
|
||||||
# -------------- certificates
|
|
||||||
type KRB_PA_PK_AS_Req = record {
|
|
||||||
string_meta : ASN1EncodingMeta;
|
|
||||||
seq_meta1 : ASN1EncodingMeta;
|
|
||||||
elem_0_meta1: ASN1EncodingMeta;
|
|
||||||
seq_meta2 : ASN1EncodingMeta;
|
|
||||||
oid : ASN1Encoding;
|
|
||||||
elem_0_meta2: ASN1EncodingMeta;
|
|
||||||
seq_meta3 : ASN1EncodingMeta;
|
|
||||||
version : ASN1Encoding;
|
|
||||||
digest_algs : ASN1Encoding;
|
|
||||||
signed_data : ASN1Encoding;
|
|
||||||
cert_meta : ASN1EncodingMeta;
|
|
||||||
cert : bytestring &length=cert_meta.length;
|
|
||||||
# Ignore everything else
|
|
||||||
: bytestring &restofdata &transient;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Octet string metadata
|
|
||||||
# -- [0] metadata
|
|
||||||
# ---- Sequence metadata
|
|
||||||
# ------ [0] metadata
|
|
||||||
# -------- Sequence metadata
|
|
||||||
# ---------- OID
|
|
||||||
# ------------ [0] metadata
|
|
||||||
# -------------- Sequence metadata
|
|
||||||
# ---------------- version
|
|
||||||
# ---------------- digestAlgorithms
|
|
||||||
# ---------------- signedData
|
|
||||||
# ---------------- certificates
|
|
||||||
type KRB_PA_PK_AS_Rep = record {
|
|
||||||
string_meta : ASN1EncodingMeta;
|
|
||||||
elem_0_meta1: ASN1EncodingMeta;
|
|
||||||
seq_meta1 : ASN1EncodingMeta;
|
|
||||||
elem_0_meta2: ASN1EncodingMeta;
|
|
||||||
seq_meta2 : ASN1EncodingMeta;
|
|
||||||
oid : ASN1Encoding;
|
|
||||||
elem_0_meta3: ASN1EncodingMeta;
|
|
||||||
seq_meta3 : ASN1EncodingMeta;
|
|
||||||
version : ASN1Encoding;
|
|
||||||
digest_algs : ASN1Encoding;
|
|
||||||
signed_data : ASN1Encoding;
|
|
||||||
cert_meta : ASN1EncodingMeta;
|
|
||||||
cert : bytestring &length=cert_meta.length;
|
|
||||||
# Ignore everything else
|
|
||||||
: bytestring &restofdata &transient;
|
|
||||||
};
|
|
||||||
|
|
||||||
type KRB_REQ_Body = record {
|
|
||||||
seq_meta : ASN1EncodingMeta;
|
|
||||||
args : KRB_REQ_Arg[];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
type KRB_REQ_Arg = record {
|
type KRB_REQ_Arg = record {
|
||||||
seq_meta : ASN1EncodingMeta;
|
seq_meta : ASN1EncodingMeta;
|
||||||
data : KRB_REQ_Arg_Data(seq_meta.index) &length=seq_meta.length;
|
data : KRB_REQ_Arg_Data(seq_meta.index) &length=seq_meta.length;
|
||||||
};
|
};
|
||||||
|
|
||||||
type KRB_REQ_Arg_Data(index: uint8) = case index of {
|
type KRB_REQ_Arg_Data(index: uint8) = case index of {
|
||||||
0 -> options : KRB_KDC_Options;
|
0 -> options : KRB_KDC_Options;
|
||||||
1 -> principal : KRB_Principal_Name;
|
1 -> principal : KRB_Principal_Name;
|
||||||
2 -> realm : ASN1OctetString;
|
2 -> realm : ASN1OctetString;
|
||||||
3 -> sname : KRB_Principal_Name;
|
3 -> sname : KRB_Principal_Name;
|
||||||
4 -> from : KRB_Time;
|
4 -> from : KRB_Time;
|
||||||
5 -> till : KRB_Time;
|
5 -> till : KRB_Time;
|
||||||
6 -> rtime : KRB_Time;
|
6 -> rtime : KRB_Time;
|
||||||
7 -> nonce : ASN1Integer;
|
7 -> nonce : ASN1Integer;
|
||||||
8 -> etype : Array;
|
8 -> etype : Array;
|
||||||
9 -> addrs : KRB_Host_Addresses;
|
9 -> addrs : KRB_Host_Addresses;
|
||||||
10 -> auth_data : ASN1OctetString; # TODO
|
10 -> auth_data : ASN1OctetString; # TODO
|
||||||
11 -> addl_tkts : KRB_Ticket_Sequence;
|
11 -> addl_tkts : KRB_Ticket_Sequence;
|
||||||
default -> unknown : bytestring &restofdata;
|
default -> unknown : bytestring &restofdata;
|
||||||
|
@ -186,94 +85,28 @@ type KRB_KDC_Options = record {
|
||||||
pad: uint8;
|
pad: uint8;
|
||||||
flags: uint32;
|
flags: uint32;
|
||||||
} &let {
|
} &let {
|
||||||
reserved : bool = (flags & 0x80000000) > 0;
|
reserved : bool = (flags & 0x80000000) > 0;
|
||||||
forwardable : bool = (flags & 0x40000000) > 0;
|
forwardable : bool = (flags & 0x40000000) > 0;
|
||||||
forwarded : bool = (flags & 0x20000000) > 0;
|
forwarded : bool = (flags & 0x20000000) > 0;
|
||||||
proxiable : bool = (flags & 0x10000000) > 0;
|
proxiable : bool = (flags & 0x10000000) > 0;
|
||||||
proxy : bool = (flags & 0x8000000) > 0;
|
proxy : bool = (flags & 0x8000000) > 0;
|
||||||
allow_postdate : bool = (flags & 0x4000000) > 0;
|
allow_postdate : bool = (flags & 0x4000000) > 0;
|
||||||
postdated : bool = (flags & 0x2000000) > 0;
|
postdated : bool = (flags & 0x2000000) > 0;
|
||||||
unused7 : bool = (flags & 0x1000000) > 0;
|
unused7 : bool = (flags & 0x1000000) > 0;
|
||||||
renewable : bool = (flags & 0x800000) > 0;
|
renewable : bool = (flags & 0x800000) > 0;
|
||||||
unused9 : bool = (flags & 0x400000) > 0;
|
unused9 : bool = (flags & 0x400000) > 0;
|
||||||
unused10 : bool = (flags & 0x200000) > 0;
|
unused10 : bool = (flags & 0x200000) > 0;
|
||||||
opt_hardware_auth : bool = (flags & 0x100000) > 0;
|
opt_hardware_auth : bool = (flags & 0x100000) > 0;
|
||||||
unused12 : bool = (flags & 0x80000) > 0;
|
unused12 : bool = (flags & 0x80000) > 0;
|
||||||
unused13 : bool = (flags & 0x40000) > 0;
|
unused13 : bool = (flags & 0x40000) > 0;
|
||||||
# ...
|
# ...
|
||||||
unused15 : bool = (flags & 0x10000) > 0;
|
unused15 : bool = (flags & 0x10000) > 0;
|
||||||
# ...
|
# ...
|
||||||
disable_transited_check : bool = (flags & 0x10) > 0;
|
disable_transited_check : bool = (flags & 0x10) > 0;
|
||||||
renewable_ok : bool = (flags & 0x8) > 0;
|
renewable_ok : bool = (flags & 0x8) > 0;
|
||||||
enc_tkt_in_skey : bool = (flags & 0x4) > 0;
|
enc_tkt_in_skey : bool = (flags & 0x4) > 0;
|
||||||
renew : bool = (flags & 0x2) > 0;
|
renew : bool = (flags & 0x2) > 0;
|
||||||
validate : bool = (flags & 0x1) > 0;
|
validate : bool = (flags & 0x1) > 0;
|
||||||
};
|
|
||||||
|
|
||||||
type KRB_Principal_Name = record {
|
|
||||||
seq_meta : ASN1EncodingMeta;
|
|
||||||
name_meta : ASN1EncodingMeta;
|
|
||||||
name_type : ASN1Integer;
|
|
||||||
seq_meta_1: ASN1EncodingMeta;
|
|
||||||
seq_meta_2: ASN1EncodingMeta;
|
|
||||||
data : ASN1OctetString[];
|
|
||||||
};
|
|
||||||
|
|
||||||
type KRB_Time = record {
|
|
||||||
meta: ASN1EncodingMeta;
|
|
||||||
time: bytestring &restofdata;
|
|
||||||
};
|
|
||||||
|
|
||||||
type KRB_Host_Addresses = record {
|
|
||||||
seq_meta : ASN1EncodingMeta;
|
|
||||||
addresses: KRB_Host_Address[];
|
|
||||||
};
|
|
||||||
|
|
||||||
type KRB_Host_Address = record {
|
|
||||||
addr_type_meta : SequenceElement(false);
|
|
||||||
addr_type : ASN1Integer;
|
|
||||||
address : SequenceElement(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
type KRB_Ticket(in_sequence: bool) = record {
|
|
||||||
have_seq : case in_sequence of {
|
|
||||||
true -> meta: ASN1EncodingMeta;
|
|
||||||
false -> none: empty;
|
|
||||||
};
|
|
||||||
app_meta : ASN1EncodingMeta;
|
|
||||||
seq_meta : ASN1EncodingMeta;
|
|
||||||
tkt_vno : SequenceElement(true);
|
|
||||||
realm : SequenceElement(true);
|
|
||||||
sname_meta: ASN1EncodingMeta;
|
|
||||||
sname : KRB_Principal_Name &length=sname_meta.length;
|
|
||||||
enc_part : KRB_Encrypted_Data;
|
|
||||||
};
|
|
||||||
|
|
||||||
type KRB_Ticket_Sequence = record {
|
|
||||||
seq_meta : ASN1EncodingMeta;
|
|
||||||
tickets : KRB_Ticket(true)[] &length=seq_meta.length;
|
|
||||||
};
|
|
||||||
|
|
||||||
type KRB_Encrypted_Data_in_Seq = record {
|
|
||||||
index_meta : ASN1EncodingMeta;
|
|
||||||
data : KRB_Encrypted_Data &length=index_meta.length;
|
|
||||||
};
|
|
||||||
|
|
||||||
type KRB_Encrypted_Data = record {
|
|
||||||
seq_meta : ASN1EncodingMeta;
|
|
||||||
etype : SequenceElement(true);
|
|
||||||
kvno_meta : ASN1EncodingMeta;
|
|
||||||
case_kvno : case have_kvno of {
|
|
||||||
true -> kvno : ASN1Integer;
|
|
||||||
false -> none : empty;
|
|
||||||
};
|
|
||||||
grab_next_meta : case have_kvno of {
|
|
||||||
true -> next_meta: ASN1EncodingMeta;
|
|
||||||
false -> none_meta: empty;
|
|
||||||
};
|
|
||||||
ciphertext : bytestring &length=have_kvno ? next_meta.length : kvno_meta.length;
|
|
||||||
} &let {
|
|
||||||
have_kvno : bool = kvno_meta.index == 1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
### KDC_REP
|
### KDC_REP
|
||||||
|
@ -282,23 +115,12 @@ type KRB_KDC_REP(pkt_type: uint8) = record {
|
||||||
seq_meta : ASN1EncodingMeta;
|
seq_meta : ASN1EncodingMeta;
|
||||||
pvno : SequenceElement(true);
|
pvno : SequenceElement(true);
|
||||||
msg_type : SequenceElement(true);
|
msg_type : SequenceElement(true);
|
||||||
padata_meta : ASN1EncodingMeta;
|
padata : KRB_PA_Data_Optional(pkt_type, 2);
|
||||||
tmp1 : case has_padata of {
|
client_realm: ASN1OctetString &length=padata.next_meta.length;
|
||||||
true -> padata : KRB_PA_Data_Sequence(pkt_type) &length=padata_meta.length;
|
cname_meta : ASN1EncodingMeta;
|
||||||
false -> n1 : empty;
|
|
||||||
};
|
|
||||||
tmp2 : case has_padata of {
|
|
||||||
true -> meta2 : ASN1EncodingMeta;
|
|
||||||
false -> n2 : empty;
|
|
||||||
};
|
|
||||||
client_realm: ASN1OctetString &length=realm_length;
|
|
||||||
cname_meta : ASN1EncodingMeta;
|
|
||||||
client_name : KRB_Principal_Name &length=cname_meta.length;
|
client_name : KRB_Principal_Name &length=cname_meta.length;
|
||||||
ticket : KRB_Ticket(true);
|
ticket : KRB_Ticket(true);
|
||||||
enc_part : KRB_Encrypted_Data_in_Seq;
|
enc_part : KRB_Encrypted_Data_in_Seq;
|
||||||
} &let {
|
|
||||||
has_padata : bool = padata_meta.index == 2;
|
|
||||||
realm_length: uint64 = has_padata ? meta2.length : padata_meta.length;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
### AP_REQ
|
### AP_REQ
|
||||||
|
@ -319,7 +141,7 @@ type KRB_AP_Options = record {
|
||||||
flags : uint32;
|
flags : uint32;
|
||||||
: padding[1];
|
: padding[1];
|
||||||
} &let {
|
} &let {
|
||||||
reserved : bool = (flags & 0x80000000) > 0;
|
reserved : bool = (flags & 0x80000000) > 0;
|
||||||
use_session_key : bool = (flags & 0x40000000) > 0;
|
use_session_key : bool = (flags & 0x40000000) > 0;
|
||||||
mutual_required : bool = (flags & 0x20000000) > 0;
|
mutual_required : bool = (flags & 0x20000000) > 0;
|
||||||
};
|
};
|
||||||
|
@ -335,77 +157,42 @@ type KRB_AP_REP = record {
|
||||||
|
|
||||||
### KRB_ERROR
|
### KRB_ERROR
|
||||||
|
|
||||||
# pvno [0] INTEGER (5),
|
|
||||||
# msg-type [1] INTEGER (30),
|
|
||||||
# ctime [2] KerberosTime OPTIONAL,
|
|
||||||
# cusec [3] Microseconds OPTIONAL,
|
|
||||||
# stime [4] KerberosTime,
|
|
||||||
# susec [5] Microseconds,
|
|
||||||
# error-code [6] Int32,
|
|
||||||
# crealm [7] Realm OPTIONAL,
|
|
||||||
# cname [8] PrincipalName OPTIONAL,
|
|
||||||
# realm [9] Realm -- service realm --,
|
|
||||||
# sname [10] PrincipalName -- service name --,
|
|
||||||
# e-text [11] KerberosString OPTIONAL,
|
|
||||||
|
|
||||||
type KRB_ERROR_MSG = record {
|
type KRB_ERROR_MSG = record {
|
||||||
seq_meta : ASN1EncodingMeta;
|
seq_meta : ASN1EncodingMeta;
|
||||||
pvno : SequenceElement(true);
|
args1 : KRB_ERROR_Arg(0)[] &until ($element.process_in_parent);
|
||||||
msg_type : SequenceElement(true);
|
error_code : ASN1Integer;
|
||||||
ctime_meta : ASN1EncodingMeta;
|
args2 : KRB_ERROR_Arg(binary_to_int64(error_code.encoding.content))[];
|
||||||
tmp1 : case has_ctime of {
|
|
||||||
true -> ctime : bytestring &length=ctime_meta.length;
|
|
||||||
false -> n1 : empty;
|
|
||||||
};
|
|
||||||
tmp2 : case has_ctime of {
|
|
||||||
true -> cusec_meta : ASN1EncodingMeta;
|
|
||||||
false -> n2 : empty;
|
|
||||||
};
|
|
||||||
tmp3 : case has_cusec of {
|
|
||||||
true -> cusec : ASN1Integer;
|
|
||||||
false -> n3 : empty;
|
|
||||||
};
|
|
||||||
tmp4 : case has_cusec of {
|
|
||||||
true -> stime_meta : ASN1EncodingMeta;
|
|
||||||
false -> n4 : empty;
|
|
||||||
};
|
|
||||||
stime : bytestring &length=stime_length;
|
|
||||||
susec : SequenceElement(true);
|
|
||||||
error_code : SequenceElement(true);
|
|
||||||
args : KRB_ERROR_Arg(binary_to_int64(error_code.data.content))[];
|
|
||||||
} &let {
|
|
||||||
has_ctime: bool = ctime_meta.index == 2;
|
|
||||||
has_cusec: bool = has_ctime ? cusec_meta.index == 3 : ctime_meta.index == 3;
|
|
||||||
stime_length: uint64 = has_ctime ? (has_cusec ? stime_meta.length : cusec_meta.length) : (has_cusec ? stime_meta.length : ctime_meta.length);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
type KRB_ERROR_Arg(error_code: uint64) = record {
|
type KRB_ERROR_Arg(error_code: int64) = record {
|
||||||
seq_meta: ASN1EncodingMeta;
|
seq_meta: ASN1EncodingMeta;
|
||||||
args : KRB_ERROR_Arg_Data(seq_meta.index, error_code) &length=seq_meta.length;
|
args : KRB_ERROR_Arg_Data(seq_meta.index, error_code) &length=arg_length;
|
||||||
|
} &let {
|
||||||
|
process_in_parent: bool = seq_meta.index == 6;
|
||||||
|
arg_length : uint64 = ( process_in_parent ? 0 : seq_meta.length);
|
||||||
};
|
};
|
||||||
|
|
||||||
type KRB_ERROR_Arg_Data(index: uint8, error_code: uint64) = case index of {
|
type KRB_ERROR_Arg_Data(index: uint8, error_code: int64) = case index of {
|
||||||
7 -> crealm : ASN1OctetString;
|
0 -> pvno : ASN1Integer;
|
||||||
8 -> cname : KRB_Principal_Name;
|
1 -> msg_type : ASN1Integer;
|
||||||
9 -> realm : ASN1OctetString;
|
2 -> ctime : KRB_Time;
|
||||||
10 -> sname : KRB_Principal_Name;
|
3 -> cusec : ASN1Integer;
|
||||||
11 -> e_text : ASN1OctetString;
|
4 -> stime : KRB_Time;
|
||||||
12 -> e_data : KRB_ERROR_E_Data(error_code);
|
5 -> susec : ASN1Integer;
|
||||||
|
6 -> err_code : empty;
|
||||||
|
7 -> crealm : ASN1OctetString;
|
||||||
|
8 -> cname : KRB_Principal_Name;
|
||||||
|
9 -> realm : ASN1OctetString;
|
||||||
|
10 -> sname : KRB_Principal_Name;
|
||||||
|
11 -> e_text : ASN1OctetString;
|
||||||
|
12 -> e_data : KRB_ERROR_E_Data(error_code);
|
||||||
};
|
};
|
||||||
|
|
||||||
type KRB_ERROR_E_Data(error_code: uint64) = case ( error_code == 25 ) of {
|
type KRB_ERROR_E_Data(error_code: uint64) = case ( error_code == 25 ) of {
|
||||||
true -> padata : KRB_ERROR_PA_Data;
|
true -> padata : KRB_PA_Data_Sequence(KRB_ERROR);
|
||||||
false -> unknown : bytestring &restofdata;
|
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;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
### KRB_SAFE
|
### KRB_SAFE
|
||||||
|
|
||||||
type KRB_SAFE_MSG = record {
|
type KRB_SAFE_MSG = record {
|
||||||
|
@ -434,11 +221,6 @@ type KRB_SAFE_Arg_Data(index: uint8) = case index of {
|
||||||
5 -> recp_addr : KRB_Host_Address;
|
5 -> recp_addr : KRB_Host_Address;
|
||||||
};
|
};
|
||||||
|
|
||||||
type KRB_Checksum = record {
|
|
||||||
checksum_type: SequenceElement(true);
|
|
||||||
checksum : SequenceElement(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
### KRB_PRIV
|
### KRB_PRIV
|
||||||
|
|
||||||
type KRB_PRIV_MSG = record {
|
type KRB_PRIV_MSG = record {
|
||||||
|
|
73
src/analyzer/protocol/krb/krb-types.pac
Normal file
73
src/analyzer/protocol/krb/krb-types.pac
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
# Fundamental KRB types
|
||||||
|
|
||||||
|
type KRB_Principal_Name = record {
|
||||||
|
seq_meta : ASN1EncodingMeta;
|
||||||
|
name_meta : ASN1EncodingMeta;
|
||||||
|
name_type : ASN1Integer;
|
||||||
|
seq_meta_1: ASN1EncodingMeta;
|
||||||
|
seq_meta_2: ASN1EncodingMeta;
|
||||||
|
data : ASN1OctetString[];
|
||||||
|
};
|
||||||
|
|
||||||
|
type KRB_Time = record {
|
||||||
|
meta: ASN1EncodingMeta;
|
||||||
|
time: bytestring &restofdata;
|
||||||
|
};
|
||||||
|
|
||||||
|
type KRB_Host_Addresses = record {
|
||||||
|
seq_meta : ASN1EncodingMeta;
|
||||||
|
addresses: KRB_Host_Address[];
|
||||||
|
};
|
||||||
|
|
||||||
|
type KRB_Host_Address = record {
|
||||||
|
addr_type_meta : SequenceElement(false);
|
||||||
|
addr_type : ASN1Integer;
|
||||||
|
address : SequenceElement(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
type KRB_Ticket(in_sequence: bool) = record {
|
||||||
|
have_seq : case in_sequence of {
|
||||||
|
true -> meta: ASN1EncodingMeta;
|
||||||
|
false -> none: empty;
|
||||||
|
};
|
||||||
|
app_meta : ASN1EncodingMeta;
|
||||||
|
seq_meta : ASN1EncodingMeta;
|
||||||
|
tkt_vno : SequenceElement(true);
|
||||||
|
realm : SequenceElement(true);
|
||||||
|
sname_meta: ASN1EncodingMeta;
|
||||||
|
sname : KRB_Principal_Name &length=sname_meta.length;
|
||||||
|
enc_part : KRB_Encrypted_Data;
|
||||||
|
};
|
||||||
|
|
||||||
|
type KRB_Ticket_Sequence = record {
|
||||||
|
seq_meta : ASN1EncodingMeta;
|
||||||
|
tickets : KRB_Ticket(true)[] &length=seq_meta.length;
|
||||||
|
};
|
||||||
|
|
||||||
|
type KRB_Encrypted_Data_in_Seq = record {
|
||||||
|
index_meta : ASN1EncodingMeta;
|
||||||
|
data : KRB_Encrypted_Data &length=index_meta.length;
|
||||||
|
};
|
||||||
|
|
||||||
|
type KRB_Encrypted_Data = record {
|
||||||
|
seq_meta : ASN1EncodingMeta;
|
||||||
|
etype : SequenceElement(true);
|
||||||
|
kvno_meta : ASN1EncodingMeta;
|
||||||
|
case_kvno : case have_kvno of {
|
||||||
|
true -> kvno : ASN1Integer;
|
||||||
|
false -> none : empty;
|
||||||
|
};
|
||||||
|
grab_next_meta : case have_kvno of {
|
||||||
|
true -> next_meta: ASN1EncodingMeta;
|
||||||
|
false -> none_meta: empty;
|
||||||
|
};
|
||||||
|
ciphertext : bytestring &length=have_kvno ? next_meta.length : kvno_meta.length;
|
||||||
|
} &let {
|
||||||
|
have_kvno : bool = kvno_meta.index == 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
type KRB_Checksum = record {
|
||||||
|
checksum_type: SequenceElement(true);
|
||||||
|
checksum : SequenceElement(true);
|
||||||
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue