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
FUZZ_TARGETS=fuzzer-preauth fuzzer-pubkey fuzzer-verify fuzzer-preauth_nomaths \
fuzzer-kexdh fuzzer-kexecdh fuzzer-kexcurve25519 fuzzer-client fuzzer-client_nomaths \
fuzzer-client_mutator fuzzer-client_mutator_nomaths
fuzzer-kexdh fuzzer-kexecdh fuzzer-kexcurve25519 fuzzer-client fuzzer-client_nomaths
FUZZER_OPTIONS = $(addsuffix .options, $(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)
$(CXX) $(CXXFLAGS) fuzz/$@.o $(LDFLAGS) $(allobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) -lcrypt
# fuzzers that use the custom mutator
fuzzer-client_mutator fuzzer-client_mutator_nomaths: allobjs += fuzz/fuzz-sshpacketmutator.o
# fuzzers that use the custom mutator - these expect a SSH network stream
MUTATOR_FUZZERS=fuzzer-client fuzzer-client_nomaths \
fuzzer-preauth fuzzer-preauth_nomaths
$(MUTATOR_FUZZERS): allobjs += fuzz/fuzz-sshpacketmutator.o
fuzzer-%.options: Makefile
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 "dbutil.h"
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 */
static void fuzz_get_packets(buffer *inp, buffer **out_packets, unsigned int *num_out_packets) {
/* 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 */
void buf_llvm_mutate(buffer *buf) {
/* Mutate a packet buffer in-place */
static void buf_llvm_mutate(buffer *buf) {
/* Position it after packet_length and padding_length */
const unsigned int offset = 5;
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 */
static buffer *oup;
static buffer *alloc_packetA;
@ -111,12 +126,11 @@ size_t LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size,
memcpy(randstate, &Seed, sizeof(Seed));
// printhex("mutator input", Data, Size);
#if 0
/* 1% chance straight llvm mutate */
if (nrand48(randstate) % 100 == 0) {
/* 0.1% chance straight llvm mutate */
if (nrand48(randstate) % 1000 == 0) {
return LLVMFuzzerMutate(Data, Size, MaxSize);
}
#endif
buffer inp_buf = {.data = Data, .size = Size, .len = Size, .pos = 0};
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);
}