From b1b59b9ee71644e368ce755af5453917df867339 Mon Sep 17 00:00:00 2001 From: Nardi Ivan Date: Wed, 21 Jun 2023 09:17:28 +0200 Subject: [PATCH] fuzz: extend fuzzing coverage Some notes: * libinjection: according to https://github.com/libinjection/libinjection/issues/44, it seems NULL characters are valid in the input string; * RTP: `rtp_get_stream_type()` is called only for RTP packets; if you want to tell RTP from RTCP you should use `is_rtp_or_rtcp()`; * TLS: unnecessary check; we already make the same check just above, at the beginning of the `while` loop --- .gitignore | 1 + fuzz/Makefile.am | 17 ++++- fuzz/fuzz_alg_hw_rsi_outliers_da.cpp | 10 ++- fuzz/fuzz_config.cpp | 31 ++++++++- fuzz/fuzz_ds_ahocorasick.cpp | 2 + fuzz/fuzz_ds_hash.cpp | 63 ++++++++++++++++++ fuzz/fuzz_ds_patricia.cpp | 4 +- fuzz/fuzz_libinjection.c | 26 ++------ fuzz/fuzz_ndpi_reader.c | 5 ++ src/lib/ndpi_main.c | 27 +++++--- src/lib/ndpi_utils.c | 7 -- src/lib/protocols/rtp.c | 11 +-- src/lib/protocols/tls.c | 4 +- src/lib/third_party/src/libinjection_xss.c | 4 ++ tests/cfgs/default/pcap/quic_cc_ack.pcapng | Bin 0 -> 2960 bytes tests/cfgs/default/pcap/stun_classic.pcap | Bin 0 -> 2000 bytes .../default/result/quic_cc_ack.pcapng.out | 26 ++++++++ .../cfgs/default/result/stun_classic.pcap.out | 25 +++++++ 18 files changed, 208 insertions(+), 55 deletions(-) create mode 100644 fuzz/fuzz_ds_hash.cpp create mode 100644 tests/cfgs/default/pcap/quic_cc_ack.pcapng create mode 100644 tests/cfgs/default/pcap/stun_classic.pcap create mode 100644 tests/cfgs/default/result/quic_cc_ack.pcapng.out create mode 100644 tests/cfgs/default/result/stun_classic.pcap.out diff --git a/.gitignore b/.gitignore index b38f12103a3..c4ec132ff01 100644 --- a/.gitignore +++ b/.gitignore @@ -68,6 +68,7 @@ /fuzz/fuzz_ds_libcache /fuzz/fuzz_ds_tree /fuzz/fuzz_ds_ptree +/fuzz/fuzz_ds_hash /fuzz/fuzz_ds_ahocorasick /fuzz/fuzz_libinjection /fuzz/fuzz_tls_certificate diff --git a/fuzz/Makefile.am b/fuzz/Makefile.am index 45efdbb3f61..535e76bfcab 100644 --- a/fuzz/Makefile.am +++ b/fuzz/Makefile.am @@ -2,7 +2,7 @@ bin_PROGRAMS = fuzz_process_packet fuzz_ndpi_reader fuzz_ndpi_reader_alloc_fail #Alghoritms bin_PROGRAMS += fuzz_alg_bins fuzz_alg_hll fuzz_alg_hw_rsi_outliers_da fuzz_alg_jitter fuzz_alg_ses_des fuzz_alg_crc32_md5 fuzz_alg_bytestream #Data structures -bin_PROGRAMS += fuzz_ds_patricia fuzz_ds_ahocorasick fuzz_ds_libcache fuzz_ds_tree fuzz_ds_ptree +bin_PROGRAMS += fuzz_ds_patricia fuzz_ds_ahocorasick fuzz_ds_libcache fuzz_ds_tree fuzz_ds_ptree fuzz_ds_hash #Third party bin_PROGRAMS += fuzz_libinjection #Internal crypto @@ -294,6 +294,21 @@ fuzz_ds_ptree_LINK=$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXX) @NDPI_CFLAGS@ $(AM_CXXFLAGS) $(CXXFLAGS) \ $(fuzz_ds_ptree_LDFLAGS) @NDPI_LDFLAGS@ $(LDFLAGS) -o $@ +fuzz_ds_hash_SOURCES = fuzz_ds_hash.cpp fuzz_common_code.c +fuzz_ds_hash_CXXFLAGS = @NDPI_CFLAGS@ $(CXXFLAGS) -DENABLE_MEM_ALLOC_FAILURES +fuzz_ds_hash_CFLAGS = @NDPI_CFLAGS@ $(CXXFLAGS) +fuzz_ds_hash_LDADD = ../src/lib/libndpi.a $(ADDITIONAL_LIBS) +fuzz_ds_hash_LDFLAGS = $(LIBS) +if HAS_FUZZLDFLAGS +fuzz_ds_hash_CXXFLAGS += $(LIB_FUZZING_ENGINE) +fuzz_ds_hash_CFLAGS += $(LIB_FUZZING_ENGINE) +fuzz_ds_hash_LDFLAGS += $(LIB_FUZZING_ENGINE) +endif +# force usage of CXX for linker +fuzz_ds_hash_LINK=$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXX) @NDPI_CFLAGS@ $(AM_CXXFLAGS) $(CXXFLAGS) \ + $(fuzz_ds_hash_LDFLAGS) @NDPI_LDFLAGS@ $(LDFLAGS) -o $@ + fuzz_libinjection_SOURCES = fuzz_libinjection.c fuzz_libinjection_CFLAGS = @NDPI_CFLAGS@ $(CXXFLAGS) fuzz_libinjection_LDADD = ../src/lib/libndpi.a $(ADDITIONAL_LIBS) diff --git a/fuzz/fuzz_alg_hw_rsi_outliers_da.cpp b/fuzz/fuzz_alg_hw_rsi_outliers_da.cpp index 3ea9551e49e..6e4f2af1751 100644 --- a/fuzz/fuzz_alg_hw_rsi_outliers_da.cpp +++ b/fuzz/fuzz_alg_hw_rsi_outliers_da.cpp @@ -16,10 +16,12 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { u_int8_t additive_seeasonal; double alpha, beta, gamma, forecast, confidence_band; float significance; - u_int32_t *values; + u_int32_t *values, predict_periods; + u_int32_t prediction; bool *outliers; - /* Use the same (integral) dataset to peform: RSI, Data analysis, HW and outliers */ + /* Use the same (integral) dataset to peform: RSI, Data analysis, HW, outliers + and linear regression */ /* Just to have some data */ if(fuzzed_data.remaining_bytes() < 1024) @@ -57,6 +59,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { max_series_len = fuzzed_data.ConsumeIntegral(); a = ndpi_alloc_data_analysis(max_series_len); + /* Init Linear Regression */ + predict_periods = fuzzed_data.ConsumeIntegral(); + /* Calculate! */ for (i = 0; i < num_values; i++) { if (rc_hw == 0) @@ -66,6 +71,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { ndpi_data_add_value(a, values[i]); } ndpi_find_outliers(values, outliers, num_values); + ndpi_predict_linear(values, num_values, predict_periods, &prediction); /* Data analysis stuff */ ndpi_data_average(a); diff --git a/fuzz/fuzz_config.cpp b/fuzz/fuzz_config.cpp index 822c2861230..2eb933f1345 100644 --- a/fuzz/fuzz_config.cpp +++ b/fuzz/fuzz_config.cpp @@ -35,7 +35,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { 6 + /* files */ ((NDPI_LRUCACHE_MAX + 1) * 5) + /* LRU caches */ 2 + 1 + 4 + /* ndpi_set_detection_preferences() */ - 1 + 3 + 1 + /* Monitoring */ + 1 + 3 + 1 + 3 + /* Monitoring */ 7 + /* Opportunistic tls */ 2 + /* Pid */ 2 + /* Category */ @@ -50,6 +50,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { ndpi_info_mod = ndpi_init_detection_module(fuzzed_data.ConsumeIntegral()); + set_ndpi_debug_function(ndpi_info_mod, NULL); + NDPI_BITMASK_RESET(enabled_bitmask); for(i = 0; i < NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS ; i++) { if(fuzzed_data.ConsumeBool()) @@ -60,6 +62,10 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { ndpi_info_mod = NULL; } + ndpi_set_user_data(ndpi_info_mod, (void *)0xabcdabcd); /* Random pointer */ + ndpi_set_user_data(ndpi_info_mod, (void *)0xabcdabcd); /* Twice to trigger overwriting */ + ndpi_get_user_data(ndpi_info_mod); + ndpi_set_tls_cert_expire_days(ndpi_info_mod, fuzzed_data.ConsumeIntegral()); if(fuzzed_data.ConsumeBool()) @@ -99,6 +105,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { ndpi_set_detection_preferences(ndpi_info_mod, ndpi_pref_max_packets_to_process, fuzzed_data.ConsumeIntegralInRange(0, (1 << 16))); + ndpi_set_detection_preferences(ndpi_info_mod, static_cast(0xFF), 0xFF); /* Invalid preference */ + if(fuzzed_data.ConsumeBool()) { ndpi_set_monitoring_state(ndpi_info_mod, NDPI_PROTOCOL_STUN, fuzzed_data.ConsumeIntegralInRange(0, (1 << 16)), @@ -106,6 +114,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { ndpi_get_monitoring_state(ndpi_info_mod, NDPI_PROTOCOL_STUN, &num, &num2); } + random_proto = fuzzed_data.ConsumeIntegralInRange(0, (1 << 16) - 1); + random_value = fuzzed_data.ConsumeIntegralInRange(0,2); + ndpi_set_monitoring_state(ndpi_info_mod, random_proto, random_value, random_value); + ndpi_get_monitoring_state(ndpi_info_mod, random_proto, &num, &num2); + ndpi_set_opportunistic_tls(ndpi_info_mod, NDPI_PROTOCOL_MAIL_SMTP, fuzzed_data.ConsumeBool()); ndpi_get_opportunistic_tls(ndpi_info_mod, NDPI_PROTOCOL_MAIL_SMTP); ndpi_set_opportunistic_tls(ndpi_info_mod, NDPI_PROTOCOL_MAIL_IMAP, fuzzed_data.ConsumeBool()); @@ -128,17 +141,24 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { ndpi_finalize_initialization(ndpi_info_mod); /* Random protocol configuration */ - pid = fuzzed_data.ConsumeIntegralInRange(0, ndpi_get_num_supported_protocols(ndpi_info_mod) + 1); + pid = fuzzed_data.ConsumeIntegralInRange(0, NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS + 1); /* + 1 to trigger invalid pid */ protoname = ndpi_get_proto_by_id(ndpi_info_mod, pid); if (protoname) { assert(ndpi_get_proto_by_name(ndpi_info_mod, protoname) == pid); } + ndpi_map_user_proto_id_to_ndpi_id(ndpi_info_mod, pid); + ndpi_map_ndpi_id_to_user_proto_id(ndpi_info_mod, pid); ndpi_set_proto_breed(ndpi_info_mod, pid, NDPI_PROTOCOL_SAFE); ndpi_set_proto_category(ndpi_info_mod, pid, NDPI_PROTOCOL_CATEGORY_MEDIA); + ndpi_is_subprotocol_informative(ndpi_info_mod, pid); + ndpi_get_proto_breed(ndpi_info_mod, pid); + + ndpi_get_proto_by_name(ndpi_info_mod, NULL); /* Error */ + ndpi_get_proto_by_name(ndpi_info_mod, "foo"); /* Invalid protocol */ /* Custom category configuration */ cat = fuzzed_data.ConsumeIntegralInRange(static_cast(NDPI_PROTOCOL_CATEGORY_CUSTOM_1), - static_cast(NDPI_PROTOCOL_CATEGORY_CUSTOM_5 + 1)); /* + 1 to trigger invalid cat */ + static_cast(NDPI_PROTOCOL_NUM_CATEGORIES + 1)); /* + 1 to trigger invalid cat */ ndpi_category_set_name(ndpi_info_mod, static_cast(cat), catname); ndpi_is_custom_category(static_cast(cat)); ndpi_category_get_name(ndpi_info_mod, static_cast(cat)); @@ -190,6 +210,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { ndpi_find_ipv4_category_userdata(ndpi_info_mod, flow.c_address.v4); ndpi_search_tcp_or_udp_raw(ndpi_info_mod, NULL, 0, ntohl(flow.c_address.v4), ntohl(flow.s_address.v4)); + + ndpi_guess_undetected_protocol_v4(ndpi_info_mod, bool_value ? &flow : NULL, + flow.l4_proto, + flow.c_address.v4, flow.c_port, + flow.s_address.v4, flow.s_port); } /* Another "strange" function: fuzz it here, for lack of a better alternative */ ndpi_search_tcp_or_udp(ndpi_info_mod, &flow); diff --git a/fuzz/fuzz_ds_ahocorasick.cpp b/fuzz/fuzz_ds_ahocorasick.cpp index e02744e52a9..f7aebd7beff 100644 --- a/fuzz/fuzz_ds_ahocorasick.cpp +++ b/fuzz/fuzz_ds_ahocorasick.cpp @@ -41,6 +41,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { else mc = NULL; + ac_automata_enable_debug(0); + a = ac_automata_init(mc); a2 = ndpi_init_automa(); diff --git a/fuzz/fuzz_ds_hash.cpp b/fuzz/fuzz_ds_hash.cpp new file mode 100644 index 00000000000..5b26d684b08 --- /dev/null +++ b/fuzz/fuzz_ds_hash.cpp @@ -0,0 +1,63 @@ +#include "ndpi_api.h" +#include "fuzz_common_code.h" + +#include +#include +#include +#include "fuzzer/FuzzedDataProvider.h" + +extern "C" void cleanup_func(ndpi_str_hash *h) { + /* Nothing to do */ + return; +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + FuzzedDataProvider fuzzed_data(data, size); + u_int16_t i, rc, num_iteration, data_len, is_added = 0; + std::vectorvalue_added; + void *value; + ndpi_str_hash *h = NULL; + + /* Just to have some data */ + if (fuzzed_data.remaining_bytes() < 1024) + return -1; + + /* To allow memory allocation failures */ + fuzz_set_alloc_callbacks_and_seed(size); + + if (fuzzed_data.ConsumeBool()) + ndpi_hash_init(&h); + else + ndpi_hash_init(NULL); + + num_iteration = fuzzed_data.ConsumeIntegral(); + for (i = 0; i < num_iteration; i++) { + + data_len = fuzzed_data.ConsumeIntegralInRange(0, 127); + std::vectordata = fuzzed_data.ConsumeBytes(data_len); + + rc = ndpi_hash_add_entry(&h, data.data(), data.size(), &i); + /* Keep one random entry really added */ + if (rc == 0 && fuzzed_data.ConsumeBool()) { + value_added = data; + is_added = 1; + } + } + + /* "Random" search */ + num_iteration = fuzzed_data.ConsumeIntegral(); + for (i = 0; i < num_iteration; i++) { + data_len = fuzzed_data.ConsumeIntegralInRange(0, 127); + std::vectordata = fuzzed_data.ConsumeBytes(data_len); + + ndpi_hash_find_entry(h, data.data(), data.size(), &value); + } + /* Search of an added entry */ + if (is_added) { + ndpi_hash_find_entry(h, value_added.data(), value_added.size(), &value); + } + + ndpi_hash_free(&h, cleanup_func); + + return 0; +} diff --git a/fuzz/fuzz_ds_patricia.cpp b/fuzz/fuzz_ds_patricia.cpp index e6ec360100f..58e098b45dc 100644 --- a/fuzz/fuzz_ds_patricia.cpp +++ b/fuzz/fuzz_ds_patricia.cpp @@ -51,7 +51,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { if(fuzzed_data.remaining_bytes() > 4) { std::vectordata = fuzzed_data.ConsumeBytes(4); ip = data.data(); - ip_len = fuzzed_data.ConsumeIntegralInRange(0, 32); + ip_len = fuzzed_data.ConsumeIntegralInRange(0, 33); /* 33 to force error */ ndpi_fill_prefix_v4(&prefix, (struct in_addr *)ip, ip_len, 32); node = ndpi_patricia_lookup(p, &prefix); /* Keep one random node really added */ @@ -71,7 +71,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { if(fuzzed_data.remaining_bytes() > 16) { std::vectordata = fuzzed_data.ConsumeBytes(16); ip = data.data(); - ip_len = fuzzed_data.ConsumeIntegralInRange(0, 128); + ip_len = fuzzed_data.ConsumeIntegralInRange(0, 129); /* 129 to force error */ ndpi_fill_prefix_v6(&prefix, (const struct in6_addr *)ip, ip_len, 128); node = ndpi_patricia_lookup(p, &prefix); /* Keep one random node really added */ diff --git a/fuzz/fuzz_libinjection.c b/fuzz/fuzz_libinjection.c index f614a62e12f..b1d897d2300 100644 --- a/fuzz/fuzz_libinjection.c +++ b/fuzz/fuzz_libinjection.c @@ -4,36 +4,24 @@ #include "../src/lib/third_party/include/libinjection_sqli.h" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - char *query; struct libinjection_sqli_state state; /* No memory allocations involved */ - /* Libinjection: it wants null-terminated string */ - - query = malloc(size + 1); - if (!query) - return 0; - memcpy(query, data, size); - query[size] = '\0'; - - - libinjection_sqli_init(&state, query, strlen(query), 0); /* Default: FLAG_QUOTE_NONE | FLAG_SQL_ANSI */ + libinjection_sqli_init(&state, (char *)data, size, 0); /* Default: FLAG_QUOTE_NONE | FLAG_SQL_ANSI */ libinjection_is_sqli(&state); - libinjection_sqli_init(&state, query, strlen(query), FLAG_QUOTE_SINGLE | FLAG_SQL_ANSI); + libinjection_sqli_init(&state, (char *)data, size, FLAG_QUOTE_SINGLE | FLAG_SQL_ANSI); libinjection_is_sqli(&state); - libinjection_sqli_init(&state, query, strlen(query), FLAG_QUOTE_DOUBLE | FLAG_SQL_ANSI); + libinjection_sqli_init(&state, (char *)data, size, FLAG_QUOTE_DOUBLE | FLAG_SQL_ANSI); libinjection_is_sqli(&state); - libinjection_sqli_init(&state, query, strlen(query), FLAG_QUOTE_NONE | FLAG_SQL_MYSQL); + libinjection_sqli_init(&state, (char *)data, size, FLAG_QUOTE_NONE | FLAG_SQL_MYSQL); libinjection_is_sqli(&state); - libinjection_sqli_init(&state, query, strlen(query), FLAG_QUOTE_SINGLE | FLAG_SQL_MYSQL); + libinjection_sqli_init(&state, (char *)data, size, FLAG_QUOTE_SINGLE | FLAG_SQL_MYSQL); libinjection_is_sqli(&state); - libinjection_sqli_init(&state, query, strlen(query), FLAG_QUOTE_DOUBLE | FLAG_SQL_MYSQL); + libinjection_sqli_init(&state, (char *)data, size, FLAG_QUOTE_DOUBLE | FLAG_SQL_MYSQL); libinjection_is_sqli(&state); - libinjection_xss(query, strlen(query)); - - free(query); + libinjection_xss((char *)data, size); libinjection_version(); diff --git a/fuzz/fuzz_ndpi_reader.c b/fuzz/fuzz_ndpi_reader.c index a91becccc3c..f29506b362e 100644 --- a/fuzz/fuzz_ndpi_reader.c +++ b/fuzz/fuzz_ndpi_reader.c @@ -82,6 +82,11 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { ndpi_load_malicious_ja3_file(workflow->ndpi_struct, "ja3_fingerprints.csv"); ndpi_load_malicious_sha1_file(workflow->ndpi_struct, "sha1_fingerprints.csv"); + ndpi_set_detection_preferences(workflow->ndpi_struct, ndpi_pref_enable_tls_block_dissection, 0 /* unused */); + + ndpi_set_monitoring_state(workflow->ndpi_struct, NDPI_PROTOCOL_STUN, + 10, NDPI_MONITORING_STUN_SUBCLASSIFIED); + memset(workflow->stats.protocol_counter, 0, sizeof(workflow->stats.protocol_counter)); memset(workflow->stats.protocol_counter_bytes, 0, diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index 839e8a3341b..1d2d728d475 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -334,6 +334,9 @@ u_int16_t ndpi_map_user_proto_id_to_ndpi_id(struct ndpi_detection_module_struct #endif #endif + if(!ndpi_str) + return(0); + if(user_proto_id < NDPI_MAX_SUPPORTED_PROTOCOLS) return(user_proto_id); else { @@ -363,6 +366,9 @@ u_int16_t ndpi_map_ndpi_id_to_user_proto_id(struct ndpi_detection_module_struct #endif #endif + if(!ndpi_str) + return(0); + if(ndpi_proto_id < NDPI_MAX_SUPPORTED_PROTOCOLS) return(ndpi_proto_id); else if(ndpi_proto_id < ndpi_str->ndpi_num_supported_protocols) { @@ -713,7 +719,6 @@ static u_int8_t ndpi_is_middle_string_char(char c) { case '.': case '-': return(1); - break; default: return(0); @@ -2225,10 +2230,11 @@ int ndpi_get_patricia_stats(struct ndpi_detection_module_struct *ndpi_struct, /* ****************************************************** */ int ndpi_fill_prefix_v4(ndpi_prefix_t *p, const struct in_addr *a, int b, int mb) { + memset(p, 0, sizeof(ndpi_prefix_t)); + if(b < 0 || b > mb) return(-1); - memset(p, 0, sizeof(ndpi_prefix_t)); p->add.sin.s_addr = a->s_addr, p->family = AF_INET, p->bitlen = b, p->ref_count = 0; return(0); @@ -2237,6 +2243,8 @@ int ndpi_fill_prefix_v4(ndpi_prefix_t *p, const struct in_addr *a, int b, int mb /* ******************************************* */ int ndpi_fill_prefix_v6(ndpi_prefix_t *prefix, const struct in6_addr *addr, int bits, int maxbits) { + memset(prefix, 0, sizeof(ndpi_prefix_t)); + if(bits < 0 || bits > maxbits) return -1; @@ -8165,11 +8173,9 @@ int ndpi_is_custom_category(ndpi_protocol_category_t category) { case NDPI_PROTOCOL_CATEGORY_CUSTOM_4: case NDPI_PROTOCOL_CATEGORY_CUSTOM_5: return(1); - break; default: return(0); - break; } } @@ -9166,19 +9172,15 @@ const char *ndpi_get_l4_proto_name(ndpi_l4_proto_info proto) { switch(proto) { case ndpi_l4_proto_unknown: return(""); - break; case ndpi_l4_proto_tcp_only: return("TCP"); - break; case ndpi_l4_proto_udp_only: return("UDP"); - break; case ndpi_l4_proto_tcp_and_udp: return("TCP/UDP"); - break; } return(""); @@ -9913,6 +9915,11 @@ u_int32_t ndpi_get_protocol_aggressiveness(struct ndpi_detection_module_struct * void ndpi_set_user_data(struct ndpi_detection_module_struct *ndpi_str, void *user_data) { + if (ndpi_str == NULL) + { + return; + } + if (ndpi_str->user_data != NULL) { NDPI_LOG_ERR(ndpi_str, "%s", "User data is already set. Overwriting.") @@ -9923,5 +9930,7 @@ void ndpi_set_user_data(struct ndpi_detection_module_struct *ndpi_str, void *use void *ndpi_get_user_data(struct ndpi_detection_module_struct *ndpi_str) { - return ndpi_str->user_data; + if(ndpi_str) + return ndpi_str->user_data; + return NULL; } diff --git a/src/lib/ndpi_utils.c b/src/lib/ndpi_utils.c index 8356c39b302..bd7c922ad8c 100644 --- a/src/lib/ndpi_utils.c +++ b/src/lib/ndpi_utils.c @@ -1627,31 +1627,24 @@ const char* ndpi_tunnel2str(ndpi_packet_tunnel tt) { switch(tt) { case ndpi_no_tunnel: return("No-Tunnel"); - break; case ndpi_gtp_tunnel: return("GTP"); - break; case ndpi_capwap_tunnel: return("CAPWAP"); - break; case ndpi_tzsp_tunnel: return("TZSP"); - break; case ndpi_l2tp_tunnel: return("L2TP"); - break; case ndpi_vxlan_tunnel: return("VXLAN"); - break; case ndpi_gre_tunnel: return("GRE"); - break; } return(""); diff --git a/src/lib/protocols/rtp.c b/src/lib/protocols/rtp.c index 68a1a2ac914..9d48aecb1f5 100644 --- a/src/lib/protocols/rtp.c +++ b/src/lib/protocols/rtp.c @@ -62,7 +62,7 @@ u_int8_t rtp_get_stream_type(u_int8_t payloadType, ndpi_multimedia_flow_type *s_ case 117: /* G.722 */ case 118: /* Comfort Noise Wideband */ *s_type = ndpi_multimedia_audio_flow; - return(1 /* RTP */); + return(1); case 34: /* H.263 [MS-H26XPF] */ case 121: /* RT Video */ @@ -70,14 +70,7 @@ u_int8_t rtp_get_stream_type(u_int8_t payloadType, ndpi_multimedia_flow_type *s_ case 123: /* H.264 FEC [MS-H264PF] */ case 127: /* x-data */ *s_type = ndpi_multimedia_video_flow; - return(1 /* RTP */); - - case 200: /* RTCP PACKET SENDER */ - case 201: /* RTCP PACKET RECEIVER */ - case 202: /* RTCP Source Description */ - case 203: /* RTCP Bye */ - *s_type = ndpi_multimedia_unknown_flow; - return(2 /* RTCP */); + return(1); default: *s_type = ndpi_multimedia_unknown_flow; diff --git a/src/lib/protocols/tls.c b/src/lib/protocols/tls.c index 709a77a96f4..157e57868c6 100644 --- a/src/lib/protocols/tls.c +++ b/src/lib/protocols/tls.c @@ -656,9 +656,7 @@ void processCertificateElements(struct ndpi_detection_module_struct *ndpi_struct dNSName); #endif - if(flow->host_server_name[0] == '\0') { - matched_name = 1; /* No SNI */ - } else if(dNSName[0] == '*') { + if(dNSName[0] == '*') { char * label = strstr(flow->host_server_name, &dNSName[1]); if(label != NULL) { diff --git a/src/lib/third_party/src/libinjection_xss.c b/src/lib/third_party/src/libinjection_xss.c index 3ef827df95f..f329d8b87d5 100644 --- a/src/lib/third_party/src/libinjection_xss.c +++ b/src/lib/third_party/src/libinjection_xss.c @@ -78,6 +78,10 @@ static int html_decode_char_at(const char* src, size_t len, size_t* consumed) return '&'; } + if (len < 4) { + return (unsigned char)(*(src+1)); + } + if (*(src+2) == 'x' || *(src+2) == 'X') { ch = (unsigned char) (*(src+3)); ch = gsHexDecodeMap[ch]; diff --git a/tests/cfgs/default/pcap/quic_cc_ack.pcapng b/tests/cfgs/default/pcap/quic_cc_ack.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..055de0c1e441ca9a41a46d57d2c647d80ea54785 GIT binary patch literal 2960 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 literal 0 HcmV?d00001 diff --git a/tests/cfgs/default/pcap/stun_classic.pcap b/tests/cfgs/default/pcap/stun_classic.pcap new file mode 100644 index 0000000000000000000000000000000000000000..64b282ae518e2535ecbde303178ad981fa839c4a GIT binary patch literal 2000 zcmb8veM}Q~7{Kvg^*Z20V{aCy^`$bLB4~Ueh@jz^uO%o<)Kohx8F>_|Ppty@1tl48j@mhHR`}NAo|c zPeBAZFw;z;sXaCx54rzG#dktHGYQv$9L#W+FZQM9ln4ptohG>GzITr0Ckg6rxme*Z zs;~YrPA61MZv#1@le@g%l1`O)5KMm%$akV8`3A8uzc|IH)zx%%#MH)EK{mbOE-Pp( zdt%uFvRzefQ&koFtjLblCpYi49WGHgK%P9-mGhjR&B3x4!3?B;ENUukKeD-DSv<98 zbKOd%Zd9sP1hRB1cX>?%mPG{f-V5Zu={sHCg|70Fht1UM$Md7(&r^9IZ@9)?zG24l zSS()$*-zCgrDb_1%e!V|@Ox$l$DH}?D9FP{4@43s8GA!TZlSX%tWrW*#b&gOjBJ8Qr z?gd@KJ(4jXpCQ~h|AINE@ifE)^FapFXzvYAYU^~Vy!oVkca~U?VEiUvG|1|3mh9v- z(xPy)9ye>D+1|ZP9C`1gw@~Sq9IY`nv=&J-L9SlOl0W@h{QuMKN#W*kxY-WP_U&b8 z;p^%LhZbB?q;8s<@q2ONaggkANLZYuTZJQu9nfHOb z!o-rDoQCcPJdJWbX^MbpM0tORbvx8*6J^*kMk}NH=Q|Ra z%1pxw4eW`_ao<;V=s15erzdlg(~o z+&mFCTcBAL(h#CJ5hfV*rdMN_B#4W6RZ4*TX9i1lvN=nFn=AQbt3Nc;Zyzrlw5}IS zq1wJ07%A5emiMg&S@ttacCy)z#LW`IhEkyUVRGf=CQ*HSDlMn?4!>{AzVb&0$f9PJ k>}2y&1#Ygw&5h9Pb1%fYwuzAQ3g}+zflG!(r{-Bc0{R?_iU0rr literal 0 HcmV?d00001 diff --git a/tests/cfgs/default/result/quic_cc_ack.pcapng.out b/tests/cfgs/default/result/quic_cc_ack.pcapng.out new file mode 100644 index 00000000000..7d6c1667b6e --- /dev/null +++ b/tests/cfgs/default/result/quic_cc_ack.pcapng.out @@ -0,0 +1,26 @@ +Guessed flow protos: 0 + +DPI Packets (UDP): 2 (1.00 pkts/flow) +Confidence DPI : 2 (flows) +Num dissector calls: 2 (1.00 diss/flow) +LRU cache ookla: 0/0/0 (insert/search/found) +LRU cache bittorrent: 0/0/0 (insert/search/found) +LRU cache zoom: 0/0/0 (insert/search/found) +LRU cache stun: 0/0/0 (insert/search/found) +LRU cache tls_cert: 0/0/0 (insert/search/found) +LRU cache mining: 0/0/0 (insert/search/found) +LRU cache msteams: 0/0/0 (insert/search/found) +LRU cache stun_zoom: 0/0/0 (insert/search/found) +Automa host: 0/0 (search/found) +Automa domain: 0/0 (search/found) +Automa tls cert: 0/0 (search/found) +Automa risk mask: 0/0 (search/found) +Automa common alpns: 0/0 (search/found) +Patricia risk mask: 4/0 (search/found) +Patricia risk: 4/0 (search/found) +Patricia protocols: 3/1 (search/found) + +QUIC 2 2784 2 + + 1 UDP 152.14.223.145:57113 -> 71.98.228.93:443 [proto: 188/QUIC][IP: 0/Unknown][Encrypted][Confidence: DPI][DPI packets: 1][cat: Web/5][1 pkts/1392 bytes -> 0 pkts/0 bytes][Goodput ratio: 97/0][< 1 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 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,100,0,0,0,0,0] + 2 UDP 183.23.159.144:37787 -> 108.140.147.22:443 [proto: 188/QUIC][IP: 276/Azure][Encrypted][Confidence: DPI][DPI packets: 1][cat: Web/5][1 pkts/1392 bytes -> 0 pkts/0 bytes][Goodput ratio: 97/0][< 1 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][PLAIN TEXT (IhUo.7y)][Plen Bins: 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,100,0,0,0,0,0] diff --git a/tests/cfgs/default/result/stun_classic.pcap.out b/tests/cfgs/default/result/stun_classic.pcap.out new file mode 100644 index 00000000000..ce9d637edd3 --- /dev/null +++ b/tests/cfgs/default/result/stun_classic.pcap.out @@ -0,0 +1,25 @@ +Guessed flow protos: 0 + +DPI Packets (UDP): 5 (5.00 pkts/flow) +Confidence DPI : 1 (flows) +Num dissector calls: 168 (168.00 diss/flow) +LRU cache ookla: 0/0/0 (insert/search/found) +LRU cache bittorrent: 0/0/0 (insert/search/found) +LRU cache zoom: 0/0/0 (insert/search/found) +LRU cache stun: 0/4/0 (insert/search/found) +LRU cache tls_cert: 0/0/0 (insert/search/found) +LRU cache mining: 0/0/0 (insert/search/found) +LRU cache msteams: 0/0/0 (insert/search/found) +LRU cache stun_zoom: 0/0/0 (insert/search/found) +Automa host: 0/0 (search/found) +Automa domain: 0/0 (search/found) +Automa tls cert: 0/0 (search/found) +Automa risk mask: 0/0 (search/found) +Automa common alpns: 0/0 (search/found) +Patricia risk mask: 2/0 (search/found) +Patricia risk: 0/0 (search/found) +Patricia protocols: 2/0 (search/found) + +RTP 22 1624 1 + + 1 UDP 172.16.63.224:55050 <-> 172.16.63.21:13958 [proto: 78.87/STUN.RTP][IP: 0/Unknown][ClearText][Confidence: DPI][DPI packets: 5][cat: Media/1][9 pkts/662 bytes <-> 13 pkts/962 bytes][Goodput ratio: 43/43][0.23 sec][bytes ratio: -0.185 (Mixed)][IAT c2s/s2c min/avg/max/stddev: 4/0 32/17 101/42 32/11][Pkt Len c2s/s2c min/avg/max/stddev: 70/74 74/74 74/74 1/0][Risk: ** Known Proto on Non Std Port **][Risk Score: 50][Plen Bins: 4,95,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,0,0]