From bd40a97a7803a50108a700e24b980ff17dc838d0 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Fri, 13 Nov 2020 21:48:29 -0800 Subject: [PATCH 1/3] GH-1264: Implement "ssh_server_host_key" event This event provides host key fingerprints for both SSH1 and SSH2. --- scripts/base/frameworks/intel/main.zeek | 3 +- scripts/base/protocols/ssh/main.zeek | 11 ----- src/analyzer/protocol/ssh/events.bif | 28 +++++++++++++ src/analyzer/protocol/ssh/ssh-analyzer.pac | 38 ++++++++++++++++++ .../output | 9 +++-- .../out | 5 +++ .../Traces/ssh/ssh1-ssh2-fingerprints.pcap | Bin 0 -> 8234 bytes .../base/protocols/ssh/fingerprints.zeek | 19 +++++++++ 8 files changed, 97 insertions(+), 16 deletions(-) create mode 100644 testing/btest/Baseline/scripts.base.protocols.ssh.fingerprints/out create mode 100644 testing/btest/Traces/ssh/ssh1-ssh2-fingerprints.pcap create mode 100644 testing/btest/scripts/base/protocols/ssh/fingerprints.zeek diff --git a/scripts/base/frameworks/intel/main.zeek b/scripts/base/frameworks/intel/main.zeek index 0d1f9aa374..8c6a85fedb 100644 --- a/scripts/base/frameworks/intel/main.zeek +++ b/scripts/base/frameworks/intel/main.zeek @@ -30,7 +30,8 @@ export { USER_NAME, ## Certificate SHA-1 hash. CERT_HASH, - ## Public key MD5 hash. (SSH server host keys are a good example.) + ## Public key MD5 hash, formatted as hexadecimal digits delimited by colons. + ## (SSH server host keys are a good example.) PUBKEY_HASH, }; diff --git a/scripts/base/protocols/ssh/main.zeek b/scripts/base/protocols/ssh/main.zeek index 373007c3a9..a26234abf5 100644 --- a/scripts/base/protocols/ssh/main.zeek +++ b/scripts/base/protocols/ssh/main.zeek @@ -111,17 +111,6 @@ export { ## ssh_server_host_key ssh_encrypted_packet ssh2_dh_server_params ## ssh2_gss_error ssh2_ecc_key global ssh_auth_result: event(c: connection, result: bool, auth_attempts: count); - - ## Event that can be handled when the analyzer sees an SSH server host - ## key. This abstracts :zeek:id:`ssh1_server_host_key` and - ## :zeek:id:`ssh2_server_host_key`. - ## - ## .. zeek:see:: ssh_server_version ssh_client_version - ## ssh_auth_successful ssh_auth_failed ssh_auth_result - ## ssh_auth_attempted ssh_capabilities ssh2_server_host_key - ## ssh1_server_host_key ssh_encrypted_packet ssh2_dh_server_params - ## ssh2_gss_error ssh2_ecc_key - global ssh_server_host_key: event(c: connection, hash: string); } module SSH; diff --git a/src/analyzer/protocol/ssh/events.bif b/src/analyzer/protocol/ssh/events.bif index 6ff62e501d..abc0c2d3f6 100644 --- a/src/analyzer/protocol/ssh/events.bif +++ b/src/analyzer/protocol/ssh/events.bif @@ -138,6 +138,34 @@ event ssh2_server_host_key%(c: connection, key: string%); ## ssh2_gss_error ssh2_ecc_key event ssh1_server_host_key%(c: connection, p: string, e: string%); +## During the :abbr:`SSH (Secure Shell)` key exchange, the server +## supplies its public host key. This event is generated when the +## appropriate key exchange message is seen for SSH1 or SSH2 and provides +## a fingerprint of the server's host key. +## +## c: The connection over which the :abbr:`SSH (Secure Shell)` +## connection took place. +## +## hash: an MD5 hash fingerprint associated with the server's host key. +## For SSH2, this is the hash of the "server public host key" string as +## seen on the wire in the Diffie-Hellman key exchange reply message +## (the string itself, excluding the 4-byte length associated with it), +## which is also the *key* parameter of :zeek:see:`ssh2_server_host_key` +## For SSH1, this is the hash of the combined multiprecision integer +## strings representing the RSA1 key's prime modulus and public exponent +## (concatenated in that order) as seen on the wire, +## which are also the parameters of :zeek:see:`ssh1_server_host_key`. +## In either case, the hash is the same "fingerprint" string as presented +## by other traditional tools, ``ssh``, ``ssh-keygen``, etc, and is the +## hexadecimal representation of all 16 MD5 hash bytes delimited by colons. +## +## .. zeek:see:: ssh_server_version ssh_client_version +## ssh_auth_successful ssh_auth_failed ssh_auth_result +## ssh_auth_attempted ssh_capabilities ssh2_server_host_key +## ssh1_server_host_key ssh_encrypted_packet ssh2_dh_server_params +## ssh2_gss_error ssh2_ecc_key +event ssh_server_host_key%(c: connection, hash: string%); + ## This event is generated when an :abbr:`SSH (Secure Shell)` ## encrypted packet is seen. This event is not handled by default, but ## is provided for heuristic analysis scripts. Note that you have to set diff --git a/src/analyzer/protocol/ssh/ssh-analyzer.pac b/src/analyzer/protocol/ssh/ssh-analyzer.pac index 59a6864083..84735440bb 100644 --- a/src/analyzer/protocol/ssh/ssh-analyzer.pac +++ b/src/analyzer/protocol/ssh/ssh-analyzer.pac @@ -2,10 +2,12 @@ #include #include #include +#include "zeek/digest.h" %} %header{ zeek::VectorValPtr name_list_to_vector(const bytestring& nl); +const char* fingerprint_md5(const unsigned char* d); %} %code{ @@ -45,6 +47,14 @@ zeek::VectorValPtr name_list_to_vector(const bytestring& nl) } return vv; } + +const char* fingerprint_md5(const unsigned char* d) + { + return zeek::util::fmt("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:" + "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", + d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], + d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]); + } %} refine flow SSH_Flow += { @@ -153,6 +163,17 @@ refine flow SSH_Flow += { connection()->zeek_analyzer()->Conn(), to_stringval(${key})); } + + if ( ssh_server_host_key ) + { + unsigned char digest[MD5_DIGEST_LENGTH]; + zeek::detail::internal_md5(${key}.data(), ${key}.length(), digest); + + zeek::BifEvent::enqueue_ssh_server_host_key(connection()->zeek_analyzer(), + connection()->zeek_analyzer()->Conn(), + zeek::make_intrusive(fingerprint_md5(digest))); + } + return true; %} @@ -165,6 +186,23 @@ refine flow SSH_Flow += { to_stringval(${p}), to_stringval(${e})); } + + if ( ssh_server_host_key ) + { + unsigned char digest[MD5_DIGEST_LENGTH]; + auto ctx = zeek::detail::hash_init(zeek::detail::Hash_MD5); + // Note: the 'p' and 'e' parameters actually have swapped meanings with + // 'p' actually being the exponent. + // Fingerprint is calculated over concatenation of modulus + exponent. + zeek::detail::hash_update(ctx, ${e}.data(), ${e}.length()); + zeek::detail::hash_update(ctx, ${p}.data(), ${p}.length()); + zeek::detail::hash_final(ctx, digest); + + zeek::BifEvent::enqueue_ssh_server_host_key(connection()->zeek_analyzer(), + connection()->zeek_analyzer()->Conn(), + zeek::make_intrusive(fingerprint_md5(digest))); + } + return true; %} diff --git a/testing/btest/Baseline/scripts.base.frameworks.intel.remove-non-existing/output b/testing/btest/Baseline/scripts.base.frameworks.intel.remove-non-existing/output index d8517f51c6..f9158f8618 100644 --- a/testing/btest/Baseline/scripts.base.frameworks.intel.remove-non-existing/output +++ b/testing/btest/Baseline/scripts.base.frameworks.intel.remove-non-existing/output @@ -1,11 +1,12 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. #separator \x09 #set_separator , #empty_field (empty) #unset_field - #path reporter -#open 2020-09-24-00-19-13 +#open XXXX-XX-XX-XX-XX-XX #fields ts level message location #types time enum string string -1600906753.185591 Reporter::INFO Tried to remove non-existing item '192.168.1.1' (Intel::ADDR). /home/christian/devel/zeek/zeek/scripts/base/frameworks/intel/./main.zeek, lines 565-566 -1600906753.185591 Reporter::INFO received termination signal (empty) -#close 2020-09-24-00-19-13 +XXXXXXXXXX.XXXXXX Reporter::INFO Tried to remove non-existing item '192.168.1.1' (Intel::ADDR). <...>/main.zeek, lines 566-567 +XXXXXXXXXX.XXXXXX Reporter::INFO received termination signal (empty) +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.ssh.fingerprints/out b/testing/btest/Baseline/scripts.base.protocols.ssh.fingerprints/out new file mode 100644 index 0000000000..dd1454e9b1 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ssh.fingerprints/out @@ -0,0 +1,5 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +ssh2 server host key fingerprint, c7eb775dd16431d61be8995fa709a1d7 +ssh server host key fingerprint, c7:eb:77:5d:d1:64:31:d6:1b:e8:99:5f:a7:09:a1:d7 +ssh1 server host key fingerprint, 5517ebfa2e7fb37b33427c9d448556da +ssh server host key fingerprint, 55:17:eb:fa:2e:7f:b3:7b:33:42:7c:9d:44:85:56:da diff --git a/testing/btest/Traces/ssh/ssh1-ssh2-fingerprints.pcap b/testing/btest/Traces/ssh/ssh1-ssh2-fingerprints.pcap new file mode 100644 index 0000000000000000000000000000000000000000..730240e9637f1685c0e94f7f685a79a98da75e7f GIT binary patch literal 8234 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 +# @TEST-EXEC: btest-diff out + +@load base/protocols/ssh + +event ssh2_server_host_key(c: connection, key: string) + { + print "ssh2 server host key fingerprint", md5_hash(key); + } + +event ssh1_server_host_key(c: connection, p: string, e: string) + { + print "ssh1 server host key fingerprint", md5_hash(e + p); + } + +event ssh_server_host_key(c: connection, hash: string) + { + print "ssh server host key fingerprint", hash; + } From 45449dad727b66dc78c43a3a18f02893844dfdb4 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Fri, 13 Nov 2020 22:23:29 -0800 Subject: [PATCH 2/3] Deprecate "ssh1_server_host_key" parameters *e* and *p* They are named such that *e* is actually the modulus, not the exponent. The replacement parameters are named *exponent* and *modulus* for clarity. --- NEWS | 4 ++++ scripts/base/protocols/ssh/main.zeek | 4 ++-- src/analyzer/protocol/ssh/events.bif | 16 +++++++++++++--- src/analyzer/protocol/ssh/ssh-analyzer.pac | 16 ++++++++-------- src/analyzer/protocol/ssh/ssh-protocol.pac | 8 ++++---- .../scripts/base/protocols/ssh/fingerprints.zeek | 4 ++-- 6 files changed, 33 insertions(+), 19 deletions(-) diff --git a/NEWS b/NEWS index 349aeb51b9..b1ffcfbee1 100644 --- a/NEWS +++ b/NEWS @@ -151,6 +151,10 @@ Deprecated Functionality - ``Type::GetAliases()`` and ``Type::AddAlias()`` are deprecated, use ``Type::Aliases()`` and ``Type::RegisterAlias()``. +- The ``ssh1_server_host_key`` event's modulus and exponent parameters, + *e* and *p*, were named in misleading way (*e* is the modulus) + and now deprecated in favor of the new *modulus* and *exponent* parameters. + Zeek 3.2.0 ========== diff --git a/scripts/base/protocols/ssh/main.zeek b/scripts/base/protocols/ssh/main.zeek index a26234abf5..199c80be8c 100644 --- a/scripts/base/protocols/ssh/main.zeek +++ b/scripts/base/protocols/ssh/main.zeek @@ -292,9 +292,9 @@ function generate_fingerprint(c: connection, key: string) c$ssh$host_key = join_string_vec(lx, ":"); } -event ssh1_server_host_key(c: connection, p: string, e: string) &priority=5 +event ssh1_server_host_key(c: connection, modulus: string, exponent: string) &priority=5 { - generate_fingerprint(c, e + p); + generate_fingerprint(c, modulus + exponent); } event ssh2_server_host_key(c: connection, key: string) &priority=5 diff --git a/src/analyzer/protocol/ssh/events.bif b/src/analyzer/protocol/ssh/events.bif index abc0c2d3f6..fd1cd776d9 100644 --- a/src/analyzer/protocol/ssh/events.bif +++ b/src/analyzer/protocol/ssh/events.bif @@ -127,16 +127,26 @@ event ssh2_server_host_key%(c: connection, key: string%); ## c: The connection over which the :abbr:`SSH (Secure Shell)` ## connection took place. ## -## p: The prime for the server's public host key. +## p: The exponent for the server's public host key (note this parameter +## is truly the exponent even though named *p* and the *exponent* parameter +## will eventually replace it). ## -## e: The exponent for the serer's public host key. +## e: The prime modulus for the server's public host key (note this parameter +## is truly the modulus even though named *e* and the *modulus* parameter +## will eventually replace it). +## +## modulus: The prime modulus of the server's public host key. +## +## exponent: The exponent of the server's public host key. ## ## .. zeek:see:: ssh_server_version ssh_client_version ## ssh_auth_successful ssh_auth_failed ssh_auth_result ## ssh_auth_attempted ssh_capabilities ssh2_server_host_key ## ssh_server_host_key ssh_encrypted_packet ssh2_dh_server_params ## ssh2_gss_error ssh2_ecc_key -event ssh1_server_host_key%(c: connection, p: string, e: string%); +event ssh1_server_host_key%(c: connection, p: string &deprecated="Remove in v4.1", e: string &deprecated="Remove in v4.1", modulus: string, exponent: string%); +event ssh1_server_host_key%(c: connection, modulus: string, exponent: string%); +event ssh1_server_host_key%(c: connection, p: string, e: string%) &deprecated="Remove in v4.1. The 'p' and 'e' parameters are misleadingly named don't use them."; ## During the :abbr:`SSH (Secure Shell)` key exchange, the server ## supplies its public host key. This event is generated when the diff --git a/src/analyzer/protocol/ssh/ssh-analyzer.pac b/src/analyzer/protocol/ssh/ssh-analyzer.pac index 84735440bb..8cbedda91d 100644 --- a/src/analyzer/protocol/ssh/ssh-analyzer.pac +++ b/src/analyzer/protocol/ssh/ssh-analyzer.pac @@ -177,25 +177,25 @@ refine flow SSH_Flow += { return true; %} - function proc_ssh1_server_host_key(p: bytestring, e: bytestring): bool + function proc_ssh1_server_host_key(exp: bytestring, mod: bytestring): bool %{ if ( ssh1_server_host_key ) { zeek::BifEvent::enqueue_ssh1_server_host_key(connection()->zeek_analyzer(), connection()->zeek_analyzer()->Conn(), - to_stringval(${p}), - to_stringval(${e})); + to_stringval(${exp}), + to_stringval(${mod}), + to_stringval(${mod}), + to_stringval(${exp})); } if ( ssh_server_host_key ) { unsigned char digest[MD5_DIGEST_LENGTH]; auto ctx = zeek::detail::hash_init(zeek::detail::Hash_MD5); - // Note: the 'p' and 'e' parameters actually have swapped meanings with - // 'p' actually being the exponent. // Fingerprint is calculated over concatenation of modulus + exponent. - zeek::detail::hash_update(ctx, ${e}.data(), ${e}.length()); - zeek::detail::hash_update(ctx, ${p}.data(), ${p}.length()); + zeek::detail::hash_update(ctx, ${mod}.data(), ${mod}.length()); + zeek::detail::hash_update(ctx, ${exp}.data(), ${exp}.length()); zeek::detail::hash_final(ctx, digest); zeek::BifEvent::enqueue_ssh_server_host_key(connection()->zeek_analyzer(), @@ -267,5 +267,5 @@ refine typeattr SSH2_ECC_INIT += &let { }; refine typeattr SSH1_PUBLIC_KEY += &let { - proc: bool = $context.flow.proc_ssh1_server_host_key(host_key_p.val, host_key_e.val); + proc: bool = $context.flow.proc_ssh1_server_host_key(host_key_exp.val, host_key_mod.val); }; diff --git a/src/analyzer/protocol/ssh/ssh-protocol.pac b/src/analyzer/protocol/ssh/ssh-protocol.pac index 99f361974f..b7ae75b2b3 100644 --- a/src/analyzer/protocol/ssh/ssh-protocol.pac +++ b/src/analyzer/protocol/ssh/ssh-protocol.pac @@ -60,11 +60,11 @@ type SSH1_Message(is_orig: bool, msg_type: uint8, length: uint32) = case msg_typ type SSH1_PUBLIC_KEY(length: uint32) = record { cookie : bytestring &length=8; server_key : uint32; - server_key_p : ssh1_mp_int; - server_key_e : ssh1_mp_int; + server_key_exp : ssh1_mp_int; + server_key_mod : ssh1_mp_int; host_key : uint32; - host_key_p : ssh1_mp_int; - host_key_e : ssh1_mp_int; + host_key_exp : ssh1_mp_int; + host_key_mod : ssh1_mp_int; flags : uint32; supported_ciphers : uint32; supported_auths : uint32; diff --git a/testing/btest/scripts/base/protocols/ssh/fingerprints.zeek b/testing/btest/scripts/base/protocols/ssh/fingerprints.zeek index 6af3c55a6a..f0ef8fad21 100644 --- a/testing/btest/scripts/base/protocols/ssh/fingerprints.zeek +++ b/testing/btest/scripts/base/protocols/ssh/fingerprints.zeek @@ -8,9 +8,9 @@ event ssh2_server_host_key(c: connection, key: string) print "ssh2 server host key fingerprint", md5_hash(key); } -event ssh1_server_host_key(c: connection, p: string, e: string) +event ssh1_server_host_key(c: connection, modulus: string, exponent: string) { - print "ssh1 server host key fingerprint", md5_hash(e + p); + print "ssh1 server host key fingerprint", md5_hash(modulus + exponent); } event ssh_server_host_key(c: connection, hash: string) From 331b94db3959844c53f1ad07915f12ab85a80ff8 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Sat, 14 Nov 2020 08:40:27 -0800 Subject: [PATCH 3/3] Simply ssh/main.zeek by using "ssh_server_host_key" for fingerprinting --- scripts/base/protocols/ssh/main.zeek | 18 ++-------- src/analyzer/protocol/ssh/ssh-analyzer.pac | 34 +++++++++---------- .../out | 4 +-- 3 files changed, 22 insertions(+), 34 deletions(-) diff --git a/scripts/base/protocols/ssh/main.zeek b/scripts/base/protocols/ssh/main.zeek index 199c80be8c..66dc01d238 100644 --- a/scripts/base/protocols/ssh/main.zeek +++ b/scripts/base/protocols/ssh/main.zeek @@ -282,24 +282,12 @@ event ssh_auth_failed(c: connection) &priority=-5 event ssh_auth_result(c, F, c$ssh$auth_attempts); } - -function generate_fingerprint(c: connection, key: string) +event ssh_server_host_key(c: connection, hash: string) &priority=5 { - if ( !c?$ssh ) + if ( ! c?$ssh ) return; - local lx = str_split_indices(md5_hash(key), vector(2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30)); - c$ssh$host_key = join_string_vec(lx, ":"); - } - -event ssh1_server_host_key(c: connection, modulus: string, exponent: string) &priority=5 - { - generate_fingerprint(c, modulus + exponent); - } - -event ssh2_server_host_key(c: connection, key: string) &priority=5 - { - generate_fingerprint(c, key); + c$ssh$host_key = hash; } event protocol_confirmation(c: connection, atype: Analyzer::Tag, aid: count) &priority=20 diff --git a/src/analyzer/protocol/ssh/ssh-analyzer.pac b/src/analyzer/protocol/ssh/ssh-analyzer.pac index 8cbedda91d..a625104917 100644 --- a/src/analyzer/protocol/ssh/ssh-analyzer.pac +++ b/src/analyzer/protocol/ssh/ssh-analyzer.pac @@ -157,13 +157,6 @@ refine flow SSH_Flow += { function proc_ssh2_server_host_key(key: bytestring): bool %{ - if ( ssh2_server_host_key ) - { - zeek::BifEvent::enqueue_ssh2_server_host_key(connection()->zeek_analyzer(), - connection()->zeek_analyzer()->Conn(), - to_stringval(${key})); - } - if ( ssh_server_host_key ) { unsigned char digest[MD5_DIGEST_LENGTH]; @@ -174,21 +167,18 @@ refine flow SSH_Flow += { zeek::make_intrusive(fingerprint_md5(digest))); } + if ( ssh2_server_host_key ) + { + zeek::BifEvent::enqueue_ssh2_server_host_key(connection()->zeek_analyzer(), + connection()->zeek_analyzer()->Conn(), + to_stringval(${key})); + } + return true; %} function proc_ssh1_server_host_key(exp: bytestring, mod: bytestring): bool %{ - if ( ssh1_server_host_key ) - { - zeek::BifEvent::enqueue_ssh1_server_host_key(connection()->zeek_analyzer(), - connection()->zeek_analyzer()->Conn(), - to_stringval(${exp}), - to_stringval(${mod}), - to_stringval(${mod}), - to_stringval(${exp})); - } - if ( ssh_server_host_key ) { unsigned char digest[MD5_DIGEST_LENGTH]; @@ -203,6 +193,16 @@ refine flow SSH_Flow += { zeek::make_intrusive(fingerprint_md5(digest))); } + if ( ssh1_server_host_key ) + { + zeek::BifEvent::enqueue_ssh1_server_host_key(connection()->zeek_analyzer(), + connection()->zeek_analyzer()->Conn(), + to_stringval(${exp}), + to_stringval(${mod}), + to_stringval(${mod}), + to_stringval(${exp})); + } + return true; %} diff --git a/testing/btest/Baseline/scripts.base.protocols.ssh.fingerprints/out b/testing/btest/Baseline/scripts.base.protocols.ssh.fingerprints/out index dd1454e9b1..2dac5bca77 100644 --- a/testing/btest/Baseline/scripts.base.protocols.ssh.fingerprints/out +++ b/testing/btest/Baseline/scripts.base.protocols.ssh.fingerprints/out @@ -1,5 +1,5 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -ssh2 server host key fingerprint, c7eb775dd16431d61be8995fa709a1d7 ssh server host key fingerprint, c7:eb:77:5d:d1:64:31:d6:1b:e8:99:5f:a7:09:a1:d7 -ssh1 server host key fingerprint, 5517ebfa2e7fb37b33427c9d448556da +ssh2 server host key fingerprint, c7eb775dd16431d61be8995fa709a1d7 ssh server host key fingerprint, 55:17:eb:fa:2e:7f:b3:7b:33:42:7c:9d:44:85:56:da +ssh1 server host key fingerprint, 5517ebfa2e7fb37b33427c9d448556da