diff options
-rw-r--r-- | example/ndpiReader.c | 4 | ||||
-rw-r--r-- | python/flow_printer.py | 31 | ||||
-rw-r--r-- | src/include/ndpi_api.h.in | 75 | ||||
-rw-r--r-- | src/lib/ndpi_main.c | 119 | ||||
-rw-r--r-- | src/lib/ndpi_serializer.c | 62 | ||||
-rw-r--r-- | src/lib/protocols/dns.c | 2 | ||||
-rw-r--r-- | src/lib/protocols/http.c | 7 | ||||
-rw-r--r-- | src/lib/protocols/kerberos.c | 4 | ||||
-rw-r--r-- | src/lib/protocols/netbios.c | 2 | ||||
-rw-r--r-- | src/lib/protocols/quic.c | 23 | ||||
-rw-r--r-- | src/lib/protocols/teamspeak.c | 68 | ||||
-rw-r--r-- | src/lib/protocols/tls.c | 3 | ||||
-rw-r--r-- | src/lib/protocols/tor.c | 2 | ||||
-rw-r--r-- | tests/pcap/dns_long_domainname.pcap | bin | 0 -> 318 bytes | |||
-rw-r--r-- | tests/pcap/teamspeak3.pcap | bin | 0 -> 2143 bytes | |||
-rw-r--r-- | tests/result/dns_long_domainname.pcap.out | 3 | ||||
-rw-r--r-- | tests/result/teamspeak3.pcap.out | 3 |
17 files changed, 227 insertions, 181 deletions
diff --git a/example/ndpiReader.c b/example/ndpiReader.c index d128f11c6..e5609f3b0 100644 --- a/example/ndpiReader.c +++ b/example/ndpiReader.c @@ -3327,10 +3327,10 @@ static void dgaUnitTest() { assert(ndpi_str != NULL); for(i=0; dga[i] != NULL; i++) - assert(ndpi_check_dga_name(ndpi_str, NULL, (char*)dga[i]) == 1); + assert(ndpi_check_dga_name(ndpi_str, NULL, (char*)dga[i], 1) == 1); for(i=0; non_dga[i] != NULL; i++) - assert(ndpi_check_dga_name(ndpi_str, NULL, (char*)non_dga[i]) == 0); + assert(ndpi_check_dga_name(ndpi_str, NULL, (char*)non_dga[i], 1) == 0); ndpi_exit_detection_module(ndpi_str); } diff --git a/python/flow_printer.py b/python/flow_printer.py index 0b533a898..5579694fa 100644 --- a/python/flow_printer.py +++ b/python/flow_printer.py @@ -2,27 +2,26 @@ # -*- coding: utf-8 -*- """ -file: flow_printer.py -This file is part of nfstream. - -Copyright (C) 2019-20 - Zied Aouini <aouinizied@gmail.com> - -nfstream is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License -as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - -nfstream is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty -of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with nfstream. +------------------------------------------------------------------------------------------------------------------------ +flow_printer.py +Copyright (C) 2019-20 - NFStream Developers +This file is part of NFStream, a Flexible Network Data Analysis Framework (https://www.nfstream.org/). +NFStream is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later +version. +NFStream is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty +of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +You should have received a copy of the GNU Lesser General Public License along with NFStream. If not, see <http://www.gnu.org/licenses/>. +------------------------------------------------------------------------------------------------------------------------ """ from nfstream import NFStreamer import sys - +# Example must run with nfstream >= 6.1.1 path = sys.argv[1] -flow_streamer = NFStreamer(source=path, statistics=True) +flow_streamer = NFStreamer(source=path, statistical_analysis=False, performance_report=1) result = {} try: for flow in flow_streamer: @@ -31,9 +30,9 @@ try: result[flow.application_name] += flow.bidirectional_packets except KeyError: result[flow.application_name] = flow.bidirectional_packets - print("Summary (Application Name: Packets):") + print("\nSummary (Application Name: Packets):") print(result) except KeyboardInterrupt: - print("Summary (Application Name: Packets):") + print("\nSummary (Application Name: Packets):") print(result) print("Terminated.") diff --git a/src/include/ndpi_api.h.in b/src/include/ndpi_api.h.in index 25c16a56d..ecc276eab 100644 --- a/src/include/ndpi_api.h.in +++ b/src/include/ndpi_api.h.in @@ -945,7 +945,7 @@ extern "C" { /* DGA */ int ndpi_check_dga_name(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow, - char *name); + char *name, u_int8_t is_hostname); /* Serializer */ int ndpi_init_serializer_ll(ndpi_serializer *serializer, ndpi_serialization_format fmt, @@ -954,54 +954,35 @@ extern "C" { void ndpi_term_serializer(ndpi_serializer *serializer); void ndpi_reset_serializer(ndpi_serializer *serializer); - int ndpi_serialize_uint32_uint32(ndpi_serializer *serializer, - u_int32_t key, u_int32_t value); - int ndpi_serialize_uint32_uint64(ndpi_serializer *serializer, - u_int32_t key, u_int64_t value); - int ndpi_serialize_uint32_int32(ndpi_serializer *serializer, - u_int32_t key, int32_t value); - int ndpi_serialize_uint32_int64(ndpi_serializer *serializer, - u_int32_t key, int64_t value); - int ndpi_serialize_uint32_float(ndpi_serializer *serializer, - u_int32_t key, float value, - const char *format /* e.f. "%.2f" */); - int ndpi_serialize_uint32_string(ndpi_serializer *serializer, - u_int32_t key, const char *value); - int ndpi_serialize_uint32_boolean(ndpi_serializer *serializer, - u_int32_t key, u_int8_t value); - - int ndpi_serialize_string_int32(ndpi_serializer *serializer, - const char *key, int32_t value); - int ndpi_serialize_string_int64(ndpi_serializer *serializer, - const char *key, int64_t value); - int ndpi_serialize_string_uint32(ndpi_serializer *serializer, - const char *key, u_int32_t value); - int ndpi_serialize_string_uint32_format(ndpi_serializer *serializer, - const char *key, u_int32_t value, - const char *format); - int ndpi_serialize_string_uint64(ndpi_serializer *serializer, - const char *key, u_int64_t value); - int ndpi_serialize_string_string(ndpi_serializer *serializer, - const char *key, const char *value); - int ndpi_serialize_string_binary(ndpi_serializer *serializer, - const char *key, const char *_value, - u_int16_t vlen); - int ndpi_serialize_string_raw(ndpi_serializer *_serializer, - const char *key, const char *_value, - u_int16_t vlen); - int ndpi_serialize_string_float(ndpi_serializer *serializer, - const char *key, float value, - const char *format /* e.f. "%.2f" */); - int ndpi_serialize_string_boolean(ndpi_serializer *serializer, - const char *key, u_int8_t value); - int ndpi_serialize_raw_record(ndpi_serializer *_serializer, - u_char *record, u_int32_t record_len); + int ndpi_serialize_uint32_uint32(ndpi_serializer *serializer, u_int32_t key, u_int32_t value); + int ndpi_serialize_uint32_uint64(ndpi_serializer *serializer, u_int32_t key, u_int64_t value); + int ndpi_serialize_uint32_int32(ndpi_serializer *serializer, u_int32_t key, int32_t value); + int ndpi_serialize_uint32_int64(ndpi_serializer *serializer, u_int32_t key, int64_t value); + int ndpi_serialize_uint32_float(ndpi_serializer *serializer, u_int32_t key, float value, const char *format /* e.f. "%.2f" */); + int ndpi_serialize_uint32_string(ndpi_serializer *serializer, u_int32_t key, const char *value); + int ndpi_serialize_uint32_boolean(ndpi_serializer *serializer, u_int32_t key, u_int8_t value); + int ndpi_serialize_binary_int32(ndpi_serializer *_serializer, const char *key, u_int16_t klen, int32_t value); + int ndpi_serialize_string_int32(ndpi_serializer *serializer, const char *key, int32_t value); + int ndpi_serialize_binary_int64(ndpi_serializer *_serializer, const char *key, u_int16_t klen, int64_t value); + int ndpi_serialize_string_int64(ndpi_serializer *serializer, const char *key, int64_t value); + int ndpi_serialize_binary_uint32(ndpi_serializer *_serializer, const char *key, u_int16_t klen, u_int32_t value); + int ndpi_serialize_string_uint32(ndpi_serializer *serializer, const char *key, u_int32_t value); + int ndpi_serialize_string_uint32_format(ndpi_serializer *serializer, const char *key, u_int32_t value, const char *format); + int ndpi_serialize_binary_uint64(ndpi_serializer *_serializer, const char *key, u_int16_t klen, u_int64_t value); + int ndpi_serialize_string_uint64(ndpi_serializer *serializer, const char *key, u_int64_t value); + int ndpi_serialize_binary_binary(ndpi_serializer *_serializer, const char *key, u_int16_t klen, const char *_value, u_int16_t vlen); + int ndpi_serialize_string_string(ndpi_serializer *serializer, const char *key, const char *value); + int ndpi_serialize_string_binary(ndpi_serializer *serializer, const char *key, const char *_value, u_int16_t vlen); + int ndpi_serialize_string_raw(ndpi_serializer *_serializer, const char *key, const char *_value, u_int16_t vlen); + int ndpi_serialize_binary_float(ndpi_serializer *_serializer, const char *key, u_int16_t klen, float value, const char *format /* e.f. "%.2f" */); + int ndpi_serialize_string_float(ndpi_serializer *serializer, const char *key, float value, const char *format /* e.f. "%.2f" */); + int ndpi_serialize_string_boolean(ndpi_serializer *serializer, const char *key, u_int8_t value); + int ndpi_serialize_raw_record(ndpi_serializer *_serializer, u_char *record, u_int32_t record_len); int ndpi_serialize_end_of_record(ndpi_serializer *serializer); - int ndpi_serialize_start_of_list(ndpi_serializer *serializer, - const char *key); + int ndpi_serialize_start_of_list(ndpi_serializer *serializer, const char *key); int ndpi_serialize_end_of_list(ndpi_serializer *serializer); - int ndpi_serialize_start_of_block(ndpi_serializer *serializer, - const char *key); + int ndpi_serialize_start_of_block_binary(ndpi_serializer *_serializer, const char *key, u_int16_t klen); + int ndpi_serialize_start_of_block(ndpi_serializer *serializer, const char *key); int ndpi_serialize_end_of_block(ndpi_serializer *serializer); char* ndpi_serializer_get_buffer(ndpi_serializer *serializer, u_int32_t *buffer_len); u_int32_t ndpi_serializer_get_buffer_len(ndpi_serializer *serializer); diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index 564f8978d..c74b4ec17 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -6663,67 +6663,99 @@ static int enough(int a, int b) { /* ******************************************************************** */ +static u_int8_t endsWith(char *str, char *ends, u_int8_t ends_len) { + u_int str_len = str ? strlen(str) : 0; + u_int8_t rc; + + if(str_len < ends_len) return(0); + + rc = (strncmp(&str[str_len-ends_len], ends, ends_len) != 0) ? 0 : 1; + +#ifdef DGA_DEBUG + printf("[DGA] %s / %s [rc: %u]\n", str, ends, rc); +#endif + + return(rc); +} + +/* ******************************************************************** */ + int ndpi_check_dga_name(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow, - char *name) { + char *name, u_int8_t is_hostname) { int len, rc = 0; - u_int8_t max_num_char_repetitions = 0, last_char = 0, num_char_repetitions = 0; - u_int8_t max_domain_element_len = 0, curr_domain_element_len = 0; + u_int8_t max_num_char_repetitions = 0, last_char = 0, num_char_repetitions = 0, num_dots = 0; + u_int8_t max_domain_element_len = 0, curr_domain_element_len = 0, first_element_is_numeric = 1; + + if(!name) return(0); +#ifdef DGA_DEBUG + printf("[DGA] %s\n", name); +#endif + len = strlen(name); if(len >= 5) { int i, j, num_found = 0, num_impossible = 0, num_bigram_checks = 0, num_digits = 0, num_vowels = 0, num_words = 0; char tmp[128], *word, *tok_tmp; - - len = snprintf(tmp, sizeof(tmp)-1, "%s", name); + u_int max_tmp_len = sizeof(tmp)-1; + + len = snprintf(tmp, max_tmp_len, "%s", name); if(len < 0) { #ifdef DGA_DEBUG printf("[DGA] Too short"); #endif return(0); - } - - for(i=0, j=0; (i<len) && (j<(sizeof(tmp)-1)); i++) { - tmp[j] = tolower(name[i]); + } else + tmp[len < max_tmp_len ? len : max_tmp_len] = '\0'; - if(last_char == tmp[j]) { - if(++num_char_repetitions > max_num_char_repetitions) - max_num_char_repetitions = num_char_repetitions; - } else - num_char_repetitions = 1, last_char = tmp[j]; + for(i=0, j=0; (i<len) && (j<max_tmp_len); i++) { + tmp[j] = tolower(name[i]); - switch(tmp[j]) { - case '.': - case '-': - case '_': - case '/': - case ')': - case '(': - case ';': - case ':': - case '[': - case ']': - case ' ': - /* - Domain/word separator chars + if(tmp[j] == '.') + num_dots++; + else if(num_dots == 0) { + if(!isdigit(tmp[j])) + first_element_is_numeric = 0; + } + + if(last_char == tmp[j]) { + if(++num_char_repetitions > max_num_char_repetitions) + max_num_char_repetitions = num_char_repetitions; + } else + num_char_repetitions = 1, last_char = tmp[j]; + + switch(tmp[j]) { + case '.': + case '-': + case '_': + case '/': + case ')': + case '(': + case ';': + case ':': + case '[': + case ']': + case ' ': + /* + Domain/word separator chars - NOTE: - this function is used also to detect other type of issues - such as invalid/suspiciuous user agent - */ - if(curr_domain_element_len > max_domain_element_len) - max_domain_element_len = curr_domain_element_len; + NOTE: + this function is used also to detect other type of issues + such as invalid/suspiciuous user agent + */ + if(curr_domain_element_len > max_domain_element_len) + max_domain_element_len = curr_domain_element_len; - curr_domain_element_len = 0; + curr_domain_element_len = 0; break; - default: - curr_domain_element_len++; - break; - } + default: + curr_domain_element_len++; + break; + } - j++; + j++; } if(curr_domain_element_len > max_domain_element_len) @@ -6735,7 +6767,12 @@ int ndpi_check_dga_name(struct ndpi_detection_module_struct *ndpi_str, #endif if( - (max_num_char_repetitions > 5 /* num or consecutive repeated chars */) + (is_hostname + && (num_dots > 5) + && (!first_element_is_numeric) + && (!endsWith(tmp, "in-addr.arpa", 12)) + ) + || (max_num_char_repetitions > 5 /* num or consecutive repeated chars */) /* In case of a name with too many consecutive chars an alert is triggered This is the case for instance of the wildcard DNS query used by NetBIOS diff --git a/src/lib/ndpi_serializer.c b/src/lib/ndpi_serializer.c index c1f52f89e..a5f14fbe4 100644 --- a/src/lib/ndpi_serializer.c +++ b/src/lib/ndpi_serializer.c @@ -130,6 +130,32 @@ static int ndpi_json_string_escape(const char *src, int src_len, char *dst, int /* ********************************** */ +#if UNUSED +/* + * Similar to snprintf, this returns the number of bytes actually written + * in any case (unlike snprintf which returns, if the output is truncated, + * the number of bytes which *would have been* written, and a negative + * value on failures) + */ +static inline int ndpi_snappend(char *buf, size_t size, const char *fmt, ...) { + int wlen; + va_list va; + + va_start(va, fmt); + wlen = snprintf(buf, size, fmt, va); + va_end(va); + + if (wlen < 0) + wlen = 0; + else if (wlen >= size) + wlen = size-1; + + return wlen; +} +#endif + +/* ********************************** */ + void ndpi_reset_serializer(ndpi_serializer *_serializer) { ndpi_private_serializer *serializer = (ndpi_private_serializer*)_serializer; @@ -1138,9 +1164,9 @@ int ndpi_serialize_uint32_boolean(ndpi_serializer *_serializer, /* ********************************** */ -static int ndpi_serialize_binary_int32(ndpi_serializer *_serializer, - const char *key, u_int16_t klen, - int32_t value) { +int ndpi_serialize_binary_int32(ndpi_serializer *_serializer, + const char *key, u_int16_t klen, + int32_t value) { ndpi_private_serializer *serializer = (ndpi_private_serializer*)_serializer; u_int32_t buff_diff = serializer->buffer.size - serializer->status.buffer.size_used; u_int32_t needed; @@ -1288,8 +1314,8 @@ int ndpi_serialize_string_int64(ndpi_serializer *_serializer, /* ********************************** */ -static int ndpi_serialize_binary_uint32(ndpi_serializer *_serializer, - const char *key, u_int16_t klen, u_int32_t value) { +int ndpi_serialize_binary_uint32(ndpi_serializer *_serializer, + const char *key, u_int16_t klen, u_int32_t value) { ndpi_private_serializer *serializer = (ndpi_private_serializer*)_serializer; u_int32_t buff_diff = serializer->buffer.size - serializer->status.buffer.size_used; u_int32_t needed; @@ -1389,9 +1415,9 @@ int ndpi_serialize_string_uint32_format(ndpi_serializer *_serializer, /* ********************************** */ -static int ndpi_serialize_binary_uint64(ndpi_serializer *_serializer, - const char *key, u_int16_t klen, - u_int64_t value) { +int ndpi_serialize_binary_uint64(ndpi_serializer *_serializer, + const char *key, u_int16_t klen, + u_int64_t value) { ndpi_private_serializer *serializer = (ndpi_private_serializer*)_serializer; u_int32_t buff_diff = serializer->buffer.size - serializer->status.buffer.size_used; u_int32_t needed; @@ -1462,11 +1488,11 @@ int ndpi_serialize_string_uint64(ndpi_serializer *_serializer, /* ********************************** */ -static int ndpi_serialize_binary_float(ndpi_serializer *_serializer, - const char *key, - u_int16_t klen, - float value, - const char *format /* e.f. "%.2f" */) { +int ndpi_serialize_binary_float(ndpi_serializer *_serializer, + const char *key, + u_int16_t klen, + float value, + const char *format /* e.f. "%.2f" */) { ndpi_private_serializer *serializer = (ndpi_private_serializer*)_serializer; u_int32_t buff_diff = serializer->buffer.size - serializer->status.buffer.size_used; u_int32_t needed; @@ -1597,11 +1623,11 @@ static int ndpi_serialize_binary_raw(ndpi_serializer *_serializer, /* ********************************** */ /* Key is a <string, len> pair, value is a <string, len> pair */ -static int ndpi_serialize_binary_binary(ndpi_serializer *_serializer, - const char *key, - u_int16_t klen, - const char *_value, - u_int16_t vlen) { +int ndpi_serialize_binary_binary(ndpi_serializer *_serializer, + const char *key, + u_int16_t klen, + const char *_value, + u_int16_t vlen) { const char *value = _value ? _value : ""; if(ndpi_is_number(key, klen)) diff --git a/src/lib/protocols/dns.c b/src/lib/protocols/dns.c index 5e6d01d69..03ac7b9d2 100644 --- a/src/lib/protocols/dns.c +++ b/src/lib/protocols/dns.c @@ -301,7 +301,7 @@ static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, st if(j > 0) { ndpi_protocol_match_result ret_match; - ndpi_check_dga_name(ndpi_struct, flow, (char*)flow->host_server_name); + ndpi_check_dga_name(ndpi_struct, flow, (char*)flow->host_server_name, 1); ret.app_protocol = ndpi_match_host_subprotocol(ndpi_struct, flow, (char *)flow->host_server_name, diff --git a/src/lib/protocols/http.c b/src/lib/protocols/http.c index 000faacdd..983a53b1c 100644 --- a/src/lib/protocols/http.c +++ b/src/lib/protocols/http.c @@ -263,15 +263,12 @@ static void ndpi_check_user_agent(struct ndpi_detection_module_struct *ndpi_stru char *ua) { if((!ua) || (ua[0] == '\0')) return; - // printf("***** [%s:%d] ==> '%s'\n", __FILE__, __LINE__, ua); - // printf("***** %u\n", ndpi_check_dga_name(ndpi_struct, NULL, "uclient-fetch]")); - if((strlen(ua) < 4) || (!strncmp(ua, "test", 4)) || (!strncmp(ua, "<?", 2)) || strchr(ua, '{') || strchr(ua, '}') - || ndpi_check_dga_name(ndpi_struct, NULL, ua) + || ndpi_check_dga_name(ndpi_struct, NULL, ua, 0) // || ndpi_match_bigram(ndpi_struct, &ndpi_struct->impossible_bigrams_automa, ua) ) { NDPI_SET_BIT(flow->risk, NDPI_HTTP_SUSPICIOUS_USER_AGENT); @@ -449,7 +446,7 @@ static void check_content_type_and_change_protocol(struct ndpi_detection_module_ flow->host_server_name[len] = '\0'; flow->extra_packets_func = NULL; /* We're good now */ - if(len > 0) ndpi_check_dga_name(ndpi_struct, flow, (char*)flow->host_server_name); + if(len > 0) ndpi_check_dga_name(ndpi_struct, flow, (char*)flow->host_server_name, 1); flow->server_id = flow->dst; if(packet->forwarded_line.ptr) { diff --git a/src/lib/protocols/kerberos.c b/src/lib/protocols/kerberos.c index 10c2b5a65..fa0ab6cb6 100644 --- a/src/lib/protocols/kerberos.c +++ b/src/lib/protocols/kerberos.c @@ -252,7 +252,9 @@ void ndpi_search_kerberos(struct ndpi_detection_module_struct *ndpi_struct, realm_offset = cname_len + name_offset + 3; /* if cname does not end with a $ then it's a username */ - if(cname_len && cname_str[cname_len-1] == '$') { + if(cname_len + && (cname_len < sizeof(cname_str)) + && (cname_str[cname_len-1] == '$')) { cname_str[cname_len-1] = '\0'; snprintf(flow->protos.kerberos.hostname, sizeof(flow->protos.kerberos.hostname), "%s", cname_str); } else diff --git a/src/lib/protocols/netbios.c b/src/lib/protocols/netbios.c index 6ca691c7e..1f3850cbd 100644 --- a/src/lib/protocols/netbios.c +++ b/src/lib/protocols/netbios.c @@ -85,7 +85,7 @@ static void ndpi_int_netbios_add_connection(struct ndpi_detection_module_struct flow->packet.payload_packet_len - off, name, sizeof(name)) > 0) { snprintf((char*)flow->host_server_name, sizeof(flow->host_server_name)-1, "%s", name); - ndpi_check_dga_name(ndpi_struct, flow, (char*)flow->host_server_name); + ndpi_check_dga_name(ndpi_struct, flow, (char*)flow->host_server_name, 1); } if(sub_protocol == NDPI_PROTOCOL_UNKNOWN) diff --git a/src/lib/protocols/quic.c b/src/lib/protocols/quic.c index f58c030f5..2a4c7294b 100644 --- a/src/lib/protocols/quic.c +++ b/src/lib/protocols/quic.c @@ -926,7 +926,9 @@ static const uint8_t *get_crypto_data(struct ndpi_detection_module_struct *ndpi_ if(counter + 2 + offset_len + 2 /*gquic_get_u16 reads 2 bytes */ > clear_payload_len) return NULL; if(clear_payload[counter + 1] != 0x01) { +#ifdef QUIC_DEBUG NDPI_LOG_ERR(ndpi_struct, "Unexpected stream ID version 0x%x\n", version); +#endif return NULL; } counter += 2 + offset_len; @@ -959,7 +961,9 @@ static const uint8_t *get_crypto_data(struct ndpi_detection_module_struct *ndpi_ if(first_nonzero_payload_byte != 0x06) { if(first_nonzero_payload_byte != 0x02 && first_nonzero_payload_byte != 0x1C) { +#ifdef QUIC_DEBUG NDPI_LOG_ERR(ndpi_struct, "Unexpected frame 0x%x\n", first_nonzero_payload_byte); +#endif } else { NDPI_LOG_DBG(ndpi_struct, "Unexpected ACK/CC frame\n"); } @@ -968,8 +972,10 @@ static const uint8_t *get_crypto_data(struct ndpi_detection_module_struct *ndpi_ if(counter + 2 + 8 >= clear_payload_len) /* quic_len reads 8 bytes, at most */ return NULL; if(clear_payload[counter + 1] != 0x00) { +#ifdef QUIC_DEBUG NDPI_LOG_ERR(ndpi_struct, "Unexpected crypto stream offset 0x%x\n", clear_payload[counter + 1]); +#endif return NULL; } counter += 2; @@ -978,8 +984,10 @@ static const uint8_t *get_crypto_data(struct ndpi_detection_module_struct *ndpi_ } if(*crypto_data_len + counter > clear_payload_len) { +#ifdef QUIC_DEBUG NDPI_LOG_ERR(ndpi_struct, "Invalid length %lu + %d > %d version 0x%x\n", (unsigned long)*crypto_data_len, counter, clear_payload_len, version); +#endif return NULL; } return crypto_data; @@ -1078,7 +1086,9 @@ static void process_chlo(struct ndpi_detection_module_struct *ndpi_struct, if(crypto_data_len < 6) return; if(memcmp(crypto_data, "CHLO", 4) != 0) { +#ifdef QUIC_DEBUG NDPI_LOG_ERR(ndpi_struct, "Unexpected handshake message"); +#endif return; } num_tags = (*(uint16_t *)&crypto_data[4]); @@ -1174,13 +1184,16 @@ static int may_be_initial_pkt(struct ndpi_detection_module_struct *ndpi_struct, if(is_gquic_ver_less_than(*version, 43) && (!pub_bit5 || pub_bit3 != 0 || pub_bit4 != 0)) { - NDPI_LOG_ERR(ndpi_struct, "Version 0x%x invalid flags 0x%x\n", - *version, first_byte); +#ifdef QUIC_DEBUG + NDPI_LOG_ERR(ndpi_struct, "Version 0x%x invalid flags 0x%x\n", *version, first_byte); +#endif return 0; } if((*version == V_Q046) && (pub_bit7 != 1 || pub_bit8 != 1)) { +#ifdef QUIC_DEBUG NDPI_LOG_ERR(ndpi_struct, "Q46 invalid flag 0x%x\n", first_byte); +#endif return 0; } if((is_version_quic(*version) || (*version == V_Q046) || (*version == V_Q050)) && @@ -1238,8 +1251,10 @@ void ndpi_search_quic(struct ndpi_detection_module_struct *ndpi_struct, */ if(!is_version_supported(version)) { - NDPI_LOG_ERR(ndpi_struct, "Unsupported version 0x%x\n", version) - NDPI_EXCLUDE_PROTO(ndpi_struct, flow); +#ifdef QUIC_DEBUG + NDPI_LOG_ERR(ndpi_struct, "Unsupported version 0x%x\n", version); +#endif + NDPI_EXCLUDE_PROTO(ndpi_struct, flow); return; } diff --git a/src/lib/protocols/teamspeak.c b/src/lib/protocols/teamspeak.c index 0fb538e36..a2a1002ff 100644 --- a/src/lib/protocols/teamspeak.c +++ b/src/lib/protocols/teamspeak.c @@ -24,7 +24,7 @@ #include "ndpi_api.h" static void ndpi_int_teamspeak_add_connection(struct ndpi_detection_module_struct - *ndpi_struct, struct ndpi_flow_struct *flow) + *ndpi_struct, struct ndpi_flow_struct *flow) { ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TEAMSPEAK, NDPI_PROTOCOL_UNKNOWN); } @@ -36,56 +36,38 @@ void ndpi_search_teamspeak(struct ndpi_detection_module_struct *ndpi_struct, str NDPI_LOG_DBG(ndpi_struct, "search teamspeak\n"); - -#ifdef WEAK_DETECTION_CODE_DISABLED - if(packet->udp != NULL) { - u_int16_t udport, usport; - - usport = ntohs(packet->udp->source), udport = ntohs(packet->udp->dest); - - /* http://www.imfirewall.com/en/protocols/teamSpeak.htm */ - if(((usport == 9987 || udport == 9987) || (usport == 8767 || udport == 8767)) && packet->payload_packet_len >= 20) { - NDPI_LOG_INFO(ndpi_struct, "found TEAMSPEAK udp\n"); - ndpi_int_teamspeak_add_connection(ndpi_struct, flow); - } - } - else -#endif - - if(packet->tcp != NULL) { -#if WEAK_DETECTION_CODE_DISABLED - u_int16_t tdport, tsport; - tsport = ntohs(packet->tcp->source), tdport = ntohs(packet->tcp->dest); -#endif - /* https://github.com/Youx/soliloque-server/wiki/Connection-packet */ - if(packet->payload_packet_len >= 20) { - if(((memcmp(packet->payload, "\xf4\xbe\x03\x00", 4) == 0)) || - ((memcmp(packet->payload, "\xf4\xbe\x02\x00", 4) == 0)) || - ((memcmp(packet->payload, "\xf4\xbe\x01\x00", 4) == 0))) { - NDPI_LOG_INFO(ndpi_struct, "found TEAMSPEAK tcp\n"); - ndpi_int_teamspeak_add_connection(ndpi_struct, flow); - } /* http://www.imfirewall.com/en/protocols/teamSpeak.htm */ + if (packet->payload_packet_len >= 20) { + if (packet->udp != NULL) { + if (memcmp(packet->payload, "TS3INIT1", strlen("TS3INIT1")) == 0) + { + NDPI_LOG_INFO(ndpi_struct, "found TEAMSPEAK udp\n"); + ndpi_int_teamspeak_add_connection(ndpi_struct, flow); } -#if WEAK_DETECTION_CODE_DISABLED - else if((tsport == 14534 || tdport == 14534) || (tsport == 51234 || tdport == 51234)) { - NDPI_LOG_INFO(ndpi_struct, "found TEAMSPEAK\n"); - ndpi_int_teamspeak_add_connection(ndpi_struct, flow); - } -#endif + } else if(packet->tcp != NULL) { + /* https://github.com/Youx/soliloque-server/wiki/Connection-packet */ + if(((memcmp(packet->payload, "\xf4\xbe\x03\x00", 4) == 0)) || + ((memcmp(packet->payload, "\xf4\xbe\x02\x00", 4) == 0)) || + ((memcmp(packet->payload, "\xf4\xbe\x01\x00", 4) == 0))) + { + NDPI_LOG_INFO(ndpi_struct, "found TEAMSPEAK tcp\n"); + ndpi_int_teamspeak_add_connection(ndpi_struct, flow); + } /* http://www.imfirewall.com/en/protocols/teamSpeak.htm */ } - + } + NDPI_EXCLUDE_PROTO(ndpi_struct, flow); return; } -void init_teamspeak_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) +void init_teamspeak_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, + NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("TeamSpeak", ndpi_struct, detection_bitmask, *id, - NDPI_PROTOCOL_TEAMSPEAK, - ndpi_search_teamspeak, - NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD, - SAVE_DETECTION_BITMASK_AS_UNKNOWN, - ADD_TO_DETECTION_BITMASK); + NDPI_PROTOCOL_TEAMSPEAK, + ndpi_search_teamspeak, + NDPI_SELECTION_BITMASK_PROTOCOL_TCP_OR_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); *id += 1; } diff --git a/src/lib/protocols/tls.c b/src/lib/protocols/tls.c index 0545d4972..134dfe614 100644 --- a/src/lib/protocols/tls.c +++ b/src/lib/protocols/tls.c @@ -1169,7 +1169,8 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct, flow->l4.tcp.tls.subprotocol_detected = 1; } - ndpi_check_dga_name(ndpi_struct, flow, flow->protos.stun_ssl.ssl.client_requested_server_name); + ndpi_check_dga_name(ndpi_struct, flow, + flow->protos.stun_ssl.ssl.client_requested_server_name, 1); } else { #ifdef DEBUG_TLS printf("[TLS] Extensions server len too short: %u vs %u\n", diff --git a/src/lib/protocols/tor.c b/src/lib/protocols/tor.c index 7318685e7..71172e211 100644 --- a/src/lib/protocols/tor.c +++ b/src/lib/protocols/tor.c @@ -48,7 +48,7 @@ int ndpi_is_tls_tor(struct ndpi_detection_module_struct *ndpi_struct, if((dot = strrchr(dummy, '.')) == NULL) return(0); name = &dot[1]; - if(ndpi_check_dga_name(ndpi_struct, flow, name)) { + if(ndpi_check_dga_name(ndpi_struct, flow, name, 1)) { ndpi_int_tor_add_connection(ndpi_struct, flow); return(1); } else { diff --git a/tests/pcap/dns_long_domainname.pcap b/tests/pcap/dns_long_domainname.pcap Binary files differnew file mode 100644 index 000000000..3f7b0f145 --- /dev/null +++ b/tests/pcap/dns_long_domainname.pcap diff --git a/tests/pcap/teamspeak3.pcap b/tests/pcap/teamspeak3.pcap Binary files differnew file mode 100644 index 000000000..31f06b82f --- /dev/null +++ b/tests/pcap/teamspeak3.pcap diff --git a/tests/result/dns_long_domainname.pcap.out b/tests/result/dns_long_domainname.pcap.out new file mode 100644 index 000000000..fd2e5950f --- /dev/null +++ b/tests/result/dns_long_domainname.pcap.out @@ -0,0 +1,3 @@ +Google 2 262 1 + + 1 UDP 192.168.1.168:65311 <-> 8.8.8.8:53 [proto: 5.126/DNS.Google][cat: Web/5][1 pkts/103 bytes <-> 1 pkts/159 bytes][Goodput ratio: 59/73][0.02 sec][Host: gmr02c.16.0.fhkfhsdkfhsk.tunnel.example.com][::][Risk: ** Suspicious DGA domain name **][PLAIN TEXT (fhkfhsdkfhsk)][Plen Bins: 0,50,0,50,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] diff --git a/tests/result/teamspeak3.pcap.out b/tests/result/teamspeak3.pcap.out new file mode 100644 index 000000000..ccde63e59 --- /dev/null +++ b/tests/result/teamspeak3.pcap.out @@ -0,0 +1,3 @@ +TeamSpeak 13 1911 1 + + 1 UDP 10.0.0.1:53187 -> 10.0.0.2:9987 [proto: 162/TeamSpeak][cat: VoIP/10][13 pkts/1911 bytes -> 0 pkts/0 bytes][Goodput ratio: 71/0][37.01 sec][bytes ratio: 1.000 (Upload)][IAT c2s/s2c min/avg/max/stddev: 0/0 387/0 1301/0 449/0][Pkt Len c2s/s2c min/avg/max/stddev: 76/0 147/0 230/0 77/0][PLAIN TEXT (DDDDDDffffff)][Plen Bins: 0,53,0,0,0,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] |