diff options
author | Ivan Nardi <12729895+IvanNardi@users.noreply.github.com> | 2023-03-20 17:00:46 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-20 17:00:46 +0100 |
commit | 0e80828e146a30bc03b60eefbf0d4c3583e243e3 (patch) | |
tree | 05a54f864aaf8625eb209e5f79107b9ebab68288 | |
parent | 9f46d41eca9c479b407b0d4f7336dc5805b0b78a (diff) |
fuzz: add a new fuzzer to test TLS certificates (#1901)
21 files changed, 95 insertions, 10 deletions
diff --git a/.gitignore b/.gitignore index 12f83d067..847a6da77 100644 --- a/.gitignore +++ b/.gitignore @@ -70,6 +70,7 @@ /fuzz/fuzz_ds_ptree /fuzz/fuzz_ds_ahocorasick /fuzz/fuzz_libinjection +/fuzz/fuzz_tls_certificate /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 @@ -89,6 +90,7 @@ /fuzz/fuzz_ds_ptree_seed_corpus.zip /fuzz/fuzz_ds_ahocorasick_seed_corpus.zip /fuzz/fuzz_libinjection_seed_corpus.zip +/fuzz/fuzz_tls_certificate_seed_corpus.zip /fuzz/fuzz_*.dict /influxdb/Makefile /install-sh diff --git a/fuzz/Makefile.am b/fuzz/Makefile.am index 7e4e922ee..08def2ff3 100644 --- a/fuzz/Makefile.am +++ b/fuzz/Makefile.am @@ -1,4 +1,4 @@ -bin_PROGRAMS = fuzz_process_packet fuzz_ndpi_reader fuzz_ndpi_reader_alloc_fail fuzz_quic_get_crypto_data fuzz_config fuzz_community_id fuzz_serialization +bin_PROGRAMS = fuzz_process_packet fuzz_ndpi_reader fuzz_ndpi_reader_alloc_fail fuzz_quic_get_crypto_data fuzz_config fuzz_community_id fuzz_serialization fuzz_tls_certificate #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 @@ -292,7 +292,18 @@ fuzz_libinjection_LINK=$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXX) @NDPI_CFLAGS@ $(AM_CXXFLAGS) $(CXXFLAGS) \ $(fuzz_libinjection_LDFLAGS) @NDPI_LDFLAGS@ $(LDFLAGS) -o $@ - +fuzz_tls_certificate_SOURCES = fuzz_tls_certificate.c fuzz_common_code.c +fuzz_tls_certificate_CFLAGS = @NDPI_CFLAGS@ $(CXXFLAGS) +fuzz_tls_certificate_LDADD = ../src/lib/libndpi.a $(ADDITIONAL_LIBS) +fuzz_tls_certificate_LDFLAGS = $(LIBS) +if HAS_FUZZLDFLAGS +fuzz_tls_certificate_CFLAGS += $(LIB_FUZZING_ENGINE) +fuzz_tls_certificate_LDFLAGS += $(LIB_FUZZING_ENGINE) +endif +# force usage of CXX for linker +fuzz_tls_certificate_LINK=$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXX) @NDPI_CFLAGS@ $(AM_CXXFLAGS) $(CXXFLAGS) \ + $(fuzz_tls_certificate_LDFLAGS) @NDPI_LDFLAGS@ $(LDFLAGS) -o $@ # required for Google oss-fuzz # see https://github.com/google/oss-fuzz/tree/master/projects/ndpi @@ -389,8 +400,12 @@ files_corpus_fuzz_libinjection := $(wildcard corpus/fuzz_libinjection/*) fuzz_libinjection_seed_corpus.zip: $(files_corpus_fuzz_libinjection) zip -j fuzz_libinjection_seed_corpus.zip $(files_corpus_fuzz_libinjection) +files_corpus_fuzz_tls_certificate := $(wildcard corpus/fuzz_tls_certificate/*) + +fuzz_tls_certificate_seed_corpus.zip: $(files_corpus_fuzz_tls_certificate) + zip -j fuzz_tls_certificate_seed_corpus.zip $(files_corpus_fuzz_tls_certificate) -corpus: fuzz_ndpi_reader_seed_corpus.zip fuzz_ndpi_reader_alloc_fail_seed_corpus.zip fuzz_quic_get_crypto_data_seed_corpus.zip fuzz_config_seed_corpus.zip fuzz_ds_patricia_seed_corpus.zip fuzz_ds_ahocorasick_seed_corpus.zip fuzz_alg_ses_des_seed_corpus.zip fuzz_alg_hw_rsi_outliers_da_seed_corpus.zip fuzz_alg_bins_seed_corpus.zip fuzz_alg_hll_seed_corpus.zip fuzz_alg_jitter_seed_corpus.zip fuzz_ds_libcache_seed_corpus.zip fuzz_community_id_seed_corpus.zip fuzz_ds_tree_seed_corpus.zip fuzz_serialization_seed_corpus.zip fuzz_ds_ptree_seed_corpus.zip fuzz_alg_crc32_md5_seed_corpus.zip fuzz_alg_bytestream_seed_corpus.zip fuzz_libinjection_seed_corpus.zip +corpus: fuzz_ndpi_reader_seed_corpus.zip fuzz_ndpi_reader_alloc_fail_seed_corpus.zip fuzz_quic_get_crypto_data_seed_corpus.zip fuzz_config_seed_corpus.zip fuzz_ds_patricia_seed_corpus.zip fuzz_ds_ahocorasick_seed_corpus.zip fuzz_alg_ses_des_seed_corpus.zip fuzz_alg_hw_rsi_outliers_da_seed_corpus.zip fuzz_alg_bins_seed_corpus.zip fuzz_alg_hll_seed_corpus.zip fuzz_alg_jitter_seed_corpus.zip fuzz_ds_libcache_seed_corpus.zip fuzz_community_id_seed_corpus.zip fuzz_ds_tree_seed_corpus.zip fuzz_serialization_seed_corpus.zip fuzz_ds_ptree_seed_corpus.zip fuzz_alg_crc32_md5_seed_corpus.zip fuzz_alg_bytestream_seed_corpus.zip fuzz_libinjection_seed_corpus.zip fuzz_tls_certificate_seed_corpus.zip #Create dictionaries exactly as expected by oss-fuzz. #This way, if we need to change/update/add something, @@ -399,6 +414,7 @@ dictionaries: cp dictionary.dict fuzz_ndpi_reader.dict cp dictionary.dict fuzz_ndpi_reader_alloc_fail.dict cp dictionary.dict fuzz_process_packet.dict + cp dictionary_tls_certificate.dict fuzz_tls_certificate.dict distdir: find . -type d | xargs -I'{}' mkdir -p '$(distdir)/{}' @@ -413,6 +429,7 @@ distdir: -o -path './corpus/fuzz_serialization/*' \ -o -path './corpus/fuzz_community_id/*' \ -o -path './corpus/fuzz_libinjection/*' \ + -o -path './corpus/fuzz_tls_certificate/*' \ -o -path './corpus/fuzz_alg_ses_des/*' \ -o -path './corpus/fuzz_alg_bins/*' \ -o -path './corpus/fuzz_alg_hll/*' \ diff --git a/fuzz/corpus/fuzz_tls_certificate/1 b/fuzz/corpus/fuzz_tls_certificate/1 Binary files differnew file mode 100644 index 000000000..12dfe718c --- /dev/null +++ b/fuzz/corpus/fuzz_tls_certificate/1 diff --git a/fuzz/corpus/fuzz_tls_certificate/2 b/fuzz/corpus/fuzz_tls_certificate/2 Binary files differnew file mode 100644 index 000000000..50f796c7b --- /dev/null +++ b/fuzz/corpus/fuzz_tls_certificate/2 diff --git a/fuzz/corpus/fuzz_tls_certificate/25bb24bf6b2dbe8357e10cd3a38f157c5b154115 b/fuzz/corpus/fuzz_tls_certificate/25bb24bf6b2dbe8357e10cd3a38f157c5b154115 new file mode 100644 index 000000000..ef9d8b0e7 --- /dev/null +++ b/fuzz/corpus/fuzz_tls_certificate/25bb24bf6b2dbe8357e10cd3a38f157c5b154115 @@ -0,0 +1 @@ +‚Hü
\ No newline at end of file diff --git a/fuzz/corpus/fuzz_tls_certificate/3 b/fuzz/corpus/fuzz_tls_certificate/3 Binary files differnew file mode 100644 index 000000000..608f16c79 --- /dev/null +++ b/fuzz/corpus/fuzz_tls_certificate/3 diff --git a/fuzz/corpus/fuzz_tls_certificate/4 b/fuzz/corpus/fuzz_tls_certificate/4 Binary files differnew file mode 100644 index 000000000..2f1e5523a --- /dev/null +++ b/fuzz/corpus/fuzz_tls_certificate/4 diff --git a/fuzz/corpus/fuzz_tls_certificate/5 b/fuzz/corpus/fuzz_tls_certificate/5 Binary files differnew file mode 100644 index 000000000..27070de96 --- /dev/null +++ b/fuzz/corpus/fuzz_tls_certificate/5 diff --git a/fuzz/corpus/fuzz_tls_certificate/6 b/fuzz/corpus/fuzz_tls_certificate/6 Binary files differnew file mode 100644 index 000000000..adf9d557e --- /dev/null +++ b/fuzz/corpus/fuzz_tls_certificate/6 diff --git a/fuzz/corpus/fuzz_tls_certificate/69cbc51f584260bfa23cba82f5fec7ce81237e26 b/fuzz/corpus/fuzz_tls_certificate/69cbc51f584260bfa23cba82f5fec7ce81237e26 new file mode 100644 index 000000000..f86eba04a --- /dev/null +++ b/fuzz/corpus/fuzz_tls_certificate/69cbc51f584260bfa23cba82f5fec7ce81237e26 @@ -0,0 +1 @@ +‚²0‚‚²0
\ No newline at end of file diff --git a/fuzz/corpus/fuzz_tls_certificate/7 b/fuzz/corpus/fuzz_tls_certificate/7 Binary files differnew file mode 100644 index 000000000..70128a98d --- /dev/null +++ b/fuzz/corpus/fuzz_tls_certificate/7 diff --git a/fuzz/corpus/fuzz_tls_certificate/7cf184f4c67ad58283ecb19349720b0cae756829 b/fuzz/corpus/fuzz_tls_certificate/7cf184f4c67ad58283ecb19349720b0cae756829 new file mode 100644 index 000000000..8ac2eb508 --- /dev/null +++ b/fuzz/corpus/fuzz_tls_certificate/7cf184f4c67ad58283ecb19349720b0cae756829 @@ -0,0 +1 @@ +H
\ No newline at end of file diff --git a/fuzz/corpus/fuzz_tls_certificate/8 b/fuzz/corpus/fuzz_tls_certificate/8 Binary files differnew file mode 100644 index 000000000..2a79b4f40 --- /dev/null +++ b/fuzz/corpus/fuzz_tls_certificate/8 diff --git a/fuzz/corpus/fuzz_tls_certificate/85f065f6c019d131ffe4e2bef840af10af47a097 b/fuzz/corpus/fuzz_tls_certificate/85f065f6c019d131ffe4e2bef840af10af47a097 new file mode 100644 index 000000000..4065fd518 --- /dev/null +++ b/fuzz/corpus/fuzz_tls_certificate/85f065f6c019d131ffe4e2bef840af10af47a097 @@ -0,0 +1 @@ +‚Hü,
\ No newline at end of file diff --git a/fuzz/corpus/fuzz_tls_certificate/9 b/fuzz/corpus/fuzz_tls_certificate/9 Binary files differnew file mode 100644 index 000000000..102260957 --- /dev/null +++ b/fuzz/corpus/fuzz_tls_certificate/9 diff --git a/fuzz/corpus/fuzz_tls_certificate/e276406b98ab53e543fe58b5c2aa124f3bda868c b/fuzz/corpus/fuzz_tls_certificate/e276406b98ab53e543fe58b5c2aa124f3bda868c Binary files differnew file mode 100644 index 000000000..525fb1612 --- /dev/null +++ b/fuzz/corpus/fuzz_tls_certificate/e276406b98ab53e543fe58b5c2aa124f3bda868c diff --git a/fuzz/corpus/fuzz_tls_certificate/e414032ad5cb3ae242e73b6f218bc481dcc97a59 b/fuzz/corpus/fuzz_tls_certificate/e414032ad5cb3ae242e73b6f218bc481dcc97a59 new file mode 100644 index 000000000..64ce7694d --- /dev/null +++ b/fuzz/corpus/fuzz_tls_certificate/e414032ad5cb3ae242e73b6f218bc481dcc97a59 @@ -0,0 +1 @@ +0‚²0‚‚²00
\ No newline at end of file diff --git a/fuzz/corpus/fuzz_tls_certificate/fb77b8f6d4ed7940dc0e2a5af6ec28c7ac81c84c b/fuzz/corpus/fuzz_tls_certificate/fb77b8f6d4ed7940dc0e2a5af6ec28c7ac81c84c new file mode 100644 index 000000000..2ba85439e --- /dev/null +++ b/fuzz/corpus/fuzz_tls_certificate/fb77b8f6d4ed7940dc0e2a5af6ec28c7ac81c84c @@ -0,0 +1 @@ +Hü
\ No newline at end of file diff --git a/fuzz/dictionary_tls_certificate.dict b/fuzz/dictionary_tls_certificate.dict new file mode 100644 index 000000000..cb363dc8a --- /dev/null +++ b/fuzz/dictionary_tls_certificate.dict @@ -0,0 +1,8 @@ +"\x55\x04\x03" +"\x55\x04\x06" +"\x55\x04\x07" +"\x55\x04\x08" +"\x55\x04\x0A" +"\x55\x04\x0B" +"\x30\x1E\x17" +"\x55\x1D\x11" diff --git a/fuzz/fuzz_tls_certificate.c b/fuzz/fuzz_tls_certificate.c new file mode 100644 index 000000000..bcbdd0e60 --- /dev/null +++ b/fuzz/fuzz_tls_certificate.c @@ -0,0 +1,47 @@ +#define NDPI_LIB_COMPILATION + +#include "ndpi_api.h" +#include "fuzz_common_code.h" + +#include <stdint.h> +#include <stdio.h> + +extern void processCertificateElements(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + u_int16_t p_offset, u_int16_t certificate_len); +struct ndpi_tcphdr tcph; +struct ndpi_iphdr iph; +struct ndpi_ipv6hdr iphv6; + +struct ndpi_detection_module_struct *ndpi_struct = NULL; +struct ndpi_flow_struct *ndpi_flow = NULL; + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + struct ndpi_packet_struct *packet; + int is_ipv6; + + if (ndpi_struct == NULL) { + fuzz_init_detection_module(&ndpi_struct); + ndpi_flow = ndpi_calloc(1, sizeof(struct ndpi_flow_struct)); + } + + if(size == 0) + return -1; + + packet = &ndpi_struct->packet; + packet->payload = data; + packet->payload_packet_len = size; + is_ipv6 = data[size - 1] % 5 ? 1 : 0; /* "Random" ipv4 vs ipv6 */ + packet->iphv6 = is_ipv6 ? &iphv6 : NULL; + packet->iph = is_ipv6 ? NULL : &iph; + packet->tcp = &tcph; + + memset(ndpi_flow, 0, sizeof(struct ndpi_flow_struct)); + strcpy(ndpi_flow->host_server_name, "doh.opendns.com"); + ndpi_flow->detected_protocol_stack[0] = NDPI_PROTOCOL_TLS; + + processCertificateElements(ndpi_struct, ndpi_flow, 0, size); + ndpi_free_flow_data(ndpi_flow); + + return 0; +} diff --git a/src/lib/protocols/tls.c b/src/lib/protocols/tls.c index 6b56529dd..c78f01876 100644 --- a/src/lib/protocols/tls.c +++ b/src/lib/protocols/tls.c @@ -247,7 +247,7 @@ static int extractRDNSequence(struct ndpi_packet_struct *packet, char *rdnSeqBuf, u_int *rdnSeqBuf_offset, u_int rdnSeqBuf_len, const char *label) { - u_int8_t str_len = packet->payload[offset+4], is_printable = 1; + u_int8_t str_len, is_printable = 1; char *str; u_int len; @@ -258,6 +258,10 @@ static int extractRDNSequence(struct ndpi_packet_struct *packet, #endif return -1; } + if((offset+4) >= packet->payload_packet_len) + return(-1); + + str_len = packet->payload[offset+4]; // packet is truncated... further inspection is not needed if((offset+4+str_len) >= packet->payload_packet_len) @@ -356,9 +360,9 @@ static void checkTLSSubprotocol(struct ndpi_detection_module_struct *ndpi_struct /* **************************************** */ /* See https://blog.catchpoint.com/2017/05/12/dissecting-tls-using-wireshark/ */ -static void processCertificateElements(struct ndpi_detection_module_struct *ndpi_struct, - struct ndpi_flow_struct *flow, - u_int16_t p_offset, u_int16_t certificate_len) { +void processCertificateElements(struct ndpi_detection_module_struct *ndpi_struct, + struct ndpi_flow_struct *flow, + u_int16_t p_offset, u_int16_t certificate_len) { struct ndpi_packet_struct *packet = &ndpi_struct->packet; u_int16_t num_found = 0, i; char buffer[64] = { '\0' }, rdnSeqBuf[2048]; @@ -427,7 +431,6 @@ static void processCertificateElements(struct ndpi_detection_module_struct *ndpi #endif } else if((packet->payload[i] == 0x30) && (packet->payload[i+1] == 0x1e) && (packet->payload[i+2] == 0x17)) { /* Certificate Validity */ - u_int8_t len = packet->payload[i+3]; u_int offset = i+4; if(num_found == 0) { @@ -450,8 +453,10 @@ static void processCertificateElements(struct ndpi_detection_module_struct *ndpi rdn_len = 0; /* Reset buffer */ } - if((offset+len) < packet->payload_packet_len) { + if(i + 3 < certificate_len && + (offset+packet->payload[i+3]) < packet->payload_packet_len) { char utcDate[32]; + u_int8_t len = packet->payload[i+3]; #ifdef DEBUG_TLS u_int j; @@ -568,7 +573,7 @@ static void processCertificateElements(struct ndpi_detection_module_struct *ndpi i += 3 /* skip the initial patten 55 1D 11 */; /* skip the first type, 0x04 == BIT STRING, and jump to it's length */ - if(packet->payload[i] == 0x04) i++; else i += 4; /* 4 bytes, with the last byte set to 04 */ + if(i < packet->payload_packet_len && packet->payload[i] == 0x04) i++; else i += 4; /* 4 bytes, with the last byte set to 04 */ if(i < packet->payload_packet_len) { i += (packet->payload[i] & 0x80) ? (packet->payload[i] & 0x7F) : 0; /* skip BIT STRING length */ |