Skip to content

Commit

Permalink
Merge branch 'topic/vbrevet/ssh_version' of https://github.com/vbreve…
Browse files Browse the repository at this point in the history
…t/zeek

* 'topic/vbrevet/ssh_version' of https://github.com/vbrevet/zeek:
  [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.
  • Loading branch information
0xxon committed Nov 16, 2020
2 parents 93469d8 + 3769ed6 commit 50a49ea
Show file tree
Hide file tree
Showing 9 changed files with 143 additions and 9 deletions.
13 changes: 13 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@

3.3.0-dev.537 | 2020-11-16 11:03:05 +0000

* [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) (Brevet Vivien)

3.3.0-dev.534 | 2020-11-12 14:31:10 -0800

* Move UnknownProtocol options to init-bare.zeek (Jon Siwek, Corelight)
Expand Down
4 changes: 4 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ New Functionality
- dns_NSEC3PARAM
- dns_BINDS

- Zeek now supports SSH clients/servers that advertise SSH version 1.99, which
is a special version indicating that the server/client supports both SSH2 and
SSH1.

Changed Functionality
---------------------

Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.3.0-dev.534
3.3.0-dev.537
54 changes: 49 additions & 5 deletions scripts/base/protocols/ssh/main.zeek
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
set_session(c);
c$ssh$server = version;
set_version(c, version);
}

event ssh_client_version(c: connection, version: string)
{
set_session(c);
c$ssh$client = version;

if ( ( |version| > 3 ) && ( version[4] == "1" ) )
c$ssh$version = 1;
if ( ( |version| > 3 ) && ( version[4] == "2" ) )
c$ssh$version = 2;
set_version(c, version);
}

event ssh_auth_attempted(c: connection, authenticated: bool) &priority=5
Expand Down
1 change: 1 addition & 0 deletions src/analyzer/protocol/ssh/consts.pac
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ enum version {
SSH1 = 1,
SSH2 = 2,
UNK = 3,
SSH199 = 4,
};

enum state {
Expand Down
62 changes: 59 additions & 3 deletions src/analyzer/protocol/ssh/ssh-protocol.pac
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,8 @@ refine connection SSH_Conn += {
int state_up_;
int state_down_;
int version_;
int version_client_;
int version_server_;
int encrypted_bytes_in_current_segment_;
bool kex_orig_;
Expand All @@ -287,6 +289,8 @@ refine connection SSH_Conn += {
state_up_ = VERSION_EXCHANGE;
state_down_ = VERSION_EXCHANGE;
version_ = UNK;
version_client_ = UNK;
version_server_ = UNK;
encrypted_bytes_in_current_segment_ = 0;
kex_seen_ = false;
Expand Down Expand Up @@ -343,15 +347,67 @@ refine connection SSH_Conn += {
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
%{
if ( is_orig && ( v.length() >= 4 ) )
if ( v.length() >= 5 )
{
if ( v[4] == '2' )
version_ = SSH2;
{
if ( is_orig )
version_client_ = SSH2;
else
version_server_ = SSH2;
}
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;
%}

Expand Down
Original file line number Diff line number Diff line change
@@ -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
Binary file added testing/btest/Traces/ssh/ssh_version_199.pcap
Binary file not shown.
6 changes: 6 additions & 0 deletions testing/btest/scripts/base/protocols/ssh/ssh_version_199.zeek
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 50a49ea

Please sign in to comment.