Fuzzing Suricata: Finding Vulnerabilities in Large Projects Sirko Höer @golle0x90 1 Fuzzing Suricata : Finding Vulnerabilities in Large Projects Sirko Höer
Special thanks ● Robert Haist, DCSO ● Victor Julien, lead developer suricata, Open Infosec Foundation (OISF) ● Henning Perl, CTO, Code Intelligence ● Sergej Dechand, CEO, Code Intelligence 2 Fuzzing Suricata : Finding Vulnerabilities in Large Projects Sirko Höer
Disclaimer ● The methodologie mentioned here reflect my experiences about fuzz-testing and are not general approaches used by the BSI ! ● All opinions about Fuzzing expressed in this presentation are my opinions only. They are not the general opinion of the BSI ! 3 Fuzzing Suricata : Finding Vulnerabilities in Large Projects Sirko Höer
Table of content Introduction ● Methodology of Fuzzing Suricata ● Example: Ethernet Decoder Heap Buffer Overflow ● Conclusion ● 4 Fuzzing Suricata : Finding Vulnerabilities in Large Projects Sirko Höer
What is suricata Facts : - about 600k lines of code - more than 600 source files Open Source IDS / IPS / NSM ● - Uses Unit Tests and AFL Fuzzing (2019) Developed by Open Information Security Foundation ● - since March 2020 integration to google oss-fuzz written in c and rust ● Buildsystem: automake ● Version 5.0.3 ● 5 Fuzzing Suricata : Finding Vulnerabilities in Large Projects Sirko Höer
Methodology of Fuzzing Projects in general Analyse, Run Fuzzers, Setup Create Fuzz-Targets, Bug investigation, Debugging Bug report 6 Fuzzing Suricata : Finding Vulnerabilities in Large Projects Sirko Höer
Methodology of Fuzzing Suricata Analyse, Run Fuzzers, Setup Create Fuzz-Targets, Bug investigation, Debugging Bug report 7 Fuzzing Suricata : Finding Vulnerabilities in Large Projects Sirko Höer
My Setup Build process How to build the project ? ● $ user@host ./autogen $ user@host ./configure $ user@host make all -j$(nproc) Build the project 8 Fuzzing Suricata : Finding Vulnerabilities in Large Projects Sirko Höer
My Setup #!/usr/bin/sh set -e export CC=clang export CXX=clang++ Build process export ASAN_OPTIONS=detect_leaks=0 ./configure --disable-rust CFLAGS="-O1 -v -g -fPIC \ How to build the project ? ● -fsanitize-coverage=indirect-calls,trace-cmp,trace-div,trace-gep \ -fsanitize= address,fuzzer-no-link ,undefined,signed-integer-overflow,bool,pointer-o Create build script with sanitzer ● verflow" \ ○ patch object file LDFLAG="-fsanitize=address,fuzzer-no-link,undefined,signed-integer-overflow,bool,p ointer-overflow \ ○ pack all together -fsanitize-coverage=indirect-calls,trace-cmp,trace-div,trace-gep" \ make -j$(nproc) … echo "patch suricata.o ..." sed -i -e 's/main/mmmm/g' suricata.o echo "patched ..." echo "generate archiv suricata_fuzz.a ..." ar rv suricata_fuzz.a *.o echo "generated ..." build_suricata.sh Build parent Create build script 9 Fuzzing Suricata : Finding Vulnerabilities in Large Projects Sirko Höer
My Setup FROM base/archlinux #install main packages RUN echo "installing basic packages ..." Build process RUN pacman -Syu --noconfirm RUN pacman -S --noconfirm \ How to build the project ? ● screen \ git \ Create build script with sanitzer ● … Build fuzzing infrastructure (Docker) ● # install dep for suricata RUN pacman -Syu --noconfirm RUN pacman -S --noconfirm \ jansson \ libnet \ libyaml \ nss ... Dockerfile Build parent Create build script Create infra. 10 Fuzzing Suricata : Finding Vulnerabilities in Large Projects Sirko Höer
My Setup FUZZERS = fuzz_app \ ... fuzz_decoder_udp ... fuzz_%: $(src_target)/fuzz_%.c $(shell mkdir -p $(build_target)/$*) clang -O1 -g \ Build process $< \ ${CFLAGS} ${LDFLAGS} \ -DCLS=64 \ How to build the project ? ● -D HAVE_MAGIC \ Create build script with sanitzer -I../src -I../libhtp \ ● -fsanitize= fuzzer,address ,undefined, \ Build fuzzing infrastructure (Docker) ● signed-integer-overflow, \ bool,pointer-overflow \ Build Makefile for fuzz-targets ● -fsanitize-coverage=trace-pc-guard \ -fsanitize-thread-memory-access \ -lstdc++ \ -lmagic -lcap-ng -lpcap -lpthread -lnet -lyaml -lpcre -lz -llzma \ ../src/suricata_fuzz.a \ ../libhtp/htp/.libs/libhtp.a \ /usr/lib/liblz4.so \ -o $(build_target)/$*/$@ ... Makefile Build parent Create build script Create infra. Makefile 11 Fuzzing Suricata : Finding Vulnerabilities in Large Projects Sirko Höer
Methodology of Fuzzing Suricata Analyse, Bug investigation, Setup Fuzz-Targets, Bug report Running Tests 12 Fuzzing Suricata : Finding Vulnerabilities in Large Projects Sirko Höer
Analyse Biggest challenge: Finding entry points suricata ├── contrib Look at Unit-Test ├── doc ● ... ├── libhtp Look at Fuzz-Test (if fuzz-tests are available) ● ... ├── rust Look at the Bug-Tracker ● ├── src │ ├── alert-debuglog.c │ ├── alert-fastlog.c │ ├── alert-prelude.c │ ├── alert-syslog.c │ ├── alert-unified2-alert.c │ ├── app-layer.c │ ├── app-layer-dcerpc.c │ ├── app-layer-dcerpc-udp.c │ ├── app-layer-detect-proto.c │ ├── app-layer-dhcp.c │ ├── app-layer-dnp3.c … │ ├── app-layer-parser.c … │ ├── decode-erspan.c │ ├── decode-ethernet.c │ ├── decode-events.c ... │ ├── decode-gre.c │ ├── suricata.c ... └── suricata-update 13 Fuzzing Suricata : Finding Vulnerabilities in Large Projects Sirko Höer
Analyse Biggest challenge: Finding entry points suricata ├── contrib Look at Unit-Test ├── doc ● ... ├── libhtp Look at Fuzz-Test (if fuzz-tests are available) ● ... ├── rust Look at the Bug-Tracker ● ├── src │ ├── alert-debuglog.c │ ├── alert-fastlog.c │ ├── alert-prelude.c │ ├── alert-syslog.c │ ├── alert-unified2-alert.c │ ├── app-layer.c │ ├── app-layer-dcerpc.c │ ├── app-layer-dcerpc-udp.c │ ├── app-layer-detect-proto.c │ ├── app-layer-dhcp.c │ ├── app-layer-dnp3.c In this case, I look at: … │ ├── app-layer-parser.c … │ ├── decode-erspan.c Entrypoint : src/suricata.c ● │ ├── decode-ethernet.c │ ├── decode-events.c Unit-Tests: src/tests/*.c ● ... │ ├── decode-gre.c │ ├── suricata.c ... └── suricata-update 14 Fuzzing Suricata : Finding Vulnerabilities in Large Projects Sirko Höer
Analyse Find interesting things Fuzz-targets for AFL: ... 1183 static void ParseCommandLineAFL(const char *opt_name, char *opt_arg){ 1184 #ifdef AFLFUZZ_RULES About 25 written Targets (2019) ● 1185 if(strcmp(opt_name, "afl-rules") == 0) { MpmTableSetup(); App-Layer: ● . SpmTableSetup(); . http-request / response ○ . exit(RuleParseDataFromFile(opt_arg)); } else smb-request / response ○ #endif smtp ○ #ifdef AFLFUZZ_APPLAYER Low-Level decoder ● if(strcmp(opt_name, "afl-http-request") == 0) { //printf("arg: //%s\n", opt_arg); IPv4 / IPv6 decoder ○ MpmTableSetup(); PPP-decoder ○ SpmTableSetup(); Ethernet-decoder AppLayerProtoDetectSetup(); ○ AppLayerParserSetup(); RegisterHTPParsers(); exit(AppLayerParserRequestFromFile(IPPROTO_TCP, ALPROTO_HTTP, opt_arg)); } ... 1268 suricata.c 15 Fuzzing Suricata : Finding Vulnerabilities in Large Projects Sirko Höer
Analyse Finding good Fuzz-Targets Example: ● RuleParseDataFromFile(...) int RuleParseDataFromFile(char *filename) { ● AppLayerParserRequestFromFile(...) ... SigTableSetup(); ● AppLayerParserFromFile(...) SCReferenceConfInit(); SCClassConfInit(); ● MimeParserDataFromFile(...) DetectEngineCtx *de_ctx = DetectEngineCtxInit(); ... while (__AFL_LOOP(10000)) { ● DecoderParseDataFromFile(...) ... size_t result = fread(&buffer, 1, sizeof(buffer), fp); ● DerParseDataFromFile(...) if (result < sizeof(buffer)) { buffer[result] = '\0'; ● ConfYamlLoadString(...) Signature *s = SigInit(de_ctx, buffer); if (s != NULL) { SigFree(s); } } ... DetectEngineCtxFree(de_ctx); SCClassConfDeinit(); SCReferenceConfDeinit(); decoder-afl.c } 16 Fuzzing Suricata : Finding Vulnerabilities in Large Projects Sirko Höer
The Fuzz-Target (Example) /* Include files */ … Creating Fuzz-Targets int LLVMFuzzerInitialize( int *argc, char ***argv) { MpmTableSetup(); SpmTableSetup(); AppLayerProtoDetectSetup(); ... AppLayerParserSetup(); if(strcmp(opt_name, "afl-http-request") == 0) { AppLayerParserRegisterProtocolParsers(); //printf("arg: //%s\n", opt_arg); MpmTableSetup(); /* Initialize random number generator */ SpmTableSetup(); srand(0); AppLayerProtoDetectSetup(); return 0; AppLayerParserSetup(); } RegisterHTPParsers(); exit(AppLayerParserRequestFromFile(IPPROTO_TCP, ALPROTO_HTTP, opt_arg)); AppProto AppProtoFromData() { ... } else if(strcmp(opt_name, "afl-tls") == 0) { return rand() % ALPROTO_MAX; //printf("arg: //%s\n", opt_arg); } MpmTableSetup(); ... SpmTableSetup(); AppLayerProtoDetectSetup(); AppLayerParserSetup(); RegisterSSLParsers(); exit(AppLayerParserFromFile(IPPROTO_TCP, ALPROTO_TLS, opt_arg)); ... suricata.c fuzz_app.c 17 Fuzzing Suricata : Finding Vulnerabilities in Large Projects Sirko Höer
Recommend
More recommend