mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Merge remote-tracking branch 'origin/topic/jsiwek/gh-1264-ssh-host-key-fingerprints' into master
* origin/topic/jsiwek/gh-1264-ssh-host-key-fingerprints: Simply ssh/main.zeek by using "ssh_server_host_key" for fingerprinting Deprecate "ssh1_server_host_key" parameters *e* and *p* GH-1264: Implement "ssh_server_host_key" event
This commit is contained in:
commit
02c0b33b54
12 changed files with 140 additions and 43 deletions
|
@ -127,16 +127,54 @@ 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
|
||||
## 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
|
||||
|
|
|
@ -2,10 +2,12 @@
|
|||
#include <cstdlib>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#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 += {
|
||||
|
@ -147,24 +157,52 @@ refine flow SSH_Flow += {
|
|||
|
||||
function proc_ssh2_server_host_key(key: bytestring): bool
|
||||
%{
|
||||
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<zeek::StringVal>(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(p: bytestring, e: bytestring): bool
|
||||
function proc_ssh1_server_host_key(exp: bytestring, mod: bytestring): bool
|
||||
%{
|
||||
if ( ssh_server_host_key )
|
||||
{
|
||||
unsigned char digest[MD5_DIGEST_LENGTH];
|
||||
auto ctx = zeek::detail::hash_init(zeek::detail::Hash_MD5);
|
||||
// Fingerprint is calculated over concatenation of modulus + exponent.
|
||||
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(),
|
||||
connection()->zeek_analyzer()->Conn(),
|
||||
zeek::make_intrusive<zeek::StringVal>(fingerprint_md5(digest)));
|
||||
}
|
||||
|
||||
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}));
|
||||
}
|
||||
|
||||
return true;
|
||||
%}
|
||||
|
||||
|
@ -229,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);
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue