Fuzzing ARM library by AFL++ 

Last article, I made a brief introduction how to fuzz an static linked ARM ELF.

https://qiita.com/menghan_chen1986/items/60018f449620553b3747

This time, I will make a simple demonstration how to fuzz a library.

:::note info
Environment
:::
Ubuntu 20.04
AFLPlusPlus(AFL++)
build-essentials
arm-linux-gnueabi-gcc
aarch64-linux-gnu-gcc
docker

:::note info
Sample C code to fuzz
:::

```c overflow.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define ERROR -1

// Function to read a file into a buffer
int read_file_to_buffer(const char *filename, char **buffer, size_t *size) {
    FILE *file = fopen(filename, "rb");
    if (!file) {
        perror("Error opening file");
        return ERROR;
    }

    // Move to the end of the file to get its size
    fseek(file, 0, SEEK_END);
    *size = ftell(file);
    fseek(file, 0, SEEK_SET);

    // Allocate memory for the buffer
    *buffer = (char *)malloc(*size);
    if (!*buffer) {
        perror("Memory allocation failed");
        fclose(file);
        return ERROR;
    }

    // Read the file into the buffer
    size_t bytes_read = fread(*buffer, 1, *size, file);
    if (bytes_read != *size) {
        perror("Error reading file");
        free(*buffer);
        fclose(file);
        return ERROR;
    }

    // Close the file
    fclose(file);
    return 0;
}

// vulnerable function
void vuln_func(char *input) {
    char buffer[64];
    // Vulnerability: Unchecked strcpy can cause buffer overflow
    strcpy(buffer, input);
    printf("Buffer: %s\n", buffer);
}

```
main.c is a harness which opens seeds file and read it as mutation.

```c main.c
#include <stdio.h>
#include <stdlib.h>
#include "overflow.h"

int main(int argc, char *argv[]) {
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
        return EXIT_FAILURE;
    }

    const char *filename = argv[1];
    char *buffer;
    size_t size;

    // Read the file into the buffer
    if (read_file_to_buffer(filename, &buffer, &size) != 0) {
        return EXIT_FAILURE;
    }

    // Use the buffer (for demonstration, we'll just print its size)
    printf("File size: %zu bytes\n", size);

    // Free the allocated buffer
    vuln_func(buffer);
    free(buffer);

    return EXIT_SUCCESS;
}

```

```c overflow.h
// overflow.h
#ifndef OVERFLOW_H
#define OVERFLOW_H

// Declare the vulnerable function
void vuln_func(char *input);
int read_file_to_buffer(const char *filename, char **buffer, size_t *size);

#endif // OVERFLOW_H
```

Makefile

```shell Makefile
CC=arm-linux-gnueabi-gcc
CFLAGS=-fPIC -Wall

all: liboverflow.so main

liboverflow.so: overflow.c
        $(CC) $(CFLAGS) -shared -o liboverflow.so overflow.c

main: main.c liboverflow.so
        $(CC) main.c -L. -loverflow -o main

clean:
        rm -f *.o *.so main
```

After running make, we can obtain main (executable) and liboverflow.so. Same as last article, we need startup Docker, pull image and then run ./build_qemu_support.sh to let alf-qemu-trace support arm.
Then, create a seeds file by running, for example

```shell
# echo "hello world!" > seeds2/test.txt
```

Final, let's start fuzzing. Note, LD_LIBRARY_PATH is set to tell where all so libraries necessary to main is. 
"-- afl-qemu-trace -L /usr/arm-linux-gnueabi" tells where interpreter is, otherwise you will get error as below.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3672531/0dc7fb0c-2ec1-2474-9c68-277d28f4a793.png)

```shell
LD_LIBRARY_PATH=/home/chen/AFLPlusPlus/test2 afl-fuzz -U -i seeds2/ -o output/ -- afl-qemu-trace -L /usr/arm-linux-gnueabi ./main @@
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3672531/4bb6ced2-1ed2-61cd-821e-cf8e9e02482c.png)

Soon, we can get a crash by checking output. Obviously, SIGABRT is received by main process because of stack overflow.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3672531/aaaa426a-585e-5676-5b67-c5cd819570c0.png)