aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuca Deri <lucaderi@users.noreply.github.com>2020-07-25 16:17:24 +0200
committerGitHub <noreply@github.com>2020-07-25 16:17:24 +0200
commitb26539d65a22aea3c91af631b56ef90452aa14c2 (patch)
tree093cf4b60c27d7956d45c6d2f4d3ac4958cdb75f
parent21e2e576146be8f4451d703c3e54a8208c4e4701 (diff)
parent6719fa30f9cfda5fe9d60b84e7afb442a9ea3517 (diff)
Merge pull request #967 from MrRadix/dev
Ssh signature checking
-rw-r--r--python/ndpi.py2
-rw-r--r--src/lib/ndpi_utils.c4
-rw-r--r--src/lib/protocols/ssh.c134
3 files changed, 116 insertions, 24 deletions
diff --git a/python/ndpi.py b/python/ndpi.py
index 31abe53dc..547570b9d 100644
--- a/python/ndpi.py
+++ b/python/ndpi.py
@@ -306,6 +306,8 @@ typedef enum {
NDPI_TLS_NOT_CARRYING_HTTPS,
NDPI_SUSPICIOUS_DGA_DOMAIN,
NDPI_MALFORMED_PACKET,
+ NDPI_SSH_OBSOLETE_CLIENT_VERSION_OR_CIPHER,
+ NDPI_SSH_OBSOLETE_SERVER_VERSION_OR_CIPHER,
/* Leave this as last member */
NDPI_MAX_RISK
} ndpi_risk_enum;
diff --git a/src/lib/ndpi_utils.c b/src/lib/ndpi_utils.c
index ac2c7173c..1d33500ff 100644
--- a/src/lib/ndpi_utils.c
+++ b/src/lib/ndpi_utils.c
@@ -1525,10 +1525,10 @@ const char* ndpi_risk2str(ndpi_risk_enum risk) {
return("Malformed packet");
case NDPI_SSH_OBSOLETE_CLIENT_VERSION_OR_CIPHER:
- return("SSH obsolete client version/cipher");
+ return("SSH Obsolete client version/cipher");
case NDPI_SSH_OBSOLETE_SERVER_VERSION_OR_CIPHER:
- return("SSH obsolete server version/cipher");
+ return("SSH Obsolete server version/cipher");
default:
snprintf(buf, sizeof(buf), "%d", (int)risk);
diff --git a/src/lib/protocols/ssh.c b/src/lib/protocols/ssh.c
index 5aca9b350..f1f0e1503 100644
--- a/src/lib/protocols/ssh.c
+++ b/src/lib/protocols/ssh.c
@@ -25,10 +25,15 @@
#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"
+#include <string.h>
+
/*
HASSH - https://github.com/salesforce/hassh
@@ -57,43 +62,128 @@
/* #define SSH_DEBUG 1 */
static void ndpi_search_ssh_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow);
-
+
/* ************************************************************************ */
-static void ssh_analyse_signature_version(struct ndpi_detection_module_struct *ndpi_struct,
+static void ssh_analyze_signature_version(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow,
char *str_to_check,
u_int8_t is_client_signature) {
+ if (str_to_check == NULL) return;
- /*
- if(obsolete_ssh_version)
- NDPI_SET_BIT(flow->risk, is_client_signature ? NDPI_SSH_OBSOLETE_CLIENT_SIGNATURE : NDPI_SSH_OBSOLETE_SERVER_SIGNATURE);
- */
+ 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;
+
+ 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);
+
+ if (matches == 3 || matches == 2) {
+ version_match = 1;
+ 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));
+ }
}
/* ************************************************************************ */
static void ssh_analyse_cipher(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow,
- char *cipher, u_int cipher_len,
+ char *ciphers, u_int cipher_len,
u_int8_t is_client_signature) {
- /*
- List of obsolete ciphers can be found at
- https://www.linuxminion.com/deprecated-ssh-cryptographic-settings/
- */
-#ifdef SSH_DEBUG
- u_int i;
-
- printf("[%s] ", is_client_signature ? "CLIENT" : "SERVER");
- for(i=0; i<cipher_len; i++)
- printf("%c", cipher[i]);
+ char *rem;
+ char *cipher;
+ u_int8_t found_obsolete_cipher = 0;
+
+ const char *obsolete_ciphers[] = {
+ "arcfour256",
+ "arcfour128",
+ "3des-cbc",
+ "blowfish-cbc",
+ "cast128-cbc",
+ "arcfour",
+ NULL,
+ };
+
+ char *copy = (char*)ndpi_calloc(cipher_len, sizeof(char));
+ if (copy == NULL) {
+ return;
+ }
- printf("\n");
-#endif
+ if (strncpy(copy, ciphers, cipher_len) == NULL)
+ return;
+
+ cipher = strtok_r(copy, ",", &rem);
+
+ while (cipher && !found_obsolete_cipher) {
+
+ for (int i = 0; obsolete_ciphers[i]; i++) {
+ if (strcmp(cipher, obsolete_ciphers[i]) == 0) {
+ found_obsolete_cipher = 1;
+ break;
+ }
+ }
+
+ cipher = strtok_r(NULL, ",", &rem);
+ }
+
+ if (found_obsolete_cipher) {
+ #ifdef SSH_DEBUG
+ printf("[SSH] [SSH obsolete cipher]\n");
+ #endif
+
+ 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);
}
-
+
/* ************************************************************************ */
static int search_ssh_again(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
@@ -328,7 +418,7 @@ static void ndpi_search_ssh_tcp(struct ndpi_detection_module_struct *ndpi_struct
flow->protos.ssh.client_signature[len] = '\0';
ndpi_ssh_zap_cr(flow->protos.ssh.client_signature, len);
- ssh_analyse_signature_version(ndpi_struct, flow, flow->protos.ssh.client_signature, 1);
+ ssh_analyze_signature_version(ndpi_struct, flow, flow->protos.ssh.client_signature, 1);
#ifdef SSH_DEBUG
printf("[SSH] [client_signature: %s]\n", flow->protos.ssh.client_signature);
@@ -348,7 +438,7 @@ static void ndpi_search_ssh_tcp(struct ndpi_detection_module_struct *ndpi_struct
flow->protos.ssh.server_signature[len] = '\0';
ndpi_ssh_zap_cr(flow->protos.ssh.server_signature, len);
- ssh_analyse_signature_version(ndpi_struct, flow, flow->protos.ssh.server_signature, 0);
+ ssh_analyze_signature_version(ndpi_struct, flow, flow->protos.ssh.server_signature, 0);
#ifdef SSH_DEBUG
printf("[SSH] [server_signature: %s]\n", flow->protos.ssh.server_signature);