From 389d1f127f6380cdb3f18e3d4bc13ab354f06804 Mon Sep 17 00:00:00 2001 From: jausten Date: Fri, 28 Jul 2023 22:02:58 -0600 Subject: [PATCH 01/13] Initial commit --- packer/interpreter/build/interpreter.h | 2 +- .../spec_lib/templates/interpreter.jinja.h | 4 +- .../src/ld_preload_fuzz.c | 52 ++++++++++--------- .../src/netfuzz/inject.c | 17 ++++++ .../src/netfuzz/syscalls.c | 31 +++++++++++ .../src/netfuzz/syscalls.h | 3 ++ 6 files changed, 81 insertions(+), 28 deletions(-) diff --git a/packer/interpreter/build/interpreter.h b/packer/interpreter/build/interpreter.h index 4302663..ccf857e 100644 --- a/packer/interpreter/build/interpreter.h +++ b/packer/interpreter/build/interpreter.h @@ -57,7 +57,7 @@ typedef struct { size_t ops_i; uint8_t* data; - size_t* data_len; + uint32_t* data_len; size_t data_i; uint32_t* instruction_counter; diff --git a/packer/interpreter/spec_lib/templates/interpreter.jinja.h b/packer/interpreter/spec_lib/templates/interpreter.jinja.h index e4955d3..d0abee0 100644 --- a/packer/interpreter/spec_lib/templates/interpreter.jinja.h +++ b/packer/interpreter/spec_lib/templates/interpreter.jinja.h @@ -43,7 +43,7 @@ typedef struct { size_t ops_i; uint8_t* data; - size_t* data_len; + uint32_t* data_len; size_t data_i; uint32_t* instruction_counter; @@ -116,7 +116,7 @@ interpreter_t* new_interpreter(){ return vm; } -void init_interpreter(interpreter_t* vm, uint16_t* ops, size_t* ops_len, uint8_t* data, size_t* data_len, uint32_t* instruction_counter){ +void init_interpreter(interpreter_t* vm, uint16_t* ops, size_t* ops_len, uint8_t* data, uint32_t* data_len, uint32_t* instruction_counter){ vm->ops=ops; vm->ops_len=ops_len; vm->ops_i = 0; diff --git a/packer/linux_x86_64-userspace/src/ld_preload_fuzz.c b/packer/linux_x86_64-userspace/src/ld_preload_fuzz.c index 22f8df6..7a96529 100644 --- a/packer/linux_x86_64-userspace/src/ld_preload_fuzz.c +++ b/packer/linux_x86_64-userspace/src/ld_preload_fuzz.c @@ -252,11 +252,26 @@ ssize_t call_vm(void *data, size_t max_size, bool return_pkt_size, bool disable_ //hprintf("%s: 2: %p\n", __func__, vm->user_data); //hprintf("%s: 3: %p\n", __func__, vm->user_data->len); - if(interpreter_run(vm)==0){ + if (!vm->data_len || *vm->data_len == 0){ DEBUG("%s: out of data\n", __func__); return -1; } + if (*vm->data_len > PACKET_BUFFER_SIZE){ + DEBUG("%s: input size %d too large for buffer\n", __func__, *vm->data_len); + return -1; + } + + DEBUG("DATA: %d\n", *(uint32_t*)vm->data); + DEBUG("Copy %d input bytes from %p to %p\n", *vm->data_len, vm->data, vm->user_data->data); + memcpy(vm->user_data->data, vm->data, *vm->data_len); + vm->user_data->len = *vm->data_len; + + // Multi-packets handled by available_data and next_data + // cannot write to data pointed by vm pointers anyways + vm->data_len = NULL; + vm->data = NULL; + #ifdef EARLY_EXIT_NODES count++; @@ -281,6 +296,7 @@ ssize_t call_vm(void *data, size_t max_size, bool return_pkt_size, bool disable_ hprintf("WARNING: num_copied: %d / num_copied: %d\n", available_data, num_copied); } */ + DEBUG("Copy %zu buffer bytes from %p to %p\n", num_copied, &data_buffer[next_data], data); memcpy(data, &data_buffer[next_data], num_copied); available_data-=num_copied; next_data+=num_copied; @@ -332,29 +348,14 @@ ssize_t getline(char **lineptr, size_t *n, FILE *stream){ #endif static void setup_interpreter(void* payload_buffer) { - uint64_t* offsets = (uint64_t*)payload_buffer; - //hprintf("checksum: %lx, %lx\n",offsets[0], INTERPRETER_CHECKSUM); - ASSERT(offsets[0] == INTERPRETER_CHECKSUM); - ASSERT(offsets[1] < 0xffffff); - ASSERT(offsets[2] < 0xffffff); - ASSERT(offsets[3] < 0xffffff); - ASSERT(offsets[4] < 0xffffff); - uint64_t* graph_size = &offsets[1]; - uint64_t* data_size = &offsets[2]; - - //printf("graph_size: %d\n", graph_size); - //printf("data_size: %d\n", graph_size); - //printf("graph_offset: %d\n", offsets[3]); - //printf("data_offset: %d\n", offsets[4]); - - uint16_t* graph_ptr = (uint16_t*)(payload_buffer+offsets[3]); - uint8_t* data_ptr = (uint8_t*)(payload_buffer+offsets[4]); - ASSERT(input_buffer_size != 0); - ASSERT(offsets[3]+(*graph_size)*sizeof(uint16_t) <= input_buffer_size); - ASSERT(offsets[4]+*data_size <= input_buffer_size); - init_interpreter(vm, graph_ptr, (size_t*)graph_size, data_ptr, (size_t*)data_size, (void*)&ijon_trace_buffer->interpreter_data.executed_opcode_num); - interpreter_user_init(vm); - vm->user_data = &vm_state; + uint32_t* offsets = (uint32_t*)payload_buffer; + + vm->data_len = offsets; + vm->data = (uint8_t*)&offsets[1]; + + DEBUG("input length %zu, %hhx ...\n", *vm->data_len, vm->data[0]); + + // vm->user_data = &vm_state; } #endif @@ -931,6 +932,7 @@ void nyx_init_start(void){ #ifndef LEGACY_MODE vm = new_interpreter(); + hprintf("interpreter: %p\n", vm); vm->user_data = &vm_state; vm->user_data->len = 0; vm->user_data->data = 0; @@ -962,7 +964,6 @@ void nyx_init_start(void){ //hprintf("========================================================\n"); while(1){ - /* fixme */ #ifndef NET_FUZZ pid = _fork(); @@ -1123,6 +1124,7 @@ int __main(int argc, char** argv, char** envp){ #ifdef LEGACY_MODE nyx_init(); #endif + return original_main(argc, argv, envp); } diff --git a/packer/linux_x86_64-userspace/src/netfuzz/inject.c b/packer/linux_x86_64-userspace/src/netfuzz/inject.c index 4408e3a..7f05b6b 100644 --- a/packer/linux_x86_64-userspace/src/netfuzz/inject.c +++ b/packer/linux_x86_64-userspace/src/netfuzz/inject.c @@ -366,6 +366,23 @@ ssize_t recv(int sockfd, void *buf, size_t len, int flags){ return ret; } +int printf(const char* format, ...) +{ + va_list arg; + + va_start(arg, format); + hprintf(format, va_arg(arg, int)); + va_end(arg); + + return 0; +} + +int puts(const char* s) +{ + hprintf(s); + return 0; +} + static bool data_avaliable(int fd){ fd_set set; struct timeval timeout; diff --git a/packer/linux_x86_64-userspace/src/netfuzz/syscalls.c b/packer/linux_x86_64-userspace/src/netfuzz/syscalls.c index 69dc866..de3f48c 100644 --- a/packer/linux_x86_64-userspace/src/netfuzz/syscalls.c +++ b/packer/linux_x86_64-userspace/src/netfuzz/syscalls.c @@ -38,6 +38,9 @@ typedef int (*real_getpeername_t)(int, struct sockaddr*, socklen_t*); typedef char* (*real_fgets_t)(char*, int, FILE*); typedef int (*real_open_t)(const char *pathname, int flags); typedef int (*real_ioctl_t)(int fd, int cmd, void *argp); +typedef int (*real_socket_t)(int a, int b, int c); +typedef int (*real_printf_t)(const char* format, ...); +typedef int (*real_puts_t)(const char* s); bool initialized = false; @@ -73,6 +76,9 @@ real_getpeername_t real_getpeername_ptr = NULL; real_fgets_t real_fgets_ptr = NULL; real_open_t real_open_ptr = NULL; real_ioctl_t real_ioctl_ptr = NULL; +real_socket_t real_socket_ptr = NULL; +real_printf_t real_printf_ptr = NULL; +real_puts_t real_puts_ptr = NULL; void init_syscall_fptr(void){ @@ -114,6 +120,9 @@ void init_syscall_fptr(void){ real_fgets_ptr = (real_fgets_t)dlsym(RTLD_NEXT, "fgets"); real_open_ptr = (real_open_t)dlsym(RTLD_NEXT, "open"); real_ioctl_ptr = (real_ioctl_t)dlsym(RTLD_NEXT, "ioctl"); + real_socket_ptr = (real_socket_t)dlsym(RTLD_NEXT, "socket"); + real_printf_ptr = (real_printf_t)dlsym(RTLD_NEXT, "printf"); + real_puts_ptr = (real_puts_t)dlsym(RTLD_NEXT, "puts"); assert(real_listen_ptr); assert(real_accept_ptr); @@ -146,6 +155,7 @@ void init_syscall_fptr(void){ assert(real_getpeername_ptr); assert(real_open_ptr); assert(real_ioctl_ptr); + assert(real_socket_ptr); initialized = true; @@ -318,3 +328,24 @@ int real_ioctl(int fd, int cmd, void *argp){ assert(real_ioctl_ptr); return real_ioctl_ptr(fd, cmd, argp); } + +int real_socket(int a, int b, int c){ + assert(real_socket_ptr); + return real_socket_ptr(a, b, c); +} + +int real_printf(const char* format, ...){ + assert(real_printf_ptr); + + va_list arg; + va_start(arg, format); + real_printf_ptr(format, va_arg(arg, int)); + va_end(arg); + + return 0; +} + +int real_puts(const char* s){ + assert(real_puts_ptr); + return real_puts_ptr(s); +} diff --git a/packer/linux_x86_64-userspace/src/netfuzz/syscalls.h b/packer/linux_x86_64-userspace/src/netfuzz/syscalls.h index f2c86e4..aa0fbbf 100644 --- a/packer/linux_x86_64-userspace/src/netfuzz/syscalls.h +++ b/packer/linux_x86_64-userspace/src/netfuzz/syscalls.h @@ -41,3 +41,6 @@ int real_getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen); char *real_fgets(char *s, int size, FILE *stream); int real_open(const char *pathname, int flags); int real_ioctl(int fd, int cmd, void *argp); +int real_socket(int, int, int); +int real_printf(const char* format, ...); +int real_puts(const char* s); From 16a8097ebb6e1261818ffc37f0562faa73e2f64d Mon Sep 17 00:00:00 2001 From: jausten Date: Wed, 2 Aug 2023 10:29:27 -0600 Subject: [PATCH 02/13] Added protobuf --- packer/linux_x86_64-userspace/compile_64.sh | 19 +++- .../src/ld_preload_fuzz.c | 90 ++++++++++++------- .../src/misc/crash_handler.c | 2 +- .../src/proto/afl_input.cpp | 79 ++++++++++++++++ .../src/proto/afl_input.h | 38 ++++++++ .../src/proto/input.proto | 11 +++ packer/nyx_packer.py | 25 +++++- packer/stuff.sh | 17 ++++ 8 files changed, 240 insertions(+), 41 deletions(-) create mode 100644 packer/linux_x86_64-userspace/src/proto/afl_input.cpp create mode 100644 packer/linux_x86_64-userspace/src/proto/afl_input.h create mode 100644 packer/linux_x86_64-userspace/src/proto/input.proto create mode 100755 packer/stuff.sh diff --git a/packer/linux_x86_64-userspace/compile_64.sh b/packer/linux_x86_64-userspace/compile_64.sh index cc12138..1442c08 100755 --- a/packer/linux_x86_64-userspace/compile_64.sh +++ b/packer/linux_x86_64-userspace/compile_64.sh @@ -18,9 +18,22 @@ else if [ "$NET_FUZZ" = "ON" ] then MODE="${UDP_MODE} ${CLIENT_MODE} ${DEBUG_MODE} ${STDOUT_STDERR_DEBUG}" - #echo "MODES => $MODE" - clang -shared -g -O0 -m64 -Werror $EXTRA $MODE -fPIC src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/inject.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c -I../../ -DNET_FUZZ -I$NYX_SPEC_FOLDER -o bin64/ld_preload_fuzz.so -ldl -Isrc - clang -shared -g -O0 -m64 -Werror -DNO_PT_NYX $EXTRA $MODE -fPIC src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/inject.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c -I../../ -DNET_FUZZ -I$NYX_SPEC_FOLDER -o bin64/ld_preload_fuzz_no_pt.so -ldl -Isrc + echo "MODES => $MODE" + protoc -Isrc/proto input.proto --cpp_out=src/proto + #clang++ -shared -g -O0 -m64 -Werror $EXTRA $MODE -fPIC src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/inject.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c -I../../ -DNET_FUZZ -I$NYX_SPEC_FOLDER -o bin64/ld_preload_fuzz.so -ldl -Isrc -Iproto src/proto/input.pb.cc -lprotobuf + #clang++ -shared -g -O0 -m64 -Werror -DNO_PT_NYX $EXTRA $MODE -fPIC src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/inject.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c -I../../ -DNET_FUZZ -I$NYX_SPEC_FOLDER -o bin64/ld_preload_fuzz_no_pt.so -ldl -Isrc -Iproto src/proto/input.pb.cc -lprotobuf + # currently working with: + clang++ -c -g -O0 -m64 -Werror -DNO_PT_NYX -DNET_FUZZ $MODE -fPIC \ + src/proto/afl_input.cpp src/proto/input.pb.cc \ + -Isrc/proto + clang -c -g -O0 -m64 -Werror -Wno-unused-value -DNO_PT_NYX -DNET_FUZZ $MODE -fPIC \ + src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c src/netfuzz/inject.c \ + -I../../ -Isrc -Isrc/proto -I/home/jausten/nyxnet/nyx-net/targets/specs/echoserver/build + clang++ -shared -g -O0 -m64 -Werror $MODE -fPIC \ + ld_preload_fuzz.o input.pb.o crash_handler.o harness_state.o inject.o socket_cache.o syscalls.o afl_input.o \ + -I../../ -Isrc -Isrc/proto -I/home/jausten/nyxnet/nyx-net/targets/specs/echoserver/build \ + -o bin64/ld_preload_fuzz_no_pt.so -lprotobuf -ldl + rm ld_preload_fuzz.o input.pb.o crash_handler.o harness_state.o inject.o socket_cache.o syscalls.o afl_input.o else diff --git a/packer/linux_x86_64-userspace/src/ld_preload_fuzz.c b/packer/linux_x86_64-userspace/src/ld_preload_fuzz.c index 7a96529..13bc2e0 100644 --- a/packer/linux_x86_64-userspace/src/ld_preload_fuzz.c +++ b/packer/linux_x86_64-userspace/src/ld_preload_fuzz.c @@ -1,4 +1,6 @@ -#define _GNU_SOURCE +#ifndef _GNU_SOURCE + #define _GNU_SOURCE +#endif #include #include @@ -22,6 +24,8 @@ #include "misc/crash_handler.h" #include "misc/harness_state.h" +#include "afl_input.h" + //#define HYPERCALL_KAFL_RELEASE_DEBUG #define likely(x) __builtin_expect((x),1) @@ -56,14 +60,13 @@ bool payload_mode = false; #ifndef LEGACY_MODE #include "interpreter.h" #else -extern void __assert(const char *func, const char *file, int line, const char *failedexpr); -#define INTERPRETER_ASSERT(x) do { if (x){}else{ __assert(__func__, __FILE__, __LINE__, #x);} } while (0) +extern void _assert(const char *func, const char *file, int line, const char *failedexpr); +#define INTERPRETER_ASSERT(x) do { if (x){}else{ _assert(__func__, __FILE__, __LINE__, #x);} } while (0) #define ASSERT(x) INTERPRETER_ASSERT(x) #endif #include "ijon_extension.h" - #define ASAN_EXIT_CODE 101 //#define REDIRECT_STDERR_TO_HPRINTF //#define REDIRECT_STDOUT_TO_HPRINTF @@ -193,7 +196,7 @@ void hprintf_payload(char* data, size_t len){ //#define COPY_PAYLOAD_MODE -ssize_t call_vm(void *data, size_t max_size, bool return_pkt_size, bool disable_dump_mode){ +ssize_t call_vm(void *data, size_t max_size, bool return_pkt_size, bool disable_dump_mode) { #ifdef EARLY_EXIT_NODES static int count = 0; @@ -237,8 +240,9 @@ ssize_t call_vm(void *data, size_t max_size, bool return_pkt_size, bool disable_ //#endif return vm->user_data->len; } -#else +#endif /* UDP_MODE */ +#ifdef LEGACY_MODE #define PACKET_BUFFER_SIZE (1<<14) static char data_buffer[PACKET_BUFFER_SIZE]; static size_t available_data= 0; @@ -252,26 +256,11 @@ ssize_t call_vm(void *data, size_t max_size, bool return_pkt_size, bool disable_ //hprintf("%s: 2: %p\n", __func__, vm->user_data); //hprintf("%s: 3: %p\n", __func__, vm->user_data->len); - if (!vm->data_len || *vm->data_len == 0){ + if(interpreter_run(vm)==0){ DEBUG("%s: out of data\n", __func__); return -1; } - if (*vm->data_len > PACKET_BUFFER_SIZE){ - DEBUG("%s: input size %d too large for buffer\n", __func__, *vm->data_len); - return -1; - } - - DEBUG("DATA: %d\n", *(uint32_t*)vm->data); - DEBUG("Copy %d input bytes from %p to %p\n", *vm->data_len, vm->data, vm->user_data->data); - memcpy(vm->user_data->data, vm->data, *vm->data_len); - vm->user_data->len = *vm->data_len; - - // Multi-packets handled by available_data and next_data - // cannot write to data pointed by vm pointers anyways - vm->data_len = NULL; - vm->data = NULL; - #ifdef EARLY_EXIT_NODES count++; @@ -296,20 +285,52 @@ ssize_t call_vm(void *data, size_t max_size, bool return_pkt_size, bool disable_ hprintf("WARNING: num_copied: %d / num_copied: %d\n", available_data, num_copied); } */ - DEBUG("Copy %zu buffer bytes from %p to %p\n", num_copied, &data_buffer[next_data], data); memcpy(data, &data_buffer[next_data], num_copied); available_data-=num_copied; next_data+=num_copied; +#else /* Not LEGACY_MODE */ + + if (afl_has_next() == 0) { + + /* Parse new packets from vm buffer */ + + if (!vm->data_len || *vm->data_len == 0){ + DEBUG("%s: out of data\n", __func__); + return -1; + } + + afl_deserialize(vm->data, *vm->data_len); + vm->data_len = NULL; + +#ifdef EARLY_EXIT_NODES + if (++count >= EARLY_EXIT_NODES){ + //hprintf("EARLY EXIT\n"); + return -1; + } +#endif + + if(vm->user_data->closed){ + DEBUG("%s: closed\n", __func__); + return -1; /* -1 -> EOF */ + } + } + + /* Serialize next packet into data buffer */ + + size_t num_copied = afl_get_next(data, max_size); + +#endif /* End not LEGACY_MODE */ + DEBUG("CALL_VM %d -> %d\n", max_size, num_copied); -//#ifdef COPY_PAYLOAD_MODE + +#ifdef COPY_PAYLOAD_MODE if(payload_mode && !disable_dump_mode){ hprintf_payload(data, num_copied); } -//#endif - //return 0; - return num_copied; #endif + + return num_copied; } #ifndef NET_FUZZ @@ -353,6 +374,7 @@ static void setup_interpreter(void* payload_buffer) { vm->data_len = offsets; vm->data = (uint8_t*)&offsets[1]; + // This should just be "INIT" DEBUG("input length %zu, %hhx ...\n", *vm->data_len, vm->data[0]); // vm->user_data = &vm_state; @@ -550,9 +572,9 @@ void capabilites_configuration(bool timeout_detection, bool agent_tracing, bool habort("Error: NYX_HOST_VERSION not found in host configuration - You are probably using an outdated version of QEMU-Nyx..."); } - hprintf("[capablities] host_config.bitmap_size: 0x%"PRIx64"\n", host_config.bitmap_size); - hprintf("[capablities] host_config.ijon_bitmap_size: 0x%"PRIx64"\n", host_config.ijon_bitmap_size); - hprintf("[capablities] host_config.payload_buffer_size: 0x%"PRIx64"x\n", host_config.payload_buffer_size); + hprintf("[capablities] host_config.bitmap_size: 0x%" PRIx64 "\n", host_config.bitmap_size); + hprintf("[capablities] host_config.ijon_bitmap_size: 0x%" PRIx64 "\n", host_config.ijon_bitmap_size); + hprintf("[capablities] host_config.payload_buffer_size: 0x%" PRIx64 "x\n", host_config.payload_buffer_size); input_buffer_size = host_config.payload_buffer_size; @@ -575,7 +597,7 @@ void capabilites_configuration(bool timeout_detection, bool agent_tracing, bool /* AFL++ LTO support */ if (get_harness_state()->afl_mode && __afl_final_loc_ptr){ unsigned int map_size = __afl_final_loc == 0 ? 65536 : __afl_final_loc; - hprintf("[capablities] overwriting bitmap_size: 0x%"PRIx64"\n", map_size); + hprintf("[capablities] overwriting bitmap_size: 0x%" PRIx64 "\n", map_size); agent_config.coverage_bitmap_size = map_size; } @@ -590,11 +612,11 @@ void capabilites_configuration(bool timeout_detection, bool agent_tracing, bool /* read debug flag */ - if(agent_config.dump_payloads){ + // if(agent_config.dump_payloads){ hprintf("[capablities] payload mode enabled\n"); payload_mode = true; //abort(); - } + // } done = true; @@ -859,7 +881,7 @@ void nyx_init_start(void){ for(i = 0; i < 4; i++){ if (range_buffer->enabled[i]){ - hprintf("[init] Intel PT range %d is enabled\t -> (0x"PRIx64"-0x"PRIx64")\n", i, range_buffer->ip[i], range_buffer->ip[i]+range_buffer->size[i]); + hprintf("[init] Intel PT range %d is enabled\t -> (0x" PRIx64 "-0x" PRIx64 ")\n", i, range_buffer->ip[i], range_buffer->ip[i]+range_buffer->size[i]); } } diff --git a/packer/linux_x86_64-userspace/src/misc/crash_handler.c b/packer/linux_x86_64-userspace/src/misc/crash_handler.c index de42e8e..773089f 100644 --- a/packer/linux_x86_64-userspace/src/misc/crash_handler.c +++ b/packer/linux_x86_64-userspace/src/misc/crash_handler.c @@ -172,7 +172,7 @@ void handle_asan(void){ } } -void __assert(const char *func, const char *file, int line, const char *failedexpr){ +void _assert(const char *func, const char *file, int line, const char *failedexpr){ sprintf(log_content, "HYPERCALL_KAFL_PANIC_EXTENDED: assert: %s %s %d: %s\n", func, file, line, failedexpr); kAFL_hypercall(HYPERCALL_KAFL_PANIC_EXTENDED, (uintptr_t)log_content); } diff --git a/packer/linux_x86_64-userspace/src/proto/afl_input.cpp b/packer/linux_x86_64-userspace/src/proto/afl_input.cpp new file mode 100644 index 0000000..2299d31 --- /dev/null +++ b/packer/linux_x86_64-userspace/src/proto/afl_input.cpp @@ -0,0 +1,79 @@ +#include "afl_input.h" +#include "input.pb.h" + +afl_input::Input g_input; +auto g_packet = g_input.packets().end(); + +extern "C" void afl_deserialize(uint8_t* buf, uint32_t size) { + g_input.ParseFromArray(buf, size); + g_packet = g_input.packets().begin(); + + printf("Deserializing %d packets...\n", g_input.packets_size()); + for (const afl_input::Packet& pkt : g_input.packets()) + { + printf("Packet dump:\n"); + for(int i = 0; i < pkt.buffer().size(); ++i) + { + printf("%02X ", pkt.buffer().data()[i]); + if ((i+1) % 16 == 0) + printf("\n"); + } + printf("\n"); + } + +}; + +extern "C" int afl_packets_size() { + return g_input.packets_size(); +} + +extern "C" void afl_delete_packet(int index) { + g_input.mutable_packets()->DeleteSubrange(index, 1); +} + +extern "C" size_t afl_get_packet(int index, void* buf, size_t size) { + afl_input::Packet packet = g_input.packets().at(index); + size_t copy_size = std::min(size, packet.buffer().size()); + + memcpy(buf, packet.buffer().data(), copy_size); + + return copy_size; +} + +extern "C" void afl_set_packet(int index, void* buf, size_t size) { + afl_input::Packet packet = g_input.mutable_packets()->at(index); + packet.ParseFromArray(buf, size); +} + +extern "C" size_t afl_serialize(void* buf,size_t size) { + + printf("Serializing packets...\n"); + for (auto pkt : g_input.packets()) + { + printf("Packet dump:\n"); + for(int i = 0; i < pkt.buffer().size(); ++i) + { + printf("%02X ", pkt.buffer().data()[i]); + if ((i+1) % 16 == 0) + printf("\n"); + } + printf("\n"); + } + + g_input.SerializeToArray(buf, size); + return std::min(size, g_input.ByteSizeLong()); +} + +extern "C" int afl_has_next() { + if (g_packet == g_input.packets().end()) + return 0; + return 1; +} + +extern "C" size_t afl_get_next(void* buf, size_t size) { + g_packet->SerializeToArray(buf, size); + + size_t out_size = std::min(size, g_packet->buffer().size()); + g_packet++; + return out_size; +} \ No newline at end of file diff --git a/packer/linux_x86_64-userspace/src/proto/afl_input.h b/packer/linux_x86_64-userspace/src/proto/afl_input.h new file mode 100644 index 0000000..1f46da2 --- /dev/null +++ b/packer/linux_x86_64-userspace/src/proto/afl_input.h @@ -0,0 +1,38 @@ +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/******************** + * Shared functions * + ********************/ + +void afl_deserialize(uint8_t* buf, uint32_t size); + +/******************************** + * Functions for custom mutator * + ********************************/ + +int afl_packets_size(); + +void afl_delete_packet(int index); + +size_t afl_get_packet(int index, void* buf, size_t size); + +void afl_set_packet(int index, void* buf, size_t size); + +size_t afl_serialize(void* buf, size_t size); + +/**************************** + * Functions for ld_preload * + ****************************/ + +int afl_has_next(); + +size_t afl_get_next(void* buf, size_t size); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/packer/linux_x86_64-userspace/src/proto/input.proto b/packer/linux_x86_64-userspace/src/proto/input.proto new file mode 100644 index 0000000..f85e0eb --- /dev/null +++ b/packer/linux_x86_64-userspace/src/proto/input.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +package afl_input; + +message Packet { + bytes buffer = 1; +} + +message Input { + repeated Packet packets = 1; +} \ No newline at end of file diff --git a/packer/nyx_packer.py b/packer/nyx_packer.py index 63e4b77..cb53c56 100755 --- a/packer/nyx_packer.py +++ b/packer/nyx_packer.py @@ -244,7 +244,7 @@ def compile(config): print(OKGREEN + INFO_PREFIX + "Recompiling..." + ENDC) - execute(["bash", "compile_64.sh"], config.config_values["AGENTS-FOLDER"] + "/linux_x86_64-userspace/", + execute(["bash", "-x", "compile_64.sh"], config.config_values["AGENTS-FOLDER"] + "/linux_x86_64-userspace/", print_output=True) else: @@ -305,6 +305,24 @@ def compile(config): download_script += dependencies + if not LEGACY_MODE: + protobuf_lib_file = "/usr/local/lib/libprotobuf.so.32" + copyfile(protobuf_lib_file, "%s/%s"%(config.argument_values["output_dir"], os.path.basename(protobuf_lib_file))) + cpp_lib_file = "/usr/lib/x86_64-linux-gnu/libstdc++.so.6" + copyfile(cpp_lib_file, "%s/%s"%(config.argument_values["output_dir"], os.path.basename(cpp_lib_file))) + m_lib_file = "/lib/x86_64-linux-gnu/libm.so.6" + copyfile(m_lib_file, "%s/%s"%(config.argument_values["output_dir"], os.path.basename(m_lib_file))) + gcc_lib_file = "/lib/x86_64-linux-gnu/libgcc_s.so.1" + copyfile(gcc_lib_file, "%s/%s"%(config.argument_values["output_dir"], os.path.basename(gcc_lib_file))) + z_lib_file = "/lib/x86_64-linux-gnu/libz.so.1" + copyfile(z_lib_file, "%s/%s"%(config.argument_values["output_dir"], os.path.basename(z_lib_file))) + + download_script += "./hget %s %s\n"%(os.path.basename(protobuf_lib_file), os.path.basename(protobuf_lib_file)) + download_script += "./hget %s %s\n"%(os.path.basename(cpp_lib_file), os.path.basename(cpp_lib_file)) + download_script += "./hget %s %s\n"%(os.path.basename(m_lib_file), os.path.basename(m_lib_file)) + download_script += "./hget %s %s\n"%(os.path.basename(gcc_lib_file), os.path.basename(gcc_lib_file)) + download_script += "./hget %s %s\n"%(os.path.basename(z_lib_file), os.path.basename(z_lib_file)) + download_script += "echo \"Let's get our target executable...\" | ./hcat\n" copyfile(config.argument_values["binary_file"], "%s/%s"%(config.argument_values["output_dir"], os.path.basename(config.argument_values["binary_file"]))) download_script += "./hget %s target_executable\n"%(os.path.basename(config.argument_values["binary_file"])) @@ -348,7 +366,7 @@ def compile(config): copyfile(ld_preload_fuzz_file, "%s/%s"%(config.argument_values["output_dir"], os.path.basename(ld_preload_fuzz_file))) ld_preload_fuzz_file = agent_folder + "ld_preload_fuzz_no_pt.so" copyfile(ld_preload_fuzz_file, "%s/%s"%(config.argument_values["output_dir"], os.path.basename(ld_preload_fuzz_file))) - + if PRE_PROCESS and PRE_PROCESS_ARGS: download_script += "chmod +x pre_process/pre_process\n" download_script += "./hget run.sh run.sh\n" @@ -405,7 +423,8 @@ def compile(config): download_script += "cat stdout.txt | ./hcat\n" download_script += "cat stderr.txt | ./hcat\n" else: - download_script += " > /dev/null 2> /dev/null\n" + #download_script += " > /dev/null 2> /dev/null\n" + download_script += "2>&1 | ./hcat\n" download_script += "dmesg | grep segfault | ./hcat\n" diff --git a/packer/stuff.sh b/packer/stuff.sh new file mode 100755 index 0000000..b995851 --- /dev/null +++ b/packer/stuff.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +# +# Pack and setup for fuzzing +# + +cd ~/aflpp_nyx/nyx_mode/packer/packer + +#python3 nyx_packer.py --purge -spec ~/nyxnet/nyx-net/targets/specs/echoserver --setup_folder ~/nyxnet/nyx-net/targets/extra_folders/echoserver_extra_folder --nyx_net --nyx_net_port 1234 ~/nyxnet/nyx-net/targets/setup_scripts/build/echoserver/echoserver /tmp/echo_packed spec instrumentation +python3 nyx_packer.py --nyx_net_debug_mode --purge -spec ~/nyxnet/nyx-net/targets/specs/echoserver --setup_folder ~/nyxnet/nyx-net/targets/extra_folders/echoserver_extra_folder --nyx_net --nyx_net_port 1234 ~/nyxnet/nyx-net/targets/setup_scripts/build/echoserver/echoserver /tmp/echo_packed spec instrumentation + +python3 nyx_config_gen.py /tmp/echo_packed Kernel + +kill -9 $(pgrep qemu) +rm -rf /tmp/out + +echo "ready to fuzz" From 70648adb8383a89f6f680542255b27ccc2ac42a9 Mon Sep 17 00:00:00 2001 From: jausten Date: Thu, 3 Aug 2023 15:36:47 -0600 Subject: [PATCH 03/13] Removed need for specs --- .gitignore | 2 + packer/common/config.py | 5 +- packer/linux_x86_64-userspace/compile_64.sh | 12 +- .../src/ld_preload_fuzz.c | 153 ++++-------------- .../src/proto/afl_input.cpp | 17 +- .../src/proto/afl_input.h | 29 +++- packer/nyx_packer.py | 7 +- packer/stuff.sh | 3 +- 8 files changed, 88 insertions(+), 140 deletions(-) diff --git a/.gitignore b/.gitignore index 431171f..46b94e4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ linux_initramfs/init.cpio.gz linux_initramfs/init_debug_shell.cpio.gz linux_initramfs/init +packer/linux_x86_64-userspace/src/proto/input.pb.cc +packer/linux_x86_64-userspace/src/proto/input.pb.h diff --git a/packer/common/config.py b/packer/common/config.py index 9879b9f..f398b4f 100644 --- a/packer/common/config.py +++ b/packer/common/config.py @@ -264,9 +264,10 @@ def __load_config(self): self.config_values = ConfigReader(os.path.dirname(os.path.realpath(__file__))+"/../nyx.ini", self.__config_section, self.__config_default).get_values() def __load_arguments(self): - modes = ["afl", "spec"] + modes = ["afl", "spec", "nyxnet"] modes_help = 'afl\t\t - pack target for an AFL-like fuzzer (such as AFL++, kAFL, Nautilus)\n' \ - 'spec\t\t - pack target for a spec fuzzer (such as Nyx\'s spec-fuzzer)\n' + 'spec\t\t - pack target for a spec fuzzer (such as Nyx\'s spec-fuzzer)\n' \ + 'nyxnet\t\t - pack target for an AFL-like fuzzer while using nyx-net' coverage_modes = ["instrumentation", "processor_trace"] coverage_modes_help = 'instrumentation\t - use compile-time instrumentation (target has to be compiled with an proper compiler)\n' \ diff --git a/packer/linux_x86_64-userspace/compile_64.sh b/packer/linux_x86_64-userspace/compile_64.sh index 1442c08..5b8d777 100755 --- a/packer/linux_x86_64-userspace/compile_64.sh +++ b/packer/linux_x86_64-userspace/compile_64.sh @@ -19,21 +19,23 @@ else then MODE="${UDP_MODE} ${CLIENT_MODE} ${DEBUG_MODE} ${STDOUT_STDERR_DEBUG}" echo "MODES => $MODE" - protoc -Isrc/proto input.proto --cpp_out=src/proto + #clang++ -shared -g -O0 -m64 -Werror $EXTRA $MODE -fPIC src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/inject.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c -I../../ -DNET_FUZZ -I$NYX_SPEC_FOLDER -o bin64/ld_preload_fuzz.so -ldl -Isrc -Iproto src/proto/input.pb.cc -lprotobuf #clang++ -shared -g -O0 -m64 -Werror -DNO_PT_NYX $EXTRA $MODE -fPIC src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/inject.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c -I../../ -DNET_FUZZ -I$NYX_SPEC_FOLDER -o bin64/ld_preload_fuzz_no_pt.so -ldl -Isrc -Iproto src/proto/input.pb.cc -lprotobuf - # currently working with: + + # New compile commands for nyxnet mode + protoc -Isrc/proto input.proto --cpp_out=src/proto clang++ -c -g -O0 -m64 -Werror -DNO_PT_NYX -DNET_FUZZ $MODE -fPIC \ src/proto/afl_input.cpp src/proto/input.pb.cc \ -Isrc/proto clang -c -g -O0 -m64 -Werror -Wno-unused-value -DNO_PT_NYX -DNET_FUZZ $MODE -fPIC \ src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c src/netfuzz/inject.c \ - -I../../ -Isrc -Isrc/proto -I/home/jausten/nyxnet/nyx-net/targets/specs/echoserver/build + -I../../ -Isrc -Isrc/proto -I../../../../custom_mutators/nyx-net/echoserver_example/specs/echoserver/include clang++ -shared -g -O0 -m64 -Werror $MODE -fPIC \ ld_preload_fuzz.o input.pb.o crash_handler.o harness_state.o inject.o socket_cache.o syscalls.o afl_input.o \ - -I../../ -Isrc -Isrc/proto -I/home/jausten/nyxnet/nyx-net/targets/specs/echoserver/build \ + -I../../ -Isrc -Isrc/proto \ -o bin64/ld_preload_fuzz_no_pt.so -lprotobuf -ldl - rm ld_preload_fuzz.o input.pb.o crash_handler.o harness_state.o inject.o socket_cache.o syscalls.o afl_input.o + rm -f ld_preload_fuzz.o input.pb.o crash_handler.o harness_state.o inject.o socket_cache.o syscalls.o afl_input.o else diff --git a/packer/linux_x86_64-userspace/src/ld_preload_fuzz.c b/packer/linux_x86_64-userspace/src/ld_preload_fuzz.c index 13bc2e0..5c8b5a2 100644 --- a/packer/linux_x86_64-userspace/src/ld_preload_fuzz.c +++ b/packer/linux_x86_64-userspace/src/ld_preload_fuzz.c @@ -57,13 +57,7 @@ bool payload_mode = false; //#endif -#ifndef LEGACY_MODE #include "interpreter.h" -#else -extern void _assert(const char *func, const char *file, int line, const char *failedexpr); -#define INTERPRETER_ASSERT(x) do { if (x){}else{ _assert(__func__, __FILE__, __LINE__, #x);} } while (0) -#define ASSERT(x) INTERPRETER_ASSERT(x) -#endif #include "ijon_extension.h" @@ -78,14 +72,12 @@ bool fuzzer_ready = false; -#ifndef LEGACY_MODE interpreter_t* vm; #ifdef NET_FUZZ socket_state_t vm_state; #else fd_state_t vm_state; #endif -#endif ssize_t (*fptr_read)(int fd, void *data, size_t size); ssize_t (*fptr_getline)(char **lineptr, size_t *n, FILE *stream); @@ -200,129 +192,50 @@ ssize_t call_vm(void *data, size_t max_size, bool return_pkt_size, bool disable_ #ifdef EARLY_EXIT_NODES static int count = 0; -#endif - -#ifdef UDP_MODE - vm->user_data->len = max_size; - vm->user_data->data = data; - if(interpreter_run(vm)==0){ - return -1; - } - -#ifdef EARLY_EXIT_NODES - count++; - - if (count >= EARLY_EXIT_NODES){ + if (count++ > EARLY_EXIT_NODES){ + //hprintf("EARLY EXIT\n"); return -1; } #endif - if(vm->user_data->closed){ - return -1; /* -1 -> EOF */ - } + static const char* data_buffer = NULL; + static size_t available_data = 0; + static size_t offset = 0; - //hprintf("max: %d / pkt_len: %d / len: %d\n", max_size, vm->user_data->pkt_len, vm->user_data->len); - if(return_pkt_size && max_size < vm->user_data->len){ -//#ifdef COPY_PAYLOAD_MODE - if(payload_mode && !disable_dump_mode){ - hprintf_payload(vm->user_data->data, vm->user_data->len); - } - //hprintf("%d vs %d\n", vm->user_data->pkt_len, max_size); -//#endif - return vm->user_data->len; - } - else{ -//#ifdef COPY_PAYLOAD_MODE - if(payload_mode && !disable_dump_mode){ - hprintf_payload(vm->user_data->data, vm->user_data->len); - } -//#endif - return vm->user_data->len; - } -#endif /* UDP_MODE */ + if (available_data <= 0) { -#ifdef LEGACY_MODE - #define PACKET_BUFFER_SIZE (1<<14) - static char data_buffer[PACKET_BUFFER_SIZE]; - static size_t available_data= 0; - static size_t next_data = 0; - - if(available_data == 0){ - vm->user_data->len = PACKET_BUFFER_SIZE; - vm->user_data->data = &data_buffer[0]; - - //hprintf("%s: 1: %p\n", __func__, vm); - //hprintf("%s: 2: %p\n", __func__, vm->user_data); - //hprintf("%s: 3: %p\n", __func__, vm->user_data->len); - - if(interpreter_run(vm)==0){ - DEBUG("%s: out of data\n", __func__); - return -1; - } + if (!afl_has_next()) { -#ifdef EARLY_EXIT_NODES - count++; + /* Parse new set of packets from vm buffer */ - if (count >= EARLY_EXIT_NODES){ - //hprintf("EARLY EXIT\n"); - return -1; - } -#endif - - if(vm->user_data->closed){ - DEBUG("%s: closed\n", __func__); + if (!vm->data_len || *vm->data_len == 0){ + DEBUG("%s: out of data\n", __func__); + return -1; + } - return -1; /* -1 -> EOF */ + afl_deserialize(vm->data, *vm->data_len); + vm->data_len = NULL; /* This assumes vm->data can only be written to once per execution */ + } - available_data = vm->user_data->len; - next_data = 0; - } - - size_t num_copied = min_size_t(available_data, max_size); - /* - if(available_data < num_copied){ - hprintf("WARNING: num_copied: %d / num_copied: %d\n", available_data, num_copied); - } - */ - memcpy(data, &data_buffer[next_data], num_copied); - available_data-=num_copied; - next_data+=num_copied; - -#else /* Not LEGACY_MODE */ - - if (afl_has_next() == 0) { - - /* Parse new packets from vm buffer */ - if (!vm->data_len || *vm->data_len == 0){ - DEBUG("%s: out of data\n", __func__); - return -1; - } + /* Serialize next packet into data buffer */ - afl_deserialize(vm->data, *vm->data_len); - vm->data_len = NULL; - -#ifdef EARLY_EXIT_NODES - if (++count >= EARLY_EXIT_NODES){ - //hprintf("EARLY EXIT\n"); - return -1; + offset = 0; + data_buffer = afl_get_next(&available_data); + if (available_data < 0) { + DEBUG("%s: packet does not fit in data_buffer\n", __func__); + return -1; } -#endif - if(vm->user_data->closed){ - DEBUG("%s: closed\n", __func__); - return -1; /* -1 -> EOF */ - } } - /* Serialize next packet into data buffer */ - - size_t num_copied = afl_get_next(data, max_size); + /* Copy requested data from current packet */ -#endif /* End not LEGACY_MODE */ + size_t num_copied = min_size_t(available_data, max_size); + memcpy(data, data_buffer+offset, num_copied); - DEBUG("CALL_VM %d -> %d\n", max_size, num_copied); + DEBUG("%s: requested %d -> wrote %d bytes\n", __func__, max_size, num_copied); #ifdef COPY_PAYLOAD_MODE if(payload_mode && !disable_dump_mode){ @@ -330,7 +243,17 @@ ssize_t call_vm(void *data, size_t max_size, bool return_pkt_size, bool disable_ } #endif +#ifdef UDP_MODE + if (return_pkt_size) num_copied = available_data; /* MSG_TRUNC behaves differently with TCP, but is not implemented */ + available_data = 0; + offset = 0; +#else + available_data -= num_copied; + offset += num_copied; +#endif + return num_copied; + } #ifndef NET_FUZZ @@ -376,8 +299,6 @@ static void setup_interpreter(void* payload_buffer) { // This should just be "INIT" DEBUG("input length %zu, %hhx ...\n", *vm->data_len, vm->data[0]); - - // vm->user_data = &vm_state; } #endif @@ -955,10 +876,6 @@ void nyx_init_start(void){ #ifndef LEGACY_MODE vm = new_interpreter(); hprintf("interpreter: %p\n", vm); - vm->user_data = &vm_state; - vm->user_data->len = 0; - vm->user_data->data = 0; - vm->user_data->closed = false; #endif uint8_t mlock_enabled = 1; diff --git a/packer/linux_x86_64-userspace/src/proto/afl_input.cpp b/packer/linux_x86_64-userspace/src/proto/afl_input.cpp index 2299d31..cf205bd 100644 --- a/packer/linux_x86_64-userspace/src/proto/afl_input.cpp +++ b/packer/linux_x86_64-userspace/src/proto/afl_input.cpp @@ -45,7 +45,7 @@ extern "C" void afl_set_packet(int index, void* buf, size_t size) { packet.ParseFromArray(buf, size); } -extern "C" size_t afl_serialize(void* buf,size_t size) { +extern "C" size_t afl_serialize(void* buf, size_t size) { printf("Serializing packets...\n"); for (auto pkt : g_input.packets()) @@ -64,16 +64,13 @@ extern "C" size_t afl_serialize(void* buf,size_t size) { return std::min(size, g_input.ByteSizeLong()); } -extern "C" int afl_has_next() { - if (g_packet == g_input.packets().end()) - return 0; - return 1; +extern "C" bool afl_has_next() { + return g_packet != g_input.packets().end(); } -extern "C" size_t afl_get_next(void* buf, size_t size) { - g_packet->SerializeToArray(buf, size); - - size_t out_size = std::min(size, g_packet->buffer().size()); +extern "C" const char* afl_get_next(size_t* out_size) { + *out_size = g_packet->buffer().size(); + const char* pkt = g_packet->buffer().data(); g_packet++; - return out_size; + return pkt; } \ No newline at end of file diff --git a/packer/linux_x86_64-userspace/src/proto/afl_input.h b/packer/linux_x86_64-userspace/src/proto/afl_input.h index 1f46da2..617e6e7 100644 --- a/packer/linux_x86_64-userspace/src/proto/afl_input.h +++ b/packer/linux_x86_64-userspace/src/proto/afl_input.h @@ -9,29 +9,54 @@ extern "C" { * Shared functions * ********************/ +/// @brief Deserializes a buffer into a protobuf message. This resets the state for `afl_has_next()` and `afl_get_next()` +/// @param buf Buffer from which protobuf will be deserialized from +/// @param size Size of buf void afl_deserialize(uint8_t* buf, uint32_t size); /******************************** * Functions for custom mutator * ********************************/ +/// @brief Gets the number of packets +/// @return The number of packets int afl_packets_size(); +/// @brief Delete the nth packet +/// @param index Index of packet to delete void afl_delete_packet(int index); +/// @brief Gets the packet data at index n and copies up to size bytes into buf +/// @param index Index of packet to get +/// @param buf Buffer packet is written to +/// @param size Size of buf +/// @return size_t afl_get_packet(int index, void* buf, size_t size); +/// @brief Replaces a packet at index n with the contents of buf +/// @param index Index of packet to replace +/// @param buf Buffer to copy packet data from +/// @param size Size of buf void afl_set_packet(int index, void* buf, size_t size); +/// @brief Serializes a protobuf message into a buffer +/// @param buf Buffer that the message will be serialized into +/// @param size Size of buf +/// @return size_t afl_serialize(void* buf, size_t size); /**************************** * Functions for ld_preload * ****************************/ -int afl_has_next(); +/// @brief Checks if there is another packet in the current set of deserialized packets that has not yet been fetched +/// @return True if there is another packet to get +bool afl_has_next(); -size_t afl_get_next(void* buf, size_t size); +/// @brief Get a pointer to the next packet in the current set of deserialized packets +/// @param out_size Pointer to size of the packet data, set by the function +/// @return Pointer to the packet data, also sets out_size +const char* afl_get_next(size_t* out_size); #ifdef __cplusplus } diff --git a/packer/nyx_packer.py b/packer/nyx_packer.py index cb53c56..6de98eb 100755 --- a/packer/nyx_packer.py +++ b/packer/nyx_packer.py @@ -174,6 +174,9 @@ def compile(config): if config.argument_values["mode"] == "afl": LEGACY_MODE = True elif config.argument_values["mode"] == "spec": + print(WARNING + WARNING_PREFIX + "The integrated nyxnet&afl++ mode is now \"nyxnet\"") + LEGACY_MODE = False + elif config.argument_values["mode"] == "nyxnet": LEGACY_MODE = False else: raise Exception("Unkown mode: %s"%(config.argument_values["mode"])) @@ -188,7 +191,7 @@ def compile(config): #print(DISABLE_PT_RANGE_A) #print(DISABLE_PT_RANGE_B) - if not LEGACY_MODE and not SPEC_FOLDER: + if config.argument_values["mode"] == "spec" and not SPEC_FOLDER: print(FAIL + "Error: spec not found!" + ENDC) return @@ -244,7 +247,7 @@ def compile(config): print(OKGREEN + INFO_PREFIX + "Recompiling..." + ENDC) - execute(["bash", "-x", "compile_64.sh"], config.config_values["AGENTS-FOLDER"] + "/linux_x86_64-userspace/", + execute(["bash", "compile_64.sh"], config.config_values["AGENTS-FOLDER"] + "/linux_x86_64-userspace/", print_output=True) else: diff --git a/packer/stuff.sh b/packer/stuff.sh index b995851..0df4de7 100755 --- a/packer/stuff.sh +++ b/packer/stuff.sh @@ -7,7 +7,8 @@ cd ~/aflpp_nyx/nyx_mode/packer/packer #python3 nyx_packer.py --purge -spec ~/nyxnet/nyx-net/targets/specs/echoserver --setup_folder ~/nyxnet/nyx-net/targets/extra_folders/echoserver_extra_folder --nyx_net --nyx_net_port 1234 ~/nyxnet/nyx-net/targets/setup_scripts/build/echoserver/echoserver /tmp/echo_packed spec instrumentation -python3 nyx_packer.py --nyx_net_debug_mode --purge -spec ~/nyxnet/nyx-net/targets/specs/echoserver --setup_folder ~/nyxnet/nyx-net/targets/extra_folders/echoserver_extra_folder --nyx_net --nyx_net_port 1234 ~/nyxnet/nyx-net/targets/setup_scripts/build/echoserver/echoserver /tmp/echo_packed spec instrumentation +#python3 nyx_packer.py --nyx_net_debug_mode --purge -spec ~/nyxnet/nyx-net/targets/specs/echoserver --setup_folder ~/nyxnet/nyx-net/targets/extra_folders/echoserver_extra_folder --nyx_net --nyx_net_port 1234 ~/nyxnet/nyx-net/targets/setup_scripts/build/echoserver/echoserver /tmp/echo_packed spec instrumentation +python3 nyx_packer.py --nyx_net_debug_mode --purge --setup_folder ~/nyxnet/nyx-net/targets/extra_folders/echoserver_extra_folder --nyx_net --nyx_net_port 1234 ~/nyxnet/nyx-net/targets/setup_scripts/build/echoserver/echoserver /tmp/echo_packed nyxnet instrumentation python3 nyx_config_gen.py /tmp/echo_packed Kernel From 388e74d286638a242515457d01e837d021f74731 Mon Sep 17 00:00:00 2001 From: jausten Date: Tue, 8 Aug 2023 10:25:05 -0600 Subject: [PATCH 04/13] Removed protobufs --- packer/linux_x86_64-userspace/compile_64.sh | 28 +++++++------- .../src/ld_preload_fuzz.c | 38 ++++++++----------- packer/nyx_packer.py | 34 ++++++++--------- 3 files changed, 46 insertions(+), 54 deletions(-) diff --git a/packer/linux_x86_64-userspace/compile_64.sh b/packer/linux_x86_64-userspace/compile_64.sh index 5b8d777..d17aaea 100755 --- a/packer/linux_x86_64-userspace/compile_64.sh +++ b/packer/linux_x86_64-userspace/compile_64.sh @@ -20,22 +20,22 @@ else MODE="${UDP_MODE} ${CLIENT_MODE} ${DEBUG_MODE} ${STDOUT_STDERR_DEBUG}" echo "MODES => $MODE" - #clang++ -shared -g -O0 -m64 -Werror $EXTRA $MODE -fPIC src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/inject.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c -I../../ -DNET_FUZZ -I$NYX_SPEC_FOLDER -o bin64/ld_preload_fuzz.so -ldl -Isrc -Iproto src/proto/input.pb.cc -lprotobuf - #clang++ -shared -g -O0 -m64 -Werror -DNO_PT_NYX $EXTRA $MODE -fPIC src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/inject.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c -I../../ -DNET_FUZZ -I$NYX_SPEC_FOLDER -o bin64/ld_preload_fuzz_no_pt.so -ldl -Isrc -Iproto src/proto/input.pb.cc -lprotobuf + clang++ -shared -g -O0 -m64 -Werror $EXTRA $MODE -fPIC src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/inject.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c -I../../ -DNET_FUZZ -I$NYX_SPEC_FOLDER -o bin64/ld_preload_fuzz.so -ldl -Isrc -Iproto src/proto/input.pb.cc -lprotobuf + clang++ -shared -g -O0 -m64 -Werror -DNO_PT_NYX $EXTRA $MODE -fPIC src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/inject.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c -I../../ -DNET_FUZZ -I$NYX_SPEC_FOLDER -o bin64/ld_preload_fuzz_no_pt.so -ldl -Isrc -Iproto src/proto/input.pb.cc -lprotobuf # New compile commands for nyxnet mode - protoc -Isrc/proto input.proto --cpp_out=src/proto - clang++ -c -g -O0 -m64 -Werror -DNO_PT_NYX -DNET_FUZZ $MODE -fPIC \ - src/proto/afl_input.cpp src/proto/input.pb.cc \ - -Isrc/proto - clang -c -g -O0 -m64 -Werror -Wno-unused-value -DNO_PT_NYX -DNET_FUZZ $MODE -fPIC \ - src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c src/netfuzz/inject.c \ - -I../../ -Isrc -Isrc/proto -I../../../../custom_mutators/nyx-net/echoserver_example/specs/echoserver/include - clang++ -shared -g -O0 -m64 -Werror $MODE -fPIC \ - ld_preload_fuzz.o input.pb.o crash_handler.o harness_state.o inject.o socket_cache.o syscalls.o afl_input.o \ - -I../../ -Isrc -Isrc/proto \ - -o bin64/ld_preload_fuzz_no_pt.so -lprotobuf -ldl - rm -f ld_preload_fuzz.o input.pb.o crash_handler.o harness_state.o inject.o socket_cache.o syscalls.o afl_input.o + # protoc -Isrc/proto input.proto --cpp_out=src/proto + # clang++ -c -g -O0 -m64 -Werror -DNO_PT_NYX -DNET_FUZZ $MODE -fPIC \ + # src/proto/afl_input.cpp src/proto/input.pb.cc \ + # -Isrc/proto + # clang -c -g -O0 -m64 -Werror -Wno-unused-value -DNO_PT_NYX -DNET_FUZZ $MODE -fPIC \ + # src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c src/netfuzz/inject.c \ + # -I../../ -Isrc -Isrc/proto -I../../../../custom_mutators/nyx-net/echoserver_example/specs/echoserver/include + # clang++ -shared -g -O0 -m64 -Werror $MODE -fPIC \ + # ld_preload_fuzz.o input.pb.o crash_handler.o harness_state.o inject.o socket_cache.o syscalls.o afl_input.o \ + # -I../../ -Isrc -Isrc/proto \ + # -o bin64/ld_preload_fuzz_no_pt.so -lprotobuf -ldl + # rm -f ld_preload_fuzz.o input.pb.o crash_handler.o harness_state.o inject.o socket_cache.o syscalls.o afl_input.o else diff --git a/packer/linux_x86_64-userspace/src/ld_preload_fuzz.c b/packer/linux_x86_64-userspace/src/ld_preload_fuzz.c index 5c8b5a2..f2996bd 100644 --- a/packer/linux_x86_64-userspace/src/ld_preload_fuzz.c +++ b/packer/linux_x86_64-userspace/src/ld_preload_fuzz.c @@ -24,8 +24,6 @@ #include "misc/crash_handler.h" #include "misc/harness_state.h" -#include "afl_input.h" - //#define HYPERCALL_KAFL_RELEASE_DEBUG #define likely(x) __builtin_expect((x),1) @@ -56,8 +54,13 @@ bool payload_mode = false; #include "netfuzz/syscalls.h" //#endif - +#ifndef LEGACY_MODE #include "interpreter.h" +#else +extern void _assert(const char *func, const char *file, int line, const char *failedexpr); +#define INTERPRETER_ASSERT(x) do { if (x){}else{ _assert(__func__, __FILE__, __LINE__, #x);} } while (0) +#define ASSERT(x) INTERPRETER_ASSERT(x) +#endif #include "ijon_extension.h" @@ -205,35 +208,24 @@ ssize_t call_vm(void *data, size_t max_size, bool return_pkt_size, bool disable_ if (available_data <= 0) { - if (!afl_has_next()) { - - /* Parse new set of packets from vm buffer */ + /* Parse new data from vm buffer */ - if (!vm->data_len || *vm->data_len == 0){ - DEBUG("%s: out of data\n", __func__); - return -1; - } - - afl_deserialize(vm->data, *vm->data_len); - vm->data_len = NULL; /* This assumes vm->data can only be written to once per execution */ - + if (!vm->data_len || *vm->data_len == 0){ + DEBUG("%s: out of data\n", __func__); + return -1; } - /* Serialize next packet into data buffer */ - + available_data = *vm->data_len; offset = 0; - data_buffer = afl_get_next(&available_data); - if (available_data < 0) { - DEBUG("%s: packet does not fit in data_buffer\n", __func__); - return -1; - } + vm->data_len = NULL; /* This assumes vm->data can only be written to once per execution */ + } - /* Copy requested data from current packet */ + /* Copy requested data from vm buffer */ size_t num_copied = min_size_t(available_data, max_size); - memcpy(data, data_buffer+offset, num_copied); + memcpy(data, vm->data+offset, num_copied); DEBUG("%s: requested %d -> wrote %d bytes\n", __func__, max_size, num_copied); diff --git a/packer/nyx_packer.py b/packer/nyx_packer.py index 6de98eb..197d069 100755 --- a/packer/nyx_packer.py +++ b/packer/nyx_packer.py @@ -308,23 +308,23 @@ def compile(config): download_script += dependencies - if not LEGACY_MODE: - protobuf_lib_file = "/usr/local/lib/libprotobuf.so.32" - copyfile(protobuf_lib_file, "%s/%s"%(config.argument_values["output_dir"], os.path.basename(protobuf_lib_file))) - cpp_lib_file = "/usr/lib/x86_64-linux-gnu/libstdc++.so.6" - copyfile(cpp_lib_file, "%s/%s"%(config.argument_values["output_dir"], os.path.basename(cpp_lib_file))) - m_lib_file = "/lib/x86_64-linux-gnu/libm.so.6" - copyfile(m_lib_file, "%s/%s"%(config.argument_values["output_dir"], os.path.basename(m_lib_file))) - gcc_lib_file = "/lib/x86_64-linux-gnu/libgcc_s.so.1" - copyfile(gcc_lib_file, "%s/%s"%(config.argument_values["output_dir"], os.path.basename(gcc_lib_file))) - z_lib_file = "/lib/x86_64-linux-gnu/libz.so.1" - copyfile(z_lib_file, "%s/%s"%(config.argument_values["output_dir"], os.path.basename(z_lib_file))) - - download_script += "./hget %s %s\n"%(os.path.basename(protobuf_lib_file), os.path.basename(protobuf_lib_file)) - download_script += "./hget %s %s\n"%(os.path.basename(cpp_lib_file), os.path.basename(cpp_lib_file)) - download_script += "./hget %s %s\n"%(os.path.basename(m_lib_file), os.path.basename(m_lib_file)) - download_script += "./hget %s %s\n"%(os.path.basename(gcc_lib_file), os.path.basename(gcc_lib_file)) - download_script += "./hget %s %s\n"%(os.path.basename(z_lib_file), os.path.basename(z_lib_file)) + # if not LEGACY_MODE: + # protobuf_lib_file = "/usr/local/lib/libprotobuf.so.32" + # copyfile(protobuf_lib_file, "%s/%s"%(config.argument_values["output_dir"], os.path.basename(protobuf_lib_file))) + # cpp_lib_file = "/usr/lib/x86_64-linux-gnu/libstdc++.so.6" + # copyfile(cpp_lib_file, "%s/%s"%(config.argument_values["output_dir"], os.path.basename(cpp_lib_file))) + # m_lib_file = "/lib/x86_64-linux-gnu/libm.so.6" + # copyfile(m_lib_file, "%s/%s"%(config.argument_values["output_dir"], os.path.basename(m_lib_file))) + # gcc_lib_file = "/lib/x86_64-linux-gnu/libgcc_s.so.1" + # copyfile(gcc_lib_file, "%s/%s"%(config.argument_values["output_dir"], os.path.basename(gcc_lib_file))) + # z_lib_file = "/lib/x86_64-linux-gnu/libz.so.1" + # copyfile(z_lib_file, "%s/%s"%(config.argument_values["output_dir"], os.path.basename(z_lib_file))) + + # download_script += "./hget %s %s\n"%(os.path.basename(protobuf_lib_file), os.path.basename(protobuf_lib_file)) + # download_script += "./hget %s %s\n"%(os.path.basename(cpp_lib_file), os.path.basename(cpp_lib_file)) + # download_script += "./hget %s %s\n"%(os.path.basename(m_lib_file), os.path.basename(m_lib_file)) + # download_script += "./hget %s %s\n"%(os.path.basename(gcc_lib_file), os.path.basename(gcc_lib_file)) + # download_script += "./hget %s %s\n"%(os.path.basename(z_lib_file), os.path.basename(z_lib_file)) download_script += "echo \"Let's get our target executable...\" | ./hcat\n" copyfile(config.argument_values["binary_file"], "%s/%s"%(config.argument_values["output_dir"], os.path.basename(config.argument_values["binary_file"]))) From 7f0835079fd1180a7fe7e907461832876acc3dd1 Mon Sep 17 00:00:00 2001 From: jausten Date: Tue, 8 Aug 2023 12:06:34 -0600 Subject: [PATCH 05/13] Fixed compile args --- packer/linux_x86_64-userspace/compile_64.sh | 4 ++-- packer/linux_x86_64-userspace/src/proto/afl_input.cpp | 4 ++-- packer/linux_x86_64-userspace/src/proto/afl_input.h | 4 ++++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packer/linux_x86_64-userspace/compile_64.sh b/packer/linux_x86_64-userspace/compile_64.sh index d17aaea..ac9ad12 100755 --- a/packer/linux_x86_64-userspace/compile_64.sh +++ b/packer/linux_x86_64-userspace/compile_64.sh @@ -20,8 +20,8 @@ else MODE="${UDP_MODE} ${CLIENT_MODE} ${DEBUG_MODE} ${STDOUT_STDERR_DEBUG}" echo "MODES => $MODE" - clang++ -shared -g -O0 -m64 -Werror $EXTRA $MODE -fPIC src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/inject.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c -I../../ -DNET_FUZZ -I$NYX_SPEC_FOLDER -o bin64/ld_preload_fuzz.so -ldl -Isrc -Iproto src/proto/input.pb.cc -lprotobuf - clang++ -shared -g -O0 -m64 -Werror -DNO_PT_NYX $EXTRA $MODE -fPIC src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/inject.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c -I../../ -DNET_FUZZ -I$NYX_SPEC_FOLDER -o bin64/ld_preload_fuzz_no_pt.so -ldl -Isrc -Iproto src/proto/input.pb.cc -lprotobuf + clang -shared -g -O0 -m64 -Werror $EXTRA $MODE -fPIC src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/inject.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c -I../../ -DNET_FUZZ -I../../../../custom_mutators/nyx-net/echoserver_example/specs/echoserver/include -o bin64/ld_preload_fuzz.so -ldl -Isrc + clang -shared -g -O0 -m64 -Werror -DNO_PT_NYX $EXTRA $MODE -fPIC src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/inject.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c -I../../ -DNET_FUZZ -I../../../../custom_mutators/nyx-net/echoserver_example/specs/echoserver/include -o bin64/ld_preload_fuzz_no_pt.so -ldl -Isrc # New compile commands for nyxnet mode # protoc -Isrc/proto input.proto --cpp_out=src/proto diff --git a/packer/linux_x86_64-userspace/src/proto/afl_input.cpp b/packer/linux_x86_64-userspace/src/proto/afl_input.cpp index cf205bd..1e84149 100644 --- a/packer/linux_x86_64-userspace/src/proto/afl_input.cpp +++ b/packer/linux_x86_64-userspace/src/proto/afl_input.cpp @@ -41,8 +41,8 @@ extern "C" size_t afl_get_packet(int index, void* buf, size_t size) { } extern "C" void afl_set_packet(int index, void* buf, size_t size) { - afl_input::Packet packet = g_input.mutable_packets()->at(index); - packet.ParseFromArray(buf, size); + afl_input::Packet* packet = g_input.mutable_packets()->Mutable(index); + packet->set_buffer(buf, size); } extern "C" size_t afl_serialize(void* buf, size_t size) { diff --git a/packer/linux_x86_64-userspace/src/proto/afl_input.h b/packer/linux_x86_64-userspace/src/proto/afl_input.h index 617e6e7..5a83c22 100644 --- a/packer/linux_x86_64-userspace/src/proto/afl_input.h +++ b/packer/linux_x86_64-userspace/src/proto/afl_input.h @@ -1,6 +1,10 @@ #include #include +#ifndef __cplusplus +#include +#endif + #ifdef __cplusplus extern "C" { #endif From d8c538f7ace652056cc3fa1a20bd4a66a4556bfb Mon Sep 17 00:00:00 2001 From: jausten Date: Thu, 24 Aug 2023 11:11:14 -0600 Subject: [PATCH 06/13] Added back nyx_net spec mode --- packer/interpreter/build/data_include.h | 5 +- packer/linux_x86_64-userspace/compile_64.sh | 20 +--- .../src/ld_preload_fuzz.c | 111 +++++++++++++++++- packer/nyx_packer.py | 13 +- 4 files changed, 122 insertions(+), 27 deletions(-) diff --git a/packer/interpreter/build/data_include.h b/packer/interpreter/build/data_include.h index 87cdb85..20195cc 100644 --- a/packer/interpreter/build/data_include.h +++ b/packer/interpreter/build/data_include.h @@ -11,9 +11,10 @@ typedef struct {size_t count; d_char* vals; } d_vec_path_string; typedef uint8_t d_foo_bla; typedef uint32_t d_foo_fuu; -#pragma pack(1) +#pragma pack(push, 1) typedef struct { d_foo_bla bla; d_flags flags; d_foo_fuu fuu; -} d_foo; \ No newline at end of file +} d_foo; +#pragma pack(pop) \ No newline at end of file diff --git a/packer/linux_x86_64-userspace/compile_64.sh b/packer/linux_x86_64-userspace/compile_64.sh index ac9ad12..b876086 100755 --- a/packer/linux_x86_64-userspace/compile_64.sh +++ b/packer/linux_x86_64-userspace/compile_64.sh @@ -17,25 +17,11 @@ else if [ "$NET_FUZZ" = "ON" ] then - MODE="${UDP_MODE} ${CLIENT_MODE} ${DEBUG_MODE} ${STDOUT_STDERR_DEBUG}" + MODE="${SPEC_MODE} ${UDP_MODE} ${CLIENT_MODE} ${DEBUG_MODE} ${STDOUT_STDERR_DEBUG}" echo "MODES => $MODE" - clang -shared -g -O0 -m64 -Werror $EXTRA $MODE -fPIC src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/inject.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c -I../../ -DNET_FUZZ -I../../../../custom_mutators/nyx-net/echoserver_example/specs/echoserver/include -o bin64/ld_preload_fuzz.so -ldl -Isrc - clang -shared -g -O0 -m64 -Werror -DNO_PT_NYX $EXTRA $MODE -fPIC src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/inject.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c -I../../ -DNET_FUZZ -I../../../../custom_mutators/nyx-net/echoserver_example/specs/echoserver/include -o bin64/ld_preload_fuzz_no_pt.so -ldl -Isrc - - # New compile commands for nyxnet mode - # protoc -Isrc/proto input.proto --cpp_out=src/proto - # clang++ -c -g -O0 -m64 -Werror -DNO_PT_NYX -DNET_FUZZ $MODE -fPIC \ - # src/proto/afl_input.cpp src/proto/input.pb.cc \ - # -Isrc/proto - # clang -c -g -O0 -m64 -Werror -Wno-unused-value -DNO_PT_NYX -DNET_FUZZ $MODE -fPIC \ - # src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c src/netfuzz/inject.c \ - # -I../../ -Isrc -Isrc/proto -I../../../../custom_mutators/nyx-net/echoserver_example/specs/echoserver/include - # clang++ -shared -g -O0 -m64 -Werror $MODE -fPIC \ - # ld_preload_fuzz.o input.pb.o crash_handler.o harness_state.o inject.o socket_cache.o syscalls.o afl_input.o \ - # -I../../ -Isrc -Isrc/proto \ - # -o bin64/ld_preload_fuzz_no_pt.so -lprotobuf -ldl - # rm -f ld_preload_fuzz.o input.pb.o crash_handler.o harness_state.o inject.o socket_cache.o syscalls.o afl_input.o + clang -shared -g -O0 -m64 -Werror -DNET_FUZZ $EXTRA $MODE -fPIC src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/inject.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c -I../../ -o bin64/ld_preload_fuzz.so -ldl -Isrc + clang -shared -g -O0 -m64 -Werror -DNET_FUZZ -DNO_PT_NYX $EXTRA $MODE -fPIC src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/inject.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c -I../../ -o bin65/ld_preload_fuzz_no_pt.so -ldl -Isrc else diff --git a/packer/linux_x86_64-userspace/src/ld_preload_fuzz.c b/packer/linux_x86_64-userspace/src/ld_preload_fuzz.c index f2996bd..caeda47 100644 --- a/packer/linux_x86_64-userspace/src/ld_preload_fuzz.c +++ b/packer/linux_x86_64-userspace/src/ld_preload_fuzz.c @@ -57,8 +57,8 @@ bool payload_mode = false; #ifndef LEGACY_MODE #include "interpreter.h" #else -extern void _assert(const char *func, const char *file, int line, const char *failedexpr); -#define INTERPRETER_ASSERT(x) do { if (x){}else{ _assert(__func__, __FILE__, __LINE__, #x);} } while (0) +extern void __assert(const char *func, const char *file, int line, const char *failedexpr); +#define INTERPRETER_ASSERT(x) do { if (x){}else{ __assert(__func__, __FILE__, __LINE__, #x);} } while (0) #define ASSERT(x) INTERPRETER_ASSERT(x) #endif @@ -190,7 +190,7 @@ void hprintf_payload(char* data, size_t len){ /* TODO: check via env var */ //#define COPY_PAYLOAD_MODE - +#ifndef SPEC_MODE ssize_t call_vm(void *data, size_t max_size, bool return_pkt_size, bool disable_dump_mode) { #ifdef EARLY_EXIT_NODES @@ -202,7 +202,6 @@ ssize_t call_vm(void *data, size_t max_size, bool return_pkt_size, bool disable_ } #endif - static const char* data_buffer = NULL; static size_t available_data = 0; static size_t offset = 0; @@ -247,6 +246,110 @@ ssize_t call_vm(void *data, size_t max_size, bool return_pkt_size, bool disable_ return num_copied; } +#else +ssize_t call_vm(void *data, size_t max_size, bool return_pkt_size, bool disable_dump_mode){ + +#ifdef EARLY_EXIT_NODES + static int count = 0; +#endif + + +#ifdef UDP_MODE + vm->user_data->len = max_size; + vm->user_data->data = data; + if(interpreter_run(vm)==0){ + return -1; + } + +#ifdef EARLY_EXIT_NODES + count++; + + if (count >= EARLY_EXIT_NODES){ + return -1; + } +#endif + + if(vm->user_data->closed){ + return -1; /* -1 -> EOF */ + } + + //hprintf("max: %d / pkt_len: %d / len: %d\n", max_size, vm->user_data->pkt_len, vm->user_data->len); + if(return_pkt_size && max_size < vm->user_data->len){ +//#ifdef COPY_PAYLOAD_MODE + if(payload_mode && !disable_dump_mode){ + hprintf_payload(vm->user_data->data, vm->user_data->len); + } + //hprintf("%d vs %d\n", vm->user_data->pkt_len, max_size); +//#endif + return vm->user_data->len; + } + else{ +//#ifdef COPY_PAYLOAD_MODE + if(payload_mode && !disable_dump_mode){ + hprintf_payload(vm->user_data->data, vm->user_data->len); + } +//#endif + return vm->user_data->len; + } +#else + + #define PACKET_BUFFER_SIZE (1<<14) + static char data_buffer[PACKET_BUFFER_SIZE]; + static size_t available_data= 0; + static size_t next_data = 0; + + if(available_data == 0){ + vm->user_data->len = PACKET_BUFFER_SIZE; + vm->user_data->data = &data_buffer[0]; + + //hprintf("%s: 1: %p\n", __func__, vm); + //hprintf("%s: 2: %p\n", __func__, vm->user_data); + //hprintf("%s: 3: %p\n", __func__, vm->user_data->len); + + if(interpreter_run(vm)==0){ + DEBUG("%s: out of data\n", __func__); + return -1; + } + +#ifdef EARLY_EXIT_NODES + count++; + + if (count >= EARLY_EXIT_NODES){ + //hprintf("EARLY EXIT\n"); + return -1; + } +#endif + + if(vm->user_data->closed){ + DEBUG("%s: closed\n", __func__); + + return -1; /* -1 -> EOF */ + } + available_data = vm->user_data->len; + next_data = 0; + } + + size_t num_copied = min_size_t(available_data, max_size); + /* + if(available_data < num_copied){ + hprintf("WARNING: num_copied: %d / num_copied: %d\n", available_data, num_copied); + } + */ + memcpy(data, &data_buffer[next_data], num_copied); + available_data-=num_copied; + next_data+=num_copied; + + DEBUG("CALL_VM %d -> %d\n", max_size, num_copied); +//#ifdef COPY_PAYLOAD_MODE + if(payload_mode && !disable_dump_mode){ + hprintf_payload(data, num_copied); + } +//#endif + //return 0; + return num_copied; +#endif +} +#endif #ifndef NET_FUZZ ssize_t read(int fd, void *data, size_t size) { diff --git a/packer/nyx_packer.py b/packer/nyx_packer.py index 197d069..314b68c 100755 --- a/packer/nyx_packer.py +++ b/packer/nyx_packer.py @@ -171,13 +171,16 @@ def compile(config): PRE_PROCESS_ARGS = config.argument_values["add_pre_process_args"] SET_CLIENT_UDP_PORT = config.argument_values["set_client_udp_port"] + # --nyx_net with afl activates nyx_net mode without specs + # --nyx_net with spec uses the old nyx_net spec mode if config.argument_values["mode"] == "afl": - LEGACY_MODE = True + if NET_FUZZ_MODE: + LEGACY_MODE = False + else: + LEGACY_MODE = True elif config.argument_values["mode"] == "spec": - print(WARNING + WARNING_PREFIX + "The integrated nyxnet&afl++ mode is now \"nyxnet\"") - LEGACY_MODE = False - elif config.argument_values["mode"] == "nyxnet": LEGACY_MODE = False + SPEC_MODE = True # Use this to differentiate between spec and non-spec mode in preload else: raise Exception("Unkown mode: %s"%(config.argument_values["mode"])) @@ -222,6 +225,8 @@ def compile(config): os.environ["NYX_SPEC_FOLDER"] = SPEC_FOLDER + "/build" if LEGACY_MODE: os.environ["LEGACY_MODE"] = "ON" + if SPEC_MODE: + os.environ["SPEC_MODE"] = "-DSPEC_MODE" if NET_FUZZ_MODE: os.environ["NET_FUZZ"] = "ON" if UDP_MODE: From 9c37189d28b834978cd11a22e7c588b50f00dbe8 Mon Sep 17 00:00:00 2001 From: jausten Date: Thu, 24 Aug 2023 12:14:16 -0600 Subject: [PATCH 07/13] Added interpreter for non-spec mode, debug fixes --- .../src/ld_preload_fuzz.c | 33 +++++++++++++++---- .../src/netfuzz/inject.c | 4 +-- packer/nyx_packer.py | 1 + 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/packer/linux_x86_64-userspace/src/ld_preload_fuzz.c b/packer/linux_x86_64-userspace/src/ld_preload_fuzz.c index caeda47..709ba33 100644 --- a/packer/linux_x86_64-userspace/src/ld_preload_fuzz.c +++ b/packer/linux_x86_64-userspace/src/ld_preload_fuzz.c @@ -54,12 +54,31 @@ bool payload_mode = false; #include "netfuzz/syscalls.h" //#endif -#ifndef LEGACY_MODE +#ifdef SPEC_MODE + +/* Spec mode uses the interpreter */ #include "interpreter.h" + #else + extern void __assert(const char *func, const char *file, int line, const char *failedexpr); #define INTERPRETER_ASSERT(x) do { if (x){}else{ __assert(__func__, __FILE__, __LINE__, #x);} } while (0) #define ASSERT(x) INTERPRETER_ASSERT(x) + +/* Nyx-net mode uses the vm data structure */ +#ifndef LEGACY_MODE +typedef struct { + uint16_t* ops; + size_t* ops_len; + size_t ops_i; + + uint8_t* data; + uint32_t* data_len; + size_t data_i; + uint32_t* instruction_counter; +} interpreter_t; +#endif + #endif #include "ijon_extension.h" @@ -76,11 +95,6 @@ bool fuzzer_ready = false; interpreter_t* vm; -#ifdef NET_FUZZ -socket_state_t vm_state; -#else -fd_state_t vm_state; -#endif ssize_t (*fptr_read)(int fd, void *data, size_t size); ssize_t (*fptr_getline)(char **lineptr, size_t *n, FILE *stream); @@ -968,8 +982,13 @@ void nyx_init_start(void){ free(ar); free(ranges); -#ifndef LEGACY_MODE +#ifdef SPEC_MODE vm = new_interpreter(); +#else +#ifndef LEGACY_MODE + vm = malloc(sizeof(interpreter_t)); + memset(vm, 0, sizeof(interpreter_t)); +#endif hprintf("interpreter: %p\n", vm); #endif diff --git a/packer/linux_x86_64-userspace/src/netfuzz/inject.c b/packer/linux_x86_64-userspace/src/netfuzz/inject.c index 7f05b6b..97d1aa6 100644 --- a/packer/linux_x86_64-userspace/src/netfuzz/inject.c +++ b/packer/linux_x86_64-userspace/src/netfuzz/inject.c @@ -371,7 +371,7 @@ int printf(const char* format, ...) va_list arg; va_start(arg, format); - hprintf(format, va_arg(arg, int)); + DEBUG(format, va_arg(arg, int)); va_end(arg); return 0; @@ -379,7 +379,7 @@ int printf(const char* format, ...) int puts(const char* s) { - hprintf(s); + DEBUG(s); return 0; } diff --git a/packer/nyx_packer.py b/packer/nyx_packer.py index 314b68c..0517374 100755 --- a/packer/nyx_packer.py +++ b/packer/nyx_packer.py @@ -170,6 +170,7 @@ def compile(config): PRE_PROCESS = config.argument_values["add_pre_process"] PRE_PROCESS_ARGS = config.argument_values["add_pre_process_args"] SET_CLIENT_UDP_PORT = config.argument_values["set_client_udp_port"] + SPEC_MODE = False # --nyx_net with afl activates nyx_net mode without specs # --nyx_net with spec uses the old nyx_net spec mode From 343fb722fa1ef66ea48997a8d8c5f23a56f91e8e Mon Sep 17 00:00:00 2001 From: jausten Date: Fri, 25 Aug 2023 10:15:23 -0600 Subject: [PATCH 08/13] Add 32 bit compile nyx net --- packer/linux_x86_64-userspace/compile_32.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packer/linux_x86_64-userspace/compile_32.sh b/packer/linux_x86_64-userspace/compile_32.sh index b723c2b..afee2b7 100755 --- a/packer/linux_x86_64-userspace/compile_32.sh +++ b/packer/linux_x86_64-userspace/compile_32.sh @@ -17,10 +17,10 @@ else if [ "$NET_FUZZ" = "ON" ] then - MODE="${UDP_MODE} ${CLIENT_MODE} ${DEBUG_MODE} ${STDOUT_STDERR_DEBUG}" + MODE="${SPEC_MODE} ${UDP_MODE} ${CLIENT_MODE} ${DEBUG_MODE} ${STDOUT_STDERR_DEBUG}" echo "MODES => $MODE" - clang -shared -g -O0 -m32 -Werror $EXTRA $MODE -fPIC src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/inject.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c -I../../ -DNET_FUZZ -I$NYX_SPEC_FOLDER -o bin32/ld_preload_fuzz.so -ldl -Isrc - clang -shared -g -O0 -m32 -Werror -DNO_PT_NYX $EXTRA $MODE -fPIC src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/inject.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c -I../../ -DNET_FUZZ -I$NYX_SPEC_FOLDER -o bin32/ld_preload_fuzz_no_pt.so -ldl -Isrc + clang -shared -g -O0 -m32 -Werror -DNET_FUZZ $EXTRA $MODE -fPIC src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/inject.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c -I../../ -o bin32/ld_preload_fuzz.so -ldl -Isrc + clang -shared -g -O0 -m32 -Werror -DNET_FUZZ -DNO_PT_NYX $EXTRA $MODE -fPIC src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/inject.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c -I../../ -o bin32/ld_preload_fuzz_no_pt.so -ldl -Isrc else From d17786ddacbd8ed9eb2c6aba33e96251fff39cb9 Mon Sep 17 00:00:00 2001 From: jausten Date: Fri, 25 Aug 2023 10:21:11 -0600 Subject: [PATCH 09/13] Remove test file --- .gitignore | 1 + packer/stuff.sh | 18 ------------------ 2 files changed, 1 insertion(+), 18 deletions(-) delete mode 100755 packer/stuff.sh diff --git a/.gitignore b/.gitignore index 46b94e4..92ad07e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ linux_initramfs/init_debug_shell.cpio.gz linux_initramfs/init packer/linux_x86_64-userspace/src/proto/input.pb.cc packer/linux_x86_64-userspace/src/proto/input.pb.h +packer/pack_test.sh diff --git a/packer/stuff.sh b/packer/stuff.sh deleted file mode 100755 index 0df4de7..0000000 --- a/packer/stuff.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -# -# Pack and setup for fuzzing -# - -cd ~/aflpp_nyx/nyx_mode/packer/packer - -#python3 nyx_packer.py --purge -spec ~/nyxnet/nyx-net/targets/specs/echoserver --setup_folder ~/nyxnet/nyx-net/targets/extra_folders/echoserver_extra_folder --nyx_net --nyx_net_port 1234 ~/nyxnet/nyx-net/targets/setup_scripts/build/echoserver/echoserver /tmp/echo_packed spec instrumentation -#python3 nyx_packer.py --nyx_net_debug_mode --purge -spec ~/nyxnet/nyx-net/targets/specs/echoserver --setup_folder ~/nyxnet/nyx-net/targets/extra_folders/echoserver_extra_folder --nyx_net --nyx_net_port 1234 ~/nyxnet/nyx-net/targets/setup_scripts/build/echoserver/echoserver /tmp/echo_packed spec instrumentation -python3 nyx_packer.py --nyx_net_debug_mode --purge --setup_folder ~/nyxnet/nyx-net/targets/extra_folders/echoserver_extra_folder --nyx_net --nyx_net_port 1234 ~/nyxnet/nyx-net/targets/setup_scripts/build/echoserver/echoserver /tmp/echo_packed nyxnet instrumentation - -python3 nyx_config_gen.py /tmp/echo_packed Kernel - -kill -9 $(pgrep qemu) -rm -rf /tmp/out - -echo "ready to fuzz" From eeac674882f740ce4090aa8a2abded50db5774a4 Mon Sep 17 00:00:00 2001 From: jausten Date: Fri, 25 Aug 2023 10:34:55 -0600 Subject: [PATCH 10/13] Added protobuf message handling files --- .../src/proto/afl_input.cpp | 26 +++++-------------- .../src/proto/afl_input.h | 3 +++ 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/packer/linux_x86_64-userspace/src/proto/afl_input.cpp b/packer/linux_x86_64-userspace/src/proto/afl_input.cpp index 1e84149..5f05503 100644 --- a/packer/linux_x86_64-userspace/src/proto/afl_input.cpp +++ b/packer/linux_x86_64-userspace/src/proto/afl_input.cpp @@ -7,21 +7,23 @@ auto g_packet = g_input.packets().end(); extern "C" void afl_deserialize(uint8_t* buf, uint32_t size) { g_input.ParseFromArray(buf, size); g_packet = g_input.packets().begin(); +} - printf("Deserializing %d packets...\n", g_input.packets_size()); +extern "C" void afl_dump_packets(void) { + printf("Packet dump:\n"); + int n = 0; for (const afl_input::Packet& pkt : g_input.packets()) { - printf("Packet dump:\n"); + printf("%d:\n", n++); for(int i = 0; i < pkt.buffer().size(); ++i) { printf("%02X ", pkt.buffer().data()[i]); if ((i+1) % 16 == 0) printf("\n"); } - printf("\n"); } - -}; + printf("\n"); +} extern "C" int afl_packets_size() { return g_input.packets_size(); @@ -46,20 +48,6 @@ extern "C" void afl_set_packet(int index, void* buf, size_t size) { } extern "C" size_t afl_serialize(void* buf, size_t size) { - - printf("Serializing packets...\n"); - for (auto pkt : g_input.packets()) - { - printf("Packet dump:\n"); - for(int i = 0; i < pkt.buffer().size(); ++i) - { - printf("%02X ", pkt.buffer().data()[i]); - if ((i+1) % 16 == 0) - printf("\n"); - } - printf("\n"); - } - g_input.SerializeToArray(buf, size); return std::min(size, g_input.ByteSizeLong()); } diff --git a/packer/linux_x86_64-userspace/src/proto/afl_input.h b/packer/linux_x86_64-userspace/src/proto/afl_input.h index 5a83c22..37a2d13 100644 --- a/packer/linux_x86_64-userspace/src/proto/afl_input.h +++ b/packer/linux_x86_64-userspace/src/proto/afl_input.h @@ -18,6 +18,9 @@ extern "C" { /// @param size Size of buf void afl_deserialize(uint8_t* buf, uint32_t size); +/// @brief Dump the contents of the packets +void afl_dump_packets(void); + /******************************** * Functions for custom mutator * ********************************/ From 73d9d51eebeb604d671ffa37ec3f1a1be63cc267 Mon Sep 17 00:00:00 2001 From: jausten Date: Fri, 25 Aug 2023 10:45:57 -0600 Subject: [PATCH 11/13] Cleaned up commented out code --- packer/common/config.py | 5 ++--- packer/nyx_packer.py | 22 +--------------------- 2 files changed, 3 insertions(+), 24 deletions(-) diff --git a/packer/common/config.py b/packer/common/config.py index f398b4f..9879b9f 100644 --- a/packer/common/config.py +++ b/packer/common/config.py @@ -264,10 +264,9 @@ def __load_config(self): self.config_values = ConfigReader(os.path.dirname(os.path.realpath(__file__))+"/../nyx.ini", self.__config_section, self.__config_default).get_values() def __load_arguments(self): - modes = ["afl", "spec", "nyxnet"] + modes = ["afl", "spec"] modes_help = 'afl\t\t - pack target for an AFL-like fuzzer (such as AFL++, kAFL, Nautilus)\n' \ - 'spec\t\t - pack target for a spec fuzzer (such as Nyx\'s spec-fuzzer)\n' \ - 'nyxnet\t\t - pack target for an AFL-like fuzzer while using nyx-net' + 'spec\t\t - pack target for a spec fuzzer (such as Nyx\'s spec-fuzzer)\n' coverage_modes = ["instrumentation", "processor_trace"] coverage_modes_help = 'instrumentation\t - use compile-time instrumentation (target has to be compiled with an proper compiler)\n' \ diff --git a/packer/nyx_packer.py b/packer/nyx_packer.py index 0517374..6728c39 100755 --- a/packer/nyx_packer.py +++ b/packer/nyx_packer.py @@ -314,24 +314,6 @@ def compile(config): download_script += dependencies - # if not LEGACY_MODE: - # protobuf_lib_file = "/usr/local/lib/libprotobuf.so.32" - # copyfile(protobuf_lib_file, "%s/%s"%(config.argument_values["output_dir"], os.path.basename(protobuf_lib_file))) - # cpp_lib_file = "/usr/lib/x86_64-linux-gnu/libstdc++.so.6" - # copyfile(cpp_lib_file, "%s/%s"%(config.argument_values["output_dir"], os.path.basename(cpp_lib_file))) - # m_lib_file = "/lib/x86_64-linux-gnu/libm.so.6" - # copyfile(m_lib_file, "%s/%s"%(config.argument_values["output_dir"], os.path.basename(m_lib_file))) - # gcc_lib_file = "/lib/x86_64-linux-gnu/libgcc_s.so.1" - # copyfile(gcc_lib_file, "%s/%s"%(config.argument_values["output_dir"], os.path.basename(gcc_lib_file))) - # z_lib_file = "/lib/x86_64-linux-gnu/libz.so.1" - # copyfile(z_lib_file, "%s/%s"%(config.argument_values["output_dir"], os.path.basename(z_lib_file))) - - # download_script += "./hget %s %s\n"%(os.path.basename(protobuf_lib_file), os.path.basename(protobuf_lib_file)) - # download_script += "./hget %s %s\n"%(os.path.basename(cpp_lib_file), os.path.basename(cpp_lib_file)) - # download_script += "./hget %s %s\n"%(os.path.basename(m_lib_file), os.path.basename(m_lib_file)) - # download_script += "./hget %s %s\n"%(os.path.basename(gcc_lib_file), os.path.basename(gcc_lib_file)) - # download_script += "./hget %s %s\n"%(os.path.basename(z_lib_file), os.path.basename(z_lib_file)) - download_script += "echo \"Let's get our target executable...\" | ./hcat\n" copyfile(config.argument_values["binary_file"], "%s/%s"%(config.argument_values["output_dir"], os.path.basename(config.argument_values["binary_file"]))) download_script += "./hget %s target_executable\n"%(os.path.basename(config.argument_values["binary_file"])) @@ -432,9 +414,7 @@ def compile(config): download_script += "cat stdout.txt | ./hcat\n" download_script += "cat stderr.txt | ./hcat\n" else: - #download_script += " > /dev/null 2> /dev/null\n" - download_script += "2>&1 | ./hcat\n" - + download_script += " > /dev/null 2> /dev/null\n" download_script += "dmesg | grep segfault | ./hcat\n" download_script += "./habort \"Target has terminated without initializing the fuzzing agent ...\"\n" From 79da03a58d656c3ce675c011dc402ed718e63660 Mon Sep 17 00:00:00 2001 From: jausten Date: Tue, 29 Aug 2023 12:16:37 -0600 Subject: [PATCH 12/13] fix typo --- packer/linux_x86_64-userspace/compile_64.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packer/linux_x86_64-userspace/compile_64.sh b/packer/linux_x86_64-userspace/compile_64.sh index b876086..7351013 100755 --- a/packer/linux_x86_64-userspace/compile_64.sh +++ b/packer/linux_x86_64-userspace/compile_64.sh @@ -21,7 +21,7 @@ else echo "MODES => $MODE" clang -shared -g -O0 -m64 -Werror -DNET_FUZZ $EXTRA $MODE -fPIC src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/inject.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c -I../../ -o bin64/ld_preload_fuzz.so -ldl -Isrc - clang -shared -g -O0 -m64 -Werror -DNET_FUZZ -DNO_PT_NYX $EXTRA $MODE -fPIC src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/inject.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c -I../../ -o bin65/ld_preload_fuzz_no_pt.so -ldl -Isrc + clang -shared -g -O0 -m64 -Werror -DNET_FUZZ -DNO_PT_NYX $EXTRA $MODE -fPIC src/ld_preload_fuzz.c src/misc/crash_handler.c src/misc/harness_state.c src/netfuzz/inject.c src/netfuzz/syscalls.c src/netfuzz/socket_cache.c -I../../ -o bin64/ld_preload_fuzz_no_pt.so -ldl -Isrc else From e986ff3b225dedbb909ef62da6fedf94d43de5a9 Mon Sep 17 00:00:00 2001 From: jausten Date: Tue, 29 Aug 2023 12:19:21 -0600 Subject: [PATCH 13/13] Fix font color --- packer/nyx_packer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packer/nyx_packer.py b/packer/nyx_packer.py index 6728c39..72953bc 100755 --- a/packer/nyx_packer.py +++ b/packer/nyx_packer.py @@ -429,7 +429,7 @@ def compile(config): f.write(download_script.replace("./hget hcat", "./hget hcat_no_pt").replace("./hget habort", "./hget habort_no_pt").replace("./hget ld_preload_fuzz.so", "./hget ld_preload_fuzz_no_pt.so")) f.close() - print(OKGREEN + INFO_PREFIX + "NYX share-dir is ready -> %s"%(config.argument_values["output_dir"])) + print(OKGREEN + INFO_PREFIX + "NYX share-dir is ready -> %s"%(config.argument_values["output_dir"]) + ENDC) return