Network applications are hard to fuzz with traditional fuzzers because they a) expect their input over network connections, and b) process multiple inputs (multiple packets) in a single run.
libdesock solves this problem by a) redirecting network I/O to stdin and stdout, and b) treating an input as a sequence of chunks that get individually fed to the application.
It functions as a library that when preloaded with LD_PRELOAD
replaces the network stack of the
libc with its own stack that emulates all network operations in user-space.
This has multiple advantages for fuzzing:
- It reduces the syscalls of the target
- It automatically synchronizes multi-threaded programs
- No extra harnessing is needed to get the fuzz input to the application
libdesock also let's you customize what happens when an application requests data over a network connection.
The default behavior is to read from stdin but this can be changed inside the "input hook" (see src/hooks.c
).
Prepend
LD_PRELOAD=libdesock.so
to the invocation of any network application or set the environment variable
AFL_PRELOAD=libdesock.so
when using AFL++.
Here is an example how to desock nginx:
Libdesock uses meson
as its build system.
meson setup ./build
cd ./build
You can configure the build using
meson configure -D <optname>=<optvalue>
You can get an overview over all options with
meson configure
The following options are specific to libdesock:
Option | Description | Default |
---|---|---|
arch |
The CPU architecture for which you are compiling libdesock.so | x86_64 |
multiple_requests |
If this is true, a delimiter will be used to return different data from subsequent read calls | false |
request_delimiter |
The delimiter that separates multiple requests | -=^..^=- |
desock_client |
If this is true, calls to connect() get hooked. This enables the desocketing of clients |
false |
desock_server |
If this is true, calls to bind() get hooked. This enables the desocketing of servers |
true |
allow_dup_stdin |
If this is true, calls to dup*() are allowed for stdin. This enables stdin redirection when running under gdb |
false |
debug_desock |
If this is true, calls to functions in libdesock.so get logged to stderr | false |
fd_table_size |
Only fds < fd_table_size can be desocketed |
128 |
interpreter |
Path to ld.so (will be determined dynamically if not set) | |
symbol_version |
If this is set, every exported symbol has this version | |
max_conns |
The number of simulatenous connections that can be desocketed. A value other than 1 doesn't make sense at the moment | 1 |
If configuration is done compile with
meson compile
This creates a shared library build/libdesock.so
and a static library build/libdesock.a
.
If you are using libdesock and AFL++ for fuzzing, the programs under test usually require a special setup to work with AFL++. Check out our examples directory for some examples on how to setup network applications for fuzzing.
Additionally, you can also read up on how libdesock was used to fuzz...
- TCP servers using libuv cannot be desocketed (yet). Desocketing of libuv currently only works with UDP servers. It only takes a small change to fix this though, if you need this, create an issue.
ioctl()
is not supported. Make sure your target does not rely onioctl
requests