Skip to content

Commit

Permalink
fuzz: add a new fuzzer to test TLS certificates (#1901)
Browse files Browse the repository at this point in the history
  • Loading branch information
IvanNardi authored Mar 20, 2023
1 parent 9f46d41 commit 0e80828
Show file tree
Hide file tree
Showing 21 changed files with 95 additions and 10 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
23 changes: 20 additions & 3 deletions fuzz/Makefile.am
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand All @@ -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)/{}'
Expand All @@ -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/*' \
Expand Down
Binary file added fuzz/corpus/fuzz_tls_certificate/1
Binary file not shown.
Binary file added fuzz/corpus/fuzz_tls_certificate/2
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
�H�
Binary file added fuzz/corpus/fuzz_tls_certificate/3
Binary file not shown.
Binary file added fuzz/corpus/fuzz_tls_certificate/4
Binary file not shown.
Binary file added fuzz/corpus/fuzz_tls_certificate/5
Binary file not shown.
Binary file added fuzz/corpus/fuzz_tls_certificate/6
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
��0���0
Binary file added fuzz/corpus/fuzz_tls_certificate/7
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
H
Binary file added fuzz/corpus/fuzz_tls_certificate/8
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
�H�,
Binary file added fuzz/corpus/fuzz_tls_certificate/9
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0��0���00�
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
H�
8 changes: 8 additions & 0 deletions fuzz/dictionary_tls_certificate.dict
Original file line number Diff line number Diff line change
@@ -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"
47 changes: 47 additions & 0 deletions fuzz/fuzz_tls_certificate.c
Original file line number Diff line number Diff line change
@@ -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;
}
19 changes: 12 additions & 7 deletions src/lib/protocols/tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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)
Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -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) {
Expand All @@ -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;
Expand Down Expand Up @@ -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 */
Expand Down

0 comments on commit 0e80828

Please sign in to comment.