mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
[SSH] Handle SSH version 1.99
SSH can set in its identification a version 1.99 (SSH-1.99-xxx). That means the client/server is compatible with SSHv1 and SSHv2. So the version choice depends of the both side. 1.99 : 1.99 => 2.0 1.99 : 1.x => 1.x 1.99 : 2.0 => 2.O (see "Compatibility With Old SSH Versions" in RFC 4253)
This commit is contained in:
parent
93469d811d
commit
3769ed6c66
6 changed files with 125 additions and 8 deletions
|
@ -166,21 +166,65 @@ function set_session(c: connection)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function set_version(c: connection, version: string)
|
||||||
|
{
|
||||||
|
if ( c$ssh?$server && c$ssh?$client && |c$ssh$client| > 4 && |c$ssh$server| > 4 )
|
||||||
|
{
|
||||||
|
if ( c$ssh$client[4] == "1" && c$ssh$server[4] == "2" )
|
||||||
|
{
|
||||||
|
# SSH199 vs SSH2 -> 2
|
||||||
|
if ( ( |c$ssh$client| > 7 ) && ( c$ssh$client[6] == "9" ) && ( c$ssh$client[7] == "9" ) )
|
||||||
|
c$ssh$version = 2;
|
||||||
|
# SSH1 vs SSH2 -> Undefined
|
||||||
|
else
|
||||||
|
c$ssh$version = 0;
|
||||||
|
}
|
||||||
|
else if ( c$ssh$client[4] == "2" && c$ssh$server[4] == "1" )
|
||||||
|
{
|
||||||
|
# SSH2 vs SSH199 -> 2
|
||||||
|
if ( ( |c$ssh$server| > 7 ) && ( c$ssh$server[6] == "9" ) && ( c$ssh$server[7] == "9" ) )
|
||||||
|
c$ssh$version = 2;
|
||||||
|
else
|
||||||
|
# SSH2 vs SSH1 -> Undefined
|
||||||
|
c$ssh$version = 0;
|
||||||
|
}
|
||||||
|
else if ( c$ssh$client[4] == "1" && c$ssh$server[4] == "1" )
|
||||||
|
{
|
||||||
|
# SSH1 vs SSH199 -> 1
|
||||||
|
if ( ( |c$ssh$server| > 7 ) && ( c$ssh$server[6] == "9" ) && ( c$ssh$server[7] == "9" ) )
|
||||||
|
{
|
||||||
|
# SSH199 vs SSH199
|
||||||
|
if (( |c$ssh$client| > 7 ) && ( c$ssh$client[6] == "9" ) && ( c$ssh$client[7] == "9" ))
|
||||||
|
c$ssh$version = 2;
|
||||||
|
else
|
||||||
|
c$ssh$version = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
# SSH1 vs SSH1 -> 1
|
||||||
|
c$ssh$version = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# SSH2 vs SSH2
|
||||||
|
else if (c$ssh$client[4] == "2" && c$ssh$server[4] == "2" )
|
||||||
|
{
|
||||||
|
c$ssh$version = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
event ssh_server_version(c: connection, version: string)
|
event ssh_server_version(c: connection, version: string)
|
||||||
{
|
{
|
||||||
set_session(c);
|
set_session(c);
|
||||||
c$ssh$server = version;
|
c$ssh$server = version;
|
||||||
|
set_version(c, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
event ssh_client_version(c: connection, version: string)
|
event ssh_client_version(c: connection, version: string)
|
||||||
{
|
{
|
||||||
set_session(c);
|
set_session(c);
|
||||||
c$ssh$client = version;
|
c$ssh$client = version;
|
||||||
|
set_version(c, version);
|
||||||
if ( ( |version| > 3 ) && ( version[4] == "1" ) )
|
|
||||||
c$ssh$version = 1;
|
|
||||||
if ( ( |version| > 3 ) && ( version[4] == "2" ) )
|
|
||||||
c$ssh$version = 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
event ssh_auth_attempted(c: connection, authenticated: bool) &priority=5
|
event ssh_auth_attempted(c: connection, authenticated: bool) &priority=5
|
||||||
|
|
|
@ -2,6 +2,7 @@ enum version {
|
||||||
SSH1 = 1,
|
SSH1 = 1,
|
||||||
SSH2 = 2,
|
SSH2 = 2,
|
||||||
UNK = 3,
|
UNK = 3,
|
||||||
|
SSH199 = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum state {
|
enum state {
|
||||||
|
|
|
@ -275,6 +275,8 @@ refine connection SSH_Conn += {
|
||||||
int state_up_;
|
int state_up_;
|
||||||
int state_down_;
|
int state_down_;
|
||||||
int version_;
|
int version_;
|
||||||
|
int version_client_;
|
||||||
|
int version_server_;
|
||||||
int encrypted_bytes_in_current_segment_;
|
int encrypted_bytes_in_current_segment_;
|
||||||
|
|
||||||
bool kex_orig_;
|
bool kex_orig_;
|
||||||
|
@ -287,6 +289,8 @@ refine connection SSH_Conn += {
|
||||||
state_up_ = VERSION_EXCHANGE;
|
state_up_ = VERSION_EXCHANGE;
|
||||||
state_down_ = VERSION_EXCHANGE;
|
state_down_ = VERSION_EXCHANGE;
|
||||||
version_ = UNK;
|
version_ = UNK;
|
||||||
|
version_client_ = UNK;
|
||||||
|
version_server_ = UNK;
|
||||||
encrypted_bytes_in_current_segment_ = 0;
|
encrypted_bytes_in_current_segment_ = 0;
|
||||||
|
|
||||||
kex_seen_ = false;
|
kex_seen_ = false;
|
||||||
|
@ -343,15 +347,67 @@ refine connection SSH_Conn += {
|
||||||
return version_;
|
return version_;
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
# If the version is 1.99, that means the client/server is compatible
|
||||||
|
# with sshv1 and sshv2. So one says version 2 and the other 1.99
|
||||||
|
# the connection will be in version 2 otherwise if its version 1.x and
|
||||||
|
# 1.99 the connection be in version 1. See RFC 4253 chapter 5.
|
||||||
function update_version(v: bytestring, is_orig: bool) : bool
|
function update_version(v: bytestring, is_orig: bool) : bool
|
||||||
%{
|
%{
|
||||||
if ( is_orig && ( v.length() >= 4 ) )
|
if ( v.length() >= 5 )
|
||||||
{
|
{
|
||||||
if ( v[4] == '2' )
|
if ( v[4] == '2' )
|
||||||
version_ = SSH2;
|
{
|
||||||
|
if ( is_orig )
|
||||||
|
version_client_ = SSH2;
|
||||||
|
else
|
||||||
|
version_server_ = SSH2;
|
||||||
|
}
|
||||||
if ( v[4] == '1' )
|
if ( v[4] == '1' )
|
||||||
version_ = SSH1;
|
{
|
||||||
|
if ( v.length() >= 8 && v[6] == '9' && v[7] == '9' )
|
||||||
|
{
|
||||||
|
if ( is_orig )
|
||||||
|
version_client_ = SSH199;
|
||||||
|
else
|
||||||
|
version_server_ = SSH199;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( is_orig)
|
||||||
|
version_client_ = SSH1;
|
||||||
|
else
|
||||||
|
version_server_ = SSH1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( version_server_ == version_client_ )
|
||||||
|
{
|
||||||
|
// SSH199 vs SSH199 -> 2
|
||||||
|
if (version_server_ == SSH199 )
|
||||||
|
version_ = SSH2;
|
||||||
|
else
|
||||||
|
version_ = version_server_;
|
||||||
|
}
|
||||||
|
// SSH1 vs SSH2 -> Undefined
|
||||||
|
else if ( version_client_ == SSH1 && version_server_ == SSH2 )
|
||||||
|
version_ = UNK;
|
||||||
|
// SSH2 vs SSH1 -> Undefined
|
||||||
|
else if ( version_client_ == SSH2 && version_server_ == SSH1 )
|
||||||
|
version_ = UNK;
|
||||||
|
// SSH199 vs SSH2 -> 2
|
||||||
|
else if ( version_client_ == SSH199 && version_server_ == SSH2 )
|
||||||
|
version_ = version_server_;
|
||||||
|
// SSH2 vs SSH199 -> 2
|
||||||
|
else if ( version_client_ == SSH2 && version_server_ == SSH199 )
|
||||||
|
version_ = version_client_;
|
||||||
|
// SSH1 vs SSH199 -> 1
|
||||||
|
else if ( version_client_ == SSH1 && version_server_ == SSH199 )
|
||||||
|
version_ = version_client_;
|
||||||
|
// SSH199 vs SSH1 -> 1
|
||||||
|
else if ( version_client_ == SSH199 && version_server_ == SSH1 )
|
||||||
|
version_ = version_server_;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
#separator \x09
|
||||||
|
#set_separator ,
|
||||||
|
#empty_field (empty)
|
||||||
|
#unset_field -
|
||||||
|
#path ssh
|
||||||
|
#open 2019-12-06-09-53-13
|
||||||
|
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version auth_success auth_attempts direction client server cipher_alg mac_alg compression_alg kex_alg host_key_alg host_key
|
||||||
|
#types time string addr port addr port count bool count enum string string string string string string string string
|
||||||
|
1213964540.292082 CHhAvVGS1DHFjwGM9 10.0.0.1 59139 10.0.0.2 22 2 T 1 - SSH-1.99-Cisco-1.25 SSH-2.0-Cisco-1.25 aes128-cbc hmac-sha1 none diffie-hellman-group1-sha1 ssh-rsa 91:0a:ed:3f:79:71:22:f9:97:66:71:f8:c9:a5:b4:10
|
||||||
|
#close 2019-12-06-09-53-13
|
BIN
testing/btest/Traces/ssh/ssh_version_199.pcap
Normal file
BIN
testing/btest/Traces/ssh/ssh_version_199.pcap
Normal file
Binary file not shown.
|
@ -0,0 +1,6 @@
|
||||||
|
# This tests a successful auth between an SSHv1.99 and SSHv2.
|
||||||
|
|
||||||
|
# @TEST-EXEC: zeek -r $TRACES/ssh/ssh_version_199.pcap %INPUT
|
||||||
|
# @TEST-EXEC: btest-diff ssh.log
|
||||||
|
|
||||||
|
@load base/protocols/ssh
|
Loading…
Add table
Add a link
Reference in a new issue