Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fuzz: extend fuzzers coverage #1952

Merged
merged 1 commit into from
Apr 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
/fuzz/fuzz_libinjection
/fuzz/fuzz_tls_certificate
/fuzz/fuzz_gcrypt_light
/fuzz/fuzz_ndpi_reader_payload_analyzer
/fuzz/fuzz_ndpi_reader_alloc_fail_seed_corpus.zip
/fuzz/fuzz_ndpi_reader_seed_corpus.zip
/fuzz/fuzz_quic_get_crypto_data_seed_corpus.zip
Expand All @@ -92,6 +93,7 @@
/fuzz/fuzz_ds_ahocorasick_seed_corpus.zip
/fuzz/fuzz_libinjection_seed_corpus.zip
/fuzz/fuzz_tls_certificate_seed_corpus.zip
/fuzz/fuzz_ndpi_reader_payload_analyzer_seed_corpus.zip
/fuzz/fuzz_*.dict
/influxdb/Makefile
/install-sh
Expand Down
4 changes: 2 additions & 2 deletions fuzz/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ fuzz_ndpi_reader_alloc_fail_LINK=$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAG
$(LIBTOOLFLAGS) --mode=link $(CXX) @NDPI_CFLAGS@ $(AM_CXXFLAGS) $(CXXFLAGS) \
$(fuzz_ndpi_reader_alloc_fail_LDFLAGS) @NDPI_LDFLAGS@ $(LDFLAGS) -o $@

fuzz_ndpi_reader_payload_analyzer_SOURCES = fuzz_ndpi_reader.c ../example/reader_util.c
fuzz_ndpi_reader_payload_analyzer_CFLAGS = -I../example/ @NDPI_CFLAGS@ $(CXXFLAGS) -DENABLE_PAYLOAD_ANALYZER
fuzz_ndpi_reader_payload_analyzer_SOURCES = fuzz_ndpi_reader.c fuzz_common_code.c ../example/reader_util.c
fuzz_ndpi_reader_payload_analyzer_CFLAGS = -I../example/ @NDPI_CFLAGS@ $(CXXFLAGS) -DENABLE_MEM_ALLOC_FAILURES -DENABLE_PAYLOAD_ANALYZER
fuzz_ndpi_reader_payload_analyzer_LDADD = ../src/lib/libndpi.a $(ADDITIONAL_LIBS)
fuzz_ndpi_reader_payload_analyzer_LDFLAGS = $(PCAP_LIB) $(LIBS)
if HAS_FUZZLDFLAGS
Expand Down
2 changes: 2 additions & 0 deletions fuzz/fuzz_alg_hw_rsi_outliers_da.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
ndpi_data_entropy(a);
ndpi_reset_data_analysis(a);

ndpi_hw_reset(&hw);

/* Data ratio */
if (num_values > 1)
ndpi_data_ratio2str(ndpi_data_ratio(values[0], values[1]));
Expand Down
3 changes: 3 additions & 0 deletions fuzz/fuzz_alg_ses_des.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
ndpi_des_add_value(&d, value, &forecast, &confidence_band);
}

ndpi_ses_reset(&s);
ndpi_des_reset(&d);

