aboutsummaryrefslogtreecommitdiff
path: root/src/lib/protocols/ssh.c
diff options
context:
space:
mode:
authorLuca Deri <deri@ntop.org>2020-07-25 16:43:54 +0200
committerLuca Deri <deri@ntop.org>2020-07-25 16:43:54 +0200
commit1c405e382ac1e39aad661bb7e095865e98c036a8 (patch)
tree5f0a5ff748ef24a34efd5ba0f2339ee0a0b57038 /src/lib/protocols/ssh.c
parentb26539d65a22aea3c91af631b56ef90452aa14c2 (diff)
SSH code cleanup
Diffstat (limited to 'src/lib/protocols/ssh.c')
-rw-r--r--src/lib/protocols/ssh.c161
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);