about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMaik Betka <9078425+voidptr127@users.noreply.github.com>2023-04-17 17:09:48 +0200
committerMaik Betka <9078425+voidptr127@users.noreply.github.com>2023-04-17 17:09:48 +0200
commit70e30958649f44e104330431cde31e80fbd8557f (patch)
tree40a57d9258695447174947b399a8f9adc70d16ef
parent413e68ab6d588b12976c5ff34e1a27eae48c26d8 (diff)
downloadafl++-70e30958649f44e104330431cde31e80fbd8557f.tar.gz
added first dummy atnwalk.c file
-rw-r--r--custom_mutators/atnwalk/atnwalk.c173
1 files changed, 173 insertions, 0 deletions
diff --git a/custom_mutators/atnwalk/atnwalk.c b/custom_mutators/atnwalk/atnwalk.c
new file mode 100644
index 00000000..483ae542
--- /dev/null
+++ b/custom_mutators/atnwalk/atnwalk.c
@@ -0,0 +1,173 @@
+#include "../../include/afl-fuzz.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+
+#define INIT_BUF_SIZE 4096
+#define SOCKET_NAME "/tmp/atnwalk.socket"
+
+// handshake constants
+const uint8_t SERVER_ARE_YOU_ALIVE = 42;
+const uint8_t SERVER_YES_I_AM_ALIVE = 213;
+
+// control bits
+const uint8_t SERVER_DECODE_BIT = 0b00000001;
+const uint8_t SERVER_ENCODE_BIT = 0b00000010;
+const uint8_t SERVER_MUTATE_BIT = 0b00000100;
+const uint8_t SERVER_CROSSOVER_BIT = 0b00001000;
+
+
+typedef struct atnwalk_mutator {
+    uint8_t *decoded_buf;
+    size_t decoded_size;
+} atnwalk_mutator_t;
+
+
+int read_all(int fd, uint8_t *buf, size_t buf_size) {
+    int n;
+    size_t offset = 0;
+    while (offset < buf_size) {
+        n = read(fd, buf + offset, buf_size - offset);
+        if (n == -1) {
+            return 0;
+        }
+        offset += n;
+    }
+    return 1;
+}
+
+
+int write_all(int fd, uint8_t *buf, size_t buf_size) {
+    int n;
+    size_t offset = 0;
+    while (offset < buf_size) {
+        n = write(fd, buf + offset, buf_size - offset);
+        if (n == -1) {
+            return 0;
+        }
+        offset += n;
+    }
+    return 1;
+}
+
+
+/**
+ * Initialize this custom mutator
+ *
+ * @param[in] afl a pointer to the internal state object. Can be ignored for
+ * now.
+ * @param[in] seed A seed for this mutator - the same seed should always mutate
+ * in the same way.
+ * @return Pointer to the data object this custom mutator instance should use.
+ *         There may be multiple instances of this mutator in one afl-fuzz run!
+ *         Return NULL on error.
+ */
+atnwalk_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
+    srand(seed);
+    atnwalk_mutator_t *data = (atnwalk_mutator_t *) malloc(sizeof(atnwalk_mutator_t));
+    if (!data) {
+        perror("afl_custom_init alloc");
+        return NULL;
+    }
+    data->decoded_buf = (uint8_t *) malloc(INIT_BUF_SIZE);
+    data->decoded_size = INIT_BUF_SIZE;
+    return data;
+}
+
+// TODO: implement
+/**
+ * Perform custom mutations on a given input
+ *
+ * (Optional for now. Required in the future)
+ *
+ * @param[in] data pointer returned in afl_custom_init for this fuzz case
+ * @param[in] buf Pointer to input data to be mutated
+ * @param[in] buf_size Size of input data
+ * @param[out] out_buf the buffer we will work on. we can reuse *buf. NULL on
+ * error.
+ * @param[in] add_buf Buffer containing the additional test case
+ * @param[in] add_buf_size Size of the additional test case
+ * @param[in] max_size Maximum size of the mutated output. The mutation must not
+ *     produce data larger than max_size.
+ * @return Size of the mutated output.
+ */
+size_t afl_custom_fuzz(atnwalk_mutator_t *data, uint8_t *buf, size_t buf_size, uint8_t **out_buf,
+                       uint8_t *add_buf, size_t add_buf_size, size_t max_size) {
+    struct sockaddr_un addr;
+    int fd_socket;
+    ssize_t n;
+    uint8_t buffer[5];
+
+    // initialize the socket
+    fd_socket = socket(AF_UNIX, SOCK_STREAM, 0);
+    if (fd_socket == -1) {
+        perror("socket");
+        *out_buf = NULL;
+        return 0;
+    }
+    memset(&addr, 0, sizeof(addr));
+    addr.sun_family = AF_UNIX;
+    strncpy(addr.sun_path, SOCKET_NAME, sizeof(addr.sun_path) - 1);
+    if (connect(fd_socket, (const struct sockaddr *) &addr, sizeof(addr)) == -1) {
+        perror("atnwalk server is down");
+        *out_buf = NULL;
+        return 0;
+    }
+
+    if (!write_all(fd_socket, buffer, 5)) {
+        perror("write to atnwalk server failed");
+        *out_buf = NULL;
+        return 0;
+    }
+
+    if (read_all(fd_socket, buffer, 5)) {
+        perror("read to atnwalk server failed");
+        exit(EXIT_FAILURE);
+    }
+
+    close(fd_socket);
+}
+
+// TODO: implement
+/**
+ * A post-processing function to use right before AFL writes the test case to
+ * disk in order to execute the target.
+ *
+ * (Optional) If this functionality is not needed, simply don't define this
+ * function.
+ *
+ * @param[in] data pointer returned in afl_custom_init for this fuzz case
+ * @param[in] buf Buffer containing the test case to be executed
+ * @param[in] buf_size Size of the test case
+ * @param[out] out_buf Pointer to the buffer containing the test case after
+ *     processing. External library should allocate memory for out_buf.
+ *     The buf pointer may be reused (up to the given buf_size);
+ * @return Size of the output buffer after processing or the needed amount.
+ *     A return of 0 indicates an error.
+ */
+size_t afl_custom_post_process(atnwalk_mutator_t *data, uint8_t *buf, size_t buf_size, uint8_t **out_buf) {
+    data->decoded_buf[0] = 'p';
+    data->decoded_buf[1] = 'u';
+    data->decoded_buf[2] = 't';
+    data->decoded_buf[3] = 's';
+    data->decoded_buf[4] = ' ';
+    data->decoded_buf[5] = ';';
+    data->decoded_buf[6] = '\n';
+    return 7;
+}
+
+// TODO: implement
+/**
+ * Deinitialize everything
+ *
+ * @param data The data ptr from afl_custom_init
+ */
+void afl_custom_deinit(atnwalk_mutator_t *data) {
+    free(data->decoded_buf);
+    free(data);
+}