145 lines
7.4 KiB
Plaintext
145 lines
7.4 KiB
Plaintext
# HASSH #
|
|
# SSH Key Initiation Exchange Fingerprinting #
|
|
# #
|
|
# Script Version: v1.5 22 August 2019 #
|
|
# Authors: Ben Reardon (breardon@salesforce.com, @benreardon) #
|
|
# : Jeff Atkinson (jatkinson@salesforce.com) #
|
|
# : John Althouse (jalthouse@salesforce.com) #
|
|
# Description: This Zeek script appends hassh data to ssh.log #
|
|
# by enumerating the SSH_MSG_KEXINIT packets sent #
|
|
# as clear text between the client and server as part #
|
|
# of the negotiation of an SSH connection. #
|
|
# #
|
|
# Copyright (c) 2018, salesforce.com, inc. #
|
|
# All rights reserved. #
|
|
# SPDX-License-Identifier: BSD-3-Clause #
|
|
# For full license text, see the LICENSE file in the repo root or #
|
|
# https://opensource.org/licenses/BSD-3-Clause #
|
|
|
|
|
|
module SSH;
|
|
|
|
export {
|
|
type HASSHStorage: record {
|
|
hasshVersion:string &log &default="1.1"; # ANY change in hassh/hasshServer composition requires Version update
|
|
hassh: string &log &optional &default="";
|
|
hasshServer: string &log &optional &default="";
|
|
|
|
# Client variables #
|
|
ckex: string &log &optional &default="";
|
|
cshka: string &log &optional &default="";
|
|
ceacts: string &log &optional &default="";
|
|
cmacts: string &log &optional &default="";
|
|
ccacts: string &log &optional &default="";
|
|
#clcts: string &log &optional &default="";
|
|
hasshAlgorithms: string &log &optional &default="";
|
|
|
|
# Server variables #
|
|
skex: string &log &optional &default="";
|
|
sshka: string &log &optional &default="";
|
|
seastc: string &log &optional &default="";
|
|
smastc: string &log &optional &default="";
|
|
scastc: string &log &optional &default="";
|
|
#slstc: string &log &optional &default="";
|
|
hasshServerAlgorithms: string &log &optional &default="";
|
|
};
|
|
}
|
|
|
|
redef record connection += {
|
|
hassh: HASSHStorage &optional;
|
|
};
|
|
|
|
redef record SSH::Info += {
|
|
hasshVersion: string &log &optional;
|
|
hassh: string &log &optional;
|
|
hasshServer: string &log &optional;
|
|
|
|
# ===> Log Client variables <=== #
|
|
# Comment out any fields that are not required to be logged in their raw form to ssh.log
|
|
#ckex: string &log &optional;
|
|
cshka: string &log &optional;
|
|
#ceacts: string &log &optional;
|
|
#cmacts: string &log &optional;
|
|
#ccacts: string &log &optional;
|
|
#clcts: string &log &optional;
|
|
hasshAlgorithms: string &log &optional;
|
|
|
|
# ===> Log Server variables <=== #
|
|
# Comment out any fields that are not required to be logged in their raw form to ssh.log
|
|
#skex: string &log &optional;
|
|
sshka: string &log &optional;
|
|
#seastc: string &log &optional;
|
|
#smastc: string &log &optional;
|
|
#scastc: string &log &optional;
|
|
#slstc: string &log &optional;
|
|
hasshServerAlgorithms: string &log &optional;
|
|
};
|
|
|
|
|
|
# Build Client Application fingerprint #
|
|
function get_hassh(c:connection, capabilities: SSH::Capabilities ) {
|
|
c$hassh = HASSHStorage();
|
|
c$hassh$ckex = join_string_vec(capabilities$kex_algorithms,",");
|
|
c$hassh$ceacts = join_string_vec(capabilities$encryption_algorithms$client_to_server,",");
|
|
c$hassh$cmacts = join_string_vec(capabilities$mac_algorithms$client_to_server,",");
|
|
c$hassh$ccacts = join_string_vec(capabilities$compression_algorithms$client_to_server,",");
|
|
c$hassh$cshka = join_string_vec(capabilities$server_host_key_algorithms,","); # The Host key algorithm set may be useful information by itself but is not included in the hassh.
|
|
#c$hassh$clcts = join_string_vec(capabilities$languages$client_to_server,","); # The Languages field may be useful information by itself but is not included in the hasshServer.
|
|
c$hassh$hasshAlgorithms = string_cat(c$hassh$ckex,";",c$hassh$ceacts,";",c$hassh$cmacts,";",c$hassh$ccacts); # Contatenate the four selected lists of algorithms (Key,Enc,MAC,Compression) to build the Client hash
|
|
c$hassh$hassh = md5_hash(c$hassh$hasshAlgorithms);
|
|
}
|
|
|
|
# Build Server Application fingerprint #
|
|
function get_hasshServer(c:connection, capabilities: SSH::Capabilities ) {
|
|
c$hassh = HASSHStorage();
|
|
c$hassh$skex = join_string_vec(capabilities$kex_algorithms,",");
|
|
c$hassh$seastc = join_string_vec(capabilities$encryption_algorithms$server_to_client,",");
|
|
c$hassh$smastc = join_string_vec(capabilities$mac_algorithms$server_to_client,",");
|
|
c$hassh$scastc = join_string_vec(capabilities$compression_algorithms$server_to_client,",");
|
|
c$hassh$sshka = join_string_vec(capabilities$server_host_key_algorithms,","); # The Host key algorithm set may be useful information by itself but is not included in the hasshServer.
|
|
#c$hassh$slstc = join_string_vec(capabilities$languages$server_to_client,","); # The Languages field may be useful information by itself but is not included in the hasshServer.
|
|
c$hassh$hasshServerAlgorithms = string_cat(c$hassh$skex,";",c$hassh$seastc,";",c$hassh$smastc,";",c$hassh$scastc); # Contatenate the four selected lists of algorithms (Key,Enc,Message,Compression) to build the Server hash
|
|
c$hassh$hasshServer = md5_hash(c$hassh$hasshServerAlgorithms);
|
|
}
|
|
|
|
# Event #
|
|
event ssh_capabilities(c: connection, cookie: string, capabilities: SSH::Capabilities) {
|
|
if ( !c?$ssh ) {return;}
|
|
c$hassh = HASSHStorage();
|
|
|
|
# Prior to 2.6.0 Zeek has a bug which it reverses the Client/server flag.
|
|
# See https://github.com/zeek/zeek/pull/191
|
|
# The "if" statements here do a version check to account for this bug in versions older than 2.6.0
|
|
|
|
if ((Version::info$version_number < 20600 && capabilities$is_server == T) || (Version::info$version_number >= 20600 && capabilities$is_server == F) ) {
|
|
get_hassh(c, capabilities);
|
|
c$ssh$hasshVersion = c$hassh$hasshVersion;
|
|
c$ssh$hassh = c$hassh$hassh;
|
|
|
|
# ===> Log Client variables <=== #
|
|
# Comment out any fields that are not required to be logged in their raw form to ssh.log
|
|
#c$ssh$ckex = c$hassh$ckex;
|
|
c$ssh$cshka = c$hassh$cshka;
|
|
#c$ssh$ceacts = c$hassh$ceacts;
|
|
#c$ssh$cmacts = c$hassh$cmacts;
|
|
#c$ssh$ccacts = c$hassh$ccacts;
|
|
#c$ssh$clcts = c$hassh$clcts;
|
|
c$ssh$hasshAlgorithms = c$hassh$hasshAlgorithms;
|
|
}
|
|
if ( (Version::info$version_number < 20600 && capabilities$is_server == F) || (Version::info$version_number >= 20600 && capabilities$is_server == T) ) {
|
|
get_hasshServer(c, capabilities);
|
|
c$ssh$hasshVersion = c$hassh$hasshVersion;
|
|
c$ssh$hasshServer = c$hassh$hasshServer;
|
|
|
|
# ===> Log Server variables <=== #
|
|
# Comment out any fields that are not required to be logged in their raw form to ssh.log
|
|
#c$ssh$skex = c$hassh$skex;
|
|
c$ssh$sshka = c$hassh$sshka;
|
|
#c$ssh$seastc = c$hassh$seastc;
|
|
#c$ssh$smastc = c$hassh$smastc;
|
|
#c$ssh$scastc = c$hassh$scastc;
|
|
#c$ssh$slstc = c$hassh$clcts;
|
|
c$ssh$hasshServerAlgorithms = c$hassh$hasshServerAlgorithms;
|
|
}
|
|
}
|