mirror of
https://github.com/clearml/dropbear
synced 2025-03-03 18:52:00 +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
|
## Fuzzing targets
|
||||||
|
|
||||||
# list of fuzz 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))
|
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)
|
fuzzer-preauth: fuzzer-preauth.o $(HEADERS) $(LIBTOM_DEPS) Makefile $(svrfuzzobjs)
|
||||||
$(CXX) $(CXXFLAGS) $@.o $(LDFLAGS) $(svrfuzzobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@
|
$(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)
|
fuzzer-pubkey: fuzzer-pubkey.o $(HEADERS) $(LIBTOM_DEPS) Makefile $(svrfuzzobjs)
|
||||||
$(CXX) $(CXXFLAGS) $@.o $(LDFLAGS) $(svrfuzzobjs) -o $@$(EXEEXT) $(LIBTOM_LIBS) $(LIBS) $(FUZZLIB) @CRYPTLIB@
|
$(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 */
|
/* helper function for gen_new_keys */
|
||||||
static void hashkeys(unsigned char *out, unsigned int outlen,
|
static void hashkeys(unsigned char *out, unsigned int outlen,
|
||||||
const hash_state * hs, const unsigned char X);
|
const hash_state * hs, const unsigned char X);
|
||||||
static void finish_kexhashbuf(void);
|
|
||||||
|
|
||||||
|
|
||||||
/* Send our list of algorithms we can use */
|
/* 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 */
|
#endif /* DROPBEAR_CURVE25519 */
|
||||||
|
|
||||||
|
|
||||||
|
void finish_kexhashbuf(void) {
|
||||||
static void finish_kexhashbuf(void) {
|
|
||||||
hash_state hs;
|
hash_state hs;
|
||||||
const struct ltc_hash_descriptor *hash_desc = ses.newkeys->algo_kex->hash_desc;
|
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 && \
|
/*#define CHECKCLEARTOWRITE() assert(ses.writepayload->len == 0 && \
|
||||||
ses.writepayload->pos == 0)*/
|
ses.writepayload->pos == 0)*/
|
||||||
|
|
||||||
|
#ifndef CHECKCLEARTOWRITE
|
||||||
#define CHECKCLEARTOWRITE()
|
#define CHECKCLEARTOWRITE()
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Define this, compile with -pg and set GMON_OUT_PREFIX=gmon to get gmon
|
/* 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.
|
* 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 fuzz_dropbear_log(int UNUSED(priority), const char* format, va_list param);
|
||||||
static void load_fixed_hostkeys(void);
|
static void load_fixed_hostkeys(void);
|
||||||
|
|
||||||
void common_setup_fuzzer(void) {
|
void fuzz_common_setup(void) {
|
||||||
fuzz.fuzzing = 1;
|
fuzz.fuzzing = 1;
|
||||||
fuzz.wrapfds = 1;
|
fuzz.wrapfds = 1;
|
||||||
fuzz.do_jmp = 1;
|
fuzz.do_jmp = 1;
|
||||||
@ -23,7 +23,7 @@ void common_setup_fuzzer(void) {
|
|||||||
crypto_init();
|
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->data = (unsigned char*)Data;
|
||||||
fuzz.input->size = Size;
|
fuzz.input->size = Size;
|
||||||
@ -51,10 +51,10 @@ static void fuzz_dropbear_log(int UNUSED(priority), const char* format, va_list
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void svr_setup_fuzzer(void) {
|
void fuzz_svr_setup(void) {
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
|
|
||||||
common_setup_fuzzer();
|
fuzz_common_setup();
|
||||||
|
|
||||||
_dropbear_exit = svr_dropbear_exit;
|
_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");
|
*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"
|
#include "fuzz-wrapfd.h"
|
||||||
|
|
||||||
// once per process
|
// once per process
|
||||||
void common_setup_fuzzer(void);
|
void fuzz_common_setup(void);
|
||||||
void svr_setup_fuzzer(void);
|
void fuzz_svr_setup(void);
|
||||||
|
|
||||||
// must be called once per fuzz iteration.
|
// must be called once per fuzz iteration.
|
||||||
// returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE
|
// 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
|
// fuzzer functions that intrude into general code
|
||||||
void fuzz_kex_fakealgos(void);
|
void fuzz_kex_fakealgos(void);
|
||||||
@ -26,6 +28,7 @@ extern const char * const * fuzz_signkey_names;
|
|||||||
void fuzz_seed(void);
|
void fuzz_seed(void);
|
||||||
void fuzz_get_socket_address(int fd, char **local_host, char **local_port,
|
void fuzz_get_socket_address(int fd, char **local_host, char **local_port,
|
||||||
char **remote_host, char **remote_port, int host_lookup);
|
char **remote_host, char **remote_port, int host_lookup);
|
||||||
|
void fuzz_fake_send_kexdh_reply(void);
|
||||||
|
|
||||||
// fake IO wrappers
|
// fake IO wrappers
|
||||||
#ifndef FUZZ_SKIP_WRAP
|
#ifndef FUZZ_SKIP_WRAP
|
||||||
@ -48,6 +51,9 @@ struct dropbear_fuzz_options {
|
|||||||
struct dropbear_hash recv_mac;
|
struct dropbear_hash recv_mac;
|
||||||
int wrapfds;
|
int wrapfds;
|
||||||
|
|
||||||
|
// whether to skip slow bignum maths
|
||||||
|
int skip_kexmaths;
|
||||||
|
|
||||||
// dropbear_exit() jumps back
|
// dropbear_exit() jumps back
|
||||||
int do_jmp;
|
int do_jmp;
|
||||||
sigjmp_buf jmp;
|
sigjmp_buf jmp;
|
||||||
|
@ -1,53 +1,6 @@
|
|||||||
#include "fuzz.h"
|
#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) {
|
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
||||||
static int once = 0;
|
return fuzz_run_preauth(Data, Size, 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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"
|
#include "debug.h"
|
||||||
|
|
||||||
static void setup_fuzzer(void) {
|
static void setup_fuzzer(void) {
|
||||||
common_setup_fuzzer();
|
fuzz_common_setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
||||||
@ -14,7 +14,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
|||||||
once = 1;
|
once = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fuzzer_set_input(Data, Size) == DROPBEAR_FAILURE) {
|
if (fuzz_set_input(Data, Size) == DROPBEAR_FAILURE) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
static void setup_fuzzer(void) {
|
static void setup_fuzzer(void) {
|
||||||
common_setup_fuzzer();
|
fuzz_common_setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
static buffer *verifydata;
|
static buffer *verifydata;
|
||||||
@ -19,7 +19,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
|||||||
once = 1;
|
once = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fuzzer_set_input(Data, Size) == DROPBEAR_FAILURE) {
|
if (fuzz_set_input(Data, Size) == DROPBEAR_FAILURE) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1
kex.h
1
kex.h
@ -34,6 +34,7 @@ void recv_msg_kexinit(void);
|
|||||||
void send_msg_newkeys(void);
|
void send_msg_newkeys(void);
|
||||||
void recv_msg_newkeys(void);
|
void recv_msg_newkeys(void);
|
||||||
void kexfirstinitialise(void);
|
void kexfirstinitialise(void);
|
||||||
|
void finish_kexhashbuf(void);
|
||||||
|
|
||||||
struct kex_dh_param *gen_kexdh_param(void);
|
struct kex_dh_param *gen_kexdh_param(void);
|
||||||
void free_kexdh_param(struct kex_dh_param *param);
|
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
|
#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_putbyte(ses.writepayload, SSH_MSG_KEXDH_REPLY);
|
||||||
buf_put_pub_key(ses.writepayload, svr_opts.hostkey,
|
buf_put_pub_key(ses.writepayload, svr_opts.hostkey,
|
||||||
ses.newkeys->algo_hostkey);
|
ses.newkeys->algo_hostkey);
|
||||||
|
Loading…
Reference in New Issue
Block a user