diff options
author | Luca Deri <deri@ntop.org> | 2020-07-25 16:43:54 +0200 |
---|---|---|
committer | Luca Deri <deri@ntop.org> | 2020-07-25 16:43:54 +0200 |
commit | 1c405e382ac1e39aad661bb7e095865e98c036a8 (patch) | |
tree | 5f0a5ff748ef24a34efd5ba0f2339ee0a0b57038 /src/lib/protocols/ssh.c | |
parent | b26539d65a22aea3c91af631b56ef90452aa14c2 (diff) |
SSH code cleanup
Diffstat (limited to 'src/lib/protocols/ssh.c')
-rw-r--r-- | src/lib/protocols/ssh.c | 161 |
1 files changed, 79 insertions, 82 deletions
diff --git a/src/lib/protocols/ssh.c b/src/lib/protocols/ssh.c index f1f0e1503..853ec1952 100644 --- a/src/lib/protocols/ssh.c +++ b/src/lib/protocols/ssh.c @@ -1,8 +1,8 @@ /* * ssh.c * - * Copyright (C) 2009-2011 by ipoque GmbH * Copyright (C) 2011-20 - ntop.org + * Copyright (C) 2009-2011 by ipoque GmbH * * This file is part of nDPI, an open source deep packet inspection * library based on the OpenDPI and PACE technology by ipoque GmbH @@ -25,9 +25,6 @@ #include "ndpi_protocol_ids.h" #define NDPI_CURRENT_PROTO NDPI_PROTOCOL_SSH -#define MAJOR_CUTOFF 7 -#define MINOR_CUTOFF 0 -#define PATCH_CUTOFF 0 #include "ndpi_api.h" #include "ndpi_md5.h" @@ -59,10 +56,15 @@ that usually is packet 14 */ -/* #define SSH_DEBUG 1 */ +// #define SSH_DEBUG 1 static void ndpi_search_ssh_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +typedef struct { + const char *signature; + u_int16_t major, minor, patch; +} ssh_pattern; + /* ************************************************************************ */ static void ssh_analyze_signature_version(struct ndpi_detection_module_struct *ndpi_struct, @@ -70,64 +72,51 @@ static void ssh_analyze_signature_version(struct ndpi_detection_module_struct *n char *str_to_check, u_int8_t is_client_signature) { - if (str_to_check == NULL) return; - - int i; - int matches; - int major = 0; - int minor = 0; - int patch = 0; - u_int8_t version_match = 0; - u_int8_t obsolete_ssh_version = 0; + if(str_to_check == NULL) return; - const char *ssh_servers_strings[] = { - "SSH-%*f-OpenSSH_%d.%d.%d", /* OpenSSH */ - "SSH-%*f-APACHE-SSHD-%d.%d.%d", /* Apache MINA SSHD */ - "SSH-%*f-FileZilla_%d.%d.%d", /* FileZilla SSH*/ - "SSH-%*f-paramiko_%d.%d.%d", /* Paramiko SSH */ - "SSH-%*f-dropbear_%d.%d", /* Dropbear SSH */ - NULL, - }; - - int versions_cutoff[][3] = { - /* maj,min,patch */ - - {7,0,0}, /* OpenSSH */ - {2,5,1}, /* Apache MINA SSHD */ - {3,40,0}, /* FileZilla SSH */ - {2,4,0}, /* Paramiko SSH */ - {2020,0,0} /* Dropbear SSH (leave patch field as 0)*/ - - }; - - for (i = 0; ssh_servers_strings[i]; i++) { - matches = sscanf(str_to_check, ssh_servers_strings[i], &major, &minor, &patch); + u_int i; + u_int8_t obsolete_ssh_version = 0; + const ssh_pattern ssh_servers_strings[] = + { + { (const char*)"SSH-%*f-OpenSSH_%d.%d.%d", 7, 0, 0 }, /* OpenSSH */ + { (const char*)"SSH-%*f-APACHE-SSHD-%d.%d.%d", 2, 5, 1 }, /* Apache MINA SSHD */ + { (const char*)"SSH-%*f-FileZilla_%d.%d.%d", 3, 40, 0 }, /* FileZilla SSH*/ + { (const char*)"SSH-%*f-paramiko_%d.%d.%d", 2, 4, 0 }, /* Paramiko SSH */ + { (const char*)"SSH-%*f-dropbear_%d.%d", 2020, 0, 0 }, /* Dropbear SSH */ + { NULL, 0, 0, 0 } + }; + + for(i = 0; ssh_servers_strings[i].signature != NULL; i++) { + int matches; + int major = 0; + int minor = 0; + int patch = 0; + matches = sscanf(str_to_check, ssh_servers_strings[i].signature, &major, &minor, &patch); + + if(matches == 3 || matches == 2) { + /* checking if is an old version */ + if(major < ssh_servers_strings[i].major) + obsolete_ssh_version = 1; + else if(major == ssh_servers_strings[i].major) { + if(minor < ssh_servers_strings[i].minor) + obsolete_ssh_version = 1; + else if(minor == ssh_servers_strings[i].minor) + if(patch < ssh_servers_strings[i].patch) + obsolete_ssh_version = 1; + } - if (matches == 3 || matches == 2) { - version_match = 1; +#ifdef SSH_DEBUG + printf("[SSH] [SSH Version: %d.%d.%d]\n", major, minor, patch); +#endif + break; } } - - if (!version_match) return; - - /* checking if is an old version */ - if (major < versions_cutoff[i][0]) obsolete_ssh_version = 1; - - else if (major == versions_cutoff[i][0]) { - if (minor < versions_cutoff[i][1]) obsolete_ssh_version = 1; - - else if (minor == versions_cutoff[i][1]) - if (patch < versions_cutoff[i][2]) obsolete_ssh_version = 1; - } - if (obsolete_ssh_version) { - #ifdef SSH_DEBUG - printf("[SSH] [SSH Version: %d.%d.%d]\n", major, minor, patch); - #endif - - NDPI_SET_BIT(flow->risk, (is_client_signature ? NDPI_SSH_OBSOLETE_CLIENT_VERSION_OR_CIPHER : NDPI_SSH_OBSOLETE_SERVER_VERSION_OR_CIPHER)); - } + if(obsolete_ssh_version) + NDPI_SET_BIT(flow->risk, + is_client_signature ? NDPI_SSH_OBSOLETE_CLIENT_VERSION_OR_CIPHER : + NDPI_SSH_OBSOLETE_SERVER_VERSION_OR_CIPHER); } /* ************************************************************************ */ @@ -140,32 +129,44 @@ static void ssh_analyse_cipher(struct ndpi_detection_module_struct *ndpi_struct, char *rem; char *cipher; u_int8_t found_obsolete_cipher = 0; - + char *cipher_copy; + /* + List of obsolete ciphers can be found at + https://www.linuxminion.com/deprecated-ssh-cryptographic-settings/ + */ const char *obsolete_ciphers[] = { - "arcfour256", - "arcfour128", - "3des-cbc", - "blowfish-cbc", - "cast128-cbc", - "arcfour", - NULL, + "arcfour256", + "arcfour128", + "3des-cbc", + "blowfish-cbc", + "cast128-cbc", + "arcfour", + NULL, }; - char *copy = (char*)ndpi_calloc(cipher_len, sizeof(char)); - if (copy == NULL) { + if((cipher_copy = (char*)ndpi_malloc(cipher_len+1)) == NULL) { +#ifdef SSH_DEBUG + printf("[SSH] Nout enough memory\n"); +#endif return; } - if (strncpy(copy, ciphers, cipher_len) == NULL) - return; - - cipher = strtok_r(copy, ",", &rem); + strncpy(cipher_copy, ciphers, cipher_len); + cipher_copy[cipher_len] = '\0'; - while (cipher && !found_obsolete_cipher) { + cipher = strtok_r(cipher_copy, ",", &rem); - for (int i = 0; obsolete_ciphers[i]; i++) { - if (strcmp(cipher, obsolete_ciphers[i]) == 0) { + while(cipher && !found_obsolete_cipher) { + u_int i; + + for(i = 0; obsolete_ciphers[i]; i++) { + if(strcmp(cipher, obsolete_ciphers[i]) == 0) { found_obsolete_cipher = 1; +#ifdef SSH_DEBUG + printf("[SSH] [SSH obsolete %s cipher][%s]\n", + is_client_signature ? "client" : "server", + obsolete_ciphers[i]); +#endif break; } } @@ -173,15 +174,11 @@ static void ssh_analyse_cipher(struct ndpi_detection_module_struct *ndpi_struct, cipher = strtok_r(NULL, ",", &rem); } - if (found_obsolete_cipher) { - #ifdef SSH_DEBUG - printf("[SSH] [SSH obsolete cipher]\n"); - #endif - + if(found_obsolete_cipher) { NDPI_SET_BIT(flow->risk, (is_client_signature ? NDPI_SSH_OBSOLETE_CLIENT_VERSION_OR_CIPHER : NDPI_SSH_OBSOLETE_SERVER_VERSION_OR_CIPHER)); } - ndpi_free(copy); + ndpi_free(cipher_copy); } /* ************************************************************************ */ @@ -411,7 +408,7 @@ static void ndpi_search_ssh_tcp(struct ndpi_detection_module_struct *ndpi_struct if(flow->l4.tcp.ssh_stage == 0) { if(packet->payload_packet_len > 7 && packet->payload_packet_len < 100 - && memcmp(packet->payload, "SSH-", 4) == 0) { + && memcmp(packet->payload, "SSH-", 4) == 0) { int len = ndpi_min(sizeof(flow->protos.ssh.client_signature)-1, packet->payload_packet_len); strncpy(flow->protos.ssh.client_signature, (const char *)packet->payload, len); @@ -431,7 +428,7 @@ static void ndpi_search_ssh_tcp(struct ndpi_detection_module_struct *ndpi_struct } } else if(flow->l4.tcp.ssh_stage == (2 - packet->packet_direction)) { if(packet->payload_packet_len > 7 && packet->payload_packet_len < 500 - && memcmp(packet->payload, "SSH-", 4) == 0) { + && memcmp(packet->payload, "SSH-", 4) == 0) { int len = ndpi_min(sizeof(flow->protos.ssh.server_signature)-1, packet->payload_packet_len); strncpy(flow->protos.ssh.server_signature, (const char *)packet->payload, len); |