return 0;
}
5 changes: 1 addition & 4 deletions fuzz/fuzz_common_code.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,16 @@ void fuzz_init_detection_module(struct ndpi_detection_module_struct **ndpi_info_
{
ndpi_init_prefs prefs = ndpi_enable_ja3_plus;
NDPI_PROTOCOL_BITMASK all;
NDPI_PROTOCOL_BITMASK debug_bitmask;

if(*ndpi_info_mod == NULL) {
*ndpi_info_mod = ndpi_init_detection_module(prefs);
NDPI_BITMASK_SET_ALL(all);
ndpi_set_protocol_detection_bitmask2(*ndpi_info_mod, &all);

#if 0
NDPI_PROTOCOL_BITMASK debug_bitmask;

NDPI_BITMASK_SET_ALL(debug_bitmask);
ndpi_set_log_level(*ndpi_info_mod, 4);
ndpi_set_debug_bitmask(*ndpi_info_mod, debug_bitmask);
#endif

ndpi_load_protocols_file(*ndpi_info_mod, "protos.txt");
ndpi_load_categories_file(*ndpi_info_mod, "categories.txt", NULL);
Expand Down
51 changes: 47 additions & 4 deletions fuzz/fuzz_config.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "ndpi_api.h"
#include "ndpi_classify.h"
#include "fuzz_common_code.h"

#include <stdint.h>
Expand All @@ -25,17 +26,19 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
struct ndpi_flow_input_info input_info;
ndpi_proto p, p2;
char out[128];
char log_ts[32];


if(fuzzed_data.remaining_bytes() < 4 + /* ndpi_init_detection_module() */
NDPI_MAX_SUPPORTED_PROTOCOLS + NDPI_MAX_NUM_CUSTOM_PROTOCOLS +
1 + /* TLS cert expire */
6 + /* files */
((NDPI_LRUCACHE_MAX + 1) * 5) + /* LRU caches */
2 + 1 + 5 + /* ndpi_set_detection_preferences() */
2 + 1 + 4 + /* ndpi_set_detection_preferences() */
7 + /* Opportunistic tls */
2 + /* Pid */
2 + /* Category */
1 + /* Tunnel */
1 + /* Bool value */
2 + /* input_info */
21 /* Min real data: ip length + 1 byte of L4 header */)
Expand Down Expand Up @@ -82,6 +85,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
ndpi_get_lru_cache_ttl(ndpi_info_mod, static_cast<lru_cache_type>(i), &num);
}

/* TODO: stub for geo stuff */
ndpi_load_geoip(ndpi_info_mod, NULL, NULL);

if(fuzzed_data.ConsumeBool())
ndpi_set_detection_preferences(ndpi_info_mod, ndpi_pref_direction_detect_disable,
fuzzed_data.ConsumeBool());
Expand All @@ -90,7 +96,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
0 /* unused */);
if(fuzzed_data.ConsumeBool())
ndpi_set_detection_preferences(ndpi_info_mod, ndpi_pref_max_packets_to_process,
fuzzed_data.ConsumeIntegralInRange(0, (1 << 24)));
fuzzed_data.ConsumeIntegralInRange(0, (1 << 16)));

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);
Expand Down Expand Up @@ -121,7 +127,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
}
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);

