mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-16 11:58:08 +00:00
add libaflppdesock
This commit is contained in:
@ -23,10 +23,12 @@
|
||||
- MacOS aflpp driver compilation fix (-fsanitize=fuzzer implementation)
|
||||
- Make AFL_DUMP_MAP_SIZE work even if the target has sanitizer issues
|
||||
- qemuafl:
|
||||
- better MIPS persistent mode support
|
||||
- Better MIPS persistent mode support
|
||||
- afl-cmin:
|
||||
- new afl-cmin.py which is much faster, will be executed by default via
|
||||
- New afl-cmin.py which is much faster, will be executed by default via
|
||||
afl-cmin if it executes successfully (thanks to @kcwu!)
|
||||
- New desocketing library: utils/libaflppdesock
|
||||
- Likely works when all other desocketing options fail
|
||||
|
||||
|
||||
### Version ++4.32c (release)
|
||||
|
12
utils/libaflppdesock/Makefile
Normal file
12
utils/libaflppdesock/Makefile
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
# For cross compilation modify this as needed
|
||||
#GLIBC_PATH := /path/to/glibc-2.xx/build/local_install
|
||||
#CROSS_CFLAGS := -mfloat-abi=soft -nostdlib -I$(GLIBC_PATH)/include -L$(GLIBC_PATH)/lib -Wl,-rpath=/lib -Wl,--dynamic-linker=/lib/ld-linux.so.3
|
||||
|
||||
all: libaflppdesock.so
|
||||
|
||||
libaflppdesock.so: libaflppdesock.c
|
||||
$(CC) $(CROSS_CFLAGS) -shared -fPIC -o libaflppdesock.so libaflppdesock.c
|
||||
|
||||
clean:
|
||||
rm -f libaflppdesock.so *~ core
|
46
utils/libaflppdesock/README.md
Normal file
46
utils/libaflppdesock/README.md
Normal file
@ -0,0 +1,46 @@
|
||||
# AFL++ TCP desocket library
|
||||
|
||||
Other desocketing solutions:
|
||||
* https://github.com/zardus/preeny (desock and desock2)
|
||||
* https://github.com/fkie-cad/libdesock
|
||||
* https://github.com/zyingp/desockmulti
|
||||
* https://github.com/vanhauser-thc/network-emulator
|
||||
|
||||
If these desocket solutions fail, then this one will likely easily work
|
||||
for you - alass with slightly lower performance.
|
||||
And it is easy to extend :-)
|
||||
|
||||
## Why might this solution work when others do not?
|
||||
|
||||
What makes this desocket library special is that only **only** intercepts
|
||||
`accept()` calls bound to a specified port. Hence any other network stuff
|
||||
the application does is still working as expected.
|
||||
|
||||
## How to use
|
||||
|
||||
`AFL_PRELOAD` this library and use the following environment variables:
|
||||
|
||||
* `DESOCK_PORT=8080` - required for intercepting incoming connections for fuzzing - sets the TCP port
|
||||
* `DESOCK_FORK=1` - intercept and prevent forking
|
||||
* `DESOCK_CLOSE_EXIT=1` - call _exit() when the desocketed file descriptor is `close`d or `shutdown`ed
|
||||
* `DESOCK_DEBUG=1` - print debug information to `stderr`
|
||||
|
||||
** Internals
|
||||
|
||||
Currently the library intercepts the following calls:
|
||||
|
||||
```
|
||||
shutdown
|
||||
close
|
||||
fork
|
||||
accept
|
||||
accept4
|
||||
listen
|
||||
bind
|
||||
setsockopt
|
||||
getsockopt
|
||||
getpeername
|
||||
getsockname
|
||||
```
|
||||
|
||||
`
|
352
utils/libaflppdesock/libaflppdesock.c
Normal file
352
utils/libaflppdesock/libaflppdesock.c
Normal file
@ -0,0 +1,352 @@
|
||||
/* desocket library by Marc "vanHauser" Heuse <vh@thc.org>
|
||||
*
|
||||
* Use this library for fuzzing if preeny's desock and desock2 solutions
|
||||
* do not work for you - these would provide faster performance.
|
||||
*
|
||||
*/
|
||||
|
||||
// default: file descriptor 0 for stdin
|
||||
#define FUZZ_INPUT_FD 0
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static void *handle;
|
||||
static bool do_fork, do_close, debug, running;
|
||||
static int port = -1;
|
||||
static int listen_fd = -1;
|
||||
|
||||
struct myin_addr {
|
||||
|
||||
unsigned int s_addr; // IPv4 address in network byte order
|
||||
|
||||
};
|
||||
|
||||
struct mysockaddr {
|
||||
|
||||
unsigned short int sin_family; // Address family: AF_INET
|
||||
unsigned short int sin_port; // Port number (network byte order)
|
||||
struct myin_addr sin_addr; // Internet address
|
||||
char sin_zero[8]; // Padding (unused)
|
||||
|
||||
};
|
||||
|
||||
#define RTLD_LAZY 0x00001
|
||||
|
||||
unsigned short int htons(unsigned short int hostshort) {
|
||||
|
||||
return (hostshort << 8) | (hostshort >> 8);
|
||||
|
||||
}
|
||||
|
||||
static void __get_handle() {
|
||||
|
||||
if (!(handle = dlopen("libc.so", RTLD_NOW))) {
|
||||
|
||||
if (!(handle = dlopen("libc.so.6", RTLD_NOW))) {
|
||||
|
||||
if (!(handle = dlopen("libc-orig.so", RTLD_LAZY))) {
|
||||
|
||||
if (!(handle = dlopen("cygwin1.dll", RTLD_LAZY))) {
|
||||
|
||||
if (!(handle = dlopen("libc.so", RTLD_NOW))) {
|
||||
|
||||
fprintf(stderr, "DESOCK: can not find libc!\n");
|
||||
exit(-1);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (getenv("DESOCK_DEBUG")) { debug = true; }
|
||||
if (getenv("DESOCK_PORT")) { port = atoi(getenv("DESOCK_PORT")); }
|
||||
if (getenv("DESOCK_FORK")) { do_fork = true; }
|
||||
if (getenv("DESOCK_CLOSE_EXIT")) { do_close = true; }
|
||||
if (debug) fprintf(stderr, "DESOCK: initialized!\n");
|
||||
|
||||
}
|
||||
|
||||
int (*o_shutdown)(int socket, int how);
|
||||
int shutdown(int socket, int how) {
|
||||
|
||||
if (port != -1 && socket == FUZZ_INPUT_FD && running) {
|
||||
|
||||
running = false;
|
||||
if (do_close) {
|
||||
|
||||
if (debug) fprintf(stderr, "DESOCK: exiting\n");
|
||||
_exit(0);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (port == -1 && do_close) {
|
||||
|
||||
if (debug) fprintf(stderr, "DESOCK: exiting\n");
|
||||
_exit(0);
|
||||
|
||||
}
|
||||
|
||||
if (!handle) { __get_handle(); }
|
||||
if (!o_shutdown) { o_shutdown = dlsym(handle, "shutdown"); }
|
||||
return o_shutdown(socket, how);
|
||||
|
||||
}
|
||||
|
||||
int (*o_close)(int socket);
|
||||
int close(int socket) {
|
||||
|
||||
if (port != -1 && socket == FUZZ_INPUT_FD && running) {
|
||||
|
||||
running = false;
|
||||
if (do_close) {
|
||||
|
||||
if (debug) fprintf(stderr, "DESOCK: exiting\n");
|
||||
_exit(0);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (listen_fd != -1 && socket == listen_fd) {
|
||||
|
||||
if (debug) fprintf(stderr, "DESOCK: close bind\n");
|
||||
listen_fd = -1;
|
||||
|
||||
}
|
||||
|
||||
if (!handle) { __get_handle(); }
|
||||
if (!o_close) { o_close = dlsym(handle, "close"); }
|
||||
return o_close(socket);
|
||||
|
||||
}
|
||||
|
||||
int (*o_fork)(void);
|
||||
int fork() {
|
||||
|
||||
if (do_fork) {
|
||||
|
||||
if (debug) fprintf(stderr, "DESOCK: fake fork\n");
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
if (!handle) { __get_handle(); }
|
||||
if (!o_fork) { o_fork = dlsym(handle, "fork"); }
|
||||
return o_fork();
|
||||
|
||||
}
|
||||
|
||||
int (*o_accept)(int sockfd, struct mysockaddr *addr,
|
||||
unsigned long int *addrlen);
|
||||
int accept(int sockfd, struct mysockaddr *addr, unsigned long int *addrlen) {
|
||||
|
||||
if (!handle) { __get_handle(); }
|
||||
if (!o_accept) { o_accept = dlsym(handle, "accept"); }
|
||||
if (!running && sockfd == listen_fd) {
|
||||
|
||||
if (debug) fprintf(stderr, "DESOCK: intercepted accept on %d\n", sockfd);
|
||||
if (addr && addrlen) {
|
||||
|
||||
// we need to fill this!
|
||||
memset(addr, 0, *addrlen);
|
||||
addr->sin_family = 2; // AF_INET
|
||||
addr->sin_port = htons(1023); // Port 1023 in network byte order
|
||||
addr->sin_addr.s_addr = 0x0100007f;
|
||||
|
||||
}
|
||||
|
||||
running = true;
|
||||
return FUZZ_INPUT_FD;
|
||||
|
||||
}
|
||||
|
||||
return o_accept(sockfd, addr, addrlen);
|
||||
|
||||
}
|
||||
|
||||
int accept4(int sockfd, struct mysockaddr *addr, unsigned long int *addrlen,
|
||||
int flags) {
|
||||
|
||||
return accept(sockfd, addr, addrlen); // ignore flags
|
||||
|
||||
}
|
||||
|
||||
int (*o_listen)(int sockfd, int backlog);
|
||||
int listen(int sockfd, int backlog) {
|
||||
|
||||
if (!handle) { __get_handle(); }
|
||||
if (!o_listen) { o_listen = dlsym(handle, "listen"); }
|
||||
if (sockfd == listen_fd) {
|
||||
|
||||
if (debug) fprintf(stderr, "DESOCK: intercepted listen on %d\n", sockfd);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
return o_listen(sockfd, backlog);
|
||||
|
||||
}
|
||||
|
||||
int (*o_bind)(int sockfd, const struct mysockaddr *addr,
|
||||
unsigned long int addrlen);
|
||||
int bind(int sockfd, const struct mysockaddr *addr, unsigned long int addrlen) {
|
||||
|
||||
if (!handle) { __get_handle(); }
|
||||
if (!o_bind) { o_bind = dlsym(handle, "bind"); }
|
||||
if (addr->sin_port == htons(port)) {
|
||||
|
||||
if (debug) fprintf(stderr, "DESOCK: intercepted bind on %d\n", sockfd);
|
||||
listen_fd = sockfd;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
return o_bind(sockfd, addr, addrlen);
|
||||
|
||||
}
|
||||
|
||||
int (*o_setsockopt)(int sockfd, int level, int optname, const void *optval,
|
||||
unsigned long int optlen);
|
||||
int setsockopt(int sockfd, int level, int optname, const void *optval,
|
||||
unsigned long int optlen) {
|
||||
|
||||
if (!handle) { __get_handle(); }
|
||||
if (!o_setsockopt) { o_setsockopt = dlsym(handle, "setsockopt"); }
|
||||
if (listen_fd == sockfd) {
|
||||
|
||||
if (debug)
|
||||
fprintf(stderr, "DESOCK: intercepted setsockopt on %d for %d\n", sockfd,
|
||||
optname);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
return o_setsockopt(sockfd, level, optname, optval, optlen);
|
||||
|
||||
}
|
||||
|
||||
int (*o_getsockopt)(int sockfd, int level, int optname, void *optval,
|
||||
unsigned long int *optlen);
|
||||
int getsockopt(int sockfd, int level, int optname, void *optval,
|
||||
unsigned long int *optlen) {
|
||||
|
||||
if (!handle) { __get_handle(); }
|
||||
if (!o_getsockopt) { o_getsockopt = dlsym(handle, "getsockopt"); }
|
||||
if (listen_fd == sockfd) {
|
||||
|
||||
if (debug)
|
||||
fprintf(stderr, "DESOCK: intercepted getsockopt on %d for %d\n", sockfd,
|
||||
optname);
|
||||
int *o = (int *)optval;
|
||||
if (o != NULL) {
|
||||
|
||||
*o = 1; // let's hope this is fine
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
return o_getsockopt(sockfd, level, optname, optval, optlen);
|
||||
|
||||
}
|
||||
|
||||
int (*o_getpeername)(int sockfd, struct mysockaddr *addr,
|
||||
unsigned long int *addrlen);
|
||||
int getpeername(int sockfd, struct mysockaddr *addr,
|
||||
unsigned long int *addrlen) {
|
||||
|
||||
if (!handle) { __get_handle(); }
|
||||
if (!o_getpeername) { o_getpeername = dlsym(handle, "getpeername"); }
|
||||
if (port != -1 && sockfd == FUZZ_INPUT_FD) {
|
||||
|
||||
if (debug) fprintf(stderr, "DESOCK: getpeername\n");
|
||||
if (addr && addrlen) {
|
||||
|
||||
// we need to fill this!
|
||||
memset(addr, 0, *addrlen);
|
||||
addr->sin_family = 2; // AF_INET
|
||||
addr->sin_port = htons(1023); // Port 1023 in network byte order
|
||||
addr->sin_addr.s_addr = 0x0100007f;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
return o_getpeername(sockfd, addr, addrlen);
|
||||
|
||||
}
|
||||
|
||||
int (*o_getsockname)(int sockfd, struct mysockaddr *addr,
|
||||
unsigned long int *addrlen);
|
||||
int getsockname(int sockfd, struct mysockaddr *addr,
|
||||
unsigned long int *addrlen) {
|
||||
|
||||
if (!handle) { __get_handle(); }
|
||||
if (!o_getsockname) { o_getsockname = dlsym(handle, "getsockname"); }
|
||||
if (port != -1 && sockfd == FUZZ_INPUT_FD) {
|
||||
|
||||
if (debug) fprintf(stderr, "DESOCK: getsockname\n");
|
||||
if (addr && addrlen) {
|
||||
|
||||
// we need to fill this!
|
||||
memset(addr, 0, *addrlen);
|
||||
addr->sin_family = 2; // AF_INET
|
||||
addr->sin_port = htons(port);
|
||||
addr->sin_addr.s_addr = 0x0100007f;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
return o_getsockname(sockfd, addr, addrlen);
|
||||
|
||||
}
|
||||
|
||||
static FILE *(*o_fdopen)(int fd, const char *mode);
|
||||
FILE *fdopen(int fd, const char *mode) {
|
||||
|
||||
if (!o_fdopen) {
|
||||
|
||||
if (!handle) { __get_handle(); }
|
||||
|
||||
o_fdopen = dlsym(handle, "fdopen");
|
||||
if (!o_fdopen) {
|
||||
|
||||
fprintf(stderr, "%s(): can not find fdopen\n", dlerror());
|
||||
exit(-1);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (fd == FUZZ_INPUT_FD && strcmp(mode, "r") != 0) {
|
||||
|
||||
if (debug) fprintf(stderr, "DESOCK: intercepted fdopen(r+) for %d\n", fd);
|
||||
return o_fdopen(fd, "r");
|
||||
|
||||
}
|
||||
|
||||
return o_fdopen(fd, mode);
|
||||
|
||||
}
|
||||
|
||||
/* TARGET SPECIFIC HOOKS - put extra needed code for your target here */
|
||||
|
Reference in New Issue
Block a user