Тренинг по afl

Нашел репо, который подкидывает отличные задачки для старта в фаззинге. Подразумевается, что у тебя в системе уже есть afl.

В репо во многих командах встречается вызов afl-clang-fast. В стандартной поставке afl, при сборке его с git’а этого бинарника не создается. Можно просто сделать на него симлинк. Все равно afl-clang это симлинк на afl-gcc. Тогда все будет работать как положено.

https://github.com/mykter/afl-training

Репо состоит из нескольких секций.

QuickStart — содержит базовое окружение. Просто чтобы запустить хоть что-то и увидеть, что оно «работает». Получить от этого вдохновение и продолжить дальше.

Harness — задачка по сложнее. Необходимо профаззить 2 функции:

// an 'nprintf' implementation - print the first len bytes of data
void lib_echo(char *data, ssize_t len);

// optimised multiply - returns x*y
int lib_mul(int x, int y);

Далее предлагается самостоятельно дописать программу-прокладку.

  1. Read a filename from argv
  2. Open the specified file and read its contents into a buffer.
  3. Pass that buffer to the target function.

Сообразим программу:

#include <unistd.h>
#include <string.h>
#include <stdio.h>

#include "library.h"

// fixed size buffer based on assumptions about the maximum size that is likely necessary to exercise all aspects of the target function
#define SIZE 100

int main(int argc, char* argv[]) {
	if(argc == 2) {
	FILE *fp;
	char *filename;
	char *buffer = NULL;
	ssize_t length=0;
	filename = argv[1];

	fp = fopen(filename, "r");
	
		if (fp) {
			fseek(fp, 0, SEEK_END); /* Go to end of file */
			length = ftell(fp); /* How many bytes did we pass ? */

			/* Set position of stream to the beginning */
			rewind(fp);

			/* Allocate the buffer (no need to initialize it with calloc) */
			buffer = malloc((length + 1) * sizeof(*buffer)); /* size + 1 byte for the \0 */


			/* Read the file into the buffer */
			fread(buffer, length, 1, fp); /* Read 1 chunk of size bytes from fp into buffer */

			/* NULL-terminate the buffer */
			buffer[length] = '\0';


			lib_echo(buffer, length);


		} else {
			printf("Failed to open the file\n");
		}

	}
}

Соберем командой:

AFL_HARDEN=1 afl-clang harness.c library.c -o harness

Запустим командой:

afl-fuzz -i in -o out ./harness @@

Найден краш. Далее можно развить тему и подобрать необходимый шеллкод и пр. вещи.