/* Custom category configuration */
cat = fuzzed_data.ConsumeIntegralInRange(static_cast<int>(NDPI_PROTOCOL_CATEGORY_CUSTOM_1),
Expand All @@ -131,20 +136,27 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
ndpi_category_get_name(ndpi_info_mod, static_cast<ndpi_protocol_category_t>(cat));
ndpi_get_category_id(ndpi_info_mod, catname);

ndpi_tunnel2str(static_cast<ndpi_packet_tunnel>(fuzzed_data.ConsumeIntegralInRange(static_cast<int>(ndpi_no_tunnel),
static_cast<int>(ndpi_gre_tunnel + 1)))); /* + 1 to trigger invalid value */

ndpi_get_num_supported_protocols(ndpi_info_mod);
ndpi_get_proto_defaults(ndpi_info_mod);
ndpi_get_ndpi_num_custom_protocols(ndpi_info_mod);
ndpi_get_ndpi_num_supported_protocols(ndpi_info_mod);

ndpi_self_check_host_match(stderr);

/* Basic code to try testing this "config" */
bool_value = fuzzed_data.ConsumeBool();
input_info.in_pkt_dir = !!fuzzed_data.ConsumeBool();
input_info.in_pkt_dir = fuzzed_data.ConsumeIntegralInRange(0,2);
input_info.seen_flow_beginning = !!fuzzed_data.ConsumeBool();
memset(&flow, 0, sizeof(flow));
std::vector<uint8_t>pkt = fuzzed_data.ConsumeRemainingBytes<uint8_t>();
assert(pkt.size() >= 21); /* To be sure check on fuzzed_data.remaining_bytes() at the beginning is right */

ndpi_detection_process_packet(ndpi_info_mod, &flow, pkt.data(), pkt.size(), 0, &input_info);
p = ndpi_detection_giveup(ndpi_info_mod, &flow, 1, &protocol_was_guessed);

assert(p.master_protocol == ndpi_get_flow_masterprotocol(ndpi_info_mod, &flow));
assert(p.app_protocol == ndpi_get_flow_appprotocol(ndpi_info_mod, &flow));
assert(p.category == ndpi_get_flow_category(ndpi_info_mod, &flow));
Expand All @@ -154,17 +166,38 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
ndpi_get_flow_risk_info(&flow, out, sizeof(out), 1);
ndpi_get_flow_ndpi_proto(ndpi_info_mod, &flow, &p2);
ndpi_is_proto(p, NDPI_PROTOCOL_TLS);
ndpi_http_method2str(flow.http.method);
ndpi_get_l4_proto_name(ndpi_get_l4_proto_info(ndpi_info_mod, p.app_protocol));
ndpi_is_subprotocol_informative(ndpi_info_mod, p.app_protocol);
ndpi_get_http_method(ndpi_info_mod, &flow);
ndpi_get_http_url(ndpi_info_mod, &flow);
ndpi_get_http_content_type(ndpi_info_mod, &flow);
ndpi_check_for_email_address(ndpi_info_mod, 0);
/* ndpi_guess_undetected_protocol() is a "strange" function. Try fuzzing it, here */
if(!ndpi_is_protocol_detected(ndpi_info_mod, p)) {
ndpi_guess_undetected_protocol(ndpi_info_mod, bool_value ? &flow : NULL,
flow.l4_proto);
if(!flow.is_ipv6) {
/* Another "strange" function (ipv4 only): fuzz it here, for lack of a better alternative */
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));
}
/* Another "strange" function: fuzz it here, for lack of a better alternative */
ndpi_search_tcp_or_udp(ndpi_info_mod, &flow);
}
if(!flow.is_ipv6) {
ndpi_network_ptree_match(ndpi_info_mod, (struct in_addr *)&flow.c_address.v4);

ndpi_risk_params params[] = { { NDPI_PARAM_HOSTNAME, flow.host_server_name},
{ NDPI_PARAM_ISSUER_DN, flow.host_server_name},
{ NDPI_PARAM_HOST_IPV4, &flow.c_address.v4} };
ndpi_check_flow_risk_exceptions(ndpi_info_mod, 3, params);
}
/* TODO: stub for geo stuff */
ndpi_get_geoip_asn(ndpi_info_mod, NULL, NULL);
ndpi_get_geoip_country_continent(ndpi_info_mod, NULL, NULL, 0, NULL, 0);

ndpi_free_flow_data(&flow);

/* Get some final stats */
Expand All @@ -180,6 +213,16 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
ndpi_get_api_version();
ndpi_get_gcrypt_version();

ndpi_get_ndpi_detection_module_size();
ndpi_detection_get_sizeof_ndpi_flow_struct();
ndpi_detection_get_sizeof_ndpi_flow_tcp_struct();
ndpi_detection_get_sizeof_ndpi_flow_udp_struct();

ndpi_get_tot_allocated_memory();
ndpi_log_timestamp(log_ts, sizeof(log_ts));

ndpi_free_geoip(ndpi_info_mod);

ndpi_exit_detection_module(ndpi_info_mod);

return 0;
Expand Down
18 changes: 16 additions & 2 deletions fuzz/fuzz_libinjection.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
char *query;
char fingerprint[8];
struct libinjection_sqli_state state;

/* No memory allocations involved */

Expand All @@ -15,11 +15,25 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
memcpy(query, data, size);
query[size] = '\0';

