aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvanhauser-thc <vh@thc.org>2024-06-28 16:00:19 +0200
committervanhauser-thc <vh@thc.org>2024-06-28 16:00:19 +0200
commitf7bbd467b53d0ee7c3ca366750ed1fa60972981c (patch)
tree4d88faf7537e51aab48496f916fcf93fd0cb576d
parent8993ba430545b867da11e119be15126de43d061c (diff)
downloadafl++-f7bbd467b53d0ee7c3ca366750ed1fa60972981c.tar.gz
add custom_send_tcp
-rw-r--r--custom_mutators/custom_send_tcp/Makefile7
-rw-r--r--custom_mutators/custom_send_tcp/README.md13
-rw-r--r--custom_mutators/custom_send_tcp/custom_send_tcp.c113
-rw-r--r--docs/Changelog.md2
4 files changed, 135 insertions, 0 deletions
diff --git a/custom_mutators/custom_send_tcp/Makefile b/custom_mutators/custom_send_tcp/Makefile
new file mode 100644
index 00000000..8549ccad
--- /dev/null
+++ b/custom_mutators/custom_send_tcp/Makefile
@@ -0,0 +1,7 @@
+all: custom_send_tcp.so
+
+custom_send_tcp.so:
+ $(CC) -Wno-unused-result -g -O3 -shared -fPIC -o custom_send_tcp.so -I../../include custom_send_tcp.c
+
+clean:
+ rm -f custom_send_tcp.so *.o *~ core
diff --git a/custom_mutators/custom_send_tcp/README.md b/custom_mutators/custom_send_tcp/README.md
new file mode 100644
index 00000000..7b4bb869
--- /dev/null
+++ b/custom_mutators/custom_send_tcp/README.md
@@ -0,0 +1,13 @@
+# Send testcases via TCP custom mutator
+
+This custom mutator sends the fuzzing testcases via TCP.
+
+`AFL_CUSTOM_MUTATOR_LATE_SEND` - MUST be set!
+`CUSTOM_SEND_IP` - the IP address to send to (basically only 127.0.0.1 makes sense)
+`CUSTOM_SEND_PORT` - the TCP port to send to
+`CUSTOM_SEND_READ` - if the custom mutator should wait for a reply from the target
+
+Example:
+```
+CUSTOM_SEND_IP=127.0.0.1 CUSTOM_SEND_PORT=8000 CUSTOM_SEND_READ=1 AFL_CUSTOM_MUTATOR_LATE_SEND=1 AFL_CUSTOM_MUTATOR_LIBRARY=custom_send_tcp.so ./afl-fuzz ...
+```
diff --git a/custom_mutators/custom_send_tcp/custom_send_tcp.c b/custom_mutators/custom_send_tcp/custom_send_tcp.c
new file mode 100644
index 00000000..53689ced
--- /dev/null
+++ b/custom_mutators/custom_send_tcp/custom_send_tcp.c
@@ -0,0 +1,113 @@
+#include <time.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <arpa/inet.h>
+#include <sys/select.h>
+
+#include "afl-fuzz.h"
+
+static int my_debug = 0;
+static int my_read = 0;
+
+#define DEBUG(...) if (my_debug) printf(__VA_ARGS__)
+
+typedef struct tcp_send_mutator {
+ afl_state_t* afl;
+ struct sockaddr_in server_addr;
+} tcp_send_mutator_t;
+
+void *afl_custom_init(afl_state_t* afl, uint32_t seed) {
+ const char* ip = getenv("CUSTOM_SEND_IP");
+ const char* port = getenv("CUSTOM_SEND_PORT");
+
+ if (getenv("AFL_DEBUG")) my_debug = 1;
+ if (getenv("CUSTOM_SEND_READ")) my_read = 1;
+
+ if (!ip || !port) {
+ fprintf(stderr, "You forgot to set CUSTOM_SEND_IP and/or CUSTOM_SEND_PORT\n");
+ exit(1);
+ }
+
+ tcp_send_mutator_t* mutator = calloc(1, sizeof(tcp_send_mutator_t));
+ if (!mutator) {
+ fprintf(stderr, "Failed to allocate mutator struct\n");
+ exit(1);
+ }
+
+ mutator->afl = afl;
+
+ bzero(&mutator->server_addr, sizeof(mutator->server_addr));
+ mutator->server_addr.sin_family = AF_INET;
+ if (inet_pton(AF_INET, ip, &mutator->server_addr.sin_addr) <= 0) {
+ fprintf(stderr, "Could not convert target ip address!\n");
+ exit(1);
+ }
+ mutator->server_addr.sin_port = htons(atoi(port));
+
+ printf("[+] Custom tcp send mutator setup ready to go!\n");
+
+ return mutator;
+}
+
+int try_connect(tcp_send_mutator_t *mutator, int sock, int max_attempts) {
+ while (max_attempts > 0) {
+ if (connect(sock, (struct sockaddr*)&mutator->server_addr, sizeof(mutator->server_addr)) == 0) {
+ return 0;
+ }
+
+ // Even with AFL_CUSTOM_LATE_SEND=1, there is a race between the
+ // application under test having started to listen for connections and
+ // afl_custom_fuzz_send being called. To address this race, we attempt
+ // to connect N times and sleep a short period of time in between
+ // connection attempts.
+ struct timespec t;
+ t.tv_sec = 0;
+ t.tv_nsec = 100;
+ nanosleep(&t, NULL);
+ --max_attempts;
+ }
+ return 1;
+}
+
+void afl_custom_fuzz_send(tcp_send_mutator_t *mutator, uint8_t *buf, size_t buf_size) {
+ int sock = socket(AF_INET, SOCK_STREAM, 0);
+
+ int written = 0;
+ if (sock >= 0 && try_connect(mutator, sock, 10000) == 0) {
+ DEBUG("connected, write()\n");
+ written = write(sock, buf, buf_size);
+ } else {
+ DEBUG("socket() or connect() error: %d\n", errno);
+ }
+
+ if (written < 0) {
+ DEBUG("write() error: %d\n", errno);
+ } else if (my_read) {
+ struct timeval timeout;
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+
+ fd_set set;
+ FD_ZERO(&set);
+ FD_SET(sock, &set);
+
+ int select_res = select(sock + 1, &set, NULL, NULL, &timeout);
+ if (select_res == -1) {
+ DEBUG("select() error: %d\n", errno);
+ } else if (select_res == 0) {
+ DEBUG("read() timeout!\n");
+ } else {
+ uint8_t buf[64];
+ (void)read(sock, buf, sizeof(buf));
+ }
+ }
+
+ close(sock);
+}
+
+void afl_custom_deinit(tcp_send_mutator_t* mutator) {
+ free(mutator);
+}
diff --git a/docs/Changelog.md b/docs/Changelog.md
index c16214e4..0212fd61 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -18,6 +18,8 @@
a function entry
- AFL_DEBUG is now the same as AFL_FRIDA_VERBOSE
- AFL_FRIDA_DEBUG_MAPS now works as expected
+ - custom mutators:
+ - custom_send_tcp custom mutator added, thanks to @dergoegge
### Version ++4.21c (release)