Fixes protocol inconsistencies (#3069)

* Added code to address inconsistencies
* Added check for discarding dig errors
* Temporarily disabled whatsapp script: an update is required. See https://developers.facebook.com/docs/whatsapp/on-premises/sunset
This commit is contained in:
Luca Deri 2025-12-31 20:54:35 +01:00 committed by GitHub
parent bfbb6eb2df
commit 8aaff75ede
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 118 additions and 77 deletions

View file

@ -135,6 +135,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
assert(ndpi_set_config(workflow->ndpi_struct, NULL, "fully_encrypted_heuristic", "1") == NDPI_CFG_OK);
assert(ndpi_set_config(workflow->ndpi_struct, "dns", "subclassification", "1") == NDPI_CFG_OK);
assert(ndpi_set_config(workflow->ndpi_struct, "tls", "application_blocks_tracking", "1") == NDPI_CFG_OK);
assert(ndpi_set_config(workflow->ndpi_struct, "tls", "blocks_analysis", "1") == NDPI_CFG_OK);
assert(ndpi_set_config(workflow->ndpi_struct, "tls", "metadata.ja_data", "1") == NDPI_CFG_OK);
assert(ndpi_set_config(workflow->ndpi_struct, "ssh", "metadata.ssh_data", "1") == NDPI_CFG_OK);
#ifndef ENABLE_CONFIG2
assert(ndpi_set_config(workflow->ndpi_struct, "stun", "max_packets_extra_dissection", "40") == NDPI_CFG_OK);
assert(ndpi_set_config(workflow->ndpi_struct, "zoom", "max_packets_extra_dissection", "255") == NDPI_CFG_OK);

View file

@ -293,7 +293,7 @@ struct ndpi_detection_module_config_struct {
int tls_cert_validity_enabled;
int tls_cert_issuer_enabled;
int tls_cert_subject_enabled;
int tls_broswer_enabled;
int tls_browser_enabled;
int tls_ja3s_fingerprint_enabled;
int tls_ja4c_fingerprint_enabled;
int tls_ja4r_fingerprint_enabled;

View file

@ -1904,7 +1904,6 @@ struct ndpi_flow_struct {
u_int8_t num_plc_stop; /* PLC Stop (0x29) */
u_int8_t num_other_funcs; /* Other function codes */
} s7comm;
} protos;
struct {

View file

@ -146,7 +146,7 @@ static const struct cfg_param {
{ "tls", "metadata.cert_validity", "enable", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(tls_cert_validity_enabled), NULL },
{ "tls", "metadata.cert_issuer", "enable", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(tls_cert_issuer_enabled), NULL },
{ "tls", "metadata.cert_subject", "enable", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(tls_cert_subject_enabled), NULL },
{ "tls", "metadata.browser", "enable", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(tls_broswer_enabled), NULL },
{ "tls", "metadata.browser", "enable", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(tls_browser_enabled), NULL },
{ "tls", "metadata.ja3s_fingerprint", "enable", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(tls_ja3s_fingerprint_enabled), NULL },
{ "tls", "metadata.ja4c_fingerprint", "enable", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(tls_ja4c_fingerprint_enabled), NULL },
{ "tls", "metadata.ja4r_fingerprint", "disable", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(tls_ja4r_fingerprint_enabled), NULL },

View file

@ -7803,66 +7803,8 @@ static u_int8_t ndpi_detection_get_l4_internal(struct ndpi_detection_module_stru
/* ****************************************************** */
void ndpi_free_flow_data(struct ndpi_flow_struct* flow) {
void ndpi_free_flow_data_protos(struct ndpi_flow_struct* flow) {
if(flow) {
if(flow->num_risk_infos) {
u_int i;
for(i=0; i<flow->num_risk_infos; i++)
ndpi_free(flow->risk_infos[i].info);
}
if(flow->tcp.fingerprint)
ndpi_free(flow->tcp.fingerprint);
if(flow->tcp.fingerprint_raw)
ndpi_free(flow->tcp.fingerprint_raw);
if(flow->ndpi.fingerprint)
ndpi_free(flow->ndpi.fingerprint);
if(flow->http.url)
ndpi_free(flow->http.url);
if(flow->http.content_type)
ndpi_free(flow->http.content_type);
if(flow->http.request_content_type)
ndpi_free(flow->http.request_content_type);
if(flow->http.referer)
ndpi_free(flow->http.referer);
if(flow->http.host)
ndpi_free(flow->http.host);
if(flow->http.user_agent)
ndpi_free(flow->http.user_agent);
if(flow->http.nat_ip)
ndpi_free(flow->http.nat_ip);
if(flow->http.detected_os)
ndpi_free(flow->http.detected_os);
if(flow->http.server)
ndpi_free(flow->http.server);
if(flow->http.filename)
ndpi_free(flow->http.filename);
if(flow->http.username)
ndpi_free(flow->http.username);
if(flow->http.password)
ndpi_free(flow->http.password);
if(flow->kerberos_buf.pktbuf)
ndpi_free(flow->kerberos_buf.pktbuf);
if(flow->monit)
ndpi_free(flow->monit);
if(flow_is_proto(flow, NDPI_PROTOCOL_QUIC) ||
flow_is_proto(flow, NDPI_PROTOCOL_TLS) ||
flow_is_proto(flow, NDPI_PROTOCOL_DTLS) ||
@ -7977,7 +7919,73 @@ void ndpi_free_flow_data(struct ndpi_flow_struct* flow) {
if(flow->protos.ssdp.user_agent)
ndpi_free(flow->protos.ssdp.user_agent);
}
}
}
/* ****************************************************** */
void ndpi_free_flow_data(struct ndpi_flow_struct* flow) {
if(flow) {
if(flow->num_risk_infos) {
u_int i;
for(i=0; i<flow->num_risk_infos; i++)
ndpi_free(flow->risk_infos[i].info);
}
if(flow->tcp.fingerprint)
ndpi_free(flow->tcp.fingerprint);
if(flow->tcp.fingerprint_raw)
ndpi_free(flow->tcp.fingerprint_raw);
if(flow->ndpi.fingerprint)
ndpi_free(flow->ndpi.fingerprint);
if(flow->http.url)
ndpi_free(flow->http.url);
if(flow->http.content_type)
ndpi_free(flow->http.content_type);
if(flow->http.request_content_type)
ndpi_free(flow->http.request_content_type);
if(flow->http.referer)
ndpi_free(flow->http.referer);
if(flow->http.host)
ndpi_free(flow->http.host);
if(flow->http.user_agent)
ndpi_free(flow->http.user_agent);
if(flow->http.nat_ip)
ndpi_free(flow->http.nat_ip);
if(flow->http.detected_os)
ndpi_free(flow->http.detected_os);
if(flow->http.server)
ndpi_free(flow->http.server);
if(flow->http.filename)
ndpi_free(flow->http.filename);
if(flow->http.username)
ndpi_free(flow->http.username);
if(flow->http.password)
ndpi_free(flow->http.password);
if(flow->kerberos_buf.pktbuf)
ndpi_free(flow->kerberos_buf.pktbuf);
if(flow->monit)
ndpi_free(flow->monit);
ndpi_free_flow_data_protos(flow);
if(flow->tls_quic.message[0].buffer)
ndpi_free(flow->tls_quic.message[0].buffer);
if(flow->tls_quic.message[1].buffer)
@ -11280,6 +11288,26 @@ bool ndpi_stack_is_http_like(struct ndpi_proto_stack *s)
static void ndpi_int_change_flow_protocol(struct ndpi_flow_struct *flow,
u_int16_t upper_detected_protocol, u_int16_t lower_detected_protocol,
ndpi_confidence_t confidence) {
#ifdef TO_IMPLEMENT_A_BETTER_CHECK
if((flow->detected_protocol_stack[0] != upper_detected_protocol)
&& (flow->detected_protocol_stack[0] != NDPI_PROTOCOL_UNKNOWN)
&& (flow->detected_protocol_stack[0] != lower_detected_protocol)
&& (flow->detected_protocol_stack[1] != lower_detected_protocol)
) {
/*
When the protocol is totally different this can be an indication
that something went wrong so better start over and clanup things
as flow->protos is an union and this can lead to inconsistencies.
TODO
In the future we should handle protocol reconfiguration better
*/
ndpi_free_flow_data_protos(flow);
memset(&flow->protos, 0, sizeof(flow->protos));
}
#endif
flow->detected_protocol_stack[0] = upper_detected_protocol;
flow->detected_protocol_stack[1] = lower_detected_protocol;

View file

@ -38,10 +38,11 @@
/* ************************************** */
#ifdef HAVE_PLUGINS
/* Load a single protocol plugin */
static bool ndpi_load_protocol_plugin(struct ndpi_detection_module_struct *ndpi_struct,
char *plugin_path) {
#ifdef HAVE_PLUGINS
void *pluginEntryFctnPtr;
void *pluginPtr;
NDPIProtocolPluginEntryPoint* (*pluginEntryFctn)(void);
@ -94,15 +95,13 @@ static bool ndpi_load_protocol_plugin(struct ndpi_detection_module_struct *ndpi_
}
return(true);
#else
return(false);
#endif
}
#endif
/* ************************************** */
u_int ndpi_load_protocol_plugins(struct ndpi_detection_module_struct *ndpi_struct,
char *dir_path) {
char *dir_path) {
#ifdef HAVE_PLUGINS
DIR *dirp;
struct dirent *dp;

View file

@ -238,10 +238,13 @@ static u_int16_t concat_hash_string(struct ndpi_detection_module_struct *ndpi_st
if(ndpi_struct->cfg.ssh_hassh_data_enabled) {
buf[buf_out_len] = '\0';
if(client_hash)
flow->protos.ssh.client_key_exchange_algorithms = ndpi_strdup(buf);
else
flow->protos.ssh.server_key_exchange_algorithms = ndpi_strdup(buf);
if(client_hash) {
if(flow->protos.ssh.client_key_exchange_algorithms == NULL)
flow->protos.ssh.client_key_exchange_algorithms = ndpi_strdup(buf);
} else {
if(flow->protos.ssh.server_key_exchange_algorithms == NULL)
flow->protos.ssh.server_key_exchange_algorithms = ndpi_strdup(buf);
}
if(flow->protos.ssh.client_key_exchange_algorithms
&& flow->protos.ssh.server_key_exchange_algorithms) {

View file

@ -133,7 +133,7 @@ static int keep_extra_dissection_tcp(struct ndpi_detection_module_struct *ndpi_s
!ndpi_struct->cfg.tls_cert_validity_enabled &&
!ndpi_struct->cfg.tls_cert_issuer_enabled &&
!ndpi_struct->cfg.tls_cert_subject_enabled &&
!ndpi_struct->cfg.tls_broswer_enabled &&
!ndpi_struct->cfg.tls_browser_enabled &&
!ndpi_struct->cfg.tls_ja3s_fingerprint_enabled &&
/* No flow risks from SH or certificate: we should have disabled all
metadata needed for flow risks, so we should not need to explicitly
@ -2691,7 +2691,7 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct,
i += 2;
} /* for */
if(ndpi_struct->cfg.tls_broswer_enabled) {
if(ndpi_struct->cfg.tls_browser_enabled) {
/* NOTE:
we do not check for duplicates as with signatures because
this is time consuming and we want to avoid overhead whem possible
@ -2781,6 +2781,7 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct,
if(ja.client.num_tls_extensions < MAX_NUM_JA) {
if((extension_id == 0xFE0D /* ECHO */)
&& (flow->l4_proto == IPPROTO_TCP)
&& ndpi_struct->cfg.tls_blocks_analysis_enabled
&& (flow->l4.tcp.tls.num_tls_blocks > 0) /* It should always be like that */) {
/*
@ -2816,6 +2817,7 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct,
printf("[TLS] SNI: [%s]\n", sni);
#endif
if(sni /* It should always be like that */
&& (flow->l4_proto == IPPROTO_TCP)
&& ndpi_struct->cfg.tls_blocks_analysis_enabled
&& (flow->l4.tcp.tls.num_tls_blocks > 0) /* It should always be like that */
) {
@ -3002,7 +3004,7 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct,
if(rc < 0) break;
}
if(ndpi_struct->cfg.tls_broswer_enabled) {
if(ndpi_struct->cfg.tls_browser_enabled) {
int chrome_signature_algorithms = 0, duplicate_found = 0, last_signature = 0;
for(i=0; i<tot_signature_algorithms_len && s_offset + (int)i + 2 < packet->payload_packet_len; i+=2) {

View file

@ -19,11 +19,12 @@ http_response=$(curl -s -o $TMP -w "%{http_code}" ${ORIGIN})
check_http_response "${http_response}"
is_file_empty "${TMP}"
\rm -f ${LIST}
echo "(2) Processing domains..."
jq -r '.[] | .connectionName' $TMP > $LIST_DOMAINS
while read -r DOMAIN
do
dig +short "${DOMAIN}" A >> ${LIST}
dig +short "${DOMAIN}" A | grep -v '^;' >> ${LIST}
# dig +short "${DOMAIN}" AAAA >> ${LIST6}
done < "${LIST_DOMAINS}"

View file

@ -20,8 +20,14 @@ RETVAL=$(( RETVAL + $? ))
RETVAL=$(( RETVAL + $? ))
./tor_ip_addresses_download.sh
RETVAL=$(( RETVAL + $? ))
./whatsapp_ip_addresses_download.sh
RETVAL=$(( RETVAL + $? ))
#
# An update is required. See https://developers.facebook.com/docs/whatsapp/on-premises/sunset
#
#./whatsapp_ip_addresses_download.sh
#RETVAL=$(( RETVAL + $? ))
./zoom_ip_addresses_download.sh
RETVAL=$(( RETVAL + $? ))
./google_cloud_ip_addresses_download.sh