libinjection_sqli(query, strlen(query), fingerprint);

libinjection_sqli_init(&state, query, strlen(query), 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_is_sqli(&state);
libinjection_sqli_init(&state, query, strlen(query), FLAG_QUOTE_DOUBLE | FLAG_SQL_ANSI);
libinjection_is_sqli(&state);
libinjection_sqli_init(&state, query, strlen(query), FLAG_QUOTE_NONE | FLAG_SQL_MYSQL);
libinjection_is_sqli(&state);
libinjection_sqli_init(&state, query, strlen(query), FLAG_QUOTE_SINGLE | FLAG_SQL_MYSQL);
libinjection_is_sqli(&state);
libinjection_sqli_init(&state, query, strlen(query), FLAG_QUOTE_DOUBLE | FLAG_SQL_MYSQL);
libinjection_is_sqli(&state);

libinjection_xss(query, strlen(query));

free(query);

libinjection_version();

return 0;
}
2 changes: 1 addition & 1 deletion fuzz/fuzz_ndpi_reader.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ u_int8_t max_num_udp_dissected_pkts = 16 /* 8 is enough for most protocols, Sign
ndpi_init_prefs init_prefs = ndpi_track_flow_payload | ndpi_enable_ja3_plus;
int enable_malloc_bins = 1;
int malloc_size_stats = 0;
int max_malloc_bins = 0;
int max_malloc_bins = 14;
struct ndpi_bin malloc_bins; /* unused */

extern void ndpi_report_payload_stats(int print);
Expand Down
8 changes: 8 additions & 0 deletions src/include/ndpi_classify.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@

#include "ndpi_includes.h"

#ifdef __cplusplus
extern "C" {
#endif

/* constants */
#define NUM_PARAMETERS_SPLT_LOGREG 208
#define NUM_PARAMETERS_BD_LOGREG 464
Expand Down Expand Up @@ -89,4 +93,8 @@ u_int64_t ndpi_timeval_to_milliseconds(pkt_timeval ts);
u_int64_t ndpi_timeval_to_microseconds(pkt_timeval ts);
void ndpi_log_timestamp(char *log_ts, u_int32_t log_ts_len);

#ifdef __cplusplus
}
#endif

#endif /* NDPI_CLASSIFY_H */
2 changes: 1 addition & 1 deletion src/include/ndpi_main.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ extern "C" {
struct ndpi_flow_struct *flow);

extern u_int16_t ndpi_check_for_email_address(struct ndpi_detection_module_struct *ndpi_struct,
u_int16_t counter);
u_int16_t counter);

