mirror of
https://github.com/clearml/dropbear
synced 2025-03-03 10:41:39 +00:00
add fuzzer-preauth_nomaths
--HG-- branch : fuzz
This commit is contained in:
parent
597f7eb5e9
commit
89bdf3b0b9
@ -247,7 +247,7 @@ default_options.h: default_options.h.in
|
||||
## Fuzzing targets
|
||||
|
||||
# list of fuzz targets
|
||||
FUZZ_TARGETS=fuzzer-preauth fuzzer-pubkey fuzzer-verify
|
||||
FUZZ_TARGETS=fuzzer-preauth fuzzer-pubkey fuzzer-verify fuzzer-preauth_nomaths
|
||||
|
||||
FUZZER_OPTIONS = $(addsuffix .options, $(FUZZ_TARGETS))
|
||||
|
||||
@ -269,6 +269,10 @@ fuzz-targets: $(FUZZ_TARGETS) $(FUZZER_OPTIONS)
|
||||
fuzzer-preauth: fuzzer-preauth.o $(HEADERS) $(LIBTOM_DEPS) Makefile $(svrfuzzobjs)
|
||||
$(CXX) $(CXXFLAGS) $@.o $(LDFLAGS) $(svrfuzzobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@
|
||||
|
||||
fuzzer-preauth_nomaths: fuzzer-preauth_nomaths.o $(HEADERS) $(LIBTOM_DEPS) Makefile $(svrfuzzobjs)
|
||||
$(CXX) $(CXXFLAGS) $@.o $(LDFLAGS) $(svrfuzzobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@
|
||||
|
||||
|
||||
fuzzer-pubkey: fuzzer-pubkey.o $(HEADERS) $(LIBTOM_DEPS) Makefile $(svrfuzzobjs)
|
||||
$(CXX) $(CXXFLAGS) $@.o $(LDFLAGS) $(svrfuzzobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@
|
||||
|
||||
|
@ -48,7 +48,6 @@ static void read_kex_algos(void);
|
||||
/* helper function for gen_new_keys */
|
||||
static void hashkeys(unsigned char *out, unsigned int outlen,
|
||||
const hash_state * hs, const unsigned char X);
|
||||
static void finish_kexhashbuf(void);
|
||||
|
||||
|
||||
/* Send our list of algorithms we can use */
|
||||
@ -769,8 +768,7 @@ void kexcurve25519_comb_key(struct kex_curve25519_param *param, buffer *buf_pub_
|
||||
#endif /* DROPBEAR_CURVE25519 */
|
||||
|
||||
|
||||
|
||||
static void finish_kexhashbuf(void) {
|
||||
void finish_kexhashbuf(void) {
|
||||
hash_state hs;
|
||||
const struct ltc_hash_descriptor *hash_desc = ses.newkeys->algo_kex->hash_desc;
|
||||
|
||||
|
2
debug.h
2
debug.h
@ -49,7 +49,9 @@
|
||||
/*#define CHECKCLEARTOWRITE() assert(ses.writepayload->len == 0 && \
|
||||
ses.writepayload->pos == 0)*/
|
||||
|
||||
#ifndef CHECKCLEARTOWRITE
|
||||
#define CHECKCLEARTOWRITE()
|
||||
#endif
|
||||
|
||||
/* Define this, compile with -pg and set GMON_OUT_PREFIX=gmon to get gmon
|
||||
* output when Dropbear forks. This will allow it gprof to be used.
|
||||
|
@ -14,7 +14,7 @@ struct dropbear_fuzz_options fuzz;
|
||||
static void fuzz_dropbear_log(int UNUSED(priority), const char* format, va_list param);
|
||||
static void load_fixed_hostkeys(void);
|
||||
|
||||
void common_setup_fuzzer(void) {
|
||||
void fuzz_common_setup(void) {
|
||||
fuzz.fuzzing = 1;
|
||||
fuzz.wrapfds = 1;
|
||||
fuzz.do_jmp = 1;
|
||||
@ -23,7 +23,7 @@ void common_setup_fuzzer(void) {
|
||||
crypto_init();
|
||||
}
|
||||
|
||||
int fuzzer_set_input(const uint8_t *Data, size_t Size) {
|
||||
int fuzz_set_input(const uint8_t *Data, size_t Size) {
|
||||
|
||||
fuzz.input->data = (unsigned char*)Data;
|
||||
fuzz.input->size = Size;
|
||||
@ -51,10 +51,10 @@ static void fuzz_dropbear_log(int UNUSED(priority), const char* format, va_list
|
||||
#endif
|
||||
}
|
||||
|
||||
void svr_setup_fuzzer(void) {
|
||||
void fuzz_svr_setup(void) {
|
||||
struct passwd *pw;
|
||||
|
||||
common_setup_fuzzer();
|
||||
fuzz_common_setup();
|
||||
|
||||
_dropbear_exit = svr_dropbear_exit;
|
||||
|
||||
@ -130,3 +130,57 @@ void fuzz_get_socket_address(int UNUSED(fd), char **local_host, char **local_por
|
||||
*remote_port = m_strdup("9876");
|
||||
}
|
||||
}
|
||||
|
||||
/* cut down version of svr_send_msg_kexdh_reply() that skips slow maths. Still populates structures */
|
||||
void fuzz_fake_send_kexdh_reply(void) {
|
||||
assert(!ses.dh_K);
|
||||
m_mp_alloc_init_multi(&ses.dh_K, NULL);
|
||||
mp_set_int(ses.dh_K, 12345678);
|
||||
finish_kexhashbuf();
|
||||
assert(!ses.dh_K);
|
||||
}
|
||||
|
||||
int fuzz_run_preauth(const uint8_t *Data, size_t Size, int skip_kexmaths) {
|
||||
static int once = 0;
|
||||
if (!once) {
|
||||
fuzz_svr_setup();
|
||||
fuzz.skip_kexmaths = skip_kexmaths;
|
||||
once = 1;
|
||||
}
|
||||
|
||||
if (fuzz_set_input(Data, Size) == DROPBEAR_FAILURE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// get prefix. input format is
|
||||
// string prefix
|
||||
// uint32 wrapfd seed
|
||||
// ... to be extended later
|
||||
// [bytes] ssh input stream
|
||||
|
||||
// be careful to avoid triggering buffer.c assertions
|
||||
if (fuzz.input->len < 8) {
|
||||
return 0;
|
||||
}
|
||||
size_t prefix_size = buf_getint(fuzz.input);
|
||||
if (prefix_size != 4) {
|
||||
return 0;
|
||||
}
|
||||
uint32_t wrapseed = buf_getint(fuzz.input);
|
||||
wrapfd_setseed(wrapseed);
|
||||
|
||||
int fakesock = 20;
|
||||
wrapfd_add(fakesock, fuzz.input, PLAIN);
|
||||
|
||||
m_malloc_set_epoch(1);
|
||||
if (setjmp(fuzz.jmp) == 0) {
|
||||
svr_session(fakesock, fakesock);
|
||||
m_malloc_free_epoch(1, 0);
|
||||
} else {
|
||||
m_malloc_free_epoch(1, 1);
|
||||
TRACE(("dropbear_exit longjmped"))
|
||||
// dropbear_exit jumped here
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
12
fuzz.h
12
fuzz.h
@ -10,12 +10,14 @@
|
||||
#include "fuzz-wrapfd.h"
|
||||
|
||||
// once per process
|
||||
void common_setup_fuzzer(void);
|
||||
void svr_setup_fuzzer(void);
|
||||
void fuzz_common_setup(void);
|
||||
void fuzz_svr_setup(void);
|
||||
|
||||
// must be called once per fuzz iteration.
|
||||
// returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE
|
||||
int fuzzer_set_input(const uint8_t *Data, size_t Size);
|
||||
int fuzz_set_input(const uint8_t *Data, size_t Size);
|
||||
|
||||
int fuzz_run_preauth(const uint8_t *Data, size_t Size, int skip_kexmaths);
|
||||
|
||||
// fuzzer functions that intrude into general code
|
||||
void fuzz_kex_fakealgos(void);
|
||||
@ -26,6 +28,7 @@ extern const char * const * fuzz_signkey_names;
|
||||
void fuzz_seed(void);
|
||||
void fuzz_get_socket_address(int fd, char **local_host, char **local_port,
|
||||
char **remote_host, char **remote_port, int host_lookup);
|
||||
void fuzz_fake_send_kexdh_reply(void);
|
||||
|
||||
// fake IO wrappers
|
||||
#ifndef FUZZ_SKIP_WRAP
|
||||
@ -48,6 +51,9 @@ struct dropbear_fuzz_options {
|
||||
struct dropbear_hash recv_mac;
|
||||
int wrapfds;
|
||||
|
||||
// whether to skip slow bignum maths
|
||||
int skip_kexmaths;
|
||||
|
||||
// dropbear_exit() jumps back
|
||||
int do_jmp;
|
||||
sigjmp_buf jmp;
|
||||
|
@ -1,53 +1,6 @@
|
||||
#include "fuzz.h"
|
||||
#include "session.h"
|
||||
#include "fuzz-wrapfd.h"
|
||||
#include "debug.h"
|
||||
|
||||
static void setup_fuzzer(void) {
|
||||
svr_setup_fuzzer();
|
||||
//debug_trace = 1;
|
||||
}
|
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
||||
static int once = 0;
|
||||
if (!once) {
|
||||
setup_fuzzer();
|
||||
once = 1;
|
||||
}
|
||||
|
||||
if (fuzzer_set_input(Data, Size) == DROPBEAR_FAILURE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// get prefix. input format is
|
||||
// string prefix
|
||||
// uint32 wrapfd seed
|
||||
// ... to be extended later
|
||||
// [bytes] ssh input stream
|
||||
|
||||
// be careful to avoid triggering buffer.c assertions
|
||||
if (fuzz.input->len < 8) {
|
||||
return 0;
|
||||
}
|
||||
size_t prefix_size = buf_getint(fuzz.input);
|
||||
if (prefix_size != 4) {
|
||||
return 0;
|
||||
}
|
||||
uint32_t wrapseed = buf_getint(fuzz.input);
|
||||
wrapfd_setseed(wrapseed);
|
||||
|
||||
int fakesock = 20;
|
||||
wrapfd_add(fakesock, fuzz.input, PLAIN);
|
||||
|
||||
m_malloc_set_epoch(1);
|
||||
if (setjmp(fuzz.jmp) == 0) {
|
||||
svr_session(fakesock, fakesock);
|
||||
m_malloc_free_epoch(1, 0);
|
||||
} else {
|
||||
m_malloc_free_epoch(1, 1);
|
||||
TRACE(("dropbear_exit longjmped"))
|
||||
// dropbear_exit jumped here
|
||||
}
|
||||
|
||||
return 0;
|
||||
return fuzz_run_preauth(Data, Size, 0);
|
||||
}
|
||||
|
||||
|
6
fuzzer-preauth_nomaths.c
Normal file
6
fuzzer-preauth_nomaths.c
Normal file
@ -0,0 +1,6 @@
|
||||
#include "fuzz.h"
|
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
||||
return fuzz_run_preauth(Data, Size, 1);
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "debug.h"
|
||||
|
||||
static void setup_fuzzer(void) {
|
||||
common_setup_fuzzer();
|
||||
fuzz_common_setup();
|
||||
}
|
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
||||
@ -14,7 +14,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
||||
once = 1;
|
||||
}
|
||||
|
||||
if (fuzzer_set_input(Data, Size) == DROPBEAR_FAILURE) {
|
||||
if (fuzz_set_input(Data, Size) == DROPBEAR_FAILURE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "debug.h"
|
||||
|
||||
static void setup_fuzzer(void) {
|
||||
common_setup_fuzzer();
|
||||
fuzz_common_setup();
|
||||
}
|
||||
|
||||
static buffer *verifydata;
|
||||
@ -19,7 +19,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
||||
once = 1;
|
||||
}
|
||||
|
||||
if (fuzzer_set_input(Data, Size) == DROPBEAR_FAILURE) {
|
||||
if (fuzz_set_input(Data, Size) == DROPBEAR_FAILURE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
1
kex.h
1
kex.h
@ -34,6 +34,7 @@ void recv_msg_kexinit(void);
|
||||
void send_msg_newkeys(void);
|
||||
void recv_msg_newkeys(void);
|
||||
void kexfirstinitialise(void);
|
||||
void finish_kexhashbuf(void);
|
||||
|
||||
struct kex_dh_param *gen_kexdh_param(void);
|
||||
void free_kexdh_param(struct kex_dh_param *param);
|
||||
|
@ -179,6 +179,13 @@ static void send_msg_kexdh_reply(mp_int *dh_e, buffer *ecdh_qs) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DROPBEAR_FUZZ
|
||||
if (fuzz.fuzzing && fuzz.skip_kexmaths) {
|
||||
fuzz_fake_send_kexdh_reply();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
buf_putbyte(ses.writepayload, SSH_MSG_KEXDH_REPLY);
|
||||
buf_put_pub_key(ses.writepayload, svr_opts.hostkey,
|
||||
ses.newkeys->algo_hostkey);
|
||||
|
Loading…
Reference in New Issue
Block a user