fuzz: adds structure aware target

so as not to fuzz libpcap
and generate structure aware signatures
pull/6004/head
Philippe Antoine 5 years ago committed by Victor Julien
parent 0105d4f017
commit e8415f249b

@ -2527,6 +2527,8 @@ fi
])
AC_SUBST(RUST_FEATURES)
AC_CHECK_LIB(fuzzpcap, FPC_IsFuzzPacketCapture, HAS_FUZZPCAP="yes")
AM_CONDITIONAL([HAS_FUZZPCAP], [test "x$HAS_FUZZPCAP" = "xyes"])
AC_ARG_ENABLE(fuzztargets,
AS_HELP_STRING([--enable-fuzztargets], [Enable fuzz targets]),[enable_fuzztargets=$enableval],[enable_fuzztargets=no])
AM_CONDITIONAL([BUILD_FUZZTARGETS], [test "x$enable_fuzztargets" = "xyes"])

@ -5,6 +5,9 @@ if BUILD_FUZZTARGETS
fuzz_confyamlloadstring fuzz_decodepcapfile \
fuzz_sigpcap fuzz_mimedecparseline
endif
if HAS_FUZZPCAP
bin_PROGRAMS += fuzz_sigpcap_aware
endif
noinst_HEADERS = \
action-globals.h \
@ -1276,6 +1279,19 @@ endif
# force usage of CXX for linker
nodist_EXTRA_fuzz_sigpcap_SOURCES = force-cxx-linking.cxx
if HAS_FUZZPCAP
nodist_fuzz_sigpcap_aware_SOURCES = tests/fuzz/fuzz_sigpcap_aware.c
fuzz_sigpcap_aware_LDFLAGS = $(LDFLAGS_FUZZ)
fuzz_sigpcap_aware_LDADD = $(LDADD_FUZZ) -lfuzzpcap
if HAS_FUZZLDFLAGS
fuzz_sigpcap_aware_LDFLAGS += $(LIB_FUZZING_ENGINE)
else
nodist_fuzz_sigpcap_aware_SOURCES += tests/fuzz/onefile.c
endif
# force usage of CXX for linker
nodist_EXTRA_fuzz_sigpcap_aware_SOURCES = force-cxx-linking.cxx
endif
nodist_fuzz_mimedecparseline_SOURCES = tests/fuzz/fuzz_mimedecparseline.c
fuzz_mimedecparseline_LDFLAGS = $(LDFLAGS_FUZZ)
fuzz_mimedecparseline_LDADD = $(LDADD_FUZZ)

@ -0,0 +1,178 @@
/**
* @file
* @author Philippe Antoine <contact@catenacyber.fr>
* fuzz target for AppLayerProtoDetectGetProto
*/
#include "suricata-common.h"
#include "source-pcap-file.h"
#include "detect-engine.h"
#include "util-classification-config.h"
#include "util-reference-config.h"
#include "app-layer.h"
#include "tm-queuehandlers.h"
#include "util-cidr.h"
#include "util-proto-name.h"
#include "detect-engine-tag.h"
#include "detect-engine-threshold.h"
#include "host-bit.h"
#include "ippair-bit.h"
#include "app-layer-htp.h"
#include "detect-fast-pattern.h"
#include "util-unittest-helper.h"
#include "conf-yaml-loader.h"
#include "pkt-var.h"
#include <fuzz_pcap.h>
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
static int initialized = 0;
ThreadVars tv;
DecodeThreadVars *dtv;
// FlowWorkerThreadData
void *fwd;
SCInstance surifuzz;
#include "confyaml.c"
static void SigGenereateAware(const uint8_t *data, size_t size, char *r, size_t *len)
{
*len = snprintf(r, 511, "alert ip any any -> any any (");
for (size_t i = 0; i + 1 < size && *len < 511; i++) {
if (data[i] & 0x80) {
size_t off = (data[i] & 0x7F + ((data[i + 1] & 0xF) << 7)) %
(sizeof(sigmatch_table) / sizeof(SigTableElmt));
if (sigmatch_table[off].flags & SIGMATCH_NOOPT ||
((data[i + 1] & 0x80) && sigmatch_table[off].flags & SIGMATCH_OPTIONAL_OPT)) {
*len += snprintf(r + *len, 511 - *len, "; %s;", sigmatch_table[off].name);
} else {
*len += snprintf(r + *len, 511 - *len, "; %s:", sigmatch_table[off].name);
}
i++;
} else {
r[*len] = data[i];
*len = *len + 1;
}
}
if (*len < 511) {
*len += snprintf(r + *len, 511 - *len, ")");
} else {
r[511] = 0;
*len = 511;
}
}
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
FPC_buffer_t pkts;
const u_char *pkt;
struct pcap_pkthdr header;
int r;
Packet *p;
size_t pos;
size_t pcap_cnt = 0;
if (initialized == 0) {
// Redirects logs to /dev/null
setenv("SC_LOG_OP_IFACE", "file", 0);
setenv("SC_LOG_FILE", "/dev/null", 0);
InitGlobal();
GlobalsInitPreConfig();
run_mode = RUNMODE_PCAP_FILE;
// redirect logs to /tmp
ConfigSetLogDirectory("/tmp/");
// disables checksums validation for fuzzing
if (ConfYamlLoadString(configNoChecksum, strlen(configNoChecksum)) != 0) {
abort();
}
// do not load rules before reproducible DetectEngineReload
remove("/tmp/fuzz.rules");
surifuzz.sig_file = strdup("/tmp/fuzz.rules");
surifuzz.sig_file_exclusive = 1;
// loads rules after init
surifuzz.delayed_detect = 1;
PostConfLoadedSetup(&surifuzz);
PreRunPostPrivsDropInit(run_mode);
PostConfLoadedDetectSetup(&surifuzz);
memset(&tv, 0, sizeof(tv));
tv.flow_queue = FlowQueueNew();
if (tv.flow_queue == NULL)
abort();
dtv = DecodeThreadVarsAlloc(&tv);
DecodeRegisterPerfCounters(dtv, &tv);
tmm_modules[TMM_FLOWWORKER].ThreadInit(&tv, NULL, &fwd);
StatsSetupPrivate(&tv);
extern intmax_t max_pending_packets;
max_pending_packets = 128;
PacketPoolInit();
initialized = 1;
}
if (size < 1 + FPC0_HEADER_LEN) {
return 0;
}
for (pos = 0; pos < size - FPC0_HEADER_LEN; pos++) {
if (data[pos] == 0) {
break;
}
}
// initialize FPC with the buffer
if (FPC_init(&pkts, data + pos + 1, size - pos - 1) < 0) {
return 0;
}
// dump signatures to a file so as to reuse SigLoadSignatures
char sigaware[512];
size_t len;
SigGenereateAware(data, pos + 1, sigaware, &len);
if (TestHelperBufferToFile(surifuzz.sig_file, (uint8_t *)sigaware, len) < 0) {
return 0;
}
if (DetectEngineReload(&surifuzz) < 0) {
return 0;
}
// loop over packets
r = FPC_next(&pkts, &header, &pkt);
p = PacketGetFromAlloc();
p->ts.tv_sec = header.ts.tv_sec;
p->ts.tv_usec = header.ts.tv_usec;
p->datalink = pkts.datalink;
while (r > 0) {
if (PacketCopyData(p, pkt, header.caplen) == 0) {
// DecodePcapFile
TmEcode ecode = tmm_modules[TMM_DECODEPCAPFILE].Func(&tv, p, dtv);
if (ecode == TM_ECODE_FAILED) {
break;
}
Packet *extra_p = PacketDequeueNoLock(&tv.decode_pq);
while (extra_p != NULL) {
PacketFreeOrRelease(extra_p);
extra_p = PacketDequeueNoLock(&tv.decode_pq);
}
tmm_modules[TMM_FLOWWORKER].Func(&tv, p, fwd);
extra_p = PacketDequeueNoLock(&tv.decode_pq);
while (extra_p != NULL) {
PacketFreeOrRelease(extra_p);
extra_p = PacketDequeueNoLock(&tv.decode_pq);
}
}
r = FPC_next(&pkts, &header, &pkt);
PACKET_RECYCLE(p);
p->ts.tv_sec = header.ts.tv_sec;
p->ts.tv_usec = header.ts.tv_usec;
p->datalink = pkts.datalink;
pcap_cnt++;
p->pcap_cnt = pcap_cnt;
}
PacketFree(p);
return 0;
}
Loading…
Cancel
Save