extern void ndpi_int_change_category(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow,
Expand Down
3 changes: 3 additions & 0 deletions src/include/ndpi_protocols.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ ndpi_port_range* ndpi_build_default_ports(ndpi_port_range *ports,
u_int16_t portE);

/* TCP/UDP protocols */
#ifdef __cplusplus
extern "C"
#endif
u_int ndpi_search_tcp_or_udp_raw(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow,
u_int8_t protocol,
Expand Down
7 changes: 5 additions & 2 deletions src/lib/ndpi_analyze.c
Original file line number Diff line number Diff line change
Expand Up @@ -1096,6 +1096,7 @@ int ndpi_hw_init(struct ndpi_hw_struct *hw,

if((hw->s = (double*)ndpi_calloc(hw->params.num_season_periods, sizeof(double))) == NULL) {
ndpi_free(hw->y);
hw->y = NULL;
return(-1);
}

Expand Down Expand Up @@ -1213,8 +1214,10 @@ void ndpi_hw_reset(struct ndpi_hw_struct *hw) {
hw->num_values = 0;
hw->u = hw->v = hw->sum_square_error = 0;

memset(&hw->y, 0, (hw->params.num_season_periods * sizeof(u_int64_t)));
memset(&hw->s, 0, (hw->params.num_season_periods * sizeof(double)));
if(hw->y)
memset(hw->y, 0, (hw->params.num_season_periods * sizeof(u_int64_t)));
if(hw->s)
memset(hw->s, 0, (hw->params.num_season_periods * sizeof(double)));
}

/* ********************************************************************************* */
Expand Down
6 changes: 4 additions & 2 deletions src/lib/ndpi_classify.c
Original file line number Diff line number Diff line change
Expand Up @@ -268,10 +268,12 @@ ndpi_merge_splt_arrays (const uint16_t *pkt_len, const pkt_timeval *pkt_time,
uint16_t *merged_lens, uint16_t *merged_times)
{
int s,r;
pkt_timeval ts_start = { 0, 0 }; /* initialize to avoid spurious warnings */
pkt_timeval ts_start;
pkt_timeval tmp, tmp_r;
pkt_timeval start_m;

ndpi_timer_clear(&ts_start);

if(r_idx + s_idx == 0) {
return ;
} else if(r_idx == 0) {
Expand Down Expand Up @@ -677,7 +679,7 @@ ndpi_timeval_to_microseconds(pkt_timeval ts)
{
u_int64_t sec = ts.tv_sec;
u_int64_t usec = ts.tv_usec;
return usec + sec * 1000 * 1000;;
return usec + sec * 1000 * 1000;
}

/* **************************************** */
Expand Down
12 changes: 8 additions & 4 deletions src/lib/ndpi_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2287,7 +2287,7 @@ u_int16_t ndpi_network_ptree_match(struct ndpi_detection_module_struct *ndpi_str
ndpi_prefix_t prefix;
ndpi_patricia_node_t *node;

if(!ndpi_str->protocols_ptree)
if(!ndpi_str || !ndpi_str->protocols_ptree)
return(NDPI_PROTOCOL_UNKNOWN);

if(ndpi_str->ndpi_num_custom_protocols == 0) {
Expand Down Expand Up @@ -2318,7 +2318,7 @@ u_int16_t ndpi_network_port_ptree_match(struct ndpi_detection_module_struct *ndp
ndpi_prefix_t prefix;
ndpi_patricia_node_t *node;

if(!ndpi_str->protocols_ptree)
if(!ndpi_str || !ndpi_str->protocols_ptree)
return(NDPI_PROTOCOL_UNKNOWN);

if(ndpi_str->ndpi_num_custom_protocols == 0) {
Expand Down Expand Up @@ -7498,8 +7498,12 @@ void ndpi_parse_packet_line_info_any(struct ndpi_detection_module_struct *ndpi_s

u_int16_t ndpi_check_for_email_address(struct ndpi_detection_module_struct *ndpi_str,
u_int16_t counter) {
struct ndpi_packet_struct *packet = &ndpi_str->packet;
struct ndpi_packet_struct *packet;

if(!ndpi_str)
return(0);

packet = &ndpi_str->packet;
NDPI_LOG_DBG2(ndpi_str, "called ndpi_check_for_email_address\n");

if(packet->payload_packet_len > counter && ((packet->payload[counter] >= 'a' && packet->payload[counter] <= 'z') ||
Expand Down Expand Up @@ -8983,7 +8987,7 @@ const char *ndpi_get_l4_proto_name(ndpi_l4_proto_info proto) {

ndpi_l4_proto_info ndpi_get_l4_proto_info(struct ndpi_detection_module_struct *ndpi_struct,
u_int16_t ndpi_proto_id) {
if(ndpi_proto_id < ndpi_struct->ndpi_num_supported_protocols) {
if(ndpi_struct && ndpi_proto_id < ndpi_struct->ndpi_num_supported_protocols) {
u_int16_t idx = ndpi_struct->proto_defaults[ndpi_proto_id].protoIdx;
NDPI_SELECTION_BITMASK_PROTOCOL_SIZE bm = ndpi_struct->callback_buffer[idx].ndpi_selection_bitmask;

Expand Down
Loading