SSH protocol now assesses the packet length at an earlier stage within binpac. Stops SSH analyzer constantly raising binpac exceptions. Seems to be because a packet continues to go through binpac when empty and only calls the next packet when asked for more data and not on operations.

This commit is contained in:
Andrew Woodford 2017-12-21 16:34:26 +00:00
parent 1c25df6f26
commit f07fdc255f
2 changed files with 25 additions and 12 deletions

View file

@ -173,6 +173,18 @@ refine flow SSH_Flow += {
connection()->bro_analyzer()->ProtocolConfirmation();
return true;
%}
function get_kex_length(v: int, packet_length: uint32): int
%{
switch (v) {
case SSH1:
return packet_length + 4 + 8 -(packet_length%8);
case SSH2:
return packet_length + 4;
default:
return 1; //currently causes the rest of the packet to dump
}
%}
};
refine typeattr SSH_Version += &let {

View file

@ -22,21 +22,23 @@ type SSH_Version(is_orig: bool) = record {
update_version : bool = $context.connection.update_version(version, is_orig);
};
type SSH_Key_Exchange(is_orig: bool) = case $context.connection.get_version() of {
SSH1 -> ssh1_msg : SSH1_Key_Exchange(is_orig);
SSH2 -> ssh2_msg : SSH2_Key_Exchange(is_orig);
type SSH_Key_Exchange(is_orig: bool) = record {
packet_length: uint32;
key_ex: case $context.connection.get_version() of {
SSH1 -> ssh1_msg : SSH1_Key_Exchange(is_orig, packet_length);
SSH2 -> ssh2_msg : SSH2_Key_Exchange(is_orig, packet_length);
};
} &length = $context.flow.get_kex_length($context.connection.get_version(), packet_length);
# SSH1 constructs
#################
type SSH1_Key_Exchange(is_orig: bool) = record {
packet_length : uint32;
type SSH1_Key_Exchange(is_orig: bool, packet_length: uint32) = record {
pad_fill : bytestring &length = 8 - (packet_length % 8);
msg_type : uint8;
message : SSH1_Message(is_orig, msg_type, packet_length - 5);
crc : uint32;
} &length = packet_length + 4 + 8 - (packet_length % 8);
} &length = packet_length + 8 - (packet_length % 8);
type SSH1_Message(is_orig: bool, msg_type: uint8, length: uint32) = case msg_type of {
SSH_SMSG_PUBLIC_KEY -> public_key : SSH1_PUBLIC_KEY(length);
@ -73,8 +75,7 @@ type ssh1_mp_int = record {
## SSH2
type SSH2_Header(is_orig: bool) = record {
packet_length : uint32;
type SSH2_Header(is_orig: bool, packet_length: uint32) = record {
padding_length : uint8;
msg_type : uint8;
} &let {
@ -82,11 +83,11 @@ type SSH2_Header(is_orig: bool) = record {
detach : bool = $context.connection.update_state(ENCRYPTED, is_orig) &if(msg_type == MSG_NEWKEYS);
};
type SSH2_Key_Exchange(is_orig: bool) = record {
header : SSH2_Header(is_orig);
type SSH2_Key_Exchange(is_orig: bool, packet_length: uint32) = record {
header : SSH2_Header(is_orig, packet_length);
payload : SSH2_Message(is_orig, header.msg_type, header.payload_length);
pad : bytestring &length=header.padding_length;
} &length=header.packet_length + 4;
} &length=packet_length;
type SSH2_Message(is_orig: bool, msg_type: uint8, length: uint32) = case $context.connection.get_state(is_orig) of {
KEX_INIT -> kex : SSH2_KEXINIT(length, is_orig);