Use SSH packet mutator for preauth too

Get rid of separate client mutator.
Have 0.1% chance of llvm random mutation
Add comments
This commit is contained in:
Matt Johnston 2020-10-29 22:41:37 +08:00
parent 6cf29061c2
commit 6aa065b1b4
4 changed files with 30 additions and 27 deletions

View File

@ -269,8 +269,7 @@ lint:
# list of fuzz targets # list of fuzz targets
FUZZ_TARGETS=fuzzer-preauth fuzzer-pubkey fuzzer-verify fuzzer-preauth_nomaths \ FUZZ_TARGETS=fuzzer-preauth fuzzer-pubkey fuzzer-verify fuzzer-preauth_nomaths \
fuzzer-kexdh fuzzer-kexecdh fuzzer-kexcurve25519 fuzzer-client fuzzer-client_nomaths \ fuzzer-kexdh fuzzer-kexecdh fuzzer-kexcurve25519 fuzzer-client fuzzer-client_nomaths
fuzzer-client_mutator fuzzer-client_mutator_nomaths
FUZZER_OPTIONS = $(addsuffix .options, $(FUZZ_TARGETS)) FUZZER_OPTIONS = $(addsuffix .options, $(FUZZ_TARGETS))
FUZZ_OBJS = $(addprefix fuzz/,$(addsuffix .o,$(FUZZ_TARGETS))) \ FUZZ_OBJS = $(addprefix fuzz/,$(addsuffix .o,$(FUZZ_TARGETS))) \
@ -293,8 +292,10 @@ fuzz-targets: $(FUZZ_TARGETS) $(FUZZER_OPTIONS)
$(FUZZ_TARGETS): $(FUZZ_OBJS) $(allobjs) $(LIBTOM_DEPS) $(FUZZ_TARGETS): $(FUZZ_OBJS) $(allobjs) $(LIBTOM_DEPS)
$(CXX) $(CXXFLAGS) fuzz/$@.o $(LDFLAGS) $(allobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) -lcrypt $(CXX) $(CXXFLAGS) fuzz/$@.o $(LDFLAGS) $(allobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) -lcrypt
# fuzzers that use the custom mutator # fuzzers that use the custom mutator - these expect a SSH network stream
fuzzer-client_mutator fuzzer-client_mutator_nomaths: allobjs += fuzz/fuzz-sshpacketmutator.o MUTATOR_FUZZERS=fuzzer-client fuzzer-client_nomaths \
fuzzer-preauth fuzzer-preauth_nomaths
$(MUTATOR_FUZZERS): allobjs += fuzz/fuzz-sshpacketmutator.o
fuzzer-%.options: Makefile fuzzer-%.options: Makefile
echo "[libfuzzer]" > $@ echo "[libfuzzer]" > $@

View File

@ -1,8 +1,28 @@
/* A mutator/crossover for SSH protocol streams.
Attempts to mutate each SSH packet individually, keeping
lengths intact.
It will prepend a SSH-2.0-dbfuzz\r\n version string.
Linking this file to a binary will make libfuzzer pick up the custom mutator.
Care is taken to avoid memory allocation which would otherwise
slow exec/s substantially */
#include "fuzz.h" #include "fuzz.h"
#include "dbutil.h" #include "dbutil.h"
size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize); size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize);
static const char* FIXED_VERSION = "SSH-2.0-dbfuzz\r\n";
static const size_t MAX_FUZZ_PACKETS = 500;
/* XXX This might need tuning */
static const size_t MAX_OUT_SIZE = 50000;
/* Splits packets from an input stream buffer "inp".
The initial SSH version identifier is discarded.
If packets are not recognised it will increment until an uint32 of valid
packet length is found. */
/* out_packets an array of num_out_packets*buffer, each of size RECV_MAX_PACKET_LEN */ /* out_packets an array of num_out_packets*buffer, each of size RECV_MAX_PACKET_LEN */
static void fuzz_get_packets(buffer *inp, buffer **out_packets, unsigned int *num_out_packets) { static void fuzz_get_packets(buffer *inp, buffer **out_packets, unsigned int *num_out_packets) {
/* Skip any existing banner. Format is /* Skip any existing banner. Format is
@ -52,8 +72,8 @@ static void fuzz_get_packets(buffer *inp, buffer **out_packets, unsigned int *nu
} }
} }
/* Mutate in-place */ /* Mutate a packet buffer in-place */
void buf_llvm_mutate(buffer *buf) { static void buf_llvm_mutate(buffer *buf) {
/* Position it after packet_length and padding_length */ /* Position it after packet_length and padding_length */
const unsigned int offset = 5; const unsigned int offset = 5;
if (buf->len < offset) { if (buf->len < offset) {
@ -69,11 +89,6 @@ void buf_llvm_mutate(buffer *buf) {
} }
static const char* FIXED_VERSION = "SSH-2.0-dbfuzz\r\n";
static const size_t MAX_FUZZ_PACKETS = 500;
/* XXX This might need tuning */
static const size_t MAX_OUT_SIZE = 50000;
/* Persistent buffers to avoid constant allocations */ /* Persistent buffers to avoid constant allocations */
static buffer *oup; static buffer *oup;
static buffer *alloc_packetA; static buffer *alloc_packetA;
@ -111,12 +126,11 @@ size_t LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size,
memcpy(randstate, &Seed, sizeof(Seed)); memcpy(randstate, &Seed, sizeof(Seed));
// printhex("mutator input", Data, Size); // printhex("mutator input", Data, Size);
#if 0
/* 1% chance straight llvm mutate */ /* 0.1% chance straight llvm mutate */
if (nrand48(randstate) % 100 == 0) { if (nrand48(randstate) % 1000 == 0) {
return LLVMFuzzerMutate(Data, Size, MaxSize); return LLVMFuzzerMutate(Data, Size, MaxSize);
} }
#endif
buffer inp_buf = {.data = Data, .size = Size, .len = Size, .pos = 0}; buffer inp_buf = {.data = Data, .size = Size, .len = Size, .pos = 0};
buffer *inp = &inp_buf; buffer *inp = &inp_buf;

View File

@ -1,6 +0,0 @@
#include "fuzz.h"
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
return fuzz_run_client(Data, Size, 0);
}

View File

@ -1,6 +0,0 @@
#include "fuzz.h"
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
return fuzz_run_client(Data, Size, 0);
}