mirror of
https://github.com/zeek/zeek.git
synced 2025-10-11 02:58:20 +00:00
A number of Kerberos fixes, following testing. Added some fields to the log, and parsed some more data.
This commit is contained in:
parent
2c8a3fce49
commit
2e8eb574f5
7 changed files with 321 additions and 152 deletions
|
@ -2975,31 +2975,6 @@ export {
|
||||||
|
|
||||||
module KRB;
|
module KRB;
|
||||||
export {
|
export {
|
||||||
## The data from the ERROR_MSG message. See :rfc:`4120`.
|
|
||||||
type KRB::Error_Msg: record {
|
|
||||||
## Protocol version number (5 for KRB5)
|
|
||||||
pvno: count;
|
|
||||||
## The message type (30 for ERROR_MSG)
|
|
||||||
msg_type: count;
|
|
||||||
## Current time on the client
|
|
||||||
client_time: time &optional;
|
|
||||||
## Current time on the server
|
|
||||||
server_time: time;
|
|
||||||
## The specific error code
|
|
||||||
error_code: count;
|
|
||||||
## Realm of the ticket
|
|
||||||
client_realm: string &optional;
|
|
||||||
## Name on the ticket
|
|
||||||
client_name: string &optional;
|
|
||||||
## Realm of the service
|
|
||||||
service_realm: string;
|
|
||||||
## Name of the service
|
|
||||||
service_name: string;
|
|
||||||
## Additional text to explain the error
|
|
||||||
error_text: string &optional;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
## KDC Options. See :rfc:`4120`
|
## KDC Options. See :rfc:`4120`
|
||||||
type KRB::KDC_Options: record {
|
type KRB::KDC_Options: record {
|
||||||
## The ticket to be issued should have its forwardable flag set.
|
## The ticket to be issued should have its forwardable flag set.
|
||||||
|
@ -3030,7 +3005,7 @@ export {
|
||||||
enc_tkt_in_skey : bool;
|
enc_tkt_in_skey : bool;
|
||||||
## The request is for a renewal
|
## The request is for a renewal
|
||||||
renew : bool;
|
renew : bool;
|
||||||
## The request ist to validate a postdated ticket.
|
## The request is to validate a postdated ticket.
|
||||||
validate : bool;
|
validate : bool;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3045,6 +3020,33 @@ export {
|
||||||
|
|
||||||
type KRB::Type_Value_Vector: vector of KRB::Type_Value;
|
type KRB::Type_Value_Vector: vector of KRB::Type_Value;
|
||||||
|
|
||||||
|
## The data from the ERROR_MSG message. See :rfc:`4120`.
|
||||||
|
type KRB::Error_Msg: record {
|
||||||
|
## Protocol version number (5 for KRB5)
|
||||||
|
pvno : count;
|
||||||
|
## The message type (30 for ERROR_MSG)
|
||||||
|
msg_type : count;
|
||||||
|
## Current time on the client
|
||||||
|
client_time : time &optional;
|
||||||
|
## Current time on the server
|
||||||
|
server_time : time;
|
||||||
|
## The specific error code
|
||||||
|
error_code : count;
|
||||||
|
## Realm of the ticket
|
||||||
|
client_realm : string &optional;
|
||||||
|
## Name on the ticket
|
||||||
|
client_name : string &optional;
|
||||||
|
## Realm of the service
|
||||||
|
service_realm : string;
|
||||||
|
## Name of the service
|
||||||
|
service_name : string;
|
||||||
|
## Additional text to explain the error
|
||||||
|
error_text : string &optional;
|
||||||
|
## Optional pre-authentication data
|
||||||
|
pa_data : vector of KRB::Type_Value &optional;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
## A Kerberos ticket. See :rfc:`4120`.
|
## A Kerberos ticket. See :rfc:`4120`.
|
||||||
type KRB::Ticket: record {
|
type KRB::Ticket: record {
|
||||||
## Protocol version number (5 for KRB5)
|
## Protocol version number (5 for KRB5)
|
||||||
|
@ -3062,9 +3064,9 @@ export {
|
||||||
## A Kerberos host address See :rfc:`4120`.
|
## A Kerberos host address See :rfc:`4120`.
|
||||||
type KRB::Host_Address: record {
|
type KRB::Host_Address: record {
|
||||||
## IPv4 or IPv6 address
|
## IPv4 or IPv6 address
|
||||||
ip : addr &optional;
|
ip : addr &log &optional;
|
||||||
## NetBIOS address
|
## NetBIOS address
|
||||||
netbios : string &optional;
|
netbios : string &log &optional;
|
||||||
## Some other type that we don't support yet
|
## Some other type that we don't support yet
|
||||||
unknown : KRB::Type_Value &optional;
|
unknown : KRB::Type_Value &optional;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
signature dpd_krb {
|
signature dpd_krb_udp {
|
||||||
ip-proto == udp
|
ip-proto == udp
|
||||||
payload /\x6c...\x30...\xa1\x03\x02\x05/
|
payload /\x6c...\x30...\xa1\x03\x02\x05/
|
||||||
enable "krb"
|
enable "krb"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,19 +9,36 @@ export {
|
||||||
|
|
||||||
type Info: record {
|
type Info: record {
|
||||||
## Timestamp for when the event happened.
|
## Timestamp for when the event happened.
|
||||||
ts: time &log;
|
ts: time &log;
|
||||||
## Unique ID for the connection.
|
## Unique ID for the connection.
|
||||||
uid: string &log;
|
uid: string &log;
|
||||||
## The connection's 4-tuple of endpoint addresses/ports.
|
## The connection's 4-tuple of endpoint addresses/ports.
|
||||||
id: conn_id &log;
|
id: conn_id &log;
|
||||||
## Client
|
## Client
|
||||||
client: string &log &optional;
|
client: string &log &optional;
|
||||||
## Service
|
## Service
|
||||||
service:string &log;
|
service: string &log;
|
||||||
## Ticket valid from
|
## Ticket valid from
|
||||||
from: time &log &optional;
|
from: time &log &optional;
|
||||||
## Ticket valid till
|
## Ticket valid till
|
||||||
till: time &log &optional;
|
till: time &log &optional;
|
||||||
|
## Forwardable ticket requested
|
||||||
|
forwardable: bool &log &optional;
|
||||||
|
## Proxiable ticket requested
|
||||||
|
proxiable: bool &log &optional;
|
||||||
|
## Postdated ticket requested
|
||||||
|
postdated: bool &log &optional;
|
||||||
|
## Renewable ticket requested
|
||||||
|
renewable: bool &log &optional;
|
||||||
|
## The request is for a renewal
|
||||||
|
renew_request: bool &log &optional;
|
||||||
|
# The request is to validate a postdated ticket
|
||||||
|
validate_request: bool &log &optional;
|
||||||
|
# Network addresses supplied by the client
|
||||||
|
network_addrs: vector of addr &log &optional;
|
||||||
|
# NetBIOS addresses supplied by the client
|
||||||
|
netbios_addrs: vector of string &log &optional;
|
||||||
|
|
||||||
## Result
|
## Result
|
||||||
result: string &log &default="unknown";
|
result: string &log &default="unknown";
|
||||||
## Error code
|
## Error code
|
||||||
|
@ -32,6 +49,19 @@ export {
|
||||||
logged: bool &default=F;
|
logged: bool &default=F;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
## The server response error texts which are *not* logged.
|
||||||
|
const ignored_errors: set[string] = {
|
||||||
|
# This will significantly increase the noisiness of the log.
|
||||||
|
# However, one attack is to iterate over principals, looking
|
||||||
|
# for ones that don't require preauth, and then performn
|
||||||
|
# an offline attack on that ticket. To detect that attack,
|
||||||
|
# log NEEDED_PREAUTH.
|
||||||
|
"NEEDED_PREAUTH",
|
||||||
|
# This is a more specific version of NEEDED_PREAUTH that's used
|
||||||
|
# by Winodws AD Kerberos.
|
||||||
|
"Need to use PA-ENC-TIMESTAMP/PA-PK-AS-REQ",
|
||||||
|
} &redef;
|
||||||
|
|
||||||
## Event that can be handled to access the KRB record as it is sent on
|
## Event that can be handled to access the KRB record as it is sent on
|
||||||
## to the loggin framework.
|
## to the loggin framework.
|
||||||
global log_krb: event(rec: Info);
|
global log_krb: event(rec: Info);
|
||||||
|
@ -53,9 +83,16 @@ event krb_error(c: connection, msg: Error_Msg)
|
||||||
{
|
{
|
||||||
local info: Info;
|
local info: Info;
|
||||||
|
|
||||||
|
if ( msg?$error_text && msg$error_text in ignored_errors )
|
||||||
|
{
|
||||||
|
if ( c?$krb )
|
||||||
|
delete c$krb;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ( c?$krb && c$krb$logged )
|
if ( c?$krb && c$krb$logged )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( c?$krb )
|
if ( c?$krb )
|
||||||
info = c$krb;
|
info = c$krb;
|
||||||
|
|
||||||
|
@ -94,16 +131,43 @@ event krb_as_req(c: connection, msg: KDC_Request)
|
||||||
{
|
{
|
||||||
if ( c?$krb && c$krb$logged )
|
if ( c?$krb && c$krb$logged )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
local info: Info;
|
local info: Info;
|
||||||
info$ts = network_time();
|
info$ts = network_time();
|
||||||
info$uid = c$uid;
|
info$uid = c$uid;
|
||||||
info$id = c$id;
|
info$id = c$id;
|
||||||
|
|
||||||
info$client = fmt("%s/%s", msg$client_name, msg$service_realm);
|
info$client = fmt("%s/%s", msg$client_name, msg$service_realm);
|
||||||
info$service = msg$service_name;
|
info$service = msg$service_name;
|
||||||
|
|
||||||
if ( msg?$from )
|
if ( msg?$from )
|
||||||
info$from = msg$from;
|
info$from = msg$from;
|
||||||
|
|
||||||
|
if ( msg?$host_addrs )
|
||||||
|
{
|
||||||
|
for ( i in msg$host_addrs )
|
||||||
|
{
|
||||||
|
if ( msg$host_addrs[i]?$ip )
|
||||||
|
{
|
||||||
|
if ( ! info?$network_addrs )
|
||||||
|
info$network_addrs = vector();
|
||||||
|
info$network_addrs[|info$network_addrs|] = msg$host_addrs[i]$ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( msg$host_addrs[i]?$netbios )
|
||||||
|
{
|
||||||
|
if ( ! info?$netbios_addrs )
|
||||||
|
info$netbios_addrs = vector();
|
||||||
|
info$netbios_addrs[|info$netbios_addrs|] = msg$host_addrs[i]$netbios;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
info$till = msg$till;
|
info$till = msg$till;
|
||||||
|
info$forwardable = msg$kdc_options$forwardable;
|
||||||
|
info$proxiable = msg$kdc_options$proxiable;
|
||||||
|
info$postdated = msg$kdc_options$postdated;
|
||||||
|
info$renewable = msg$kdc_options$renewable;
|
||||||
|
|
||||||
c$krb = info;
|
c$krb = info;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ void KRB_Analyzer::DeliverPacket(int len, const u_char* data, bool orig,
|
||||||
}
|
}
|
||||||
catch ( const binpac::Exception& e )
|
catch ( const binpac::Exception& e )
|
||||||
{
|
{
|
||||||
|
printf("BinPAC Exception: %s\n", e.c_msg());
|
||||||
ProtocolViolation(e.c_msg());
|
ProtocolViolation(e.c_msg());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,11 +5,12 @@ connection KRB_Conn(bro_analyzer: BroAnalyzer) {
|
||||||
|
|
||||||
flow KRB_Flow(is_orig: bool) {
|
flow KRB_Flow(is_orig: bool) {
|
||||||
datagram = KRB_PDU withcontext(connection, this);
|
datagram = KRB_PDU withcontext(connection, this);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
%header{
|
%header{
|
||||||
Val* GetTimeFromAsn1(const KRB_Time* atime);
|
Val* GetTimeFromAsn1(const KRB_Time* atime);
|
||||||
|
Val* GetTimeFromAsn1(StringVal* atime);
|
||||||
|
|
||||||
Val* GetStringFromPrincipalName(const KRB_Principal_Name* pname);
|
Val* GetStringFromPrincipalName(const KRB_Principal_Name* pname);
|
||||||
|
|
||||||
Val* asn1_integer_to_val(const ASN1Encoding* i, TypeTag t);
|
Val* asn1_integer_to_val(const ASN1Encoding* i, TypeTag t);
|
||||||
|
@ -20,18 +21,26 @@ RecordVal* proc_krb_kdc_options(const KRB_KDC_Options* opts);
|
||||||
|
|
||||||
%code{
|
%code{
|
||||||
Val* GetTimeFromAsn1(const KRB_Time* atime)
|
Val* GetTimeFromAsn1(const KRB_Time* atime)
|
||||||
|
{
|
||||||
|
return GetTimeFromAsn1(bytestring_to_val(atime->time()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Val* GetTimeFromAsn1(StringVal* atime)
|
||||||
{
|
{
|
||||||
time_t lResult = 0;
|
time_t lResult = 0;
|
||||||
|
|
||||||
char lBuffer[16];
|
char lBuffer[17];
|
||||||
char* pBuffer = lBuffer;
|
char* pBuffer = lBuffer;
|
||||||
|
|
||||||
size_t lTimeLength = atime->time().length();
|
size_t lTimeLength = atime->Len();
|
||||||
char * pString = (char *) atime->time().data();
|
char * pString = (char *) atime->Bytes();
|
||||||
|
|
||||||
if ( lTimeLength != 15 )
|
if ( lTimeLength != 15 && lTimeLength != 17 )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (lTimeLength == 17 )
|
||||||
|
pString = pString + 2;
|
||||||
|
|
||||||
memcpy(pBuffer, pString, 15);
|
memcpy(pBuffer, pString, 15);
|
||||||
*(pBuffer+15) = '\0';
|
*(pBuffer+15) = '\0';
|
||||||
|
|
||||||
|
@ -53,7 +62,7 @@ Val* GetTimeFromAsn1(const KRB_Time* atime)
|
||||||
lResult = 0;
|
lResult = 0;
|
||||||
|
|
||||||
return new Val(double(lResult), TYPE_TIME);
|
return new Val(double(lResult), TYPE_TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
Val* GetStringFromPrincipalName(const KRB_Principal_Name* pname)
|
Val* GetStringFromPrincipalName(const KRB_Principal_Name* pname)
|
||||||
{
|
{
|
||||||
|
@ -102,7 +111,6 @@ refine connection KRB_Conn += {
|
||||||
|
|
||||||
function proc_krb_kdc_req(msg: KRB_KDC_REQ): bool
|
function proc_krb_kdc_req(msg: KRB_KDC_REQ): bool
|
||||||
%{
|
%{
|
||||||
|
|
||||||
if ( ( binary_to_int64(${msg.msg_type.data.content}) == 10 ) && ! krb_as_req )
|
if ( ( binary_to_int64(${msg.msg_type.data.content}) == 10 ) && ! krb_as_req )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -126,9 +134,6 @@ refine connection KRB_Conn += {
|
||||||
case 1:
|
case 1:
|
||||||
// will be generated as separate event
|
// will be generated as separate event
|
||||||
break;
|
break;
|
||||||
case 2:
|
|
||||||
// encrypted timestamp is unreadable
|
|
||||||
break;
|
|
||||||
case 3:
|
case 3:
|
||||||
{
|
{
|
||||||
RecordVal * type_val = new RecordVal(BifType::Record::KRB::Type_Value);
|
RecordVal * type_val = new RecordVal(BifType::Record::KRB::Type_Value);
|
||||||
|
@ -139,17 +144,20 @@ refine connection KRB_Conn += {
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
RecordVal * type_val = new RecordVal(BifType::Record::KRB::Type_Value);
|
if ( ${msg.padata.padata_elems[i].pa_data_element.unknown}.length() )
|
||||||
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}));
|
RecordVal * type_val = new RecordVal(BifType::Record::KRB::Type_Value);
|
||||||
padata->Assign(padata->Size(), type_val);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rv->Assign(2, padata);
|
rv->Assign(2, padata);
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( uint i = 0; i < ${msg.body.args}->size(); ++i )
|
for ( uint i = 0; i < ${msg.body.args}->size(); ++i )
|
||||||
{
|
{
|
||||||
switch ( ${msg.body.args[i].seq_meta.index} )
|
switch ( ${msg.body.args[i].seq_meta.index} )
|
||||||
|
@ -197,7 +205,7 @@ refine connection KRB_Conn += {
|
||||||
for ( uint j = 0; j < ${msg.body.args[i].data.addrs.addresses}->size(); ++j )
|
for ( uint j = 0; j < ${msg.body.args[i].data.addrs.addresses}->size(); ++j )
|
||||||
{
|
{
|
||||||
RecordVal* addr = new RecordVal(BifType::Record::KRB::Host_Address);
|
RecordVal* addr = new RecordVal(BifType::Record::KRB::Host_Address);
|
||||||
switch ( binary_to_int64(${msg.body.args[i].data.addrs.addresses[j].addr_type.data.content}) )
|
switch ( binary_to_int64(${msg.body.args[i].data.addrs.addresses[j].addr_type.encoding.content}) )
|
||||||
{
|
{
|
||||||
case 2:
|
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)));
|
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)));
|
||||||
|
@ -210,7 +218,7 @@ refine connection KRB_Conn += {
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
RecordVal* unk = new RecordVal(BifType::Record::KRB::Type_Value);
|
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.data}, TYPE_COUNT));
|
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}));
|
unk->Assign(1, bytestring_to_val(${msg.body.args[i].data.addrs.addresses[j].address.data.content}));
|
||||||
addr->Assign(2, unk);
|
addr->Assign(2, unk);
|
||||||
break;
|
break;
|
||||||
|
@ -344,31 +352,23 @@ 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));
|
||||||
|
rv->Assign(1, asn1_integer_to_val(${msg.msg_type.data}, TYPE_COUNT));
|
||||||
|
if ( ${msg.has_ctime} )
|
||||||
|
rv->Assign(2, GetTimeFromAsn1(bytestring_to_val(${msg.ctime})));
|
||||||
|
|
||||||
|
// 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++ )
|
for ( uint i = 0; i < ${msg.args}->size(); i++ )
|
||||||
{
|
{
|
||||||
switch ( ${msg.args[i].seq_meta.index} )
|
switch ( ${msg.args[i].seq_meta.index} )
|
||||||
{
|
{
|
||||||
case 0:
|
|
||||||
rv->Assign(0, asn1_integer_to_val(${msg.args[i].args.pvno}, TYPE_COUNT));
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
rv->Assign(1, asn1_integer_to_val(${msg.args[i].args.msg_type}, TYPE_COUNT));
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
rv->Assign(2, GetTimeFromAsn1(${msg.args[i].args.ctime}));
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
// TODO
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
rv->Assign(3, GetTimeFromAsn1(${msg.args[i].args.stime}));
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
// TODO
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
rv->Assign(4, asn1_integer_to_val(${msg.args[i].args.error_code}, TYPE_COUNT));
|
|
||||||
break;
|
|
||||||
case 7:
|
case 7:
|
||||||
rv->Assign(5, bytestring_to_val(${msg.args[i].args.crealm.encoding.content}));
|
rv->Assign(5, bytestring_to_val(${msg.args[i].args.crealm.encoding.content}));
|
||||||
break;
|
break;
|
||||||
|
@ -384,6 +384,42 @@ refine connection KRB_Conn += {
|
||||||
case 11:
|
case 11:
|
||||||
rv->Assign(9, bytestring_to_val(${msg.args[i].args.e_text.encoding.content}));
|
rv->Assign(9, bytestring_to_val(${msg.args[i].args.e_text.encoding.content}));
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -410,13 +446,24 @@ refine connection KRB_Conn += {
|
||||||
// Not implemented
|
// Not implemented
|
||||||
return true;
|
return true;
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
function debug_req_arg(msg: KRB_REQ_Arg_Data): bool
|
||||||
|
%{
|
||||||
|
printf("KRB_REQ_Arg index=%d\n", ${msg.index});
|
||||||
|
return true;
|
||||||
|
%}
|
||||||
|
|
||||||
|
function debug_asn1_encoding_meta(msg: ASN1EncodingMeta): bool
|
||||||
|
%{
|
||||||
|
printf("ASN1 Element tag=%x, length=%d\n", ${msg.tag}, ${msg.length});
|
||||||
|
return true;
|
||||||
|
%}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
refine typeattr KRB_AS_REQ += &let {
|
refine typeattr KRB_AS_REQ += &let {
|
||||||
proc: bool = $context.connection.proc_krb_kdc_req(data);
|
proc: bool = $context.connection.proc_krb_kdc_req(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
refine typeattr KRB_TGS_REQ += &let {
|
refine typeattr KRB_TGS_REQ += &let {
|
||||||
proc: bool = $context.connection.proc_krb_kdc_req(data);
|
proc: bool = $context.connection.proc_krb_kdc_req(data);
|
||||||
|
@ -454,3 +501,10 @@ refine typeattr KRB_CRED_MSG += &let {
|
||||||
proc: bool = $context.connection.proc_krb_cred_msg(this);
|
proc: bool = $context.connection.proc_krb_cred_msg(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#refine typeattr KRB_REQ_Arg_Data += &let {
|
||||||
|
# proc: bool = $context.connection.debug_req_arg(this);
|
||||||
|
#};
|
||||||
|
|
||||||
|
#refine typeattr ASN1EncodingMeta += &let {
|
||||||
|
# proc: bool = $context.connection.debug_asn1_encoding_meta(this);
|
||||||
|
#};
|
|
@ -4,13 +4,14 @@ type ASN1Encoding = record {
|
||||||
};
|
};
|
||||||
|
|
||||||
type ASN1EncodingMeta = record {
|
type ASN1EncodingMeta = record {
|
||||||
tag: uint8;
|
tag: uint8;
|
||||||
len: uint8;
|
len: uint8;
|
||||||
more_len: bytestring &length = long_len ? len & 0x7f : 0;
|
more_len: bytestring &length = long_len ? (len & 0x7f) : 0;
|
||||||
} &let {
|
} &let {
|
||||||
long_len: bool = len & 0x80;
|
long_len: bool = (len & 0x80) > 0;
|
||||||
length: uint64 = long_len ? binary_to_int64(more_len) : len & 0x7f;
|
length: uint64 = long_len ? binary_to_int64(more_len) : len;
|
||||||
index: uint8 = tag - 160;
|
has_index: bool = (tag >= 160);
|
||||||
|
index: uint8 = tag - 160;
|
||||||
};
|
};
|
||||||
|
|
||||||
type ASN1Integer = record {
|
type ASN1Integer = record {
|
||||||
|
|
|
@ -55,7 +55,7 @@ type KRB_KDC_REQ = record {
|
||||||
padata_meta: ASN1EncodingMeta;
|
padata_meta: ASN1EncodingMeta;
|
||||||
tmp1 : case has_padata of {
|
tmp1 : case has_padata of {
|
||||||
true -> padata : KRB_PA_Data_Sequence &length=padata_meta.length;
|
true -> padata : KRB_PA_Data_Sequence &length=padata_meta.length;
|
||||||
false -> n1 : empty;
|
false -> n1 : empty;
|
||||||
};
|
};
|
||||||
tmp2 : case has_padata of {
|
tmp2 : case has_padata of {
|
||||||
true -> meta2 : ASN1EncodingMeta;
|
true -> meta2 : ASN1EncodingMeta;
|
||||||
|
@ -64,7 +64,7 @@ type KRB_KDC_REQ = record {
|
||||||
body : KRB_REQ_Body &length=body_length;
|
body : KRB_REQ_Body &length=body_length;
|
||||||
} &let {
|
} &let {
|
||||||
has_padata : bool = padata_meta.index == 3;
|
has_padata : bool = padata_meta.index == 3;
|
||||||
body_length: uint8 = has_padata ? meta2.length : padata_meta.length;
|
body_length: uint64 = has_padata ? meta2.length : padata_meta.length;
|
||||||
};
|
};
|
||||||
|
|
||||||
type KRB_PA_Data_Sequence = record {
|
type KRB_PA_Data_Sequence = record {
|
||||||
|
@ -73,19 +73,18 @@ type KRB_PA_Data_Sequence = record {
|
||||||
};
|
};
|
||||||
|
|
||||||
type KRB_PA_Data = record {
|
type KRB_PA_Data = record {
|
||||||
seq_meta : ASN1EncodingMeta;
|
seq_meta : ASN1EncodingMeta;
|
||||||
pa_data_type : SequenceElement(true);
|
pa_data_type : SequenceElement(true);
|
||||||
pa_data_elem_meta : ASN1EncodingMeta;
|
pa_data_elem_meta : ASN1EncodingMeta;
|
||||||
pa_data_element : KRB_PA_Data_Element(data_type);
|
pa_data_element : KRB_PA_Data_Element(data_type, pa_data_elem_meta.length);
|
||||||
} &let {
|
} &let {
|
||||||
data_type: int64 = binary_to_int64(pa_data_type.data.content);
|
data_type: int64 = binary_to_int64(pa_data_type.data.content);
|
||||||
};
|
};
|
||||||
|
|
||||||
type KRB_PA_Data_Element(type: int64) = case type of {
|
type KRB_PA_Data_Element(type: int64, length: uint64) = case type of {
|
||||||
1 -> pa_tgs_req : KRB_AP_REQ;
|
1 -> pa_tgs_req : KRB_AP_REQ;
|
||||||
2 -> pa_enc_timestamp : KRB_Encrypted_Data;
|
|
||||||
3 -> pa_pw_salt : ASN1OctetString;
|
3 -> pa_pw_salt : ASN1OctetString;
|
||||||
default -> unknown : bytestring &restofdata;
|
default -> unknown : bytestring &length=length;
|
||||||
};
|
};
|
||||||
|
|
||||||
type KRB_REQ_Body = record {
|
type KRB_REQ_Body = record {
|
||||||
|
@ -99,47 +98,48 @@ type KRB_REQ_Arg = record {
|
||||||
};
|
};
|
||||||
|
|
||||||
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
type KRB_KDC_Options = record {
|
type KRB_KDC_Options = record {
|
||||||
meta : ASN1EncodingMeta;
|
meta : ASN1EncodingMeta;
|
||||||
|
pad: uint8;
|
||||||
flags: uint32;
|
flags: uint32;
|
||||||
} &let {
|
} &let {
|
||||||
reserved : bool = flags & 0x80000000;
|
reserved : bool = (flags & 0x80000000) > 0;
|
||||||
forwardable : bool = flags & 0x40000000;
|
forwardable : bool = (flags & 0x40000000) > 0;
|
||||||
forwarded : bool = flags & 0x20000000;
|
forwarded : bool = (flags & 0x20000000) > 0;
|
||||||
proxiable : bool = flags & 0x10000000;
|
proxiable : bool = (flags & 0x10000000) > 0;
|
||||||
proxy : bool = flags & 0x8000000;
|
proxy : bool = (flags & 0x8000000) > 0;
|
||||||
allow_postdate : bool = flags & 0x4000000;
|
allow_postdate : bool = (flags & 0x4000000) > 0;
|
||||||
postdated : bool = flags & 0x2000000;
|
postdated : bool = (flags & 0x2000000) > 0;
|
||||||
unused7 : bool = flags & 0x1000000;
|
unused7 : bool = (flags & 0x1000000) > 0;
|
||||||
renewable : bool = flags & 0x800000;
|
renewable : bool = (flags & 0x800000) > 0;
|
||||||
unused9 : bool = flags & 0x400000;
|
unused9 : bool = (flags & 0x400000) > 0;
|
||||||
unused10 : bool = flags & 0x200000;
|
unused10 : bool = (flags & 0x200000) > 0;
|
||||||
opt_hardware_auth : bool = flags & 0x100000;
|
opt_hardware_auth : bool = (flags & 0x100000) > 0;
|
||||||
unused12 : bool = flags & 0x80000;
|
unused12 : bool = (flags & 0x80000) > 0;
|
||||||
unused13 : bool = flags & 0x40000;
|
unused13 : bool = (flags & 0x40000) > 0;
|
||||||
# ...
|
# ...
|
||||||
unused15 : bool = flags & 0x10000;
|
unused15 : bool = (flags & 0x10000) > 0;
|
||||||
# ...
|
# ...
|
||||||
disable_transited_check : bool = flags & 0x10;
|
disable_transited_check : bool = (flags & 0x10) > 0;
|
||||||
renewable_ok : bool = flags & 0x8;
|
renewable_ok : bool = (flags & 0x8) > 0;
|
||||||
enc_tkt_in_skey : bool = flags & 0x4;
|
enc_tkt_in_skey : bool = (flags & 0x4) > 0;
|
||||||
renew : bool = flags & 0x2;
|
renew : bool = (flags & 0x2) > 0;
|
||||||
validate : bool = flags & 0x1;
|
validate : bool = (flags & 0x1) > 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
type KRB_Principal_Name = record {
|
type KRB_Principal_Name = record {
|
||||||
|
@ -148,7 +148,7 @@ type KRB_Principal_Name = record {
|
||||||
name_type : ASN1Integer;
|
name_type : ASN1Integer;
|
||||||
seq_meta_1: ASN1EncodingMeta;
|
seq_meta_1: ASN1EncodingMeta;
|
||||||
seq_meta_2: ASN1EncodingMeta;
|
seq_meta_2: ASN1EncodingMeta;
|
||||||
data : ASN1OctetString[] &length=seq_meta_2.length;
|
data : ASN1OctetString[];
|
||||||
};
|
};
|
||||||
|
|
||||||
type KRB_Time = record {
|
type KRB_Time = record {
|
||||||
|
@ -162,12 +162,13 @@ type KRB_Host_Addresses = record {
|
||||||
};
|
};
|
||||||
|
|
||||||
type KRB_Host_Address = record {
|
type KRB_Host_Address = record {
|
||||||
addr_type: SequenceElement(true);
|
addr_type_meta : SequenceElement(false);
|
||||||
address : SequenceElement(true);
|
addr_type : ASN1Integer;
|
||||||
|
address : SequenceElement(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
type KRB_Ticket(in_sequence: bool) = record {
|
type KRB_Ticket(in_sequence: bool) = record {
|
||||||
have_seq : case in_sequence of {
|
have_seq : case in_sequence of {
|
||||||
true -> meta: ASN1EncodingMeta;
|
true -> meta: ASN1EncodingMeta;
|
||||||
false -> none: empty;
|
false -> none: empty;
|
||||||
};
|
};
|
||||||
|
@ -176,7 +177,7 @@ type KRB_Ticket(in_sequence: bool) = record {
|
||||||
tkt_vno : SequenceElement(true);
|
tkt_vno : SequenceElement(true);
|
||||||
realm : SequenceElement(true);
|
realm : SequenceElement(true);
|
||||||
sname_meta: ASN1EncodingMeta;
|
sname_meta: ASN1EncodingMeta;
|
||||||
sname : KRB_Principal_Name;
|
sname : KRB_Principal_Name &length=sname_meta.length;
|
||||||
enc_part : KRB_Encrypted_Data;
|
enc_part : KRB_Encrypted_Data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -187,7 +188,7 @@ type KRB_Ticket_Sequence = record {
|
||||||
|
|
||||||
type KRB_Encrypted_Data_in_Seq = record {
|
type KRB_Encrypted_Data_in_Seq = record {
|
||||||
index_meta : ASN1EncodingMeta;
|
index_meta : ASN1EncodingMeta;
|
||||||
data : KRB_Encrypted_Data;
|
data : KRB_Encrypted_Data &length=index_meta.length;
|
||||||
};
|
};
|
||||||
|
|
||||||
type KRB_Encrypted_Data = record {
|
type KRB_Encrypted_Data = record {
|
||||||
|
@ -223,12 +224,13 @@ type KRB_KDC_REP = record {
|
||||||
false -> n2 : empty;
|
false -> n2 : empty;
|
||||||
};
|
};
|
||||||
client_realm: ASN1OctetString &length=realm_length;
|
client_realm: ASN1OctetString &length=realm_length;
|
||||||
client_name : KRB_Principal_Name;
|
cname_meta : ASN1EncodingMeta;
|
||||||
|
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 {
|
} &let {
|
||||||
has_padata : bool = padata_meta.index == 2;
|
has_padata : bool = padata_meta.index == 2;
|
||||||
realm_length: uint8 = has_padata ? meta2.length : padata_meta.length;
|
realm_length: uint64 = has_padata ? meta2.length : padata_meta.length;
|
||||||
};
|
};
|
||||||
|
|
||||||
### AP_REQ
|
### AP_REQ
|
||||||
|
@ -249,9 +251,9 @@ type KRB_AP_Options = record {
|
||||||
flags : uint32;
|
flags : uint32;
|
||||||
: padding[1];
|
: padding[1];
|
||||||
} &let {
|
} &let {
|
||||||
reserved : bool = flags & 0x80000000;
|
reserved : bool = (flags & 0x80000000) > 0;
|
||||||
use_session_key : bool = flags & 0x40000000;
|
use_session_key : bool = (flags & 0x40000000) > 0;
|
||||||
mutual_required : bool = flags & 0x20000000;
|
mutual_required : bool = (flags & 0x20000000) > 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -265,30 +267,73 @@ 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;
|
||||||
args : KRB_ERROR_Arg[];
|
pvno : SequenceElement(true);
|
||||||
|
msg_type : SequenceElement(true);
|
||||||
|
ctime_meta : ASN1EncodingMeta;
|
||||||
|
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 = record {
|
type KRB_ERROR_Arg(error_code: uint64) = record {
|
||||||
seq_meta: ASN1EncodingMeta;
|
seq_meta: ASN1EncodingMeta;
|
||||||
args : KRB_ERROR_Arg_Data(seq_meta.index) &length=seq_meta.length;
|
args : KRB_ERROR_Arg_Data(seq_meta.index, error_code) &length=seq_meta.length;
|
||||||
};
|
};
|
||||||
|
|
||||||
type KRB_ERROR_Arg_Data(index: uint8) = case index of {
|
type KRB_ERROR_Arg_Data(index: uint8, error_code: uint64) = case index of {
|
||||||
0 -> pvno : ASN1Integer;
|
|
||||||
1 -> msg_type : ASN1Integer;
|
|
||||||
2 -> ctime : KRB_Time;
|
|
||||||
3 -> cusec : ASN1Integer;
|
|
||||||
4 -> stime : KRB_Time;
|
|
||||||
5 -> susec : ASN1Integer;
|
|
||||||
6 -> error_code : ASN1Integer;
|
|
||||||
7 -> crealm : ASN1OctetString;
|
7 -> crealm : ASN1OctetString;
|
||||||
8 -> cname : KRB_Principal_Name;
|
8 -> cname : KRB_Principal_Name;
|
||||||
9 -> realm : ASN1OctetString;
|
9 -> realm : ASN1OctetString;
|
||||||
10 -> sname : KRB_Principal_Name;
|
10 -> sname : KRB_Principal_Name;
|
||||||
11 -> e_text : ASN1OctetString;
|
11 -> e_text : ASN1OctetString;
|
||||||
12 -> e_data : ASN1OctetString;
|
12 -> e_data : KRB_ERROR_PA_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;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
### KRB_SAFE
|
### KRB_SAFE
|
||||||
|
@ -313,7 +358,7 @@ type KRB_SAFE_Arg = record {
|
||||||
type KRB_SAFE_Arg_Data(index: uint8) = case index of {
|
type KRB_SAFE_Arg_Data(index: uint8) = case index of {
|
||||||
0 -> user_data : ASN1OctetString;
|
0 -> user_data : ASN1OctetString;
|
||||||
1 -> timestamp : KRB_Time;
|
1 -> timestamp : KRB_Time;
|
||||||
2 -> usec : ASN1Integer;
|
2 -> usec : ASN1Integer;
|
||||||
3 -> seq_number : ASN1Integer;
|
3 -> seq_number : ASN1Integer;
|
||||||
4 -> sender_addr: KRB_Host_Address;
|
4 -> sender_addr: KRB_Host_Address;
|
||||||
5 -> recp_addr : KRB_Host_Address;
|
5 -> recp_addr : KRB_Host_Address;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue